Fedora 11, Cairo 1.8.8, GTK 2.16.5. When jumping between certain increments of pixelsize, GTK/Cairo appears to render the wrong size font when hinting is enabled. (This does not appear when hinting is disabled). How to Duplicate: 1. Go to GNOME Appearance\Font properties. 2. Under Details, set 72 DPI (makes fontsize corresponds to fontconfig's pixelsize). 3. Back at the font tab, open both a) a font selection dialog (for Application font) and b) the Details box from the Font tab. 4. Examine DejaVu Sans, Book, size 12.5. 5. On the open Details dialog, switch between None and Slight/Medium/Whichever-you-like hinting. 6. Notice how the font glyph is rendered at a small size when hinting is turned on. (Note that unhinted pixel sizes 12.0-12.49 appear nearly identical. They show minor variations in size when hinted. But a hinted pixelsize 12.5 glyph is actually -smaller- than its unhinted version). It clearly does not make sense that size 12.5 becomes -smaller- when hinting is disabled. (This problem occurs with any font, from pixelsize 12.5 to pixelsize 13.1, and again within pixelsizes 14.5-14.99. It may also occur in other pixelsizes I have not checked.) [Font-screen-grabs were taken using GNOME's Appearance\Fonts dialog, with DPI 72 (at which font size corresponds to fontconfig's pixelsize scale), and then assembled in the GIMP]. I was unsure if this was a bug in GTK, cairo, or freetype. But according to my layman guess, freetype merely generates glyphs, GTK uses cairo to draw, and cairo uses freetype (I believe), so cairo it is. No idea what specific component of cairo though.
Created attachment 28654 [details] hinting size mismatch between 12.49 and 12.50 There is no distinguishable difference between a hinted 12.49 and 12.5 size glpyh (whether slight, medium, or full), whereas unhinted has a significant difference.
Created attachment 28655 [details] hinting mismatch between 14.5 and 14.99 Note how that for 14.5>=pixelsize<15.0, again, the hinted glyph is rendered from a smaller size than the unhinted one. (It is hard to tell by the height. Note by the width: 14.5-unhint is clearly much wider than 14.5-slight, whereas 15.0-unhint very closely matches the dimensions of its hinted version, but with more sharper vertical hinting.
Hinting is the process of adjusting the outlines of the glyph to fit to the pixel grid to produce better contrast. The pixel grid is discrete so this cannot be a continuous process. At some sizes, sizes will suddenly jump larger. http://people.redhat.com/otaylor/grid-fitting/ discuss this process and how it interacts with positioning and horizontal metrics in some detail. What you are seeing is a normal consequence of hinting and not a bug. You can actually turn off hinting of metrics in cairo and only turn on the hinting of glyph shapes, but I don't think you'll find the result satisfactory.
I am familiar with the idea of hinting and the problem of fitting a scaled glyph to discrete pixels. And I completely understand that due to metric hinting, Cairo will sometimes show significant discrepancies between two very close font sizes. This occurs even when glyph hinting is turned off, in GTK. I have no problem with metric hinting in general. But please examine my pictures again: In both of my examples, the slight-glyph-hinted font has a different metric size than the no-glyph-hinted font. Whether or not the glyph is hinted, shouldn't Cairo always use the same metric size? Why does the metric hinting change when glyph hinting is enabled? It makes the metric size of fonts look completely different between hinted and unhinted fonts of the same size. Glyph hinting should definitely hint the glyph, but it should not change the metric hinting.
(In reply to comment #4) > Glyph hinting should definitely hint the > glyph, but it should not change the metric hinting. Why? If you want linear metrics, just disable metrics hinting. That simple.
I DO want metric hinting. I just want the metric hinting to be applied consistently regardless of whether the -shapes- are then glyph-hinted or not. Again, first example. 14.5 Deja Vu Sans. The text block with slight-glyph-hinting is 10% thinner than no-glyph-hinted hinted version. The same font size, two different actual metric sizes. Turning on -glyph- hinting should not cause such a large change in the -metric- hinting. NOTE: In my layperson mind I am assuming that "metric hinting" is based on fitting the unhinted glyphs and should be the same whether the shapes are then "glyph-hinted" afterwards or not. I like metric hinting. I understand that each hinting type creates subtle differences in text size. But as far as I can understand, glyph hinting should not change the metric hinting. Cairo's clearly does. Do you guys not see in the images that turning on glyph hinting arbitrarily seems to apply odd metric hinting to certain sizes? 14.5 and 12.5 seem very bizarre to me. If this is normal, then I stand corrected and apologize deeply for the noise.
When you hint the glyph outlines and the same glyph is not .8 pixel wider, you MUST also change the metrics-hinted width, otherwise the result will look ugly. That's all.
(In reply to comment #7) > When you hint the glyph outlines and the same glyph is not .8 pixel wider, you > MUST also change the metrics-hinted width, otherwise the result will look ugly. > That's all. > Well, that makes sense. It just seems dumb that the resultant glyph is even more inaccurate size-wise than just using the original unhinted metric. But if the result would be ugly without metric correction, then alas I guess I have to deal with it. How do you disable metric-hinting, anyway? I didn't even know that was possible; I don't think I'll like it, but I am curious. Also, one last thing...shouldn't slight-hinting give you the same width no matter what? I thought slight-hinting only hinted the vertical direction, never horizontal, and wouldn't need any metric correction for width.
(In reply to comment #8) > (In reply to comment #7) > > When you hint the glyph outlines and the same glyph is not .8 pixel wider, you > > MUST also change the metrics-hinted width, otherwise the result will look ugly. > > That's all. > > > > Well, that makes sense. > > It just seems dumb that the resultant glyph is even more inaccurate size-wise > than just using the original unhinted metric. But if the result would be ugly > without metric correction, then alas I guess I have to deal with it. > > How do you disable metric-hinting, anyway? I didn't even know that was > possible; I don't think I'll like it, but I am curious. There's no option for it. Search for cairo_font_options_set_hint_metrics in gtk+/gtk/gtksettings.c > Also, one last thing...shouldn't slight-hinting give you the same width no > matter what? I thought slight-hinting only hinted the vertical direction, > never horizontal, and wouldn't need any metric correction for width. I don't remember how slight-hinting works. Again, we're just getting the metrics and outline from FreeType, and rounding the metrics if metrics-hinting is enabled.
>> Also, one last thing...shouldn't slight-hinting give you the same >> width no matter what? I thought slight-hinting only hinted the >> vertical direction, never horizontal, and wouldn't need any metric >> correction for width. > I don't remember how slight-hinting works. Again, we're just getting > the metrics and outline from FreeType, and rounding the metrics if > metrics-hinting is enabled. Slight Hinting (aka the Light Autofit module, in freetype-speak) does exactly as he said: it adjusts the glyph outlines in the vertical direction¹ only for the express purpose of not changing the horizontal metrics. Properly set text should accumulate the fractions even when snapping the glyphs to pixels; it should skip extra pixels w/in whitespace, as required, to closely match the unrounded positioning. From the point of view of cairo’s api, that would be easiest if it is passed a line at a time; a bit more difficult if it is passed a ‘word’ at a time, and a lot more paperwork if it is passed a glyph at a time. 1] I cannot remember — and am not checking — whether that becomes «in the horizontal direction only» when setting vertical scripts.
James, that's irrelevant. It should work fine. Lemme take a look.
Ok, I see the bug in the code. Such a mess I don't want to touch it with a 10ft pole... Maybe I should wait until I get to clean it all. In short, right now we're assuming that if glyph hinting is happening, FreeType is hinting metrics already, so we don't try. Whereas if hinting is off, we do the hinting. If you want to experiment, see if changing cairo/src/cairo-ft-font.c, inside _cairo_ft_scaled_glyph_init(), changing the following condition: if (hint_metrics && (load_flags & FT_LOAD_NO_HINTING)) to: if (hint_metrics) helps.
You mean I wasn't crazy and the metric hinting actually -is- misbehaving? If so, could this be set to some sort of open bug status? :) James: judging by the KDE programs that use vertical glyphs (like Amarok's sidebar in 2.0.x), even with slight hinting, they seem to be hinted in -both- directions no matter what - no distinction between slight, medium, and full. Makes glyphs look atrocious so when I run KDE I always set hinting to none. Not sure if that's what you mean by "vertical glyphs". But this is an old observation - I figured if anybody thought it was a big deal they'd have fixed it by now.
As I said, it's a mess. I appreciate feedback on the change I suggested.
I could possibly try compiling my own cairo (scary thought). Has to wait until this weekend though, and I wouldn't be surprised if I screwed it up. If you don't mind my asking, how is it a mess? One line doesn't look too bad.
The one-line change is not the end of story. It will help me better understand what's going on though.
I'm afraid I've been a very bad dude. Haven't had the time to try a cairo recompilation, and this week isn't looking good either. Whenever I have anything to show for it I'll post back though.
Still haven't tested a cairo recompilation, but I had a thought -- I wonder if this bug is why DejaVu Sans-10-slight has never matched between GNOME and OpenOffice/KDE (which match each other, but not GTK). It's always taller in GTK but shorter and fatter in Qt/OOo at size 10. Two different GUI toolkits render the font differently (but consistently) from GTK. Unlikely to be their problem.
Created attachment 32536 [details] compare 72dpi with 96dpi - no hinting This is a screenshot that demonstrates the problem much clearer. You can compare it with the next attachment to see the effect of hinting at both 72dpi and 96dpi.
Created attachment 32537 [details] compare 72dpi with 96dpi - slight hinting Open both in tabs to quickly compare them. Per the rules for Slight Hinting, only vertical hinting should occur. The width of glyphs should not change. Strangely, 72DPI has no problems. At other DPIs (96 is used as an example), the fonts mismatch and there are subtle size problems between none-hinting and slight-hinting. [To tell the difference with 72DPI, pay attention to the bold words. They are easy to see. For 96DPI, you can clearly see the size of the words change.] As a simple workaround you could run GNOME at 72DPI, but many GTK programs have slight discrepancies at 72DPI.
Created attachment 32543 [details] [review] Proposed patch to fix metric hinting. I finally learned how to setup VMs, make a patch, etc. Couldn't figure out how to use SRPMs in Fedora so I compiled straight from cairo-1.8.8 source release. With Behdad's change above and a configure/make/make install, nothing happened. The fonts still showed size irregularities between none and slight-hinted versions. The results are identical to the hinting-compare-* pictures.
So, you mean the patch is NOT working, right?
(In reply to comment #22) > So, you mean the patch is NOT working, right? > Yes, the patch did not work. After making the change, recompiling, and installing, the metric hinting problem still persisted.
I just tried running CentOS 5.4, which has Cairo 1.2.4, I believe (from the package manager). It has the same problem, so this goes pretty far back. With one difference: in Cairo 1.2.4, 96DPI looks nearly perfect, with slight hinting functioning almost flawlessly. But all of the metric hinting problems are evident in 72DPI instead. It's probably crazy to diff 1.2.5 against 1.8.8, but at some point the hinting process must have changed to shift inaccuracies from 72DPI to 96DPI. At any rate, it's only different, not fixed - the true problem seems really old.
It's been a few years since the last comment on this bug. Is this still an issue?
-- GitLab Migration Automatic Message -- This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/cairo/cairo/issues/259.
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.