patches/sdl-pango-01-api-adds.diff
author jurikm
Sun, 12 Feb 2012 14:04:10 +0000
changeset 8245 383896da4129
parent 408 fe755932607a
permissions -rw-r--r--
SFEsauerbraten.spec: add IPS package name

# --- SDE-COPYRIGHT-NOTE-BEGIN ---
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
# 
# Filename: package/.../sdlpango/SDL_Pango_0.1.2-API-adds.patch
# Copyright (C) 2006 The OpenSDE Project
# 
# More information can be found in the files COPYING and README.
# 
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
# --- SDE-COPYRIGHT-NOTE-END ---

--- SDL_Pango-0.1.2/src/SDL_Pango.h.original	2006-12-13 15:36:50.000000000 +0100
+++ SDL_Pango-0.1.2/src/SDL_Pango.h	2006-12-13 16:16:07.000000000 +0100
@@ -1,205 +1,219 @@
-/*  SDL_Pango.h -- A companion library to SDL for working with Pango.
-    Copyright (C) 2004 NAKAMURA Ken'ichi
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
-*/
-
-/*! @file
-    @brief Header file of SDL_Pango
-
-    @author NAKAMURA Ken'ichi
-    @date   2004/08/26
-    $Revision: 1.3 $
-*/
-
-#ifndef SDL_PANGO_H
-#define SDL_PANGO_H
-
-#include "SDL.h"
-
-#include "begin_code.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-typedef struct _contextImpl SDLPango_Context;
-
-/*!
-    General 4 X 4 matrix struct.
-*/
-typedef struct _SDLPango_Matrix {
-    Uint8 m[4][4];  /*! Matrix variables */
-} SDLPango_Matrix;
-
-const SDLPango_Matrix _MATRIX_WHITE_BACK
-    = {255, 0, 0, 0,
-       255, 0, 0, 0,
-       255, 0, 0, 0,
-       255, 255, 0, 0,};
-
-/*!
-    Specifies white back and black letter.
-*/
-const SDLPango_Matrix *MATRIX_WHITE_BACK = &_MATRIX_WHITE_BACK;
-
-const SDLPango_Matrix _MATRIX_BLACK_BACK
-    = {0, 255, 0, 0,
-       0, 255, 0, 0,
-       0, 255, 0, 0,
-       255, 255, 0, 0,};
-/*!
-    Specifies black back and white letter.
-*/
-const SDLPango_Matrix *MATRIX_BLACK_BACK = &_MATRIX_BLACK_BACK;
-
-const SDLPango_Matrix _MATRIX_TRANSPARENT_BACK_BLACK_LETTER
-    = {0, 0, 0, 0,
-       0, 0, 0, 0,
-       0, 0, 0, 0,
-       0, 255, 0, 0,};
-/*!
-    Specifies transparent back and black letter.
-*/
-const SDLPango_Matrix *MATRIX_TRANSPARENT_BACK_BLACK_LETTER = &_MATRIX_TRANSPARENT_BACK_BLACK_LETTER;
-
-const SDLPango_Matrix _MATRIX_TRANSPARENT_BACK_WHITE_LETTER
-    = {255, 255, 0, 0,
-       255, 255, 0, 0,
-       255, 255, 0, 0,
-       0, 255, 0, 0,};
-/*!
-    Specifies transparent back and white letter.
-*/
-const SDLPango_Matrix *MATRIX_TRANSPARENT_BACK_WHITE_LETTER = &_MATRIX_TRANSPARENT_BACK_WHITE_LETTER;
-
-const SDLPango_Matrix _MATRIX_TRANSPARENT_BACK_TRANSPARENT_LETTER
-    = {255, 255, 0, 0,
-       255, 255, 0, 0,
-       255, 255, 0, 0,
-       0, 0, 0, 0,};
-/*!
-    Specifies transparent back and transparent letter.
-    This is useful for KARAOKE like rendering.
-*/
-const SDLPango_Matrix *MATRIX_TRANSPARENT_BACK_TRANSPARENT_LETTER = &_MATRIX_TRANSPARENT_BACK_TRANSPARENT_LETTER;
-
-/*!
-    Specifies direction of text. See Pango reference for detail
-*/
-typedef enum {
-    SDLPANGO_DIRECTION_LTR, /*! Left to right */
-    SDLPANGO_DIRECTION_RTL, /*! Right to left */
-    SDLPANGO_DIRECTION_WEAK_LTR,    /*! Left to right (weak) */
-    SDLPANGO_DIRECTION_WEAK_RTL,    /*! Right to left (weak) */
-    SDLPANGO_DIRECTION_NEUTRAL	/*! Neutral */
-} SDLPango_Direction;
-
-
-
-extern DECLSPEC int SDLCALL SDLPango_Init();
-
-extern DECLSPEC int SDLCALL SDLPango_WasInit();
-
-extern DECLSPEC SDLPango_Context* SDLCALL SDLPango_CreateContext();
-
-extern DECLSPEC void SDLCALL SDLPango_FreeContext(
-    SDLPango_Context *context);
-
-extern DECLSPEC void SDLCALL SDLPango_SetSurfaceCreateArgs(
-    SDLPango_Context *context,
-    Uint32 flags,
-    int depth,
-    Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
-
-extern DECLSPEC SDL_Surface * SDLCALL SDLPango_CreateSurfaceDraw(
-    SDLPango_Context *context);
-
-extern DECLSPEC void SDLCALL SDLPango_Draw(
-    SDLPango_Context *context,
-    SDL_Surface *surface,
-    int x, int y);
-
-extern DECLSPEC void SDLCALL SDLPango_SetDpi(
-    SDLPango_Context *context,
-    double dpi_x, double dpi_y);
-
-extern DECLSPEC void SDLCALL SDLPango_SetMinimumSize(
-    SDLPango_Context *context,
-    int width, int height);
-
-extern DECLSPEC void SDLCALL SDLPango_SetDefaultColor(
-    SDLPango_Context *context,
-    const SDLPango_Matrix *color_matrix);
-
-extern DECLSPEC int SDLCALL SDLPango_GetLayoutWidth(
-    SDLPango_Context *context);
-
-extern DECLSPEC int SDLCALL SDLPango_GetLayoutHeight(
-    SDLPango_Context *context);
-
-extern DECLSPEC void SDLCALL SDLPango_SetMarkup(
-    SDLPango_Context *context,
-    const char *markup,
-    int length);
-
-extern DECLSPEC void SDLCALL SDLPango_SetText(
-    SDLPango_Context *context,
-    const char *markup,
-    int length);
-
-extern DECLSPEC void SDLCALL SDLPango_SetLanguage(
-    SDLPango_Context *context,
-    const char *language_tag);
-
-extern DECLSPEC void SDLCALL SDLPango_SetBaseDirection(
-    SDLPango_Context *context,
-    SDLPango_Direction direction);
-
-
-#ifdef __FT2_BUILD_UNIX_H__
-
-extern DECLSPEC void SDLCALL SDLPango_CopyFTBitmapToSurface(
-    const FT_Bitmap *bitmap,
-    SDL_Surface *surface,
-    const SDLPango_Matrix *matrix,
-    SDL_Rect *rect);
-
-#endif	/* __FT2_BUILD_UNIX_H__ */
-
-
-#ifdef __PANGO_H__
-
-extern DECLSPEC PangoFontMap* SDLCALL SDLPango_GetPangoFontMap(
-    SDLPango_Context *context);
-
-extern DECLSPEC PangoFontDescription* SDLCALL SDLPango_GetPangoFontDescription(
-    SDLPango_Context *context);
-
-extern DECLSPEC PangoLayout* SDLCALL SDLPango_GetPangoLayout(
-    SDLPango_Context *context);
-
-#endif /* __PANGO_H__ */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#include "close_code.h"
-
-#endif	/* SDL_PANGO_H */
+/*  SDL_Pango.h -- A companion library to SDL for working with Pango.
+    Copyright (C) 2004 NAKAMURA Ken'ichi
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+*/
+
+/*! @file
+    @brief Header file of SDL_Pango
+
+    @author NAKAMURA Ken'ichi
+    @date   2004/08/26
+    $Revision: 1.3 $
+*/
+
+#ifndef SDL_PANGO_H
+#define SDL_PANGO_H
+
+#include "SDL.h"
+
+#include "begin_code.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+typedef struct _contextImpl SDLPango_Context;
+
+/*!
+    General 4 X 4 matrix struct.
+*/
+typedef struct _SDLPango_Matrix {
+    Uint8 m[4][4];  /*! Matrix variables */
+} SDLPango_Matrix;
+
+const SDLPango_Matrix _MATRIX_WHITE_BACK
+    = {255, 0, 0, 0,
+       255, 0, 0, 0,
+       255, 0, 0, 0,
+       255, 255, 0, 0,};
+
+/*!
+    Specifies white back and black letter.
+*/
+const SDLPango_Matrix *MATRIX_WHITE_BACK = &_MATRIX_WHITE_BACK;
+
+const SDLPango_Matrix _MATRIX_BLACK_BACK
+    = {0, 255, 0, 0,
+       0, 255, 0, 0,
+       0, 255, 0, 0,
+       255, 255, 0, 0,};
+/*!
+    Specifies black back and white letter.
+*/
+const SDLPango_Matrix *MATRIX_BLACK_BACK = &_MATRIX_BLACK_BACK;
+
+const SDLPango_Matrix _MATRIX_TRANSPARENT_BACK_BLACK_LETTER
+    = {0, 0, 0, 0,
+       0, 0, 0, 0,
+       0, 0, 0, 0,
+       0, 255, 0, 0,};
+/*!
+    Specifies transparent back and black letter.
+*/
+const SDLPango_Matrix *MATRIX_TRANSPARENT_BACK_BLACK_LETTER = &_MATRIX_TRANSPARENT_BACK_BLACK_LETTER;
+
+const SDLPango_Matrix _MATRIX_TRANSPARENT_BACK_WHITE_LETTER
+    = {255, 255, 0, 0,
+       255, 255, 0, 0,
+       255, 255, 0, 0,
+       0, 255, 0, 0,};
+/*!
+    Specifies transparent back and white letter.
+*/
+const SDLPango_Matrix *MATRIX_TRANSPARENT_BACK_WHITE_LETTER = &_MATRIX_TRANSPARENT_BACK_WHITE_LETTER;
+
+const SDLPango_Matrix _MATRIX_TRANSPARENT_BACK_TRANSPARENT_LETTER
+    = {255, 255, 0, 0,
+       255, 255, 0, 0,
+       255, 255, 0, 0,
+       0, 0, 0, 0,};
+/*!
+    Specifies transparent back and transparent letter.
+    This is useful for KARAOKE like rendering.
+*/
+const SDLPango_Matrix *MATRIX_TRANSPARENT_BACK_TRANSPARENT_LETTER = &_MATRIX_TRANSPARENT_BACK_TRANSPARENT_LETTER;
+
+/*!
+    Specifies direction of text. See Pango reference for detail
+*/
+typedef enum {
+    SDLPANGO_DIRECTION_LTR, /*! Left to right */
+    SDLPANGO_DIRECTION_RTL, /*! Right to left */
+    SDLPANGO_DIRECTION_WEAK_LTR,    /*! Left to right (weak) */
+    SDLPANGO_DIRECTION_WEAK_RTL,    /*! Right to left (weak) */
+    SDLPANGO_DIRECTION_NEUTRAL	/*! Neutral */
+} SDLPango_Direction;
+
+/*!
+    Specifies alignment of text. See Pango reference for detail
+*/
+typedef enum {
+    SDLPANGO_ALIGN_LEFT,
+    SDLPANGO_ALIGN_CENTER,
+    SDLPANGO_ALIGN_RIGHT
+} SDLPango_Alignment;
+
+extern DECLSPEC int SDLCALL SDLPango_Init();
+
+extern DECLSPEC int SDLCALL SDLPango_WasInit();
+
+extern DECLSPEC SDLPango_Context* SDLCALL SDLPango_CreateContext_GivenFontDesc(const char* font_desc);
+extern DECLSPEC SDLPango_Context* SDLCALL SDLPango_CreateContext();
+
+extern DECLSPEC void SDLCALL SDLPango_FreeContext(
+    SDLPango_Context *context);
+
+extern DECLSPEC void SDLCALL SDLPango_SetSurfaceCreateArgs(
+    SDLPango_Context *context,
+    Uint32 flags,
+    int depth,
+    Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
+
+extern DECLSPEC SDL_Surface * SDLCALL SDLPango_CreateSurfaceDraw(
+    SDLPango_Context *context);
+
+extern DECLSPEC void SDLCALL SDLPango_Draw(
+    SDLPango_Context *context,
+    SDL_Surface *surface,
+    int x, int y);
+
+extern DECLSPEC void SDLCALL SDLPango_SetDpi(
+    SDLPango_Context *context,
+    double dpi_x, double dpi_y);
+
+extern DECLSPEC void SDLCALL SDLPango_SetMinimumSize(
+    SDLPango_Context *context,
+    int width, int height);
+
+extern DECLSPEC void SDLCALL SDLPango_SetDefaultColor(
+    SDLPango_Context *context,
+    const SDLPango_Matrix *color_matrix);
+
+extern DECLSPEC int SDLCALL SDLPango_GetLayoutWidth(
+    SDLPango_Context *context);
+
+extern DECLSPEC int SDLCALL SDLPango_GetLayoutHeight(
+    SDLPango_Context *context);
+
+extern DECLSPEC void SDLCALL SDLPango_SetMarkup(
+    SDLPango_Context *context,
+    const char *markup,
+    int length);
+
+extern DECLSPEC void SDLCALL SDLPango_SetText_GivenAlignment(
+    SDLPango_Context *context,
+    const char *text,
+    int length,
+    SDLPango_Alignment alignment);
+
+extern DECLSPEC void SDLCALL SDLPango_SetText(
+    SDLPango_Context *context,
+    const char *markup,
+    int length);
+
+extern DECLSPEC void SDLCALL SDLPango_SetLanguage(
+    SDLPango_Context *context,
+    const char *language_tag);
+
+extern DECLSPEC void SDLCALL SDLPango_SetBaseDirection(
+    SDLPango_Context *context,
+    SDLPango_Direction direction);
+
+
+#ifdef __FT2_BUILD_UNIX_H__
+
+extern DECLSPEC void SDLCALL SDLPango_CopyFTBitmapToSurface(
+    const FT_Bitmap *bitmap,
+    SDL_Surface *surface,
+    const SDLPango_Matrix *matrix,
+    SDL_Rect *rect);
+
+#endif	/* __FT2_BUILD_UNIX_H__ */
+
+
+#ifdef __PANGO_H__
+
+extern DECLSPEC PangoFontMap* SDLCALL SDLPango_GetPangoFontMap(
+    SDLPango_Context *context);
+
+extern DECLSPEC PangoFontDescription* SDLCALL SDLPango_GetPangoFontDescription(
+    SDLPango_Context *context);
+
+extern DECLSPEC PangoLayout* SDLCALL SDLPango_GetPangoLayout(
+    SDLPango_Context *context);
+
+#endif /* __PANGO_H__ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "close_code.h"
+
+#endif	/* SDL_PANGO_H */
--- SDL_Pango-0.1.2/src/SDL_Pango.c.original	2006-12-13 15:36:40.000000000 +0100
+++ SDL_Pango-0.1.2/src/SDL_Pango.c	2006-12-13 16:14:46.000000000 +0100
@@ -1,1175 +1,1190 @@
-/*  SDL_Pango.c -- A companion library to SDL for working with Pango.
-    Copyright (C) 2004 NAKAMURA Ken'ichi
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
-*/
-
-/*!
-    \mainpage
-
-    \section intro Introduction
-
-    Pango is the text rendering engine of GNOME 2.x. SDL_Pango connects the 
-    engine to SDL. In Windows, pre-built binary package (MSI and merge module) 
-    is provided.
-
-    \subsection dist Distribution
-
-    If you are a game software developer, you should know the difficulties of 
-    distribution. So I will start to introduce SDL_Pango from the viewpoint 
-    of distribution.
-
-    In Un*x, SDL_Pango is hard to use as system-independent module, because 
-    it depends on fontconfig and Pango which are designed as system-singleton 
-    modules. If you use SDL_Pango, your software will require those modules 
-    installed to target system. If your software is shipped as shrink-wrap 
-    package, it may cause much problem on your support desk. You should 
-    carefully design your installation process.
-
-    In Windows, SDL_Pango is distributed as "merge module" which contains 
-    fontconfig and Pango. Those binaries are modified as side-by-side components.
-    You should use Windows Installer and merge the module 
-    on your MSI package. The merge module not only contains files, but also includes 
-    custom action which must be run at installation.
-
-    \subsection api High-level API
-
-    From the viewpoint of text rendering, the heart of SDL_Pango is high-level API. 
-    Other text rendering APIs, like DrawText() of Windows, font and text must be 
-    specified separately. In SDL_Pango, font specification is embedded in text like 
-    HTML:
-
-    \code
-    <span font_family="Courier New"><i>This is Courier New and italic.</i></span>
-    \endcode
-
-    Color, size, subscript/superscript, obliquing, weight, and other many features 
-    are also available in same way.
-
-    \subsection i18n Internationalized Text
-
-    Internationalized text is another key feature. Text is specified by UTF-8. RTL 
-    script (Arabic and Hebrew) and complicated rendering (Arabic, Indic and Thai) are 
-    supported. You can see it with GNOME 2.x.
-
-    \section get Getting Started
-
-    \subsection getlatest Get latest files
-
-    Get latest files from http://sourceforge.net/projects/sdlpango/ .
-
-    \subsection install Install Header and Library
-
-    In Windows and VS2003, I strongly recommend you to install MSI package. It contains Pango 
-    and fontconfig binaries which are modified as side-by-side components. It is 
-    nearly impossible to build them. (I spent much time to build them...)
-
-    In MinGW, I recommend you to use VS2003. Otherwise you may run into the maze of 
-    distribution. If you insist MinGW, you should use MinGW binary archive.
-
-    In Un*x, installation consists of: 
-
-    \code
-    ./configure
-    make
-    make install
-    \endcode
-
-    \subsection inc Includes
-
-    To use SDL_Pango functions in a C/C++ source code file, you must use the SDL_Pango.h 
-    include file:
-
-    \code
-    #include "SDL_Pango.h"
-    \endcode
-
-    In Windows, SDL_Pango.h is installed on \c \%ProgramFiles\%\\SDL_Pango \c Development\\include 
-    (usually \c C:\\Program \c Files\\SDL_Pango \c Development\\include). You should add this 
-    directory to include path.
-
-    \subsection comp Compiling
-
-    In Un*x, to link with SDL_Pango you should use sdl-config to get the required SDL 
-    compilation options. After that, compiling with SDL_Pango is quite easy.
-
-    Note: Some systems may not have the SDL_Pango library and include file in the same 
-    place as the SDL library and includes are located, in that case you will need to 
-    add more -I and -L paths to these command lines.
-
-    Simple Example for compiling an object file:
-
-    \code
-    cc -c `sdl-config --cflags` mysource.c
-    \endcode
-
-    Simple Example for linking an object file:
-
-    \code
-    cc -o myprogram mysource.o `sdl-config --libs` -lSDL_Pango
-    \endcode
-
-    Now myprogram is ready to run. 
-    
-    You can see a sample of autoconfiscation in 'test' directory.
-
-    In Windows, MSI package installs many dlls to \c \%ProgramFiles\%\\SDL_Pango \c Development\\import_lib. 
-    To link with SDL_Pango you should use SDL_Pango.lib.
-
-    SDL_Pango.dll depends on many dlls and other many files. Those dlls are installed on 
-    \c \%ProgramFiles\%\\SDL_Pango \c Development\\bin. MSI package adds the directory to PATH environment 
-    variable.
-
-    \section devel Development
-
-    \subsection font Font Handling
-
-    In Un*x, font handling depends on fontconfig of your system.
-
-    In Windows, local.conf of fontconfig is placed on \c \%ProgramFiles\%\\SDL_Pango \c Development\\etc\\fonts. 
-    You should know about fontconfig's font cache mechanism.
-
-    \subsection example Step-by-step Example
-
-    The operation of SDL_Pango is done via context.
-
-    \code
-    SDLPango_Context *context = SDLPango_CreateContext();
-    \endcode
-
-    Specify default colors and minimum surface size.
-
-    \code
-    SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_WHITE_LETTER);
-    SDLPango_SetMinimumSize(context, 640, 0);
-    \endcode
-
-    Set markup text.
-
-    \code
-    SDLPango_SetMarkup(context, "This is <i>markup</i> text.", -1);
-    \endcode
-
-    Now you can get the size of surface.
-
-    \code
-    int w = SDLPango_GetLayoutWidth(context);
-    int h = SDLPango_GetLayoutHeight(context);
-    \endcode
-
-    Create surface to draw.
-
-    \code
-    int margin_x = 10;
-    int margin_y = 10;
-    SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 
-	w + margin_x * 2, h + margin_y * 2,
-	32, (Uint32)(255 << (8 * 3)), (Uint32)(255 << (8 * 2)),
-	(Uint32)(255 << (8 * 1)), 255);
-    \endcode
-
-    And draw on it.
-
-    \code
-    SDLPango_Draw(context, surface, margin_x, margin_y);
-    \endcode
-
-    You must free the surface by yourself.
-
-    \code
-    SDL_FreeSurface(surface);
-    \endcode
-
-    Free context.
-
-    \code
-    SDLPango_FreeContext(context);
-    \endcode
-
-    You can see actual code in \c test/testbench.cpp.
-
-    \subsection pack Packaging
-
-    In Un*x, do it yourself.
-
-    In Windows, font files must be installed on apprication folder (usually 
-    \c C:\\Program \c Files\\[Manufacturer]\\[ProductName]). The property of 
-    apprication folder must be \c TARGETDIR (this is default setting of VS2003). 
-    SDL.dll also must be installed on apprication folder. Add SDL_Pango.msm to 
-    your MSI package.
-
-    \section ack Acknowledgment
-
-    SDL_Pango is developed with financial assistance of Information-technology Promotion Agency, Japan.
-
-- NAKAMURA Ken'ichi <[email protected]>
-    
-*/
-
-/*! @file
-    @brief Implementation of SDL_Pango
-
-    @author NAKAMURA Ken'ichi
-    @date   2004/12/07
-    $Revision: 1.6 $
-*/
-
-#include <pango/pango.h>
-#include <pango/pangoft2.h>
-
-#include "SDL_Pango.h"
-
-//! non-zero if initialized
-static int IS_INITIALIZED = 0;
-
-#define DEFAULT_FONT_FAMILY "Sans"
-#define DEFAULT_FONT_SIZE 12
-#define DEFAULT_DPI 96
-#define _MAKE_FONT_NAME(family, size) family " " #size
-#define MAKE_FONT_NAME(family, size) _MAKE_FONT_NAME(family, size)
-#define DEFAULT_DEPTH 32
-#define DEFAULT_RMASK (Uint32)(255 << (8 * 3))
-#define DEFAULT_GMASK (Uint32)(255 << (8 * 2))
-#define DEFAULT_BMASK (Uint32)(255 << (8 * 1))
-#define DEFAULT_AMASK (Uint32)255
-
-static FT_Bitmap *createFTBitmap(int width, int height);
-
-static void freeFTBitmap(FT_Bitmap *bitmap);
-
-static void getItemProperties (
-    PangoItem      *item,
-    PangoUnderline *uline,
-    gboolean       *strikethrough,
-    gint           *rise,
-    PangoColor     *fg_color,
-    gboolean       *fg_set,
-    PangoColor     *bg_color,
-    gboolean       *bg_set,
-    gboolean       *shape_set,
-    PangoRectangle *ink_rect,
-    PangoRectangle *logical_rect);
-
-static void clearFTBitmap(FT_Bitmap *bitmap);
-
-typedef struct _surfaceArgs {
-    Uint32 flags;
-    int depth;
-    Uint32 Rmask;
-    Uint32 Gmask;
-    Uint32 Bmask;
-    Uint32 Amask;
-} surfaceArgs;
-
-typedef struct _contextImpl {
-    PangoContext *context;
-    PangoFontMap *font_map;
-    PangoFontDescription *font_desc;
-    PangoLayout *layout;
-    surfaceArgs surface_args;
-    FT_Bitmap *tmp_ftbitmap;
-    SDLPango_Matrix color_matrix;
-    int min_width;
-    int min_height;
-} contextImpl;
-
-
-/*!
-    Initialize the Glib and Pango API.
-    This must be called before using other functions in this library,
-    excepting SDLPango_WasInit.
-    SDL does not have to be initialized before this call.
-
-
-    @return always 0.
-*/
-int
-SDLPango_Init()
-{
-    g_type_init();
-
-    IS_INITIALIZED = -1;
-
-    return 0;
-}
-
-/*!
-    Query the initilization status of the Glib and Pango API.
-    You may, of course, use this before SDLPango_Init to avoid
-    initilizing twice in a row.
-
-    @return zero when already initialized.
-    non-zero when not initialized.
-*/
-int
-SDLPango_WasInit()
-{
-    return IS_INITIALIZED;
-}
-
-/*!
-    Draw glyphs on rect.
-
-    @param *context [in] Context
-    @param *surface [out] Surface to draw on it
-    @param *color_matrix [in] Foreground and background color
-    @param *font [in] Innter variable of Pango
-    @param *glyphs [in] Innter variable of Pango
-    @param *rect [in] Draw on this area
-    @param baseline [in] Horizontal location of glyphs
-*/
-static void
-drawGlyphString(
-    SDLPango_Context *context,
-    SDL_Surface *surface,
-    SDLPango_Matrix *color_matrix,
-    PangoFont *font,
-    PangoGlyphString *glyphs,
-    SDL_Rect *rect,
-    int baseline)
-{
-    pango_ft2_render(context->tmp_ftbitmap, font, glyphs, rect->x, rect->y + baseline);
-
-    SDLPango_CopyFTBitmapToSurface(
-	context->tmp_ftbitmap,
-	surface,
-	color_matrix,
-	rect);
-
-    clearFTBitmap(context->tmp_ftbitmap);
-}
-
-/*!
-    Draw horizontal line of a pixel.
-
-    @param *surface [out] Surface to draw on it
-    @param *color_matrix [in] Foreground and background color
-    @param y [in] Y location of line
-    @param start [in] Left of line
-    @param end [in] Right of line
-*/
-static void drawHLine(
-    SDL_Surface *surface,
-    SDLPango_Matrix *color_matrix,
-    int y,
-    int start,
-    int end)
-{
-    Uint8 *p;
-    Uint16 *p16;
-    Uint32 *p32;
-    Uint32 color;
-    int ix;
-    int pixel_bytes = surface->format->BytesPerPixel;
-
-    if (y < 0 || y >= surface->h)
-	return;
-
-    if (end <= 0 || start >= surface->w)
-	return;
-
-    if (start < 0)
-	start = 0;
-
-    if (end >= surface->w)
-	end = surface->w;
-
-    p = (Uint8 *)(surface->pixels) + y * surface->pitch + start * pixel_bytes;
-    color = SDL_MapRGBA(surface->format,
-	color_matrix->m[0][1],
-	color_matrix->m[1][1], 
-	color_matrix->m[2][1], 
-	color_matrix->m[3][1]);
-
-    switch(pixel_bytes) {
-    case 2:
-	p16 = (Uint16 *)p;
-	for (ix = 0; ix < end - start; ix++)
-	    *p16++ = (Uint16)color;
-	break;
-    case 4:
-	p32 = (Uint32 *)p;
-	for (ix = 0; ix < end - start; ix++)
-	    *p32++ = color;
-	break;
-    default:
-	SDL_SetError("surface->format->BytesPerPixel is invalid value");
-	break;
-    }
-}
-
-/*!
-    Draw a line.
-
-    @param *context [in] Context
-    @param *surface [out] Surface to draw on it
-    @param *line [in] Innter variable of Pango
-    @param x [in] X location of line
-    @param y [in] Y location of line
-    @param height [in] Height of line
-    @param baseline [in] Rise / sink of line (for super/subscript)
-*/
-static void
-drawLine(
-    SDLPango_Context *context,
-    SDL_Surface *surface,
-    PangoLayoutLine *line,
-    gint x, 
-    gint y, 
-    gint height,
-    gint baseline)
-{
-    GSList *tmp_list = line->runs;
-    PangoColor fg_color, bg_color;
-    PangoRectangle logical_rect;
-    PangoRectangle ink_rect;
-    int x_off = 0;
-
-    while (tmp_list) {
-	SDLPango_Matrix color_matrix = context->color_matrix;
-	PangoUnderline uline = PANGO_UNDERLINE_NONE;
-	gboolean strike, fg_set, bg_set, shape_set;
-	gint rise, risen_y;
-	PangoLayoutRun *run = tmp_list->data;
-	SDL_Rect d_rect;
-
-	tmp_list = tmp_list->next;
-
-	getItemProperties(run->item,
-	    &uline, &strike, &rise,
-	    &fg_color, &fg_set, &bg_color, &bg_set,
-	    &shape_set, &ink_rect, &logical_rect);
-
-	risen_y = y + baseline - PANGO_PIXELS (rise);
-
-	if(fg_set) {
-	    color_matrix.m[0][1] = (Uint8)(fg_color.red >> 8);
-	    color_matrix.m[1][1] = (Uint8)(fg_color.green >> 8);
-	    color_matrix.m[2][1] = (Uint8)(fg_color.blue >> 8);
-	    color_matrix.m[3][1] = 255;
-	    if(color_matrix.m[3][0] == 0) {
-		color_matrix.m[0][0] = (Uint8)(fg_color.red >> 8);
-		color_matrix.m[1][0] = (Uint8)(fg_color.green >> 8);
-		color_matrix.m[2][0] = (Uint8)(fg_color.blue >> 8);
-	    }
-	}
-
-	if (bg_set) {
-	    color_matrix.m[0][0] = (Uint8)(bg_color.red >> 8);
-	    color_matrix.m[1][0] = (Uint8)(bg_color.green >> 8);
-	    color_matrix.m[2][0] = (Uint8)(bg_color.blue >> 8);
-	    color_matrix.m[3][0] = 255;
-	}
-
-	if(! shape_set) {
-	    if (uline == PANGO_UNDERLINE_NONE)
-		pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
-					    NULL, &logical_rect);
-	    else
-		pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
-					    &ink_rect, &logical_rect);
-
-	    d_rect.w = (Uint16)PANGO_PIXELS(logical_rect.width);
-	    d_rect.h = (Uint16)height;
-	    d_rect.x = (Uint16)(x + PANGO_PIXELS (x_off));
-	    d_rect.y = (Uint16)(risen_y - baseline);
-
-	    if((! context->tmp_ftbitmap) || d_rect.w + d_rect.x > context->tmp_ftbitmap->width
-		|| d_rect.h + d_rect.y > context->tmp_ftbitmap->rows)
-	    {
-		freeFTBitmap(context->tmp_ftbitmap);
-		context->tmp_ftbitmap = createFTBitmap(d_rect.w + d_rect.x, d_rect.h + d_rect.y);
-	    }
-
-	    drawGlyphString(context, surface, 
-		&color_matrix, 
-		run->item->analysis.font, run->glyphs, &d_rect, baseline);
-	}
-        switch (uline) {
-	case PANGO_UNDERLINE_NONE:
-	    break;
-	case PANGO_UNDERLINE_DOUBLE:
-	    drawHLine(surface, &color_matrix,
-		risen_y + 4,
-		x + PANGO_PIXELS (x_off + ink_rect.x),
-		x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width));
-	  /* Fall through */
-	case PANGO_UNDERLINE_SINGLE:
-	    drawHLine(surface, &color_matrix,
-		risen_y + 2,
-		x + PANGO_PIXELS (x_off + ink_rect.x),
-		x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width));
-	    break;
-	case PANGO_UNDERLINE_ERROR:
-	    {
-		int point_x;
-		int counter = 0;
-		int end_x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width);
-
-		for (point_x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1;
-		    point_x <= end_x;
-		    point_x += 2)
-		{
-		    if (counter)
-			drawHLine(surface, &color_matrix,
-			    risen_y + 2,
-			    point_x, MIN (point_x + 1, end_x));
-		    else
-			drawHLine(surface, &color_matrix,
-			    risen_y + 3,
-			    point_x, MIN (point_x + 1, end_x));
-    		
-		    counter = (counter + 1) % 2;
-		}
-	    }
-	    break;
-	case PANGO_UNDERLINE_LOW:
-	    drawHLine(surface, &color_matrix,
-		risen_y + PANGO_PIXELS (ink_rect.y + ink_rect.height),
-		x + PANGO_PIXELS (x_off + ink_rect.x),
-		x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width));
-	  break;
-	}
-
-        if (strike)
-	    drawHLine(surface, &color_matrix,
-		risen_y + PANGO_PIXELS (logical_rect.y + logical_rect.height / 2),
-		x + PANGO_PIXELS (x_off + logical_rect.x),
-		x + PANGO_PIXELS (x_off + logical_rect.x + logical_rect.width));
-
-	x_off += logical_rect.width;
-    }
-}
-
-/*!
-    Innter function of Pango. Stolen from GDK.
-
-    @param *item [in] The item to get property
-    @param *uline [out] Kind of underline
-    @param *strikethrough [out] Strike-through line
-    @param *rise [out] Rise/sink of line (for super/subscript)
-    @param *fg_color [out] Color of foreground
-    @param *fg_set [out] True if fg_color set
-    @param *bg_color [out] Color of background
-    @param *bg_set [out] True if bg_color valid
-    @param *shape_set [out] True if ink_rect and logical_rect valid
-    @param *ink_rect [out] Ink rect
-    @param *logical_rect [out] Logical rect
-*/
-static void
-getItemProperties (
-    PangoItem *item,
-    PangoUnderline *uline,
-    gboolean *strikethrough,
-    gint *rise,
-    PangoColor *fg_color,
-    gboolean *fg_set,
-    PangoColor *bg_color,
-    gboolean *bg_set,
-    gboolean *shape_set,
-    PangoRectangle *ink_rect,
-    PangoRectangle *logical_rect)
-{
-    GSList *tmp_list = item->analysis.extra_attrs;
-
-    if (strikethrough)
-	*strikethrough = FALSE;
-  
-    if (fg_set)
-        *fg_set = FALSE;
-
-    if (bg_set)
-	*bg_set = FALSE;
-
-    if (shape_set)
-	*shape_set = FALSE;
-
-    if (rise)
-	*rise = 0;
-
-    while (tmp_list) {
-	PangoAttribute *attr = tmp_list->data;
-
-	switch (attr->klass->type) {
-	case PANGO_ATTR_UNDERLINE:
-	    if (uline)
-		*uline = ((PangoAttrInt *)attr)->value;
-	    break;
-
-	case PANGO_ATTR_STRIKETHROUGH:
-	    if (strikethrough)
-		*strikethrough = ((PangoAttrInt *)attr)->value;
-	    break;
-    	
-	case PANGO_ATTR_FOREGROUND:
-	    if (fg_color)
-		*fg_color = ((PangoAttrColor *)attr)->color;
-	    if (fg_set)
-		*fg_set = TRUE;
-	    break;
-    	
-	case PANGO_ATTR_BACKGROUND:
-	    if (bg_color)
-		*bg_color = ((PangoAttrColor *)attr)->color;
-	    if (bg_set)
-		*bg_set = TRUE;
-	    break;
-
-	case PANGO_ATTR_SHAPE:
-	    if (shape_set)
-		*shape_set = TRUE;
-	    if (logical_rect)
-		*logical_rect = ((PangoAttrShape *)attr)->logical_rect;
-	    if (ink_rect)
-		*ink_rect = ((PangoAttrShape *)attr)->ink_rect;
-	    break;
-
-	case PANGO_ATTR_RISE:
-	    if (rise)
-		*rise = ((PangoAttrInt *)attr)->value;
-	    break;
-    	
-	default:
-	    break;
-	}
-	tmp_list = tmp_list->next;
-    }
-}
-
-/*!
-    Copy bitmap to surface. 
-    From (x, y)-(w, h) to (x, y)-(w, h) of rect. 
-
-    @param *bitmap [in] Grayscale bitmap
-    @param *surface [out] Surface
-    @param *matrix [in] Foreground and background color
-    @param *rect [in] Rect to copy
-*/
-void
-SDLPango_CopyFTBitmapToSurface(
-    const FT_Bitmap *bitmap,
-    SDL_Surface *surface,
-    const SDLPango_Matrix *matrix,
-    SDL_Rect *rect)
-{
-    int i;
-    Uint8 *p_ft;
-    Uint8 *p_sdl;
-    int width = rect->w;
-    int height = rect->h;
-    int x = rect->x;
-    int y = rect->y;
-
-    if(x + width > surface->w) {
-	width = surface->w - x;
-	if(width <= 0)
-	    return;
-    }
-    if(y + height > surface->h) {
-	height = surface->h - y;
-	if(height <= 0)
-	    return;
-    }
-
-    if(SDL_LockSurface(surface)) {
-	SDL_SetError("surface lock failed");
-	SDL_FreeSurface(surface);
-	return;
-    }
-
-    p_ft = (Uint8 *)bitmap->buffer + (bitmap->pitch * y);
-    p_sdl = (Uint8 *)surface->pixels + (surface->pitch * y);
-    for(i = 0; i < height; i ++) {
-	int k;
-	for(k = 0; k < width; k ++) {
-	    /* TODO: rewrite by matrix calculation library */
-	    Uint8 pixel[4];	/* 4: RGBA */
-	    int n;
-
-	    for(n = 0; n < 4; n ++) {
-		Uint16 w;
-		w = ((Uint16)matrix->m[n][0] * (256 - p_ft[k + x])) + ((Uint16)matrix->m[n][1] * p_ft[k + x]);
-		pixel[n] = (Uint8)(w >> 8);
-	    }
-
-	    switch(surface->format->BytesPerPixel) {
-	    case 2:
-		((Uint16 *)p_sdl)[k + x] = (Uint16)SDL_MapRGBA(surface->format, pixel[0], pixel[1], pixel[2], pixel[3]);
-		break;
-	    case 4:
-		((Uint32 *)p_sdl)[k + x] = SDL_MapRGBA(surface->format, pixel[0], pixel[1], pixel[2], pixel[3]);
-		break;
-	    default:
-		SDL_SetError("surface->format->BytesPerPixel is invalid value");
-		return;
-	    }
-	}
-	p_ft += bitmap->pitch;
-	p_sdl += surface->pitch;
-    }
-
-    SDL_UnlockSurface(surface);
-}
-
-/*!
-    Create a context which contains Pango objects.
-
-    @return A pointer to the context as a SDLPango_Context*.
-*/
-SDLPango_Context*
-SDLPango_CreateContext()
-{
-    SDLPango_Context *context = g_malloc(sizeof(SDLPango_Context));
-    G_CONST_RETURN char *charset;
-
-    context->font_map = pango_ft2_font_map_new ();
-    pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (context->font_map), DEFAULT_DPI, DEFAULT_DPI);
-
-    context->context = pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (context->font_map));
-
-    g_get_charset(&charset);
-    pango_context_set_language (context->context, pango_language_from_string (charset));
-    pango_context_set_base_dir (context->context, PANGO_DIRECTION_LTR);
-
-    context->font_desc = pango_font_description_from_string(
-	MAKE_FONT_NAME (DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE));
-
-    context->layout = pango_layout_new (context->context);
-
-    SDLPango_SetSurfaceCreateArgs(context, SDL_SWSURFACE | SDL_SRCALPHA, DEFAULT_DEPTH,
-	DEFAULT_RMASK, DEFAULT_GMASK, DEFAULT_BMASK, DEFAULT_AMASK);
-
-    context->tmp_ftbitmap = NULL;
-
-    context->color_matrix = *MATRIX_TRANSPARENT_BACK_BLACK_LETTER;
-
-    context->min_height = 0;
-    context->min_width = 0;
-
-    return context;
-}
-
-/*!
-    Free a context.
-
-    @param *context [i/o] Context to be free
-*/
-void
-SDLPango_FreeContext(SDLPango_Context *context)
-{
-    freeFTBitmap(context->tmp_ftbitmap);
-
-    g_object_unref (context->layout);
-
-    pango_font_description_free(context->font_desc);
-
-    g_object_unref(context->context);
-
-    g_object_unref(context->font_map);
-
-    g_free(context);
-}
-
-/*!
-    Specify Arguments when create a surface.
-    When SDL_Pango creates a surface, the arguments are used.
-
-    @param *context [i/o] Context
-    @param flags [in] Same as SDL_CreateRGBSurface()
-    @param depth [in] Same as SDL_CreateRGBSurface()
-    @param Rmask [in] Same as SDL_CreateRGBSurface()
-    @param Gmask [in] Same as SDL_CreateRGBSurface()
-    @param Bmask [in] Same as SDL_CreateRGBSurface()
-    @param Amask [in] Same as SDL_CreateRGBSurface()
-*/
-void
-SDLPango_SetSurfaceCreateArgs(
-    SDLPango_Context *context,
-    Uint32 flags,
-    int depth,
-    Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
-{
-    context->surface_args.flags = flags;
-    context->surface_args.depth = depth;
-    context->surface_args.Rmask = Rmask;
-    context->surface_args.Gmask = Gmask;
-    context->surface_args.Bmask = Bmask;
-    context->surface_args.Amask = Amask;
-}
-
-/*!
-    Create a surface and draw text on it.
-    The size of surface is same as lauout size.
-
-    @param *context [in] Context
-    @return A newly created surface
-*/
-SDL_Surface * SDLPango_CreateSurfaceDraw(
-    SDLPango_Context *context)
-{
-    PangoRectangle logical_rect;
-    SDL_Surface *surface;
-    int width, height;
-
-    pango_layout_get_extents (context->layout, NULL, &logical_rect);
-    width = PANGO_PIXELS (logical_rect.width);
-    height = PANGO_PIXELS (logical_rect.height);
-    if(width < context->min_width)
-	width = context->min_width;
-    if(height < context->min_height)
-	height = context->min_height;
-
-    surface = SDL_CreateRGBSurface(
-	context->surface_args.flags,
-	width, height, context->surface_args.depth,
-	context->surface_args.Rmask,
-	context->surface_args.Gmask,
-	context->surface_args.Bmask,
-	context->surface_args.Amask);
-
-    SDLPango_Draw(context, surface, 0, 0);
-
-    return surface;
-}
-
-/*!
-    Draw text on a existing surface.
-
-    @param *context [in] Context
-    @param *surface [i/o] Surface to draw on it
-    @param x [in] X of left-top of drawing area
-    @param y [in] Y of left-top of drawing area
-*/
-void
-SDLPango_Draw(
-    SDLPango_Context *context,
-    SDL_Surface *surface,
-    int x, int y)
-{
-    PangoLayoutIter *iter;
-    PangoRectangle logical_rect;
-    int width, height;
-
-    if(! surface) {
-	SDL_SetError("surface is NULL");
-	return;
-    }
-
-    iter = pango_layout_get_iter (context->layout);
-
-    pango_layout_get_extents (context->layout, NULL, &logical_rect);
-    width = PANGO_PIXELS (logical_rect.width);
-    height = PANGO_PIXELS (logical_rect.height);
-
-    SDL_FillRect(surface, NULL, SDL_MapRGBA(surface->format, 0, 0, 0, 0));
-
-    if((! context->tmp_ftbitmap) || context->tmp_ftbitmap->width < width
-	|| context->tmp_ftbitmap->rows < height)
-    {
-	freeFTBitmap(context->tmp_ftbitmap);
-        context->tmp_ftbitmap = createFTBitmap(width, height);
-    }
-
-    do {
-	PangoLayoutLine *line;
-	int baseline;
-
-	line = pango_layout_iter_get_line (iter);
-
-	pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
-	baseline = pango_layout_iter_get_baseline (iter);
-
-	drawLine(
-	    context,
-	    surface,
-	    line,
-	    x + PANGO_PIXELS (logical_rect.x),
-	    y + PANGO_PIXELS (logical_rect.y),
-	    PANGO_PIXELS (logical_rect.height),
-	    PANGO_PIXELS (baseline - logical_rect.y));
-    } while (pango_layout_iter_next_line (iter));
-
-    pango_layout_iter_free (iter);
-}
-
-/*!
-    Allocate buffer and create a FTBitmap object.
-
-    @param width [in] Width
-    @param height [in] Height
-    @return FTBitmap object
-*/
-static FT_Bitmap *
-createFTBitmap(
-    int width, int height)
-{
-    FT_Bitmap *bitmap;
-    guchar *buf;
-
-    bitmap = g_malloc(sizeof(FT_Bitmap));
-    bitmap->width = width;
-    bitmap->rows = height;
-    bitmap->pitch = (width + 3) & ~3;
-    bitmap->num_grays = 256;
-    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
-    buf = g_malloc (bitmap->pitch * bitmap->rows);
-    memset (buf, 0x00, bitmap->pitch * bitmap->rows);
-    bitmap->buffer = buf;
-
-    return bitmap;
-}
-
-/*!
-    Free a FTBitmap object.
-
-    @param *bitmap [i/o] FTbitmap to be free
-*/
-static void
-freeFTBitmap(
-    FT_Bitmap *bitmap)
-{
-    if(bitmap) {
-	g_free(bitmap->buffer);
-	g_free(bitmap);
-    }
-}
-
-/*!
-    Clear a FTBitmap object.
-
-    @param *bitmap [i/o] FTbitmap to be clear
-*/
-static void
-clearFTBitmap(
-    FT_Bitmap *bitmap)
-{
-    Uint8 *p = (Uint8 *)bitmap->buffer;
-    int length = bitmap->pitch * bitmap->rows;
-
-    memset(p, 0, length);
-}
-
-/*!
-    Specify minimum size of drawing rect.
-
-    @param *context [i/o] Context
-    @param width [in] Width. -1 means no wrapping mode.
-    @param height [in] Height. zero/minus value means non-specified.
-*/
-void
-SDLPango_SetMinimumSize(
-    SDLPango_Context *context,
-    int width, int height)
-{
-    int pango_width;
-    if(width > 0)
-	pango_width = width * PANGO_SCALE;
-    else
-	pango_width = -1;
-    pango_layout_set_width(context->layout, pango_width);
-
-    context->min_width = width;
-    context->min_height = height;
-}
-
-/*!
-    Specify default color.
-
-    @param *context [i/o] Context
-    @param *color_matrix [in] Foreground and background color
-*/
-void
-SDLPango_SetDefaultColor(
-    SDLPango_Context *context,
-    const SDLPango_Matrix *color_matrix)
-{
-    context->color_matrix = *color_matrix;
-}
-
-/*!
-    Get layout width.
-
-    @param *context [in] Context
-    @return Width
-*/
-int
-SDLPango_GetLayoutWidth(
-    SDLPango_Context *context)
-{
-    PangoRectangle logical_rect;
-
-    pango_layout_get_extents (context->layout, NULL, &logical_rect);
-
-    return PANGO_PIXELS (logical_rect.width);
-}
-
-/*!
-    Get layout height.
-
-    @param *context [in] Context
-    @return Height
-*/
-int
-SDLPango_GetLayoutHeight(
-    SDLPango_Context *context)
-{
-    PangoRectangle logical_rect;
-
-    pango_layout_get_extents (context->layout, NULL, &logical_rect);
-
-    return PANGO_PIXELS (logical_rect.height);
-}
-
-/*!
-    Set markup text to context.
-    Text must be utf-8.
-    Markup format is same as pango.
-
-    @param *context [i/o] Context
-    @param *markup [in] Markup text
-    @param length [in] Text length. -1 means NULL-terminated text.
-*/
-void
-SDLPango_SetMarkup(
-    SDLPango_Context *context,
-    const char *markup,
-    int length)
-{
-    pango_layout_set_markup (context->layout, markup, length);
-    pango_layout_set_auto_dir (context->layout, TRUE);
-    pango_layout_set_alignment (context->layout, PANGO_ALIGN_LEFT);
-    pango_layout_set_font_description (context->layout, context->font_desc);
-}
-
-/*!
-    Set plain text to context.
-    Text must be utf-8.
-
-    @param *context [i/o] Context
-    @param *text [in] Plain text
-    @param length [in] Text length. -1 means NULL-terminated text.
-*/
-void
-SDLPango_SetText(
-    SDLPango_Context *context,
-    const char *text,
-    int length)
-{
-    pango_layout_set_attributes(context->layout, NULL);
-    pango_layout_set_text (context->layout, text, length);
-    pango_layout_set_auto_dir (context->layout, TRUE);
-    pango_layout_set_alignment (context->layout, PANGO_ALIGN_LEFT);
-    pango_layout_set_font_description (context->layout, context->font_desc);
-}
-
-/*!
-    Set DPI to context.
-
-    @param *context [i/o] Context
-    @param dpi_x [in] X dpi
-    @param dpi_y [in] Y dpi
-*/
-void
-SDLPango_SetDpi(
-    SDLPango_Context *context,
-    double dpi_x, double dpi_y)
-{
-    pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (context->font_map), dpi_x, dpi_y);
-}
-
-/*!
-    Set language to context.
-
-    @param *context [i/o] Context
-    @param *language_tag [in] A RFC-3066 format language tag 
-*/
-void SDLCALL SDLPango_SetLanguage(
-    SDLPango_Context *context,
-    const char *language_tag)
-{
-    pango_context_set_language (context->context, pango_language_from_string (language_tag));
-}
-
-/*!
-    Set base direction to context.
-
-    @param *context [i/o] Context
-    @param direction [in] Direction
-*/
-void SDLCALL SDLPango_SetBaseDirection(
-    SDLPango_Context *context,
-    SDLPango_Direction direction)
-{
-    PangoDirection pango_dir;
-
-    switch(direction) {
-    case SDLPANGO_DIRECTION_LTR:
-	pango_dir = PANGO_DIRECTION_LTR;
-	break;
-    case SDLPANGO_DIRECTION_RTL:
-	pango_dir = PANGO_DIRECTION_RTL;
-	break;
-    case SDLPANGO_DIRECTION_WEAK_LTR:
-	pango_dir = PANGO_DIRECTION_WEAK_LTR;
-	break;
-    case SDLPANGO_DIRECTION_WEAK_RTL:
-	pango_dir = PANGO_DIRECTION_WEAK_RTL;
-	break;
-    case SDLPANGO_DIRECTION_NEUTRAL:
-	pango_dir = PANGO_DIRECTION_NEUTRAL;
-	break;
-    default:
-	SDL_SetError("unknown direction value");
-	return;
-    }
-
-    pango_context_set_base_dir (context->context, pango_dir);
-}
-
-/*!
-    Get font map from context.
-
-    @param *context [in] Context
-    @return Font map
-*/
-PangoFontMap* SDLCALL SDLPango_GetPangoFontMap(
-    SDLPango_Context *context)
-{
-    return context->font_map;
-}
-
-/*!
-    Get font description from context.
-
-    @param *context [in] Context
-    @return Font description
-*/
-PangoFontDescription* SDLCALL SDLPango_GetPangoFontDescription(
-    SDLPango_Context *context)
-{
-    return context->font_desc;
-}
-
-/*!
-    Get layout from context.
-
-    @param *context [in] Context
-    @return Layout
-*/
-PangoLayout* SDLCALL SDLPango_GetPangoLayout(
-    SDLPango_Context *context)
-{
-    return context->layout;
-}
+/*  SDL_Pango.c -- A companion library to SDL for working with Pango.
+    Copyright (C) 2004 NAKAMURA Ken'ichi
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+*/
+
+/*!
+    \mainpage
+
+    \section intro Introduction
+
+    Pango is the text rendering engine of GNOME 2.x. SDL_Pango connects the 
+    engine to SDL. In Windows, pre-built binary package (MSI and merge module) 
+    is provided.
+
+    \subsection dist Distribution
+
+    If you are a game software developer, you should know the difficulties of 
+    distribution. So I will start to introduce SDL_Pango from the viewpoint 
+    of distribution.
+
+    In Un*x, SDL_Pango is hard to use as system-independent module, because 
+    it depends on fontconfig and Pango which are designed as system-singleton 
+    modules. If you use SDL_Pango, your software will require those modules 
+    installed to target system. If your software is shipped as shrink-wrap 
+    package, it may cause much problem on your support desk. You should 
+    carefully design your installation process.
+
+    In Windows, SDL_Pango is distributed as "merge module" which contains 
+    fontconfig and Pango. Those binaries are modified as side-by-side components.
+    You should use Windows Installer and merge the module 
+    on your MSI package. The merge module not only contains files, but also includes 
+    custom action which must be run at installation.
+
+    \subsection api High-level API
+
+    From the viewpoint of text rendering, the heart of SDL_Pango is high-level API. 
+    Other text rendering APIs, like DrawText() of Windows, font and text must be 
+    specified separately. In SDL_Pango, font specification is embedded in text like 
+    HTML:
+
+    \code
+    <span font_family="Courier New"><i>This is Courier New and italic.</i></span>
+    \endcode
+
+    Color, size, subscript/superscript, obliquing, weight, and other many features 
+    are also available in same way.
+
+    \subsection i18n Internationalized Text
+
+    Internationalized text is another key feature. Text is specified by UTF-8. RTL 
+    script (Arabic and Hebrew) and complicated rendering (Arabic, Indic and Thai) are 
+    supported. You can see it with GNOME 2.x.
+
+    \section get Getting Started
+
+    \subsection getlatest Get latest files
+
+    Get latest files from http://sourceforge.net/projects/sdlpango/ .
+
+    \subsection install Install Header and Library
+
+    In Windows and VS2003, I strongly recommend you to install MSI package. It contains Pango 
+    and fontconfig binaries which are modified as side-by-side components. It is 
+    nearly impossible to build them. (I spent much time to build them...)
+
+    In MinGW, I recommend you to use VS2003. Otherwise you may run into the maze of 
+    distribution. If you insist MinGW, you should use MinGW binary archive.
+
+    In Un*x, installation consists of: 
+
+    \code
+    ./configure
+    make
+    make install
+    \endcode
+
+    \subsection inc Includes
+
+    To use SDL_Pango functions in a C/C++ source code file, you must use the SDL_Pango.h 
+    include file:
+
+    \code
+    #include "SDL_Pango.h"
+    \endcode
+
+    In Windows, SDL_Pango.h is installed on \c \%ProgramFiles\%\\SDL_Pango \c Development\\include 
+    (usually \c C:\\Program \c Files\\SDL_Pango \c Development\\include). You should add this 
+    directory to include path.
+
+    \subsection comp Compiling
+
+    In Un*x, to link with SDL_Pango you should use sdl-config to get the required SDL 
+    compilation options. After that, compiling with SDL_Pango is quite easy.
+
+    Note: Some systems may not have the SDL_Pango library and include file in the same 
+    place as the SDL library and includes are located, in that case you will need to 
+    add more -I and -L paths to these command lines.
+
+    Simple Example for compiling an object file:
+
+    \code
+    cc -c `sdl-config --cflags` mysource.c
+    \endcode
+
+    Simple Example for linking an object file:
+
+    \code
+    cc -o myprogram mysource.o `sdl-config --libs` -lSDL_Pango
+    \endcode
+
+    Now myprogram is ready to run. 
+    
+    You can see a sample of autoconfiscation in 'test' directory.
+
+    In Windows, MSI package installs many dlls to \c \%ProgramFiles\%\\SDL_Pango \c Development\\import_lib. 
+    To link with SDL_Pango you should use SDL_Pango.lib.
+
+    SDL_Pango.dll depends on many dlls and other many files. Those dlls are installed on 
+    \c \%ProgramFiles\%\\SDL_Pango \c Development\\bin. MSI package adds the directory to PATH environment 
+    variable.
+
+    \section devel Development
+
+    \subsection font Font Handling
+
+    In Un*x, font handling depends on fontconfig of your system.
+
+    In Windows, local.conf of fontconfig is placed on \c \%ProgramFiles\%\\SDL_Pango \c Development\\etc\\fonts. 
+    You should know about fontconfig's font cache mechanism.
+
+    \subsection example Step-by-step Example
+
+    The operation of SDL_Pango is done via context.
+
+    \code
+    SDLPango_Context *context = SDLPango_CreateContext();
+    \endcode
+
+    Specify default colors and minimum surface size.
+
+    \code
+    SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_WHITE_LETTER);
+    SDLPango_SetMinimumSize(context, 640, 0);
+    \endcode
+
+    Set markup text.
+
+    \code
+    SDLPango_SetMarkup(context, "This is <i>markup</i> text.", -1);
+    \endcode
+
+    Now you can get the size of surface.
+
+    \code
+    int w = SDLPango_GetLayoutWidth(context);
+    int h = SDLPango_GetLayoutHeight(context);
+    \endcode
+
+    Create surface to draw.
+
+    \code
+    int margin_x = 10;
+    int margin_y = 10;
+    SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 
+	w + margin_x * 2, h + margin_y * 2,
+	32, (Uint32)(255 << (8 * 3)), (Uint32)(255 << (8 * 2)),
+	(Uint32)(255 << (8 * 1)), 255);
+    \endcode
+
+    And draw on it.
+
+    \code
+    SDLPango_Draw(context, surface, margin_x, margin_y);
+    \endcode
+
+    You must free the surface by yourself.
+
+    \code
+    SDL_FreeSurface(surface);
+    \endcode
+
+    Free context.
+
+    \code
+    SDLPango_FreeContext(context);
+    \endcode
+
+    You can see actual code in \c test/testbench.cpp.
+
+    \subsection pack Packaging
+
+    In Un*x, do it yourself.
+
+    In Windows, font files must be installed on apprication folder (usually 
+    \c C:\\Program \c Files\\[Manufacturer]\\[ProductName]). The property of 
+    apprication folder must be \c TARGETDIR (this is default setting of VS2003). 
+    SDL.dll also must be installed on apprication folder. Add SDL_Pango.msm to 
+    your MSI package.
+
+    \section ack Acknowledgment
+
+    SDL_Pango is developed with financial assistance of Information-technology Promotion Agency, Japan.
+
+- NAKAMURA Ken'ichi <[email protected]>
+    
+*/
+
+/*! @file
+    @brief Implementation of SDL_Pango
+
+    @author NAKAMURA Ken'ichi
+    @date   2004/12/07
+    $Revision: 1.6 $
+*/
+
+#include <pango/pango.h>
+#include <pango/pangoft2.h>
+
+#include "SDL_Pango.h"
+
+//! non-zero if initialized
+static int IS_INITIALIZED = 0;
+
+#define DEFAULT_FONT_FAMILY "Sans"
+#define DEFAULT_FONT_SIZE 12
+#define DEFAULT_DPI 96
+#define _MAKE_FONT_NAME(family, size) family " " #size
+#define MAKE_FONT_NAME(family, size) _MAKE_FONT_NAME(family, size)
+#define DEFAULT_DEPTH 32
+#define DEFAULT_RMASK (Uint32)(255 << (8 * 3))
+#define DEFAULT_GMASK (Uint32)(255 << (8 * 2))
+#define DEFAULT_BMASK (Uint32)(255 << (8 * 1))
+#define DEFAULT_AMASK (Uint32)255
+
+static FT_Bitmap *createFTBitmap(int width, int height);
+
+static void freeFTBitmap(FT_Bitmap *bitmap);
+
+static void getItemProperties (
+    PangoItem      *item,
+    PangoUnderline *uline,
+    gboolean       *strikethrough,
+    gint           *rise,
+    PangoColor     *fg_color,
+    gboolean       *fg_set,
+    PangoColor     *bg_color,
+    gboolean       *bg_set,
+    gboolean       *shape_set,
+    PangoRectangle *ink_rect,
+    PangoRectangle *logical_rect);
+
+static void clearFTBitmap(FT_Bitmap *bitmap);
+
+typedef struct _surfaceArgs {
+    Uint32 flags;
+    int depth;
+    Uint32 Rmask;
+    Uint32 Gmask;
+    Uint32 Bmask;
+    Uint32 Amask;
+} surfaceArgs;
+
+typedef struct _contextImpl {
+    PangoContext *context;
+    PangoFontMap *font_map;
+    PangoFontDescription *font_desc;
+    PangoLayout *layout;
+    surfaceArgs surface_args;
+    FT_Bitmap *tmp_ftbitmap;
+    SDLPango_Matrix color_matrix;
+    int min_width;
+    int min_height;
+} contextImpl;
+
+
+/*!
+    Initialize the Glib and Pango API.
+    This must be called before using other functions in this library,
+    excepting SDLPango_WasInit.
+    SDL does not have to be initialized before this call.
+
+
+    @return always 0.
+*/
+int
+SDLPango_Init()
+{
+    g_type_init();
+
+    IS_INITIALIZED = -1;
+
+    return 0;
+}
+
+/*!
+    Query the initilization status of the Glib and Pango API.
+    You may, of course, use this before SDLPango_Init to avoid
+    initilizing twice in a row.
+
+    @return zero when already initialized.
+    non-zero when not initialized.
+*/
+int
+SDLPango_WasInit()
+{
+    return IS_INITIALIZED;
+}
+
+/*!
+    Draw glyphs on rect.
+
+    @param *context [in] Context
+    @param *surface [out] Surface to draw on it
+    @param *color_matrix [in] Foreground and background color
+    @param *font [in] Innter variable of Pango
+    @param *glyphs [in] Innter variable of Pango
+    @param *rect [in] Draw on this area
+    @param baseline [in] Horizontal location of glyphs
+*/
+static void
+drawGlyphString(
+    SDLPango_Context *context,
+    SDL_Surface *surface,
+    SDLPango_Matrix *color_matrix,
+    PangoFont *font,
+    PangoGlyphString *glyphs,
+    SDL_Rect *rect,
+    int baseline)
+{
+    pango_ft2_render(context->tmp_ftbitmap, font, glyphs, rect->x, rect->y + baseline);
+
+    SDLPango_CopyFTBitmapToSurface(
+	context->tmp_ftbitmap,
+	surface,
+	color_matrix,
+	rect);
+
+    clearFTBitmap(context->tmp_ftbitmap);
+}
+
+/*!
+    Draw horizontal line of a pixel.
+
+    @param *surface [out] Surface to draw on it
+    @param *color_matrix [in] Foreground and background color
+    @param y [in] Y location of line
+    @param start [in] Left of line
+    @param end [in] Right of line
+*/
+static void drawHLine(
+    SDL_Surface *surface,
+    SDLPango_Matrix *color_matrix,
+    int y,
+    int start,
+    int end)
+{
+    Uint8 *p;
+    Uint16 *p16;
+    Uint32 *p32;
+    Uint32 color;
+    int ix;
+    int pixel_bytes = surface->format->BytesPerPixel;
+
+    if (y < 0 || y >= surface->h)
+	return;
+
+    if (end <= 0 || start >= surface->w)
+	return;
+
+    if (start < 0)
+	start = 0;
+
+    if (end >= surface->w)
+	end = surface->w;
+
+    p = (Uint8 *)(surface->pixels) + y * surface->pitch + start * pixel_bytes;
+    color = SDL_MapRGBA(surface->format,
+	color_matrix->m[0][1],
+	color_matrix->m[1][1], 
+	color_matrix->m[2][1], 
+	color_matrix->m[3][1]);
+
+    switch(pixel_bytes) {
+    case 2:
+	p16 = (Uint16 *)p;
+	for (ix = 0; ix < end - start; ix++)
+	    *p16++ = (Uint16)color;
+	break;
+    case 4:
+	p32 = (Uint32 *)p;
+	for (ix = 0; ix < end - start; ix++)
+	    *p32++ = color;
+	break;
+    default:
+	SDL_SetError("surface->format->BytesPerPixel is invalid value");
+	break;
+    }
+}
+
+/*!
+    Draw a line.
+
+    @param *context [in] Context
+    @param *surface [out] Surface to draw on it
+    @param *line [in] Innter variable of Pango
+    @param x [in] X location of line
+    @param y [in] Y location of line
+    @param height [in] Height of line
+    @param baseline [in] Rise / sink of line (for super/subscript)
+*/
+static void
+drawLine(
+    SDLPango_Context *context,
+    SDL_Surface *surface,
+    PangoLayoutLine *line,
+    gint x, 
+    gint y, 
+    gint height,
+    gint baseline)
+{
+    GSList *tmp_list = line->runs;
+    PangoColor fg_color, bg_color;
+    PangoRectangle logical_rect;
+    PangoRectangle ink_rect;
+    int x_off = 0;
+
+    while (tmp_list) {
+	SDLPango_Matrix color_matrix = context->color_matrix;
+	PangoUnderline uline = PANGO_UNDERLINE_NONE;
+	gboolean strike, fg_set, bg_set, shape_set;
+	gint rise, risen_y;
+	PangoLayoutRun *run = tmp_list->data;
+	SDL_Rect d_rect;
+
+	tmp_list = tmp_list->next;
+
+	getItemProperties(run->item,
+	    &uline, &strike, &rise,
+	    &fg_color, &fg_set, &bg_color, &bg_set,
+	    &shape_set, &ink_rect, &logical_rect);
+
+	risen_y = y + baseline - PANGO_PIXELS (rise);
+
+	if(fg_set) {
+	    color_matrix.m[0][1] = (Uint8)(fg_color.red >> 8);
+	    color_matrix.m[1][1] = (Uint8)(fg_color.green >> 8);
+	    color_matrix.m[2][1] = (Uint8)(fg_color.blue >> 8);
+	    color_matrix.m[3][1] = 255;
+	    if(color_matrix.m[3][0] == 0) {
+		color_matrix.m[0][0] = (Uint8)(fg_color.red >> 8);
+		color_matrix.m[1][0] = (Uint8)(fg_color.green >> 8);
+		color_matrix.m[2][0] = (Uint8)(fg_color.blue >> 8);
+	    }
+	}
+
+	if (bg_set) {
+	    color_matrix.m[0][0] = (Uint8)(bg_color.red >> 8);
+	    color_matrix.m[1][0] = (Uint8)(bg_color.green >> 8);
+	    color_matrix.m[2][0] = (Uint8)(bg_color.blue >> 8);
+	    color_matrix.m[3][0] = 255;
+	}
+
+	if(! shape_set) {
+	    if (uline == PANGO_UNDERLINE_NONE)
+		pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
+					    NULL, &logical_rect);
+	    else
+		pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
+					    &ink_rect, &logical_rect);
+
+	    d_rect.w = (Uint16)PANGO_PIXELS(logical_rect.width);
+	    d_rect.h = (Uint16)height;
+	    d_rect.x = (Uint16)(x + PANGO_PIXELS (x_off));
+	    d_rect.y = (Uint16)(risen_y - baseline);
+
+	    if((! context->tmp_ftbitmap) || d_rect.w + d_rect.x > context->tmp_ftbitmap->width
+		|| d_rect.h + d_rect.y > context->tmp_ftbitmap->rows)
+	    {
+		freeFTBitmap(context->tmp_ftbitmap);
+		context->tmp_ftbitmap = createFTBitmap(d_rect.w + d_rect.x, d_rect.h + d_rect.y);
+	    }
+
+	    drawGlyphString(context, surface, 
+		&color_matrix, 
+		run->item->analysis.font, run->glyphs, &d_rect, baseline);
+	}
+        switch (uline) {
+	case PANGO_UNDERLINE_NONE:
+	    break;
+	case PANGO_UNDERLINE_DOUBLE:
+	    drawHLine(surface, &color_matrix,
+		risen_y + 4,
+		x + PANGO_PIXELS (x_off + ink_rect.x),
+		x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width));
+	  /* Fall through */
+	case PANGO_UNDERLINE_SINGLE:
+	    drawHLine(surface, &color_matrix,
+		risen_y + 2,
+		x + PANGO_PIXELS (x_off + ink_rect.x),
+		x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width));
+	    break;
+	case PANGO_UNDERLINE_ERROR:
+	    {
+		int point_x;
+		int counter = 0;
+		int end_x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width);
+
+		for (point_x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1;
+		    point_x <= end_x;
+		    point_x += 2)
+		{
+		    if (counter)
+			drawHLine(surface, &color_matrix,
+			    risen_y + 2,
+			    point_x, MIN (point_x + 1, end_x));
+		    else
+			drawHLine(surface, &color_matrix,
+			    risen_y + 3,
+			    point_x, MIN (point_x + 1, end_x));
+    		
+		    counter = (counter + 1) % 2;
+		}
+	    }
+	    break;
+	case PANGO_UNDERLINE_LOW:
+	    drawHLine(surface, &color_matrix,
+		risen_y + PANGO_PIXELS (ink_rect.y + ink_rect.height),
+		x + PANGO_PIXELS (x_off + ink_rect.x),
+		x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width));
+	  break;
+	}
+
+        if (strike)
+	    drawHLine(surface, &color_matrix,
+		risen_y + PANGO_PIXELS (logical_rect.y + logical_rect.height / 2),
+		x + PANGO_PIXELS (x_off + logical_rect.x),
+		x + PANGO_PIXELS (x_off + logical_rect.x + logical_rect.width));
+
+	x_off += logical_rect.width;
+    }
+}
+
+/*!
+    Innter function of Pango. Stolen from GDK.
+
+    @param *item [in] The item to get property
+    @param *uline [out] Kind of underline
+    @param *strikethrough [out] Strike-through line
+    @param *rise [out] Rise/sink of line (for super/subscript)
+    @param *fg_color [out] Color of foreground
+    @param *fg_set [out] True if fg_color set
+    @param *bg_color [out] Color of background
+    @param *bg_set [out] True if bg_color valid
+    @param *shape_set [out] True if ink_rect and logical_rect valid
+    @param *ink_rect [out] Ink rect
+    @param *logical_rect [out] Logical rect
+*/
+static void
+getItemProperties (
+    PangoItem *item,
+    PangoUnderline *uline,
+    gboolean *strikethrough,
+    gint *rise,
+    PangoColor *fg_color,
+    gboolean *fg_set,
+    PangoColor *bg_color,
+    gboolean *bg_set,
+    gboolean *shape_set,
+    PangoRectangle *ink_rect,
+    PangoRectangle *logical_rect)
+{
+    GSList *tmp_list = item->analysis.extra_attrs;
+
+    if (strikethrough)
+	*strikethrough = FALSE;
+  
+    if (fg_set)
+        *fg_set = FALSE;
+
+    if (bg_set)
+	*bg_set = FALSE;
+
+    if (shape_set)
+	*shape_set = FALSE;
+
+    if (rise)
+	*rise = 0;
+
+    while (tmp_list) {
+	PangoAttribute *attr = tmp_list->data;
+
+	switch (attr->klass->type) {
+	case PANGO_ATTR_UNDERLINE:
+	    if (uline)
+		*uline = ((PangoAttrInt *)attr)->value;
+	    break;
+
+	case PANGO_ATTR_STRIKETHROUGH:
+	    if (strikethrough)
+		*strikethrough = ((PangoAttrInt *)attr)->value;
+	    break;
+    	
+	case PANGO_ATTR_FOREGROUND:
+	    if (fg_color)
+		*fg_color = ((PangoAttrColor *)attr)->color;
+	    if (fg_set)
+		*fg_set = TRUE;
+	    break;
+    	
+	case PANGO_ATTR_BACKGROUND:
+	    if (bg_color)
+		*bg_color = ((PangoAttrColor *)attr)->color;
+	    if (bg_set)
+		*bg_set = TRUE;
+	    break;
+
+	case PANGO_ATTR_SHAPE:
+	    if (shape_set)
+		*shape_set = TRUE;
+	    if (logical_rect)
+		*logical_rect = ((PangoAttrShape *)attr)->logical_rect;
+	    if (ink_rect)
+		*ink_rect = ((PangoAttrShape *)attr)->ink_rect;
+	    break;
+
+	case PANGO_ATTR_RISE:
+	    if (rise)
+		*rise = ((PangoAttrInt *)attr)->value;
+	    break;
+    	
+	default:
+	    break;
+	}
+	tmp_list = tmp_list->next;
+    }
+}
+
+/*!
+    Copy bitmap to surface. 
+    From (x, y)-(w, h) to (x, y)-(w, h) of rect. 
+
+    @param *bitmap [in] Grayscale bitmap
+    @param *surface [out] Surface
+    @param *matrix [in] Foreground and background color
+    @param *rect [in] Rect to copy
+*/
+void
+SDLPango_CopyFTBitmapToSurface(
+    const FT_Bitmap *bitmap,
+    SDL_Surface *surface,
+    const SDLPango_Matrix *matrix,
+    SDL_Rect *rect)
+{
+    int i;
+    Uint8 *p_ft;
+    Uint8 *p_sdl;
+    int width = rect->w;
+    int height = rect->h;
+    int x = rect->x;
+    int y = rect->y;
+
+    if(x + width > surface->w) {
+	width = surface->w - x;
+	if(width <= 0)
+	    return;
+    }
+    if(y + height > surface->h) {
+	height = surface->h - y;
+	if(height <= 0)
+	    return;
+    }
+
+    if(SDL_LockSurface(surface)) {
+	SDL_SetError("surface lock failed");
+	SDL_FreeSurface(surface);
+	return;
+    }
+
+    p_ft = (Uint8 *)bitmap->buffer + (bitmap->pitch * y);
+    p_sdl = (Uint8 *)surface->pixels + (surface->pitch * y);
+    for(i = 0; i < height; i ++) {
+	int k;
+	for(k = 0; k < width; k ++) {
+	    /* TODO: rewrite by matrix calculation library */
+	    Uint8 pixel[4];	/* 4: RGBA */
+	    int n;
+
+	    for(n = 0; n < 4; n ++) {
+		Uint16 w;
+		w = ((Uint16)matrix->m[n][0] * (256 - p_ft[k + x])) + ((Uint16)matrix->m[n][1] * p_ft[k + x]);
+		pixel[n] = (Uint8)(w >> 8);
+	    }
+
+	    switch(surface->format->BytesPerPixel) {
+	    case 2:
+		((Uint16 *)p_sdl)[k + x] = (Uint16)SDL_MapRGBA(surface->format, pixel[0], pixel[1], pixel[2], pixel[3]);
+		break;
+	    case 4:
+		((Uint32 *)p_sdl)[k + x] = SDL_MapRGBA(surface->format, pixel[0], pixel[1], pixel[2], pixel[3]);
+		break;
+	    default:
+		SDL_SetError("surface->format->BytesPerPixel is invalid value");
+		return;
+	    }
+	}
+	p_ft += bitmap->pitch;
+	p_sdl += surface->pitch;
+    }
+
+    SDL_UnlockSurface(surface);
+}
+
+SDLPango_Context*
+SDLPango_CreateContext_GivenFontDesc(const char* font_desc)
+{
+    SDLPango_Context *context = g_malloc(sizeof(SDLPango_Context));
+    G_CONST_RETURN char *charset;
+
+    context->font_map = pango_ft2_font_map_new ();
+    pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (context->font_map), DEFAULT_DPI, DEFAULT_DPI);
+
+    context->context = pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (context->font_map));
+
+    g_get_charset(&charset);
+    pango_context_set_language (context->context, pango_language_from_string (charset));
+    pango_context_set_base_dir (context->context, PANGO_DIRECTION_LTR);
+
+    context->font_desc = pango_font_description_from_string(font_desc);
+
+    context->layout = pango_layout_new (context->context);
+
+    SDLPango_SetSurfaceCreateArgs(context, SDL_SWSURFACE | SDL_SRCALPHA, DEFAULT_DEPTH,
+	DEFAULT_RMASK, DEFAULT_GMASK, DEFAULT_BMASK, DEFAULT_AMASK);
+
+    context->tmp_ftbitmap = NULL;
+
+    context->color_matrix = *MATRIX_TRANSPARENT_BACK_BLACK_LETTER;
+
+    context->min_height = 0;
+    context->min_width = 0;
+
+    return context;
+}
+
+/*!
+    Create a context which contains Pango objects.
+
+    @return A pointer to the context as a SDLPango_Context*.
+*/
+SDLPango_Context*
+SDLPango_CreateContext()
+{
+     SDLPango_CreateContext_GivenFontDesc(MAKE_FONT_NAME(DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE));
+}
+
+/*!
+    Free a context.
+
+    @param *context [i/o] Context to be free
+*/
+void
+SDLPango_FreeContext(SDLPango_Context *context)
+{
+    freeFTBitmap(context->tmp_ftbitmap);
+
+    g_object_unref (context->layout);
+
+    pango_font_description_free(context->font_desc);
+
+    g_object_unref(context->context);
+
+    g_object_unref(context->font_map);
+
+    g_free(context);
+}
+
+/*!
+    Specify Arguments when create a surface.
+    When SDL_Pango creates a surface, the arguments are used.
+
+    @param *context [i/o] Context
+    @param flags [in] Same as SDL_CreateRGBSurface()
+    @param depth [in] Same as SDL_CreateRGBSurface()
+    @param Rmask [in] Same as SDL_CreateRGBSurface()
+    @param Gmask [in] Same as SDL_CreateRGBSurface()
+    @param Bmask [in] Same as SDL_CreateRGBSurface()
+    @param Amask [in] Same as SDL_CreateRGBSurface()
+*/
+void
+SDLPango_SetSurfaceCreateArgs(
+    SDLPango_Context *context,
+    Uint32 flags,
+    int depth,
+    Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
+{
+    context->surface_args.flags = flags;
+    context->surface_args.depth = depth;
+    context->surface_args.Rmask = Rmask;
+    context->surface_args.Gmask = Gmask;
+    context->surface_args.Bmask = Bmask;
+    context->surface_args.Amask = Amask;
+}
+
+/*!
+    Create a surface and draw text on it.
+    The size of surface is same as lauout size.
+
+    @param *context [in] Context
+    @return A newly created surface
+*/
+SDL_Surface * SDLPango_CreateSurfaceDraw(
+    SDLPango_Context *context)
+{
+    PangoRectangle logical_rect;
+    SDL_Surface *surface;
+    int width, height;
+
+    pango_layout_get_extents (context->layout, NULL, &logical_rect);
+    width = PANGO_PIXELS (logical_rect.width);
+    height = PANGO_PIXELS (logical_rect.height);
+    if(width < context->min_width)
+	width = context->min_width;
+    if(height < context->min_height)
+	height = context->min_height;
+
+    surface = SDL_CreateRGBSurface(
+	context->surface_args.flags,
+	width, height, context->surface_args.depth,
+	context->surface_args.Rmask,
+	context->surface_args.Gmask,
+	context->surface_args.Bmask,
+	context->surface_args.Amask);
+
+    SDLPango_Draw(context, surface, 0, 0);
+
+    return surface;
+}
+
+/*!
+    Draw text on a existing surface.
+
+    @param *context [in] Context
+    @param *surface [i/o] Surface to draw on it
+    @param x [in] X of left-top of drawing area
+    @param y [in] Y of left-top of drawing area
+*/
+void
+SDLPango_Draw(
+    SDLPango_Context *context,
+    SDL_Surface *surface,
+    int x, int y)
+{
+    PangoLayoutIter *iter;
+    PangoRectangle logical_rect;
+    int width, height;
+
+    if(! surface) {
+	SDL_SetError("surface is NULL");
+	return;
+    }
+
+    iter = pango_layout_get_iter (context->layout);
+
+    pango_layout_get_extents (context->layout, NULL, &logical_rect);
+    width = PANGO_PIXELS (logical_rect.width);
+    height = PANGO_PIXELS (logical_rect.height);
+
+    SDL_FillRect(surface, NULL, SDL_MapRGBA(surface->format, 0, 0, 0, 0));
+
+    if((! context->tmp_ftbitmap) || context->tmp_ftbitmap->width < width
+	|| context->tmp_ftbitmap->rows < height)
+    {
+	freeFTBitmap(context->tmp_ftbitmap);
+        context->tmp_ftbitmap = createFTBitmap(width, height);
+    }
+
+    do {
+	PangoLayoutLine *line;
+	int baseline;
+
+	line = pango_layout_iter_get_line (iter);
+
+	pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
+	baseline = pango_layout_iter_get_baseline (iter);
+
+	drawLine(
+	    context,
+	    surface,
+	    line,
+	    x + PANGO_PIXELS (logical_rect.x),
+	    y + PANGO_PIXELS (logical_rect.y),
+	    PANGO_PIXELS (logical_rect.height),
+	    PANGO_PIXELS (baseline - logical_rect.y));
+    } while (pango_layout_iter_next_line (iter));
+
+    pango_layout_iter_free (iter);
+}
+
+/*!
+    Allocate buffer and create a FTBitmap object.
+
+    @param width [in] Width
+    @param height [in] Height
+    @return FTBitmap object
+*/
+static FT_Bitmap *
+createFTBitmap(
+    int width, int height)
+{
+    FT_Bitmap *bitmap;
+    guchar *buf;
+
+    bitmap = g_malloc(sizeof(FT_Bitmap));
+    bitmap->width = width;
+    bitmap->rows = height;
+    bitmap->pitch = (width + 3) & ~3;
+    bitmap->num_grays = 256;
+    bitmap->pixel_mode = FT_PIXEL_MODE_GRAY;
+    buf = g_malloc (bitmap->pitch * bitmap->rows);
+    memset (buf, 0x00, bitmap->pitch * bitmap->rows);
+    bitmap->buffer = buf;
+
+    return bitmap;
+}
+
+/*!
+    Free a FTBitmap object.
+
+    @param *bitmap [i/o] FTbitmap to be free
+*/
+static void
+freeFTBitmap(
+    FT_Bitmap *bitmap)
+{
+    if(bitmap) {
+	g_free(bitmap->buffer);
+	g_free(bitmap);
+    }
+}
+
+/*!
+    Clear a FTBitmap object.
+
+    @param *bitmap [i/o] FTbitmap to be clear
+*/
+static void
+clearFTBitmap(
+    FT_Bitmap *bitmap)
+{
+    Uint8 *p = (Uint8 *)bitmap->buffer;
+    int length = bitmap->pitch * bitmap->rows;
+
+    memset(p, 0, length);
+}
+
+/*!
+    Specify minimum size of drawing rect.
+
+    @param *context [i/o] Context
+    @param width [in] Width. -1 means no wrapping mode.
+    @param height [in] Height. zero/minus value means non-specified.
+*/
+void
+SDLPango_SetMinimumSize(
+    SDLPango_Context *context,
+    int width, int height)
+{
+    int pango_width;
+    if(width > 0)
+	pango_width = width * PANGO_SCALE;
+    else
+	pango_width = -1;
+    pango_layout_set_width(context->layout, pango_width);
+
+    context->min_width = width;
+    context->min_height = height;
+}
+
+/*!
+    Specify default color.
+
+    @param *context [i/o] Context
+    @param *color_matrix [in] Foreground and background color
+*/
+void
+SDLPango_SetDefaultColor(
+    SDLPango_Context *context,
+    const SDLPango_Matrix *color_matrix)
+{
+    context->color_matrix = *color_matrix;
+}
+
+/*!
+    Get layout width.
+
+    @param *context [in] Context
+    @return Width
+*/
+int
+SDLPango_GetLayoutWidth(
+    SDLPango_Context *context)
+{
+    PangoRectangle logical_rect;
+
+    pango_layout_get_extents (context->layout, NULL, &logical_rect);
+
+    return PANGO_PIXELS (logical_rect.width);
+}
+
+/*!
+    Get layout height.
+
+    @param *context [in] Context
+    @return Height
+*/
+int
+SDLPango_GetLayoutHeight(
+    SDLPango_Context *context)
+{
+    PangoRectangle logical_rect;
+
+    pango_layout_get_extents (context->layout, NULL, &logical_rect);
+
+    return PANGO_PIXELS (logical_rect.height);
+}
+
+/*!
+    Set markup text to context.
+    Text must be utf-8.
+    Markup format is same as pango.
+
+    @param *context [i/o] Context
+    @param *markup [in] Markup text
+    @param length [in] Text length. -1 means NULL-terminated text.
+*/
+void
+SDLPango_SetMarkup(
+    SDLPango_Context *context,
+    const char *markup,
+    int length)
+{
+    pango_layout_set_markup (context->layout, markup, length);
+    pango_layout_set_auto_dir (context->layout, TRUE);
+    pango_layout_set_alignment (context->layout, PANGO_ALIGN_LEFT);
+    pango_layout_set_font_description (context->layout, context->font_desc);
+}
+
+void
+SDLPango_SetText_GivenAlignment(
+    SDLPango_Context *context,
+    const char *text,
+    int length,
+    SDLPango_Alignment alignment)
+{
+    pango_layout_set_attributes(context->layout, NULL);
+    pango_layout_set_text (context->layout, text, length);
+    pango_layout_set_auto_dir (context->layout, TRUE);
+    pango_layout_set_alignment (context->layout, alignment);
+    pango_layout_set_font_description (context->layout, context->font_desc);
+}
+
+/*!
+    Set plain text to context.
+    Text must be utf-8.
+
+    @param *context [i/o] Context
+    @param *text [in] Plain text
+    @param length [in] Text length. -1 means NULL-terminated text.
+*/
+void
+SDLPango_SetText(
+    SDLPango_Context *context,
+    const char *text,
+    int length)
+{
+     SDLPango_SetText_GivenAlignment(context, text, length, SDLPANGO_ALIGN_LEFT);
+}
+
+/*!
+    Set DPI to context.
+
+    @param *context [i/o] Context
+    @param dpi_x [in] X dpi
+    @param dpi_y [in] Y dpi
+*/
+void
+SDLPango_SetDpi(
+    SDLPango_Context *context,
+    double dpi_x, double dpi_y)
+{
+    pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (context->font_map), dpi_x, dpi_y);
+}
+
+/*!
+    Set language to context.
+
+    @param *context [i/o] Context
+    @param *language_tag [in] A RFC-3066 format language tag 
+*/
+void SDLCALL SDLPango_SetLanguage(
+    SDLPango_Context *context,
+    const char *language_tag)
+{
+    pango_context_set_language (context->context, pango_language_from_string (language_tag));
+}
+
+/*!
+    Set base direction to context.
+
+    @param *context [i/o] Context
+    @param direction [in] Direction
+*/
+void SDLCALL SDLPango_SetBaseDirection(
+    SDLPango_Context *context,
+    SDLPango_Direction direction)
+{
+    PangoDirection pango_dir;
+
+    switch(direction) {
+    case SDLPANGO_DIRECTION_LTR:
+	pango_dir = PANGO_DIRECTION_LTR;
+	break;
+    case SDLPANGO_DIRECTION_RTL:
+	pango_dir = PANGO_DIRECTION_RTL;
+	break;
+    case SDLPANGO_DIRECTION_WEAK_LTR:
+	pango_dir = PANGO_DIRECTION_WEAK_LTR;
+	break;
+    case SDLPANGO_DIRECTION_WEAK_RTL:
+	pango_dir = PANGO_DIRECTION_WEAK_RTL;
+	break;
+    case SDLPANGO_DIRECTION_NEUTRAL:
+	pango_dir = PANGO_DIRECTION_NEUTRAL;
+	break;
+    default:
+	SDL_SetError("unknown direction value");
+	return;
+    }
+
+    pango_context_set_base_dir (context->context, pango_dir);
+}
+
+/*!
+    Get font map from context.
+
+    @param *context [in] Context
+    @return Font map
+*/
+PangoFontMap* SDLCALL SDLPango_GetPangoFontMap(
+    SDLPango_Context *context)
+{
+    return context->font_map;
+}
+
+/*!
+    Get font description from context.
+
+    @param *context [in] Context
+    @return Font description
+*/
+PangoFontDescription* SDLCALL SDLPango_GetPangoFontDescription(
+    SDLPango_Context *context)
+{
+    return context->font_desc;
+}
+
+/*!
+    Get layout from context.
+
+    @param *context [in] Context
+    @return Layout
+*/
+PangoLayout* SDLCALL SDLPango_GetPangoLayout(
+    SDLPango_Context *context)
+{
+    return context->layout;
+}