GNOME Bugzilla – Bug 424976
'r' apparently misplaced when rendered in DejaVu Sans
Last modified: 2007-05-14 04:03:44 UTC
The letter 'r', when rendered many times in succession, is placed at irregular intervals. This seems to occur only when using the "DejaVu Sans" font, which is the default choice for "application font" (used in text fields and labels) of modern Linux distributions. You can test this by creating a label containing the string "rrrrrrr...", such as with this Python one-liner: python -c \ 'import gtk;w=gtk.Window();w.add(gtk.Label("r"*50));w.show_all();gtk.main()' The attached image shows the problem as seen on my system: every fourth 'r' is placed closer to the preceding letter, as if misplaced by a rounding artifact. I was able to repeat this on GTK+ 2.10.6 and on GTK+ 2.10.11, on different Linux distributions. It is baffling that this only seems to occur when GTK+ renders text using the "DejaVu Sans" font. If you choose another font, 'r' gets rendered correctly. If you use the Qt or Firefox[1] renderer, it also shows correctly. Changing font rendering settings (such as antialiasing settings) had no effect. [1] You can test Firefox's renderer using something like <span style="font-family: DejaVu Sans; font-size: 13">rrrrrrrrrrrrrrrrrrrrr</span>
Created attachment 85623 [details] Image showing the incorrect rendering of 'r'
This type of issue almost always means that you are getting non-integer metrics. That could be: - A font bug (maybe) - A FreeType bug - A Cairo bug - A Pango bug It's not a GTK+ bug. (You can force using non-integer metrics by passing the right values pango_cairo_context_set_font_options(), but you should not be getting them by default for screen display.)
Thanks for the hint. What would be the most straightforward way to test which one of the components gets it wrong? For example, is there an example program that forces FreeType to render a string into a pixmap?
Dupe of bug 390835, but since this bug has more information, I dup that one.
*** Bug 390835 has been marked as a duplicate of this bug. ***
Note that the launchpad URL mentioned in that bug report contains a lot of useful information. It's at: https://bugs.launchpad.net/ubuntu/+source/pango1.0/+bug/77443
It's also likely to be complete poppycock. (I wrote it.) Though the ideas kind of make sense, one only has to type "ffffff" (as also explained in the other bug report) to see that the rasterizations /aren't/ always re-used. I still can't figure this out. :P Behdad, what's going on? :D
I'm close to 100% positive that the rasterizations are always reused - can you really show a screenshot where multiple types of 'f' characters are drawn, or are you just saying that you don't see the jitter in positioning of the f? As long as a character has an integer advance, you won't see the jitter. Using multiple rasterizations at different positions ("phases" is the technical term) can produce superior rendering results, but it takes a great deal more memory ... the figures I've seen is that to get the full benefit you might need up to 16 phases in both directions - 256x times the memory. Even with 4 phases is 16x times the memory. It's something that could be fooled around with in the future, but not the immediate bug here. For screen rendering, we want integer advances. If I was trying to diagnose the problem, the first thing I'd want to determine is whether: A) The wrong value of the "hint_metrics" option gets passed to cairo Or: B) The right value of hint_metrics (on) gets passed, but implementation is wrong. Try the attached program - when I run it I see: - Jitter in the left column (hint_metrics off) - No jitter in the right column (hint_metrics on) You can experiment with changing the font and size (call to pango_font_description_from_string()) and changing the hinting style (call cairo_font_style_set_hint_style() - could be MEDIUM or FULL instead of NONE) to better match your situation. If the behavior of this test program is good, then the bug may actually be a GTK+ bug ... since the font options for GTK+ programs are set by GTK+ based on your system settings. If the behavior is bad (you see jitter with hint_metrics on), then hopefully we can characterize better exactly when the bad behavior occurs. [ Compile with gcc -o hint-metrics -Wall `pkg-config --cflags --libs gtk+-2.0` hint-metrics.c ]
Created attachment 85654 [details] Test case
When I run the program unchanged, I see the same thing you see -- jitter on some letters in the left column, no jitter on any letter in the right column. I tried using changing fonts and observed the following: when using Bitstream Vera Sans, Times New Roman, and Arial, I saw what you saw (jitter only in left column, sometimes depending on hint style, but no jitter in the right column). But when I specified the "DejaVu Sans 10" font, both left and right columns showed jitter for the letter 'r'. Most of the other letters showed significant jitter in the left column, but no jitter in the right column (except for 'r'). In fact, as far as I could tell, *only* the letter 'r' was incorrectly spaced in the right column using DejaVu Sans. In conclusion, the "bad" behavior (jitter on 'r' with hint_metrics on) does occur when using the "DejaVu Sans 10" font, with or without hinting.
OK, that narrows the problem down to an interaction between: - Cairo - FreeType - The font Which is better than where we started from. What are the exact versions of those you are testing with? Were those experiments done using CAIRO_HINT_STYLE_NONE (That is, unchanged from the way I had it?) Can you provide a screenshot of the test program exhibiting the jitter for r in hte right column?
Owen, see http://bugzilla.gnome.org/attachment.cgi?id=83573&action=view (from the older bug I posted) for an example of a rasterization *not* being re-used!
Created attachment 85667 [details] Screenshot of 'r' misplaced with hint metrics on
I use Cairo 1.2.4 and FreeType 2.2.1. The font comes from a "ttf-dejavu" package with version 2.7. The above results were obtained with CAIRO_HINT_STYLE_NONE (and later repeated with other hint styles), the default in your program. In fact, the only modification required to see the problem is changing the font name on line 31 to "DejaVu Sans 10". Screenshot in attachment 85667 [details].
Hrovje: The screenshot there isn't HINT_STYLE_NONE, is it supposed to be? If hint style is set from fonts.conf, I think it overrides any options set by the program or user. (I ask this, because it's a lot easier for me to understand how this problem can occur with non-NONE hinting, where we trust FreeType to return integer metrics, than with NONE hinting, where we quantize the metrics to integer values ourself. See cairo-ft-font.c:_cairo_ft_scaled_glyph_init()) Alex: That makes 0 sense to me. zero. I deny the possibility. :-). AFAIK, the position at which the glyph is rendered isn't even taken account when rasterizing the glyph. See cairo-ft-font.c:_render_glyph_bitmap().
Owen, the screenshot is obtained by running your program with just the font name changed, as described previously. If something else needs to be done to get non-NONE hinting, please let me know what it is. I looked at /etc/fonts/fonts.conf, but it's not obvious to me that anything in that file is overriding the CAIRO_HINT_STYLE_NONE flag specified by the program.
Maybe it is HINT_STYLE_NONE and DejaVu Sans just happens not to need much hinting. I'm not really sure. (Further investigation probably would involve matching versions (at least of the font) and tracing into the cairo-ft-font.c source code, something I'm not set up to do in the immediate future. Hopefully someone else will pick this up.)
Owen, can you really overlook what's happening with the f? I can assure you it's no April Fool! :( (Bitstream Vera Sans, BTW.)
I can make wild guesses: - You have a hacked up version up version of Pango and/or Cairo that has code in it to draw at multiple phases - Your whole screen is run through some sort of scaling that affects different pixels differently (compiz is broken and is drawing the textures at the wrong size I don't know...) - A UFO is hovering over your house and emitting gamma ray particles that periodically change some of the cached glyph images But basically none of those are useful. I'm not saying you are making up that screenshot, but it doesn't conform to my understanding of the way way that Cairo on X11 works. Cairo will, in my understanding: - Create a single glyph bitmap for an f in that font at that size - Download it to the server - To draw a string of fffff, it will tell the X server, "draw glyph 10 at positions 10, 20, 30, 40, 50, and 60" Honestly, it's probably just some amusing combination of things that we didn't expect working together to produce the effect, but I can't think of what. Here's one theory that's a *little* less crazy than the above: - Your system is trying to use a font that is exactly, say, 13.5 pixels high - That is getting rounded at different times to 13 pixels or 14 pixels - Your are seeing the combination of those two But I don't really believe it more than any of my other theories. In the end, it's again a question of figuring out how to reproduce it reliably and digging in with a debugger.
Are you saying that this doesn't happen with Red Hat, then? All I need to do is type "fffffff" into any GtkEntry to see it in Ubuntu (and it has been like this since as long as I can remember, across various installations).
For what it's worth, I'm using Ubuntu and I've never seen the 'f' problem. Maybe it's a different bug?
Ubuntu is known to be broken in that they turn hinting off... I've fixed numerous rounding/hinting bugs in past year that unless you are running latest development versions of cairo, pango, and gtk+, you must probably are hitting a bug I already fixed... The rrrrrrrrrrr bug still remains, and I'll dig into it one day...
Ubuntu might well be broken in other respects, but I believe it didn't cause the problem reported in this bug (the "rrrrrrrrrr" misplacement). I've seen the exact same problem on SuSE and, for what it's worth, I don't normally see the other misplacements displayed in the left column of Owen's test program. Could someone with sufficient authority please upgrade the status of this bug from UNCONFIRMED to NEW or ASSIGNED, whichever is more appropriate?
(In reply to comment #16) > Owen, the screenshot is obtained by running your program with just the font > name changed, as described previously. When I try this (with cvs freetype and a somewhat old svn DejaVu) the f glyphs alternate stem widths: 2px, 1px, 2px, 1px, ... My hypothesis is that I'm looking at five ff glyphs rather than 10 f glyphs. Ie, ligatures are applied. Vera, IIRC, does not lig f glyphs by default. I believe that at least some version of the DejaVu fonts do.
I get this with Vera and DejaVu on Ubuntu Feisty. Both have the "ff" ligature, and its rendering (U+FB00) is EXACTLY the same as the double f. Comic Sans MS is known to have quite a distinct "fi" ligature, but it doesn't seem to be used. I guess this is a different bug. Will sort this out. Thanks for the clue, James!
Oops. Turns out I wasn't using Vera at all, but rather my system's "Sans", which is mapped to DejaVu Sans. This *doesn't* affect Bitstream Vera after all!
This was fixed a while ago. http://behdad.org/blog/mces/image/metricshinting-kerning.png