testgtk::labels and other pango layouts are broken due to this issue. The patch below registers the failing of GetGlyphOutlineW() but does not report the failing status back through the API. Instead it initializes the returned sizes to zero. This is consitent with other status handling in _cairo_win32_scaled_font_glyph_extents() and fixes the issue for me. But maybe the whole function should be changed to return back failed status ... diff --exclude-from=c:\util\tool\diff.ign -u --recursive from-cvs/cairo/cairo/src/cairo-win32-font.c my-gtk/cairo/cairo/src/cairo-win32-font.c --- from-cvs/cairo/cairo/src/cairo-win32-font.c Thu Jul 28 22:24:57 2005 +++ my-gtk/cairo/cairo/src/cairo-win32-font.c Sat Jul 30 20:30:05 2005 @@ -722,8 +722,11 @@ status = cairo_win32_scaled_font_select_font (&scaled_font->base, hdc); if (status) return status; - GetGlyphOutlineW (hdc, glyphs[0].index, GGO_METRICS | GGO_GLYPH_INDEX, - &metrics, 0, NULL, &matrix); + if (GetGlyphOutlineW (hdc, glyphs[0].index, GGO_METRICS | GGO_GLYPH_INDEX, + &metrics, 0, NULL, &matrix) == GDI_ERROR) { + status = _cairo_win32_print_gdi_error ("GetGlyphOutlineW"); + memset (&metrics, 0, sizeof(GLYPHMETRICS)); + } cairo_win32_scaled_font_done_font (&scaled_font->base); if (scaled_font->swap_axes) { @@ -757,8 +760,11 @@ * of the font. */ status = _cairo_win32_scaled_font_select_unscaled_font (&scaled_font->base, hdc); - GetGlyphOutlineW (hdc, glyphs[0].index, GGO_METRICS | GGO_GLYPH_INDEX, - &metrics, 0, NULL, &matrix); + if (GetGlyphOutlineW (hdc, glyphs[0].index, GGO_METRICS | GGO_GLYPH_INDEX, + &metrics, 0, NULL, &matrix) == GDI_ERROR) { + status = _cairo_win32_print_gdi_error ("GetGlyphOutlineW"); + memset (&metrics, 0, sizeof(GLYPHMETRICS)); + } _cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base); extents->x_bearing = (double)metrics.gmptGlyphOrigin.x / scaled_font->em_square;
Leaving aside the fix (which is likely right), why are not-available glyphs being passed to this function? Does that need debugging?
There may be a bug in Pango causing this, but I'm definitely not the expert. But I think is quite usual for Pango to ask for not existing glyphs - and finally render them as boxes.
No, that should never happen. Pango always is using glyph IDs that it got from Uniscribe or by querying the Win32 API.
So there is a bug in basic_engine_shape ? The GDI_ERROR seems to be triggered by measuring the extents for pango_win32_get_unknown_glyph (). _cairo_win32_scaled_font_glyph_extents(void * 0x00d61a20, cairo_glyph_t * 0x0012c490, int 1, cairo_text_extents_t * 0x0012c460) line 727 _cairo_scaled_font_glyph_extents(_cairo_scaled_font * 0x00d61a20, cairo_glyph_t * 0x0012c490, int 1, cairo_text_extents_t * 0x0012c460) line 900 + 25 bytes cairo_scaled_font_glyph_extents(_cairo_scaled_font * 0x00d61a20, cairo_glyph_t * 0x0012c51c, int 1, cairo_text_extents_t * 0x0012c4e8) line 1188 pango_cairo_win32_font_get_glyph_extents(_PangoFont * 0x00d60170, unsigned int 268490076, _PangoRectangle * 0x00000000, _PangoRectangle * 0x0012c564) line 187 + 19 bytes pango_font_get_glyph_extents(_PangoFont * 0x00d60170, unsigned int 268490076, _PangoRectangle * 0x00000000, _PangoRectangle * 0x0012c564) line 1190 + 24 bytes set_glyph(_PangoFont * 0x00d60170, _PangoGlyphString * 0x00d5faf0, int 0, int 0, unsigned int 268490076) line 205 + 31 bytes basic_engine_shape(_PangoEngineShape * 0x00d0bfe0, _PangoFont * 0x00d60170, const char * 0x00d5e4ea, int 6, _PangoAnalysis * 0x00d6148c, _PangoGlyphString * 0x00d5faf0) line 1039 + 41 bytes _pango_engine_shape_shape(_PangoEngineShape * 0x00d0bfe0, _PangoFont * 0x00d60170, const char * 0x00d5e4ea, int 6, _PangoAnalysis * 0x00d6148c, _PangoGlyphString * 0x00d5faf0) line 77 + 32 bytes pango_shape(const char * 0x00d5e4ea, int 6, _PangoAnalysis * 0x00d6148c, _PangoGlyphString * 0x00d5faf0) line 48 + 34 bytes shape_run(_PangoLayoutLine * 0x00d60010, _ParaBreakState * 0x0012c704, _PangoItem * 0x00d61480) line 2689 + 35 bytes process_item(_PangoLayout * 0x00d5e460, _PangoLayoutLine * 0x00d60010, _ParaBreakState * 0x0012c704, int 0, int 0) line 2780 + 17 bytes process_line(_PangoLayout * 0x00d5e460, _ParaBreakState * 0x0012c704) line 2988 + 29 bytes pango_layout_check_lines(_PangoLayout * 0x00d5e460) line 3285 + 13 bytes pango_layout_get_extents_internal(_PangoLayout * 0x00d5e460, _PangoRectangle * 0x00000000, _PangoRectangle * 0x0012c878, _GSList * * 0x00000000) line 2013 + 9 bytes pango_layout_get_extents(_PangoLayout * 0x00d5e460, _PangoRectangle * 0x00000000, _PangoRectangle * 0x0012c878) line 2178 + 19 bytes gtk_label_size_request(_GtkWidget * 0x00cef628, _GtkRequisition * 0x00cef644) line 2017 + 18 bytes
Move bugs against "cvs" version to "0.9.3" so we can remove the "cvs" version.
pango_win32_get_unknown_glyph() returns the passed-in Unicode character ORed with PANGO_WIN32_UNKNOWN_FLAG. In 2.6 days, the glyph indexes eventually were passed to pango_win32_render() which notices this flag and replaces it with glyph index 0 (which apparently in all TrueType fonts is the invalid glyph?). cairo does not know about this PANGO_WIN32_UNKNOWN_FLAG so it thinks the glyph index is a valid one. As to why invalid glyphs are tried to be rendered in the first place, I don't know. I could reproduce this problem only after editing the "sans" line in pango.aliases, setting it to just "sans = arial", so that some of the non-ASCII labels in testgtk::labels aren't covered. But why isn't it noticed earlier that the "sans" font doesn't cover the attempted characters, I don't know.
0 is present in all TrueType fonts - it is typically a box, though in some cases it can also be blank. I think the right thing to do is: Create a PANGO_UNKNOWN_FLAG in some private header and use it consistently across all backends (we have a bunch of UNKNOWN flags now, all with the same value) Make pangocairo-render.c draw a box itself for anything marked with this flag rather than passing it to cairo. (Doing hex boxes in pangocairo-render.c is an open work item, but empty boxes are a simple first step.) (http://bugzilla.gnome.org/show_bug.cgi?id=313551) The patch in this bug should be applied, of course.
Patch committed to HEAD. (Does cairo use any separate stable branch?) Should this bug be kept open until Pango is fixed not to call cairo for undefined glyphs?
(In reply to comment #8) > Patch committed to HEAD. (Does cairo use any separate stable branch?) Yes. Things that are strictly bug-fixes, (as this appears to be), should be committed to the current maintenance branch. The tag you want now is: -r BRANCH_1_0 Please commit this fix on that branch as well. Thanks!
Committed to BRANCH_1_0, too. (Without the error message, though, as cairo 1.0.2 presumably will still be most often used with a Pango that causes invalid glyph indixes to be passed to this function.)
Sounds perfect. Thanks so much! -Carl
Pango draws cute hexboxes for all cairo backends now.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.