From 85aec3aab36c8daaa8d4fc7bb7e22a14eccb8665 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Mon, 21 Oct 2002 22:58:20 +0000 Subject: Change semantics of this flag. If defined, also need to set env var 2002-10-22 Tor Lillqvist * pango/pangowin32-private.h (PANGO_WIN32_DEBUGGING): Change semantics of this flag. If defined, also need to set env var PANGO_WIN32_DEBUG to get the copious debugging output. Change PING() macro accordingly. Add variable pango_win32_debug. * pango/pangowin32.c (pango_win32_get_dc): New function. Code factored out from pango_win32_font_class_init() and pango_win32_font_map_class_init(). (pango_win32_get_debug_flag): New function. (pango_win32_render): Handle y offsets, too. Potentially need to call ExtTextOutW several times, one for each run of sequential glyphs with the same y offset. * pango/pangowin32.h: Declare above new functions, in the part only for shaper engine use. * pango/pangowin32.def: Export above new functions. * pango/pangowin32-fontmap.c (pango_win32_font_map_class_init): Call pango_win32_get_dc() as mentioned above. --- ChangeLog | 23 +++++ ChangeLog.pre-1-10 | 23 +++++ ChangeLog.pre-1-2 | 23 +++++ ChangeLog.pre-1-4 | 23 +++++ ChangeLog.pre-1-6 | 23 +++++ ChangeLog.pre-1-8 | 23 +++++ pango/pangowin32-fontmap.c | 5 +- pango/pangowin32-private.h | 30 ++++-- pango/pangowin32.c | 245 +++++++++++++++++++++++++++++++-------------- pango/pangowin32.def | 2 + pango/pangowin32.h | 4 + 11 files changed, 334 insertions(+), 90 deletions(-) diff --git a/ChangeLog b/ChangeLog index db6e1973..7e24ecb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2002-10-22 Tor Lillqvist + + * pango/pangowin32-private.h (PANGO_WIN32_DEBUGGING): Change + semantics of this flag. If defined, also need to set env var + PANGO_WIN32_DEBUG to get the copious debugging output. + Change PING() macro accordingly. Add variable pango_win32_debug. + + * pango/pangowin32.c (pango_win32_get_dc): New function. Code + factored out from pango_win32_font_class_init() and + pango_win32_font_map_class_init(). + (pango_win32_get_debug_flag): New function. + (pango_win32_render): Handle y offsets, too. Potentially need to + call ExtTextOutW several times, one for each run of sequential + glyphs with the same y offset. + + * pango/pangowin32.h: Declare above new functions, in the part + only for shaper engine use. + + * pango/pangowin32.def: Export above new functions. + + * pango/pangowin32-fontmap.c (pango_win32_font_map_class_init): + Call pango_win32_get_dc() as mentioned above. + 2002-10-15 Changwoo Ryu * modules/hangul/hangul-x.c (hangul_engine_shape): Fixed leaks diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index db6e1973..7e24ecb9 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,26 @@ +2002-10-22 Tor Lillqvist + + * pango/pangowin32-private.h (PANGO_WIN32_DEBUGGING): Change + semantics of this flag. If defined, also need to set env var + PANGO_WIN32_DEBUG to get the copious debugging output. + Change PING() macro accordingly. Add variable pango_win32_debug. + + * pango/pangowin32.c (pango_win32_get_dc): New function. Code + factored out from pango_win32_font_class_init() and + pango_win32_font_map_class_init(). + (pango_win32_get_debug_flag): New function. + (pango_win32_render): Handle y offsets, too. Potentially need to + call ExtTextOutW several times, one for each run of sequential + glyphs with the same y offset. + + * pango/pangowin32.h: Declare above new functions, in the part + only for shaper engine use. + + * pango/pangowin32.def: Export above new functions. + + * pango/pangowin32-fontmap.c (pango_win32_font_map_class_init): + Call pango_win32_get_dc() as mentioned above. + 2002-10-15 Changwoo Ryu * modules/hangul/hangul-x.c (hangul_engine_shape): Fixed leaks diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2 index db6e1973..7e24ecb9 100644 --- a/ChangeLog.pre-1-2 +++ b/ChangeLog.pre-1-2 @@ -1,3 +1,26 @@ +2002-10-22 Tor Lillqvist + + * pango/pangowin32-private.h (PANGO_WIN32_DEBUGGING): Change + semantics of this flag. If defined, also need to set env var + PANGO_WIN32_DEBUG to get the copious debugging output. + Change PING() macro accordingly. Add variable pango_win32_debug. + + * pango/pangowin32.c (pango_win32_get_dc): New function. Code + factored out from pango_win32_font_class_init() and + pango_win32_font_map_class_init(). + (pango_win32_get_debug_flag): New function. + (pango_win32_render): Handle y offsets, too. Potentially need to + call ExtTextOutW several times, one for each run of sequential + glyphs with the same y offset. + + * pango/pangowin32.h: Declare above new functions, in the part + only for shaper engine use. + + * pango/pangowin32.def: Export above new functions. + + * pango/pangowin32-fontmap.c (pango_win32_font_map_class_init): + Call pango_win32_get_dc() as mentioned above. + 2002-10-15 Changwoo Ryu * modules/hangul/hangul-x.c (hangul_engine_shape): Fixed leaks diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index db6e1973..7e24ecb9 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,3 +1,26 @@ +2002-10-22 Tor Lillqvist + + * pango/pangowin32-private.h (PANGO_WIN32_DEBUGGING): Change + semantics of this flag. If defined, also need to set env var + PANGO_WIN32_DEBUG to get the copious debugging output. + Change PING() macro accordingly. Add variable pango_win32_debug. + + * pango/pangowin32.c (pango_win32_get_dc): New function. Code + factored out from pango_win32_font_class_init() and + pango_win32_font_map_class_init(). + (pango_win32_get_debug_flag): New function. + (pango_win32_render): Handle y offsets, too. Potentially need to + call ExtTextOutW several times, one for each run of sequential + glyphs with the same y offset. + + * pango/pangowin32.h: Declare above new functions, in the part + only for shaper engine use. + + * pango/pangowin32.def: Export above new functions. + + * pango/pangowin32-fontmap.c (pango_win32_font_map_class_init): + Call pango_win32_get_dc() as mentioned above. + 2002-10-15 Changwoo Ryu * modules/hangul/hangul-x.c (hangul_engine_shape): Fixed leaks diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index db6e1973..7e24ecb9 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,26 @@ +2002-10-22 Tor Lillqvist + + * pango/pangowin32-private.h (PANGO_WIN32_DEBUGGING): Change + semantics of this flag. If defined, also need to set env var + PANGO_WIN32_DEBUG to get the copious debugging output. + Change PING() macro accordingly. Add variable pango_win32_debug. + + * pango/pangowin32.c (pango_win32_get_dc): New function. Code + factored out from pango_win32_font_class_init() and + pango_win32_font_map_class_init(). + (pango_win32_get_debug_flag): New function. + (pango_win32_render): Handle y offsets, too. Potentially need to + call ExtTextOutW several times, one for each run of sequential + glyphs with the same y offset. + + * pango/pangowin32.h: Declare above new functions, in the part + only for shaper engine use. + + * pango/pangowin32.def: Export above new functions. + + * pango/pangowin32-fontmap.c (pango_win32_font_map_class_init): + Call pango_win32_get_dc() as mentioned above. + 2002-10-15 Changwoo Ryu * modules/hangul/hangul-x.c (hangul_engine_shape): Fixed leaks diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index db6e1973..7e24ecb9 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,26 @@ +2002-10-22 Tor Lillqvist + + * pango/pangowin32-private.h (PANGO_WIN32_DEBUGGING): Change + semantics of this flag. If defined, also need to set env var + PANGO_WIN32_DEBUG to get the copious debugging output. + Change PING() macro accordingly. Add variable pango_win32_debug. + + * pango/pangowin32.c (pango_win32_get_dc): New function. Code + factored out from pango_win32_font_class_init() and + pango_win32_font_map_class_init(). + (pango_win32_get_debug_flag): New function. + (pango_win32_render): Handle y offsets, too. Potentially need to + call ExtTextOutW several times, one for each run of sequential + glyphs with the same y offset. + + * pango/pangowin32.h: Declare above new functions, in the part + only for shaper engine use. + + * pango/pangowin32.def: Export above new functions. + + * pango/pangowin32-fontmap.c (pango_win32_font_map_class_init): + Call pango_win32_get_dc() as mentioned above. + 2002-10-15 Changwoo Ryu * modules/hangul/hangul-x.c (hangul_engine_shape): Fixed leaks diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c index f919717a..8a9caba2 100644 --- a/pango/pangowin32-fontmap.c +++ b/pango/pangowin32-fontmap.c @@ -188,8 +188,7 @@ pango_win32_font_map_class_init (PangoFontMapClass *class) class->load_font = pango_win32_font_map_load_font; class->list_families = pango_win32_font_map_list_families; - if (pango_win32_hdc == NULL) - pango_win32_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL); + pango_win32_get_dc (); } static PangoWin32FontMap *fontmap = NULL; @@ -782,7 +781,7 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap, * same entry at the moment and it isn't crashing on g_free () ??? * Maybe a memory leak ... */ - switch (lfp->lfPitchAndFamily & (0x0F << 4)) /* bit 4...7 */ + switch (lfp->lfPitchAndFamily & 0xF0) { case FF_MODERN : /* monospace */ PING(("monospace")); diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h index dc1f5faa..b1014214 100644 --- a/pango/pangowin32-private.h +++ b/pango/pangowin32-private.h @@ -24,20 +24,27 @@ #ifndef __PANGOWIN32_PRIVATE_H__ #define __PANGOWIN32_PRIVATE_H__ -/* Define if you want copious debugging output. */ -/* #define PANGO_WIN32_DEBUGGING 1 */ +/* Define if you want the possibility to get copious debugging output. + * (You still need to set the PANGO_WIN32_DEBUG environment variable + * to get it.) + */ +#define PANGO_WIN32_DEBUGGING 1 #ifdef PANGO_WIN32_DEBUGGING #ifdef __GNUC__ #define PING(printlist) \ -(printf ("%s:%d ", __PRETTY_FUNCTION__, __LINE__), \ - printf printlist, \ - printf ("\n")) +(pango_win32_debug ? \ + (printf ("%s:%d ", __PRETTY_FUNCTION__, __LINE__), \ + printf printlist, \ + printf ("\n")) : \ + 0) #else #define PING(printlist) \ -(printf ("%s:%d ", __FILE__, __LINE__), \ - printf printlist, \ - printf ("\n")) +(pango_win32_debug ? \ + (printf ("%s:%d ", __FILE__, __LINE__), \ + printf printlist, \ + printf ("\n")) : \ + 0) #endif #else /* !PANGO_WIN32_DEBUGGING */ #define PING(printlist) @@ -72,9 +79,9 @@ struct _PangoWin32Font /* Written by pango_win32_get_hfont: */ HFONT hfont; - gint tm_ascent; - gint tm_descent; - gint tm_overhang; + gint tm_ascent; + gint tm_descent; + gint tm_overhang; PangoWin32Face *win32face; @@ -198,5 +205,6 @@ gboolean pango_win32_get_name_record (HDC hdc, extern HDC pango_win32_hdc; extern OSVERSIONINFO pango_win32_os_version_info; +extern gboolean pango_win32_debug; #endif /* __PANGOWIN32_PRIVATE_H__ */ diff --git a/pango/pangowin32.c b/pango/pangowin32.c index 4141e405..5c745827 100644 --- a/pango/pangowin32.c +++ b/pango/pangowin32.c @@ -43,6 +43,7 @@ HDC pango_win32_hdc; OSVERSIONINFO pango_win32_os_version_info; +gboolean pango_win32_debug = FALSE; typedef struct _PangoWin32FontClass PangoWin32FontClass; @@ -177,6 +178,37 @@ pango_win32_font_init (PangoWin32Font *win32font) win32font->glyph_info = g_hash_table_new_full (NULL, NULL, NULL, g_free); } +HDC +pango_win32_get_dc (void) +{ + if (pango_win32_hdc == NULL) + { + pango_win32_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL); + memset (&pango_win32_os_version_info, 0, + sizeof (pango_win32_os_version_info)); + pango_win32_os_version_info.dwOSVersionInfoSize = + sizeof (OSVERSIONINFO); + GetVersionEx (&pango_win32_os_version_info); + + /* Also do some generic pangowin32 initialisations... this function + * is a suitable place for those as it is called from a couple + * of class_init functions. + */ +#ifdef PANGO_WIN32_DEBUGGING + if (getenv ("PANGO_WIN32_DEBUG") != NULL) + pango_win32_debug = TRUE; +#endif + } + + return pango_win32_hdc; +} + +gboolean +pango_win32_get_debug_flag (void) +{ + return pango_win32_debug; +} + static void pango_win32_font_class_init (PangoWin32FontClass *class) { @@ -194,15 +226,7 @@ pango_win32_font_class_init (PangoWin32FontClass *class) font_class->get_glyph_extents = pango_win32_font_get_glyph_extents; font_class->get_metrics = pango_win32_font_get_metrics; - if (pango_win32_hdc == NULL) - { - pango_win32_hdc = CreateDC ("DISPLAY", NULL, NULL, NULL); - memset (&pango_win32_os_version_info, 0, - sizeof (pango_win32_os_version_info)); - pango_win32_os_version_info.dwOSVersionInfoSize = - sizeof (OSVERSIONINFO); - GetVersionEx (&pango_win32_os_version_info); - } + pango_win32_get_dc (); } PangoWin32Font * @@ -244,16 +268,34 @@ pango_win32_render (HDC hdc, int x, int y) { - HFONT old_hfont = NULL; - HFONT hfont; - int i, num_valid_glyphs; + HFONT hfont, old_hfont = NULL; + int i, j, num_valid_glyphs; guint16 *glyph_indexes; gint *dX; - gint last_x = 0; - PangoGlyphUnit start_x_offset = 0, x_offset = 0; + gint this_x; + PangoGlyphUnit start_x_offset, x_offset, next_x_offset, cur_y_offset; g_return_if_fail (glyphs != NULL); +#ifdef PANGO_WIN32_DEBUGGING + if (pango_win32_debug) + { + PING (("num_glyphs:%d", glyphs->num_glyphs)); + for (i = 0; i < glyphs->num_glyphs; i++) + { + printf (" %d:%d", glyphs->glyphs[i].glyph, glyphs->glyphs[i].geometry.width); + if (glyphs->glyphs[i].geometry.x_offset != 0 || + glyphs->glyphs[i].geometry.y_offset != 0) + printf (":%d,%d", glyphs->glyphs[i].geometry.x_offset, + glyphs->glyphs[i].geometry.y_offset); + } + printf ("\n"); + } +#endif + + if (glyphs->num_glyphs == 0) + return; + hfont = pango_win32_get_hfont (font); if (!hfont) return; @@ -263,66 +305,107 @@ pango_win32_render (HDC hdc, glyph_indexes = g_new (guint16, glyphs->num_glyphs); dX = g_new (INT, glyphs->num_glyphs); -#ifdef PANGO_WIN32_DEBUGGING - PING (("num_glyphs:%d", glyphs->num_glyphs)); - printf (" "); - for (i = 0; i num_glyphs; i++) - printf ("%d:%d ", glyphs->glyphs[i].glyph, glyphs->glyphs[i].geometry.width); - printf ("\n"); -#endif + /* Render glyphs using one ExtTextOutW() call for each run of glyphs + * that have the same y offset. The big majoroty of glyphs will have + * y offset of zero, so in general, the whole glyph string will be + * rendered by one call to ExtTextOutW(). + * + * In order to minimize buildup of rounding errors, we keep track of + * where the glyphs should be rendered in PangoGlyphUnits, and round + * to pixels separately for each glyph, + */ + + i = 0; - num_valid_glyphs = 0; - for (i = 0; i num_glyphs; i++) + /* Outer loop through all glyphs in string */ + while (i < glyphs->num_glyphs) { - if (glyphs->glyphs[i].glyph == 0) + cur_y_offset = glyphs->glyphs[i].geometry.y_offset; + num_valid_glyphs = 0; + x_offset = 0; + start_x_offset = glyphs->glyphs[i].geometry.x_offset; + this_x = PANGO_PIXELS (start_x_offset); + + /* Inner loop through glyphs with the same y offset, or code + * point zero (just spacing). + */ + while (i < glyphs->num_glyphs && + (glyphs->glyphs[i].glyph == 0 || cur_y_offset == glyphs->glyphs[i].geometry.y_offset)) { - /* Code point 0 glyphs should not be rendered, but their - * indicated width (set up by PangoLayout) should be taken - * into account. - */ - - /* If the string starts with spacing, must shift the - * starting point for the glyphs actually rendered. For - * spacing in the middle of the glyph string, add to the dX - * of the previous glyph to be rendered. - */ - if (num_valid_glyphs == 0) - start_x_offset += glyphs->glyphs[i].geometry.width; - else + if (glyphs->glyphs[i].glyph == 0) { - x_offset += glyphs->glyphs[i].geometry.width; - dX[num_valid_glyphs-1] = PANGO_PIXELS (x_offset) - last_x; - } - } - else - { - if (glyphs->glyphs[i].glyph & PANGO_WIN32_UNKNOWN_FLAG) - { - /* Glyph index is actually the char value that doesn't - * have any glyph (ORed with the flag). We should really - * do the same that pango_xft_real_render() does: render - * a box with the char value in hex inside it in a tiny - * font. Later. For now, use the TrueType invalid glyph - * at 0. + /* Code point 0 glyphs should not be rendered, but their + * indicated width (set up by PangoLayout) should be taken + * into account. + */ + + /* If the string starts with spacing, must shift the + * starting point for the glyphs actually rendered. For + * spacing in the middle of the glyph string, add to the dX + * of the previous glyph to be rendered. */ - glyph_indexes[num_valid_glyphs] = 0; + if (num_valid_glyphs == 0) + start_x_offset += glyphs->glyphs[i].geometry.width; + else + { + x_offset += glyphs->glyphs[i].geometry.width; + dX[num_valid_glyphs-1] = PANGO_PIXELS (x_offset) - this_x; + } } else - glyph_indexes[num_valid_glyphs] = glyphs->glyphs[i].glyph; + { + if (glyphs->glyphs[i].glyph & PANGO_WIN32_UNKNOWN_FLAG) + { + /* Glyph index is actually the char value that doesn't + * have any glyph (ORed with the flag). We should really + * do the same that pango_xft_real_render() does: render + * a box with the char value in hex inside it in a tiny + * font. Later. For now, use the TrueType invalid glyph + * at 0. + */ + glyph_indexes[num_valid_glyphs] = 0; + } + else + glyph_indexes[num_valid_glyphs] = glyphs->glyphs[i].glyph; + + x_offset += glyphs->glyphs[i].geometry.width; + + /* If the next glyph has an X offset, take that into consideration now */ + if (i < glyphs->num_glyphs - 1) + next_x_offset = glyphs->glyphs[i+1].geometry.x_offset; + else + next_x_offset = 0; + + dX[num_valid_glyphs] = PANGO_PIXELS (x_offset + next_x_offset) - this_x; - if (num_valid_glyphs > 0) - last_x += dX[num_valid_glyphs-1]; - x_offset += glyphs->glyphs[i].geometry.width; - dX[num_valid_glyphs] = PANGO_PIXELS (x_offset) - last_x; - num_valid_glyphs++; + /* Prepare for next glyph */ + this_x += dX[num_valid_glyphs]; + num_valid_glyphs++; + } + i++; + } +#ifdef PANGO_WIN32_DEBUGGING + if (pango_win32_debug) + { + printf ("ExtTextOutW at %d,%d deltas:", + x + PANGO_PIXELS (start_x_offset), + y + PANGO_PIXELS (cur_y_offset)); + for (j = 0; j < num_valid_glyphs; j++) + printf (" %d", dX[j]); + printf ("\n"); } +#endif + + ExtTextOutW (hdc, + x + PANGO_PIXELS (start_x_offset), + y + PANGO_PIXELS (cur_y_offset), + ETO_GLYPH_INDEX, + NULL, + glyph_indexes, num_valid_glyphs, + dX); + x += this_x; } - ExtTextOutW (hdc, x + PANGO_PIXELS (start_x_offset), y, - ETO_GLYPH_INDEX, - NULL, - glyph_indexes, num_valid_glyphs, - dX); SelectObject (hdc, old_hfont); /* restore */ g_free (glyph_indexes); @@ -1231,10 +1314,13 @@ pango_win32_font_calc_coverage (PangoFont *font, if (id_range_offset[i] == 0) { #ifdef PANGO_WIN32_DEBUGGING - if (end_count[i] == start_count[i]) - printf ("%04x ", start_count[i]); - else - printf ("%04x:%04x ", start_count[i], end_count[i]); + if (pango_win32_debug) + { + if (end_count[i] == start_count[i]) + printf ("%04x ", start_count[i]); + else + printf ("%04x:%04x ", start_count[i], end_count[i]); + } #endif for (ch = start_count[i]; ch <= end_count[i]; @@ -1270,10 +1356,13 @@ pango_win32_font_calc_coverage (PangoFont *font, #ifdef PANGO_WIN32_DEBUGGING else if (ch0 < G_MAXUINT) { - if (ch > ch0 + 2) - printf ("%04x:%04x ", ch0, ch - 1); - else - printf ("%04x ", ch0); + if (pango_win32_debug) + { + if (ch > ch0 + 2) + printf ("%04x:%04x ", ch0, ch - 1); + else + printf ("%04x ", ch0); + } ch0 = G_MAXUINT; } #endif @@ -1281,15 +1370,19 @@ pango_win32_font_calc_coverage (PangoFont *font, #ifdef PANGO_WIN32_DEBUGGING if (ch0 < G_MAXUINT) { - if (ch > ch0 + 2) - printf ("%04x:%04x ", ch0, ch - 1); - else - printf ("%04x ", ch0); + if (pango_win32_debug) + { + if (ch > ch0 + 2) + printf ("%04x:%04x ", ch0, ch - 1); + else + printf ("%04x ", ch0); + } } #endif } } #ifdef PANGO_WIN32_DEBUGGING - printf ("\n"); + if (pango_win32_debug) + printf ("\n"); #endif } diff --git a/pango/pangowin32.def b/pango/pangowin32.def index 9592753c..0754abcc 100644 --- a/pango/pangowin32.def +++ b/pango/pangowin32.def @@ -13,6 +13,8 @@ EXPORTS pango_win32_fontmap_cache_add pango_win32_fontmap_cache_remove pango_win32_get_context + pango_win32_get_dc + pango_win32_get_debug_flag pango_win32_get_shaper_map pango_win32_get_unknown_glyph pango_win32_make_matching_logfont diff --git a/pango/pangowin32.h b/pango/pangowin32.h index 49dcd08a..ece1b829 100644 --- a/pango/pangowin32.h +++ b/pango/pangowin32.h @@ -68,6 +68,10 @@ PangoGlyph pango_win32_get_unknown_glyph (PangoFont *font, gint pango_win32_font_get_glyph_index(PangoFont *font, gunichar wc); +HDC pango_win32_get_dc (void); + +gboolean pango_win32_get_debug_flag (void); + #endif /* API for libraries that want to use PangoWin32 mixed with classic -- cgit v1.2.1