GNOME Bugzilla – Bug 600085
pango_font_find_shaper returns NULL on Mac OS X / Quartz
Last modified: 2010-03-19 15:19:31 UTC
Created attachment 146536 [details] Screenshot demonstrating cell lables I have built cairo and pango to use Quartz for rendering on Mac OS X 10.6 (Snow Leopard). When I build and run gnumeric, I find that the cell labels' text is not rendered properly. All of gnumeric's other text is rendered properly (e.g., menus). I have noticed that libgoffice is linked against /opt/local/lib/libpangoft2-1.0.0.dylib, while neither pango nor cairo use Freetype (they use Quartz).
Looks like a font issue. Not a libgoffice bug, but a gnumeric one, btw.
The symbols in the cell headers indicate that pango is unable to render the necessary glyphs. The font used is the default Application Font (for example in gnome set in the Appearance Preferences.) Apparently you have a font set that pango can't handle.
Andreas, there is probably something else since in that case, I guess that the menus would not be properly displayed. If the issue comes from gnumeric, the problem is most likely in item-bar.c. I have no access to any Apple made machine, so it's difficult to guess what happens. I don't know why goffice is linked against libpangoft2, we have no direct dependency, AFAIK.
According to the screenshot he has the missing glyph symbols (including the glyph number rendered).
Sure, but clearly we don't get a correct font from gtk+, now I have no idea about why.
This is going to be hard to debug for anyone not on this system.
*** Bug 601462 has been marked as a duplicate of this bug. ***
In response to comment #5, I replaced item-bar.c's desc = pango_font_description_copy (src_desc); with desc = pango_font_description_from_string ("monospace bold 12"); and saw no change. The cell label type was still rendered as mentioned in the original description.
It may be more interesting to change ib->normal_font = pango_context_load_font (context, desc); to ib->normal_font = pango_context_load_font (context, desc); g_print ("normalfont: %s", pango_font_description_to_string (pango_font_describe (ib->normal_font))); and then see in the console whether there is any surprising output. PS: this leaks a fontdescription and a string but it is intended for debugging only.
I did as instructed in comment #9 and received the following output: 1: normalfont: Lucida Grande 12 2: normalfont: Lucida Grande 12 [...] This font works fine when I enter some text into a cell and change the cell's font to Lucida Grande 12.
This is not the output I had expected or hoped for. While it is annoyting trying to debug this remotely, perhaps you wouldn't mind changing the code back to what it was and in ib_draw_cell replace ib->pango.item->analysis.font = g_object_ref (font); with ib->pango.item->analysis.font = g_object_ref (font); g_print ("font: %s", pango_font_description_to_string (pango_font_describe (font))); We should get the same output as before (which wouldn't tell us anything). But perhaps we see something different.
I received the following output after adding the statement in comment #11: 3: font: Lucida Grande Bold 12 3: font: Lucida Grande 12
I assume that you got two of the lines with Bold and lots of the other lines. (Of course they are probably only separate lines if you did "font: %s\n".) That would be as expected. For the record only, I get: font: Bitstream Vera Sans Bold 9.9990234375 font: Bitstream Vera Sans 9.9990234375
Would you please change the code at the same place as in comment #11 to: ib->pango.item->analysis.font = g_object_ref (font); g_print ("font: %s\n", pango_font_description_to_string (pango_font_describe (font))); g_print ("PA: %p %p %u %u %u %u %p\n", ib->pango.item->analysis.shape_engine, ib->pango.item->analysis.lang_engine, ib->pango.item->analysis.level, ib->pango.item->analysis.gravity, ib->pango.item->analysis.flags, ib->pango.item->analysis.script, ib->pango.item->analysis.language); Basically, we seem to have a valid font, so perhaps something is not right with our handcrafted PangoAnalysis.
With the change from comment 14, I see: font: Lucida Grande Bold 12 PA: 0x0 0x0 0 0 0 0 0x10152f7d8 and font: Lucida Grande 12 PA: 0x0 0x0 0 0 0 0 0x10152f7d8
Now we are getting somewhere: ib->pango.item->analysis.shape_engine is NULL, so we have no attached engine to render the glyphs. We now need to figure out why it is NULL. Note that ib->pango.item->analysis.lang_engine is also NULL, but that isn't a problem, you are using an english script.
ib->pango.item->analysis.shape_engine should be set in item_bar_calc_size. Perhaps you can add there two g_print code lines to get: ib->pango.item->analysis.shape_engine = pango_font_find_shaper (ib->normal_font, ib->pango.item->analysis.language, 'A'); g_print ("font: %s\n", pango_font_description_to_string (pango_font_describe (ib->normal_font))); g_print ("shaper: %p\n", ib->pango.item->analysis.shape_engine); Note that the first line (the pango_font_find_shaper call and assignment) is already in that function. Thanks
With the change from comment 17, I see: font: Lucida Grande 12 shaper: 0x0
So, pango_font_find_shaper (ib->normal_font, ib->pango.item->analysis.language, 'A'); returns NULL, while ib->normal_font is a valid font. I would consider that a Pango bug rather than a Gnumeric one.
Behdad, why would pango return a NULL shaper? See comment 19.
Which version, using which backend? What's the contents of pango.modules file?
Michael, what is your Pango version? Can you answer Behdad's questions?
Version is pango 1.26.0. Backend is Quartz Cairo 1.8.10, --enable-quartz, --enable-quartz-font & --enable-quartz-image. pango.modules: /opt/local/lib/pango/1.6.0/modules/pango-arabic-fc.so ArabicScriptEngineFc PangoEngineShape PangoRenderFc arabic:* nko:* /opt/local/lib/pango/1.6.0/modules/pango-arabic-lang.so ArabicScriptEngineLang PangoEngineLang PangoRenderNone arabic:* /opt/local/lib/pango/1.6.0/modules/pango-basic-atsui.so BasicScriptEngineATSUI PangoEngineShape PangoRenderATSUI common: /opt/local/lib/pango/1.6.0/modules/pango-basic-fc.so BasicScriptEngineFc PangoEngineShape PangoRenderFc latin:* cyrillic:* greek:* armenian:* georgian:* runic:* ogham:* bopomofo:* cherokee:* coptic:* deseret:* ethiopic:* gothic:* han:* hiragana:* katakana:* old-italic:* canadian-aboriginal:* yi:* braille:* cypriot:* limbu:* osmanya:* shavian:* linear-b:* ugaritic:* glagolitic:* cuneiform:* phoenician:* common: /opt/local/lib/pango/1.6.0/modules/pango-hangul-fc.so HangulScriptEngineFc PangoEngineShape PangoRenderFc hangul:* /opt/local/lib/pango/1.6.0/modules/pango-hebrew-fc.so HebrewScriptEngineFc PangoEngineShape PangoRenderFc hebrew:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so devaScriptEngineFc PangoEngineShape PangoRenderFc devanagari:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so bengScriptEngineFc PangoEngineShape PangoRenderFc bengali:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so guruScriptEngineFc PangoEngineShape PangoRenderFc gurmukhi:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so gujrScriptEngineFc PangoEngineShape PangoRenderFc gujarati:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so oryaScriptEngineFc PangoEngineShape PangoRenderFc oriya:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so tamlScriptEngineFc PangoEngineShape PangoRenderFc tamil:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so teluScriptEngineFc PangoEngineShape PangoRenderFc telugu:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so kndaScriptEngineFc PangoEngineShape PangoRenderFc kannada:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so mlymScriptEngineFc PangoEngineShape PangoRenderFc malayalam:* /opt/local/lib/pango/1.6.0/modules/pango-indic-fc.so sinhScriptEngineFc PangoEngineShape PangoRenderFc sinhala:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so devaIndicScriptEngineLang PangoEngineLang PangoRenderNone devanagari:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so bengIndicScriptEngineLang PangoEngineLang PangoRenderNone bengali:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so guruIndicScriptEngineLang PangoEngineLang PangoRenderNone gurmukhi:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so gujrIndicScriptEngineLang PangoEngineLang PangoRenderNone gujarati:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so oryaIndicScriptEngineLang PangoEngineLang PangoRenderNone oriya:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so tamlIndicScriptEngineLang PangoEngineLang PangoRenderNone tamil:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so teluIndicScriptEngineLang PangoEngineLang PangoRenderNone telugu:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so kndaIndicScriptEngineLang PangoEngineLang PangoRenderNone kannada:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so mlymIndicScriptEngineLang PangoEngineLang PangoRenderNone malayalam:* /opt/local/lib/pango/1.6.0/modules/pango-indic-lang.so sinhIndicScriptEngineLang PangoEngineLang PangoRenderNone sinhala:* /opt/local/lib/pango/1.6.0/modules/pango-khmer-fc.so KhmerScriptEngineFc PangoEngineShape PangoRenderFc khmer:* /opt/local/lib/pango/1.6.0/modules/pango-syriac-fc.so SyriacScriptEngineFc PangoEngineShape PangoRenderFc syriac:* /opt/local/lib/pango/1.6.0/modules/pango-thai-fc.so ThaiScriptEngineFc PangoEngineShape PangoRenderFc thai:* lao:* /opt/local/lib/pango/1.6.0/modules/pango-tibetan-fc.so TibetanScriptEngineFc PangoEngineShape PangoRenderFc tibetan:*
Weird. Can you debug inside and see what's going on? Regardless, having code like this in gnumeric doesn't look quite right to me. What are you trying to do, calling such lowlevel pango functions?
Behdad, I didn't write that code, but looking at the "basic pango interface" I see pango_shape (which we use) requiring a PangoAnalysis. The only "basic pango" function that may yield one is pango_itemize which returns a GLIST of PangoAnalyis items. Since we know that we have only one item, using pango_itemize seems overkill, so we are using lower level functionality to build a single pango analyis we can use for all the column and row headers. Which high level pango interface would you suggset?
We are trying to get a lot of little text fragments ("A", "B", ..., and "1", "2", ...) on the screen in a hurry, bypassing the layout mechanism since we don't want things line broken anyway.
I strongly recommend against initializing PangoAnalysis yourself. Call pango_itemize() even if you only want one item. Also, the key to speed is in caching. What I do in vte for example (see vtepangocairo.c) is to use PangoLayout to shape each letter once and then cache the resulting PangoGlyphString or PangoLayoutLine or PangoLayout depending on how complex the resulting glyphs are. It may be worthwhile to make that code available in pangocairo itself maybe.
If we shape each letter individually, are we going to miss out on ligatures or kerning? (Ligatures aren't likely in this case. Kerning is for "AV", fo example.)
Ah, I thought you want to render individual letters separately.
I'll write a patch to use pango_itemize to create the PangoAnalysis rather than initializing it oursleves. We can then try to use the same PangoAnalysis for all other row and column numbers and see whether that changes things. (This will preserve ligatures and kerning since we still call pango_shape.)
Created attachment 156495 [details] [review] proposed patch This patch replaces our own construction of the PangoAnalysis with one obtained from a call to pango_itemize. Michael, would you please try out whether this changes anything at your end.
Created attachment 156496 [details] [review] sslightly safer patch We should probably initialize the pango item in ib to NULL.
Created attachment 156499 [details] [review] patch with renamed variables In this patch the variables are renamed to not include the "pango_" prefix as requested by Morten.
This patch in comment #33 fixes the problem. The cell labels are now rendered as 1, 2, 3 and A, B, C on Mac OS X with GTK/Quartz. Thank you Andreas and Behdad.
I will commit the patch tomorrow.
This problem has been fixed in the development version. The fix will be available in the next major software release. Thank you for your bug report.