You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2811 lines
76 KiB

# --- 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 <nakamura@sbp.fp.a.u-tokyo.ac.jp>
-
-*/
-
-/*! @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 <nakamura@sbp.fp.a.u-tokyo.ac.jp>
+
+*/
+
+/*! @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;
+}