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
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; |
|
+}
|
|
|