1 /* SDL_Pango.c -- A companion library to SDL for working with Pango.
2 Copyright (C) 2004 NAKAMURA Ken'ichi
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 \section intro Introduction
24 Pango is the text rendering engine of GNOME 2.x. SDL_Pango connects the
25 engine to SDL. In Windows, pre-built binary package (MSI and merge module)
28 \subsection dist Distribution
30 If you are a game software developer, you should know the difficulties of
31 distribution. So I will start to introduce SDL_Pango from the viewpoint
34 In Un*x, SDL_Pango is hard to use as system-independent module, because
35 it depends on fontconfig and Pango which are designed as system-singleton
36 modules. If you use SDL_Pango, your software will require those modules
37 installed to target system. If your software is shipped as shrink-wrap
38 package, it may cause much problem on your support desk. You should
39 carefully design your installation process.
41 In Windows, SDL_Pango is distributed as "merge module" which contains
42 fontconfig and Pango. Those binaries are modified as side-by-side components.
43 You should use Windows Installer and merge the module
44 on your MSI package. The merge module not only contains files, but also includes
45 custom action which must be run at installation.
47 \subsection api High-level API
49 From the viewpoint of text rendering, the heart of SDL_Pango is high-level API.
50 Other text rendering APIs, like DrawText() of Windows, font and text must be
51 specified separately. In SDL_Pango, font specification is embedded in text like
55 <span font_family="Courier New"><i>This is Courier New and italic.</i></span>
58 Color, size, subscript/superscript, obliquing, weight, and other many features
59 are also available in same way.
61 \subsection i18n Internationalized Text
63 Internationalized text is another key feature. Text is specified by UTF-8. RTL
64 script (Arabic and Hebrew) and complicated rendering (Arabic, Indic and Thai) are
65 supported. You can see it with GNOME 2.x.
67 \section get Getting Started
69 \subsection getlatest Get latest files
71 Get latest files from http://sourceforge.net/projects/sdlpango/ .
73 \subsection install Install Header and Library
75 In Windows and VS2003, I strongly recommend you to install MSI package. It contains Pango
76 and fontconfig binaries which are modified as side-by-side components. It is
77 nearly impossible to build them. (I spent much time to build them...)
79 In MinGW, I recommend you to use VS2003. Otherwise you may run into the maze of
80 distribution. If you insist MinGW, you should use MinGW binary archive.
82 In Un*x, installation consists of:
90 \subsection inc Includes
92 To use SDL_Pango functions in a C/C++ source code file, you must use the SDL_Pango.h
96 #include "SDL_Pango.h"
99 In Windows, SDL_Pango.h is installed on \c \%ProgramFiles\%\\SDL_Pango \c Development\\include
100 (usually \c C:\\Program \c Files\\SDL_Pango \c Development\\include). You should add this
101 directory to include path.
103 \subsection comp Compiling
105 In Un*x, to link with SDL_Pango you should use sdl-config to get the required SDL
106 compilation options. After that, compiling with SDL_Pango is quite easy.
108 Note: Some systems may not have the SDL_Pango library and include file in the same
109 place as the SDL library and includes are located, in that case you will need to
110 add more -I and -L paths to these command lines.
112 Simple Example for compiling an object file:
115 cc -c `sdl-config --cflags` mysource.c
118 Simple Example for linking an object file:
121 cc -o myprogram mysource.o `sdl-config --libs` -lSDL_Pango
124 Now myprogram is ready to run.
126 You can see a sample of autoconfiscation in 'test' directory.
128 In Windows, MSI package installs many dlls to \c \%ProgramFiles\%\\SDL_Pango \c Development\\import_lib.
129 To link with SDL_Pango you should use SDL_Pango.lib.
131 SDL_Pango.dll depends on many dlls and other many files. Those dlls are installed on
132 \c \%ProgramFiles\%\\SDL_Pango \c Development\\bin. MSI package adds the directory to PATH environment
135 \section devel Development
137 \subsection font Font Handling
139 In Un*x, font handling depends on fontconfig of your system.
141 In Windows, local.conf of fontconfig is placed on \c \%ProgramFiles\%\\SDL_Pango \c Development\\etc\\fonts.
142 You should know about fontconfig's font cache mechanism.
144 \subsection example Step-by-step Example
146 The operation of SDL_Pango is done via context.
149 SDLPango_Context *context = SDLPango_CreateContext();
152 Specify default colors and minimum surface size.
155 SDLPango_SetDefaultColor(context, MATRIX_TRANSPARENT_BACK_WHITE_LETTER);
156 SDLPango_SetMinimumSize(context, 640, 0);
162 SDLPango_SetMarkup(context, "This is <i>markup</i> text.", -1);
165 Now you can get the size of surface.
168 int w = SDLPango_GetLayoutWidth(context);
169 int h = SDLPango_GetLayoutHeight(context);
172 Create surface to draw.
177 SDL_Surface *surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
178 w + margin_x * 2, h + margin_y * 2,
179 32, (Uint32)(255 << (8 * 3)), (Uint32)(255 << (8 * 2)),
180 (Uint32)(255 << (8 * 1)), 255);
186 SDLPango_Draw(context, surface, margin_x, margin_y);
189 You must free the surface by yourself.
192 SDL_FreeSurface(surface);
198 SDLPango_FreeContext(context);
201 You can see actual code in \c test/testbench.cpp.
203 \subsection pack Packaging
205 In Un*x, do it yourself.
207 In Windows, font files must be installed on apprication folder (usually
208 \c C:\\Program \c Files\\[Manufacturer]\\[ProductName]). The property of
209 apprication folder must be \c TARGETDIR (this is default setting of VS2003).
210 SDL.dll also must be installed on apprication folder. Add SDL_Pango.msm to
213 \section ack Acknowledgment
215 SDL_Pango is developed with financial assistance of Information-technology Promotion Agency, Japan.
217 - NAKAMURA Ken'ichi <nakamura@sbp.fp.a.u-tokyo.ac.jp>
222 @brief Implementation of SDL_Pango
224 @author NAKAMURA Ken'ichi
229 #include <pango/pango.h>
230 #include <pango/pangoft2.h>
232 #include "SDL_Pango.h"
234 //! non-zero if initialized
235 static int IS_INITIALIZED
= 0;
237 #define DEFAULT_FONT_FAMILY "sans-serif"
238 #define DEFAULT_FONT_SIZE 12
239 #define DEFAULT_DPI 96
240 #define _MAKE_FONT_NAME(family, size) family " " #size
241 #define MAKE_FONT_NAME(family, size) _MAKE_FONT_NAME(family, size)
242 #define DEFAULT_DEPTH 32
243 #define DEFAULT_RMASK (Uint32)(255 << (8 * 3))
244 #define DEFAULT_GMASK (Uint32)(255 << (8 * 2))
245 #define DEFAULT_BMASK (Uint32)(255 << (8 * 1))
246 #define DEFAULT_AMASK (Uint32)255
248 static FT_Bitmap
*createFTBitmap(int width
, int height
);
250 static void freeFTBitmap(FT_Bitmap
*bitmap
);
252 static void getItemProperties (
254 PangoUnderline
*uline
,
255 gboolean
*strikethrough
,
257 PangoColor
*fg_color
,
259 PangoColor
*bg_color
,
262 PangoRectangle
*ink_rect
,
263 PangoRectangle
*logical_rect
);
265 static void clearFTBitmap(FT_Bitmap
*bitmap
);
267 typedef struct _surfaceArgs
{
276 typedef struct _contextImpl
{
277 PangoContext
*context
;
278 PangoFontMap
*font_map
;
279 PangoFontDescription
*font_desc
;
281 surfaceArgs surface_args
;
282 FT_Bitmap
*tmp_ftbitmap
;
283 SDLPango_Matrix color_matrix
;
289 const SDLPango_Matrix _MATRIX_WHITE_BACK
296 Specifies white back and black letter.
298 const SDLPango_Matrix
*MATRIX_WHITE_BACK
= &_MATRIX_WHITE_BACK
;
300 const SDLPango_Matrix _MATRIX_BLACK_BACK
306 Specifies black back and white letter.
308 const SDLPango_Matrix
*MATRIX_BLACK_BACK
= &_MATRIX_BLACK_BACK
;
310 const SDLPango_Matrix _MATRIX_TRANSPARENT_BACK_BLACK_LETTER
316 Specifies transparent back and black letter.
318 const SDLPango_Matrix
*MATRIX_TRANSPARENT_BACK_BLACK_LETTER
= &_MATRIX_TRANSPARENT_BACK_BLACK_LETTER
;
320 const SDLPango_Matrix _MATRIX_TRANSPARENT_BACK_WHITE_LETTER
326 Specifies transparent back and white letter.
328 const SDLPango_Matrix
*MATRIX_TRANSPARENT_BACK_WHITE_LETTER
= &_MATRIX_TRANSPARENT_BACK_WHITE_LETTER
;
330 const SDLPango_Matrix _MATRIX_TRANSPARENT_BACK_TRANSPARENT_LETTER
336 Specifies transparent back and transparent letter.
337 This is useful for KARAOKE like rendering.
339 const SDLPango_Matrix
*MATRIX_TRANSPARENT_BACK_TRANSPARENT_LETTER
= &_MATRIX_TRANSPARENT_BACK_TRANSPARENT_LETTER
;
343 Initialize the Glib and Pango API.
344 This must be called before using other functions in this library,
345 excepting SDLPango_WasInit.
346 SDL does not have to be initialized before this call.
362 Query the initilization status of the Glib and Pango API.
363 You may, of course, use this before SDLPango_Init to avoid
364 initilizing twice in a row.
366 @return zero when already initialized.
367 non-zero when not initialized.
372 return IS_INITIALIZED
;
378 @param *context [in] Context
379 @param *surface [out] Surface to draw on it
380 @param *color_matrix [in] Foreground and background color
381 @param *font [in] Innter variable of Pango
382 @param *glyphs [in] Innter variable of Pango
383 @param *rect [in] Draw on this area
384 @param baseline [in] Horizontal location of glyphs
388 SDLPango_Context
*context
,
389 SDL_Surface
*surface
,
390 SDLPango_Matrix
*color_matrix
,
392 PangoGlyphString
*glyphs
,
396 pango_ft2_render(context
->tmp_ftbitmap
, font
, glyphs
, rect
->x
, rect
->y
+ baseline
);
398 SDLPango_CopyFTBitmapToSurface(
399 context
->tmp_ftbitmap
,
404 clearFTBitmap(context
->tmp_ftbitmap
);
408 Draw horizontal line of a pixel.
410 @param *surface [out] Surface to draw on it
411 @param *color_matrix [in] Foreground and background color
412 @param y [in] Y location of line
413 @param start [in] Left of line
414 @param end [in] Right of line
416 static void drawHLine(
417 SDL_Surface
*surface
,
418 SDLPango_Matrix
*color_matrix
,
428 int pixel_bytes
= surface
->format
->BytesPerPixel
;
430 if (y
< 0 || y
>= surface
->h
)
433 if (end
<= 0 || start
>= surface
->w
)
439 if (end
>= surface
->w
)
442 p
= (Uint8
*)(surface
->pixels
) + y
* surface
->pitch
+ start
* pixel_bytes
;
443 color
= SDL_MapRGBA(surface
->format
,
444 color_matrix
->m
[0][1],
445 color_matrix
->m
[1][1],
446 color_matrix
->m
[2][1],
447 color_matrix
->m
[3][1]);
449 switch(pixel_bytes
) {
452 for (ix
= 0; ix
< end
- start
; ix
++)
453 *p16
++ = (Uint16
)color
;
457 for (ix
= 0; ix
< end
- start
; ix
++)
461 SDL_SetError("surface->format->BytesPerPixel is invalid value");
469 @param *context [in] Context
470 @param *surface [out] Surface to draw on it
471 @param *line [in] Innter variable of Pango
472 @param x [in] X location of line
473 @param y [in] Y location of line
474 @param height [in] Height of line
475 @param baseline [in] Rise / sink of line (for super/subscript)
479 SDLPango_Context
*context
,
480 SDL_Surface
*surface
,
481 PangoLayoutLine
*line
,
487 GSList
*tmp_list
= line
->runs
;
488 PangoColor fg_color
, bg_color
;
489 PangoRectangle logical_rect
;
490 PangoRectangle ink_rect
;
494 SDLPango_Matrix color_matrix
= context
->color_matrix
;
495 PangoUnderline uline
= PANGO_UNDERLINE_NONE
;
496 gboolean strike
, fg_set
, bg_set
, shape_set
;
498 PangoLayoutRun
*run
= tmp_list
->data
;
501 tmp_list
= tmp_list
->next
;
503 getItemProperties(run
->item
,
504 &uline
, &strike
, &rise
,
505 &fg_color
, &fg_set
, &bg_color
, &bg_set
,
506 &shape_set
, &ink_rect
, &logical_rect
);
508 risen_y
= y
+ baseline
- PANGO_PIXELS (rise
);
511 color_matrix
.m
[0][1] = (Uint8
)(fg_color
.red
>> 8);
512 color_matrix
.m
[1][1] = (Uint8
)(fg_color
.green
>> 8);
513 color_matrix
.m
[2][1] = (Uint8
)(fg_color
.blue
>> 8);
514 color_matrix
.m
[3][1] = 255;
515 if(color_matrix
.m
[3][0] == 0) {
516 color_matrix
.m
[0][0] = (Uint8
)(fg_color
.red
>> 8);
517 color_matrix
.m
[1][0] = (Uint8
)(fg_color
.green
>> 8);
518 color_matrix
.m
[2][0] = (Uint8
)(fg_color
.blue
>> 8);
523 color_matrix
.m
[0][0] = (Uint8
)(bg_color
.red
>> 8);
524 color_matrix
.m
[1][0] = (Uint8
)(bg_color
.green
>> 8);
525 color_matrix
.m
[2][0] = (Uint8
)(bg_color
.blue
>> 8);
526 color_matrix
.m
[3][0] = 255;
530 if (uline
== PANGO_UNDERLINE_NONE
)
531 pango_glyph_string_extents (run
->glyphs
, run
->item
->analysis
.font
,
532 NULL
, &logical_rect
);
534 pango_glyph_string_extents (run
->glyphs
, run
->item
->analysis
.font
,
535 &ink_rect
, &logical_rect
);
537 d_rect
.w
= (Uint16
)PANGO_PIXELS(logical_rect
.width
);
538 d_rect
.h
= (Uint16
)height
;
539 d_rect
.x
= (Uint16
)(x
+ PANGO_PIXELS (x_off
));
540 d_rect
.y
= (Uint16
)(risen_y
- baseline
);
542 if((! context
->tmp_ftbitmap
) || d_rect
.w
+ d_rect
.x
> context
->tmp_ftbitmap
->width
543 || d_rect
.h
+ d_rect
.y
> context
->tmp_ftbitmap
->rows
)
545 freeFTBitmap(context
->tmp_ftbitmap
);
546 context
->tmp_ftbitmap
= createFTBitmap(d_rect
.w
+ d_rect
.x
, d_rect
.h
+ d_rect
.y
);
549 drawGlyphString(context
, surface
,
551 run
->item
->analysis
.font
, run
->glyphs
, &d_rect
, baseline
);
554 case PANGO_UNDERLINE_NONE
:
556 case PANGO_UNDERLINE_DOUBLE
:
557 drawHLine(surface
, &color_matrix
,
559 x
+ PANGO_PIXELS (x_off
+ ink_rect
.x
),
560 x
+ PANGO_PIXELS (x_off
+ ink_rect
.x
+ ink_rect
.width
));
562 case PANGO_UNDERLINE_SINGLE
:
563 drawHLine(surface
, &color_matrix
,
565 x
+ PANGO_PIXELS (x_off
+ ink_rect
.x
),
566 x
+ PANGO_PIXELS (x_off
+ ink_rect
.x
+ ink_rect
.width
));
568 case PANGO_UNDERLINE_ERROR
:
572 int end_x
= x
+ PANGO_PIXELS (x_off
+ ink_rect
.x
+ ink_rect
.width
);
574 for (point_x
= x
+ PANGO_PIXELS (x_off
+ ink_rect
.x
) - 1;
579 drawHLine(surface
, &color_matrix
,
581 point_x
, MIN (point_x
+ 1, end_x
));
583 drawHLine(surface
, &color_matrix
,
585 point_x
, MIN (point_x
+ 1, end_x
));
587 counter
= (counter
+ 1) % 2;
591 case PANGO_UNDERLINE_LOW
:
592 drawHLine(surface
, &color_matrix
,
593 risen_y
+ PANGO_PIXELS (ink_rect
.y
+ ink_rect
.height
),
594 x
+ PANGO_PIXELS (x_off
+ ink_rect
.x
),
595 x
+ PANGO_PIXELS (x_off
+ ink_rect
.x
+ ink_rect
.width
));
600 drawHLine(surface
, &color_matrix
,
601 risen_y
+ PANGO_PIXELS (logical_rect
.y
+ logical_rect
.height
/ 2),
602 x
+ PANGO_PIXELS (x_off
+ logical_rect
.x
),
603 x
+ PANGO_PIXELS (x_off
+ logical_rect
.x
+ logical_rect
.width
));
605 x_off
+= logical_rect
.width
;
610 Innter function of Pango. Stolen from GDK.
612 @param *item [in] The item to get property
613 @param *uline [out] Kind of underline
614 @param *strikethrough [out] Strike-through line
615 @param *rise [out] Rise/sink of line (for super/subscript)
616 @param *fg_color [out] Color of foreground
617 @param *fg_set [out] True if fg_color set
618 @param *bg_color [out] Color of background
619 @param *bg_set [out] True if bg_color valid
620 @param *shape_set [out] True if ink_rect and logical_rect valid
621 @param *ink_rect [out] Ink rect
622 @param *logical_rect [out] Logical rect
627 PangoUnderline
*uline
,
628 gboolean
*strikethrough
,
630 PangoColor
*fg_color
,
632 PangoColor
*bg_color
,
635 PangoRectangle
*ink_rect
,
636 PangoRectangle
*logical_rect
)
638 GSList
*tmp_list
= item
->analysis
.extra_attrs
;
641 *strikethrough
= FALSE
;
656 PangoAttribute
*attr
= tmp_list
->data
;
658 switch (attr
->klass
->type
) {
659 case PANGO_ATTR_UNDERLINE
:
661 *uline
= ((PangoAttrInt
*)attr
)->value
;
664 case PANGO_ATTR_STRIKETHROUGH
:
666 *strikethrough
= ((PangoAttrInt
*)attr
)->value
;
669 case PANGO_ATTR_FOREGROUND
:
671 *fg_color
= ((PangoAttrColor
*)attr
)->color
;
676 case PANGO_ATTR_BACKGROUND
:
678 *bg_color
= ((PangoAttrColor
*)attr
)->color
;
683 case PANGO_ATTR_SHAPE
:
687 *logical_rect
= ((PangoAttrShape
*)attr
)->logical_rect
;
689 *ink_rect
= ((PangoAttrShape
*)attr
)->ink_rect
;
692 case PANGO_ATTR_RISE
:
694 *rise
= ((PangoAttrInt
*)attr
)->value
;
700 tmp_list
= tmp_list
->next
;
705 Copy bitmap to surface.
706 From (x, y)-(w, h) to (x, y)-(w, h) of rect.
708 @param *bitmap [in] Grayscale bitmap
709 @param *surface [out] Surface
710 @param *matrix [in] Foreground and background color
711 @param *rect [in] Rect to copy
714 SDLPango_CopyFTBitmapToSurface(
715 const FT_Bitmap
*bitmap
,
716 SDL_Surface
*surface
,
717 const SDLPango_Matrix
*matrix
,
724 int height
= rect
->h
;
728 if(x
+ width
> surface
->w
) {
729 width
= surface
->w
- x
;
733 if(y
+ height
> surface
->h
) {
734 height
= surface
->h
- y
;
739 if(SDL_LockSurface(surface
)) {
740 SDL_SetError("surface lock failed");
741 SDL_FreeSurface(surface
);
745 p_ft
= (Uint8
*)bitmap
->buffer
+ (bitmap
->pitch
* y
);
746 p_sdl
= (Uint8
*)surface
->pixels
+ (surface
->pitch
* y
);
747 for(i
= 0; i
< height
; i
++) {
749 for(k
= 0; k
< width
; k
++) {
750 /* TODO: rewrite by matrix calculation library */
751 Uint8 pixel
[4]; /* 4: RGBA */
754 for(n
= 0; n
< 4; n
++) {
756 w
= ((Uint16
)matrix
->m
[n
][0] * (256 - p_ft
[k
+ x
])) + ((Uint16
)matrix
->m
[n
][1] * p_ft
[k
+ x
]);
757 pixel
[n
] = (Uint8
)(w
>> 8);
760 switch(surface
->format
->BytesPerPixel
) {
762 ((Uint16
*)p_sdl
)[k
+ x
] = (Uint16
)SDL_MapRGBA(surface
->format
, pixel
[0], pixel
[1], pixel
[2], pixel
[3]);
765 ((Uint32
*)p_sdl
)[k
+ x
] = SDL_MapRGBA(surface
->format
, pixel
[0], pixel
[1], pixel
[2], pixel
[3]);
768 SDL_SetError("surface->format->BytesPerPixel is invalid value");
772 p_ft
+= bitmap
->pitch
;
773 p_sdl
+= surface
->pitch
;
776 SDL_UnlockSurface(surface
);
781 SDLPango_CreateContext_GivenFontDesc(const char* font_desc
)
783 SDLPango_Context
*context
= g_malloc(sizeof(SDLPango_Context
));
784 G_CONST_RETURN
char *charset
;
786 context
->font_map
= pango_ft2_font_map_new ();
787 pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (context
->font_map
), DEFAULT_DPI
, DEFAULT_DPI
);
789 context
->context
= pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (context
->font_map
));
791 g_get_charset(&charset
);
792 pango_context_set_language (context
->context
, pango_language_from_string (charset
));
793 pango_context_set_base_dir (context
->context
, PANGO_DIRECTION_LTR
);
795 context
->font_desc
= pango_font_description_from_string(font_desc
);
797 context
->layout
= pango_layout_new (context
->context
);
799 SDLPango_SetSurfaceCreateArgs(context
, SDL_SWSURFACE
| SDL_SRCALPHA
, DEFAULT_DEPTH
,
800 DEFAULT_RMASK
, DEFAULT_GMASK
, DEFAULT_BMASK
, DEFAULT_AMASK
);
802 context
->tmp_ftbitmap
= NULL
;
804 context
->color_matrix
= *MATRIX_TRANSPARENT_BACK_BLACK_LETTER
;
806 context
->min_height
= 0;
807 context
->min_width
= 0;
813 Create a context which contains Pango objects.
815 @return A pointer to the context as a SDLPango_Context*.
818 SDLPango_CreateContext()
820 SDLPango_CreateContext_GivenFontDesc(MAKE_FONT_NAME(DEFAULT_FONT_FAMILY
, DEFAULT_FONT_SIZE
));
826 @param *context [i/o] Context to be free
829 SDLPango_FreeContext(SDLPango_Context
*context
)
831 freeFTBitmap(context
->tmp_ftbitmap
);
833 g_object_unref (context
->layout
);
835 pango_font_description_free(context
->font_desc
);
837 g_object_unref(context
->context
);
839 g_object_unref(context
->font_map
);
845 Specify Arguments when create a surface.
846 When SDL_Pango creates a surface, the arguments are used.
848 @param *context [i/o] Context
849 @param flags [in] Same as SDL_CreateRGBSurface()
850 @param depth [in] Same as SDL_CreateRGBSurface()
851 @param Rmask [in] Same as SDL_CreateRGBSurface()
852 @param Gmask [in] Same as SDL_CreateRGBSurface()
853 @param Bmask [in] Same as SDL_CreateRGBSurface()
854 @param Amask [in] Same as SDL_CreateRGBSurface()
857 SDLPango_SetSurfaceCreateArgs(
858 SDLPango_Context
*context
,
861 Uint32 Rmask
, Uint32 Gmask
, Uint32 Bmask
, Uint32 Amask
)
863 context
->surface_args
.flags
= flags
;
864 context
->surface_args
.depth
= depth
;
865 context
->surface_args
.Rmask
= Rmask
;
866 context
->surface_args
.Gmask
= Gmask
;
867 context
->surface_args
.Bmask
= Bmask
;
868 context
->surface_args
.Amask
= Amask
;
872 Create a surface and draw text on it.
873 The size of surface is same as lauout size.
875 @param *context [in] Context
876 @return A newly created surface
878 SDL_Surface
* SDLPango_CreateSurfaceDraw(
879 SDLPango_Context
*context
)
881 PangoRectangle logical_rect
;
882 SDL_Surface
*surface
;
885 pango_layout_get_extents (context
->layout
, NULL
, &logical_rect
);
886 width
= PANGO_PIXELS (logical_rect
.width
);
887 height
= PANGO_PIXELS (logical_rect
.height
);
888 if(width
< context
->min_width
)
889 width
= context
->min_width
;
890 if(height
< context
->min_height
)
891 height
= context
->min_height
;
893 surface
= SDL_CreateRGBSurface(
894 context
->surface_args
.flags
,
895 width
, height
, context
->surface_args
.depth
,
896 context
->surface_args
.Rmask
,
897 context
->surface_args
.Gmask
,
898 context
->surface_args
.Bmask
,
899 context
->surface_args
.Amask
);
901 SDLPango_Draw(context
, surface
, 0, 0);
907 Draw text on a existing surface.
909 @param *context [in] Context
910 @param *surface [i/o] Surface to draw on it
911 @param x [in] X of left-top of drawing area
912 @param y [in] Y of left-top of drawing area
916 SDLPango_Context
*context
,
917 SDL_Surface
*surface
,
920 PangoLayoutIter
*iter
;
921 PangoRectangle logical_rect
;
925 SDL_SetError("surface is NULL");
929 iter
= pango_layout_get_iter (context
->layout
);
931 pango_layout_get_extents (context
->layout
, NULL
, &logical_rect
);
932 width
= PANGO_PIXELS (logical_rect
.width
);
933 height
= PANGO_PIXELS (logical_rect
.height
);
935 if (width
&& height
) {
936 SDL_FillRect(surface
, NULL
, SDL_MapRGBA(surface
->format
, 0, 0, 0, 0));
939 if((! context
->tmp_ftbitmap
) || context
->tmp_ftbitmap
->width
< width
940 || context
->tmp_ftbitmap
->rows
< height
)
942 freeFTBitmap(context
->tmp_ftbitmap
);
943 context
->tmp_ftbitmap
= createFTBitmap(width
, height
);
947 PangoLayoutLine
*line
;
950 line
= pango_layout_iter_get_line (iter
);
952 pango_layout_iter_get_line_extents (iter
, NULL
, &logical_rect
);
953 baseline
= pango_layout_iter_get_baseline (iter
);
959 x
+ PANGO_PIXELS (logical_rect
.x
),
960 y
+ PANGO_PIXELS (logical_rect
.y
),
961 PANGO_PIXELS (logical_rect
.height
),
962 PANGO_PIXELS (baseline
- logical_rect
.y
));
963 } while (pango_layout_iter_next_line (iter
));
965 pango_layout_iter_free (iter
);
969 Allocate buffer and create a FTBitmap object.
971 @param width [in] Width
972 @param height [in] Height
973 @return FTBitmap object
977 int width
, int height
)
982 bitmap
= g_malloc(sizeof(FT_Bitmap
));
983 bitmap
->width
= width
;
984 bitmap
->rows
= height
;
985 bitmap
->pitch
= (width
+ 3) & ~3;
986 bitmap
->num_grays
= 256;
987 bitmap
->pixel_mode
= FT_PIXEL_MODE_GRAY
;
988 buf
= g_malloc (bitmap
->pitch
* bitmap
->rows
);
989 memset (buf
, 0x00, bitmap
->pitch
* bitmap
->rows
);
990 bitmap
->buffer
= buf
;
996 Free a FTBitmap object.
998 @param *bitmap [i/o] FTbitmap to be free
1005 g_free(bitmap
->buffer
);
1011 Clear a FTBitmap object.
1013 @param *bitmap [i/o] FTbitmap to be clear
1019 Uint8
*p
= (Uint8
*)bitmap
->buffer
;
1020 int length
= bitmap
->pitch
* bitmap
->rows
;
1022 memset(p
, 0, length
);
1026 Specify minimum size of drawing rect.
1028 @param *context [i/o] Context
1029 @param width [in] Width. -1 means no wrapping mode.
1030 @param height [in] Height. zero/minus value means non-specified.
1033 SDLPango_SetMinimumSize(
1034 SDLPango_Context
*context
,
1035 int width
, int height
)
1039 pango_width
= width
* PANGO_SCALE
;
1042 pango_layout_set_width(context
->layout
, pango_width
);
1044 context
->min_width
= width
;
1045 context
->min_height
= height
;
1049 Specify default color.
1051 @param *context [i/o] Context
1052 @param *color_matrix [in] Foreground and background color
1055 SDLPango_SetDefaultColor(
1056 SDLPango_Context
*context
,
1057 const SDLPango_Matrix
*color_matrix
)
1059 context
->color_matrix
= *color_matrix
;
1065 @param *context [in] Context
1069 SDLPango_GetLayoutWidth(
1070 SDLPango_Context
*context
)
1072 PangoRectangle logical_rect
;
1074 pango_layout_get_extents (context
->layout
, NULL
, &logical_rect
);
1076 return PANGO_PIXELS (logical_rect
.width
);
1082 @param *context [in] Context
1086 SDLPango_GetLayoutHeight(
1087 SDLPango_Context
*context
)
1089 PangoRectangle logical_rect
;
1091 pango_layout_get_extents (context
->layout
, NULL
, &logical_rect
);
1093 return PANGO_PIXELS (logical_rect
.height
);
1097 Set markup text to context.
1099 Markup format is same as pango.
1101 @param *context [i/o] Context
1102 @param *markup [in] Markup text
1103 @param length [in] Text length. -1 means NULL-terminated text.
1107 SDLPango_Context
*context
,
1111 pango_layout_set_markup (context
->layout
, markup
, length
);
1112 pango_layout_set_auto_dir (context
->layout
, TRUE
);
1113 pango_layout_set_alignment (context
->layout
, PANGO_ALIGN_LEFT
);
1114 pango_layout_set_font_description (context
->layout
, context
->font_desc
);
1118 SDLPango_SetText_GivenAlignment(
1119 SDLPango_Context
*context
,
1122 SDLPango_Alignment alignment
)
1124 pango_layout_set_attributes(context
->layout
, NULL
);
1125 pango_layout_set_text (context
->layout
, text
, length
);
1126 pango_layout_set_auto_dir (context
->layout
, TRUE
);
1127 pango_layout_set_alignment (context
->layout
, alignment
);
1128 pango_layout_set_font_description (context
->layout
, context
->font_desc
);
1132 Set plain text to context.
1135 @param *context [i/o] Context
1136 @param *text [in] Plain text
1137 @param length [in] Text length. -1 means NULL-terminated text.
1141 SDLPango_Context
*context
,
1145 SDLPango_SetText_GivenAlignment(context
, text
, length
, SDLPANGO_ALIGN_LEFT
);
1151 @param *context [i/o] Context
1152 @param dpi_x [in] X dpi
1153 @param dpi_y [in] Y dpi
1157 SDLPango_Context
*context
,
1158 double dpi_x
, double dpi_y
)
1160 pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (context
->font_map
), dpi_x
, dpi_y
);
1164 Set language to context.
1166 @param *context [i/o] Context
1167 @param *language_tag [in] A RFC-3066 format language tag
1169 void SDLCALL
SDLPango_SetLanguage(
1170 SDLPango_Context
*context
,
1171 const char *language_tag
)
1173 pango_context_set_language (context
->context
, pango_language_from_string (language_tag
));
1177 Set base direction to context.
1179 @param *context [i/o] Context
1180 @param direction [in] Direction
1182 void SDLCALL
SDLPango_SetBaseDirection(
1183 SDLPango_Context
*context
,
1184 SDLPango_Direction direction
)
1186 PangoDirection pango_dir
;
1189 case SDLPANGO_DIRECTION_LTR
:
1190 pango_dir
= PANGO_DIRECTION_LTR
;
1192 case SDLPANGO_DIRECTION_RTL
:
1193 pango_dir
= PANGO_DIRECTION_RTL
;
1195 case SDLPANGO_DIRECTION_WEAK_LTR
:
1196 pango_dir
= PANGO_DIRECTION_WEAK_LTR
;
1198 case SDLPANGO_DIRECTION_WEAK_RTL
:
1199 pango_dir
= PANGO_DIRECTION_WEAK_RTL
;
1201 case SDLPANGO_DIRECTION_NEUTRAL
:
1202 pango_dir
= PANGO_DIRECTION_NEUTRAL
;
1205 SDL_SetError("unknown direction value");
1209 pango_context_set_base_dir (context
->context
, pango_dir
);
1213 Get font map from context.
1215 @param *context [in] Context
1218 PangoFontMap
* SDLCALL
SDLPango_GetPangoFontMap(
1219 SDLPango_Context
*context
)
1221 return context
->font_map
;
1225 Get font description from context.
1227 @param *context [in] Context
1228 @return Font description
1230 PangoFontDescription
* SDLCALL
SDLPango_GetPangoFontDescription(
1231 SDLPango_Context
*context
)
1233 return context
->font_desc
;
1237 Get layout from context.
1239 @param *context [in] Context
1242 PangoLayout
* SDLCALL
SDLPango_GetPangoLayout(
1243 SDLPango_Context
*context
)
1245 return context
->layout
;