Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
> Note, we need a FreeType API for getting to the module-name from the face, or > a direct getter of the stem-darkening on the face. Werner had this to say: > Get the font format with `FT_Get_Font_Format'; the returned string can > then be mapped to the corresponding module name. > > CFF -> cff > TrueType -> truetype > > For the auto-hinter this doesn't work, of course, since it is > completely agnostic of the font format. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
> Here is a proof of concept: https://codereview.qt-project.org/#/c/177325/ Oh nice, didn't expect something so soon. Will have a look. > Note, we need a FreeType API for getting to the module-name from the face, or > a direct getter of the stem-darkening on the face. Ah, hm. I only know of a way from within the FT source. Will get back to you. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
Here is a proof of concept: https://codereview.qt-project.org/#/c/177325/ Note, we need a FreeType API for getting to the module-name from the face, or a direct getter of the stem-darkening on the face. Best regards `Allan ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
On Sunday 20 November 2016, Nikolaus Waxweiler wrote: > > Anyway, on the API front. Forcing to autohinter is probably not > > acceptable. So we could enable stem darkening where native available, > > but then we need to know if what engine a face is using, or better yet > > specifically if the engine used right now on this face did stem > > darkening. > > I was just thinking. Can Qt mix font rendering modes on a face-by-face > basis? Even without FT_Face_Option(), you can query the font driver for > a face and the autohinter for stem darkening as described in [1]. If > FT_Property_Get returns an error for the property, the driver has no > means of darkening stems at all. Note that this is a font > driver/autohinter wide setting, affecting all faces that pass through them. > > So, how about something like this: for each face that should be > rendered, first query the driver (or the autohinter if it's to be used) > if it supports stem darkening. If so, turn it on while rendering the > face and use linear alpha blending and gamma correction (maybe with a > factor of 1.8 like Adobe recommends). If there is no stem darkening > support, blend naively. Qt can't do that right now, right now it can only be controlled all or nothing by QPA platform or font-engine, but controlling it on a face-by-face basis was exactly the possible solution I was considering, but it requires exposing the data from the face-specific QFontEngine class to the drawing back-end. At least for the rasterizing engine. The whole thing first needs some cleanup in 5.9 though, it has been adjusted a bit too much for separate platforms to match native text rendering, and is not very consistent or elegant at the moment. `Allan ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
> Anyway, on the API front. Forcing to autohinter is probably not acceptable. > So > we could enable stem darkening where native available, but then we need to > know if what engine a face is using, or better yet specifically if the engine > used right now on this face did stem darkening. I was just thinking. Can Qt mix font rendering modes on a face-by-face basis? Even without FT_Face_Option(), you can query the font driver for a face and the autohinter for stem darkening as described in [1]. If FT_Property_Get returns an error for the property, the driver has no means of darkening stems at all. Note that this is a font driver/autohinter wide setting, affecting all faces that pass through them. So, how about something like this: for each face that should be rendered, first query the driver (or the autohinter if it's to be used) if it supports stem darkening. If so, turn it on while rendering the face and use linear alpha blending and gamma correction (maybe with a factor of 1.8 like Adobe recommends). If there is no stem darkening support, blend naively. Or: also blend correctly, but use a lower gamma correction factor (e.g. 1.4 like GDI uses iirc). As it stands, this would only enable correct rendering for .otf and if the autohinter is involved. Support for more font drivers could then be done from within FreeType without source modifications in Qt. [1]: https://www.freetype.org/freetype2/docs/reference/ft2-cff_driver.html#no-stem-darkening(cff) -- Use FT_Property_Get instead, obviously. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
> I am just curious from a philosophical point of view how come stem > darkening is even needed. Gamma-corrected blending might end up > paler, but it should be a more correct result, so it just odd that it > looks wrong and that a compensation is needed. Somewhere we must have > done something that relied on naive blending. Maybe in the design of > the fonts? The result is indeed more correct, but LoDPI screens ruin everything ;) You could say that this is indirectly the fault of the font's design. Stem darkening is a pragmatic solution to increase contrast. The algorithm used by FT adjusts the darkening depending on the pixel size and font design. Thinner fonts are darkened more than bolder fonts. The darkening becomes stronger at smaller pixel sizes. Above a threshold (at larger pixel sizes), no darkening is applied. This implies that the font engine must have more control over the final appearance of a glyph and this is... difficult if it involves the explicit nature of TrueType hinting. > Also I notice in your example you also use a too low gamma value. The > standard in screens in between 2.2 and 2.4, and when using that I > generally see an inversion in the contrast balance. The 1.8 comes from internal testing at Adobe. I was told they tested font rendering on a variety of screens and determined 1.8 to be a good compromise. I think Microsoft uses 1.4 for GDI font rendering? > Look at the attached example. Ideally with correct blending text > should look equally "bold" regardless of background and foreground > color. It is obvious white on black with naive blending is too weak, > but the color on white text with GC blending is just as weak, while > white on black is now as bold as color on white used to be. If I > used a gamma of 1.6 it would look more balanced, but my screen has a > gamma of either 2.4 or sRGB , so why does using the right value give > the an unbalanced result? Hm, I think this is a perception issue. In your example, I find the third column to be more balanced than the first. The brain sees white-on-black differently than black-on-white, so a designer has to compensate for the non-linearity :) This is especially noticeable if your brain is accustomed to naive blending. White-on-black looks similar on macOS. > Anyway, on the API front. Forcing to autohinter is probably not > acceptable. So we could enable stem darkening where native available, > but then we need to know if what engine a face is using, or better > yet specifically if the engine used right now on this face did stem > darkening. I can implement something for the TT engine (v40 backwards compat. mode), maybe even soon. You can test for native stem darkening like so (src/base/ftobjs.c:633): ``` error = FT_Property_Get( library, driver->clazz->root.module_name, "no-stem-darkening", _darkening_driver ); if ( error ) { driver_can_darken_stems = FALSE; stem_darkening_driver = FALSE; } else { driver_can_darken_stems = TRUE; stem_darkening_driver = !stem_darkening_driver; } ``` (Gotta run, look up the doc for FT_Property_Get. Getting an error back means that the font driver probably won't do stem darkening. TT is tricky as noted above, must implement first before I can give a definite answer) ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
On Saturday 19 November 2016, Nikolaus Waxweiler wrote: > >> Correct font rendering with linear alpha blending and gamma correction > >> can make text look pale like reported in > >> https://bugreports.qt.io/browse/QTBUG-41590 due to the way the math > >> behind it works out. Stem darkening compensates for the paleness. > > > > Any idea why exactly? > > I'm not sure what you're asking. Do you mean why LAB+GC results in > pale(r) text? The paleness is an expected side-effect of gamma > correction on low-DPI screens. > No I understand the math. I am just curious from a philosophical point of view how come stem darkening is even needed. Gamma-corrected blending might end up paler, but it should be a more correct result, so it just odd that it looks wrong and that a compensation is needed. Somewhere we must have done something that relied on naive blending. Maybe in the design of the fonts? Also I notice in your example you also use a too low gamma value. The standard in screens in between 2.2 and 2.4, and when using that I generally see an inversion in the contrast balance. Look at the attached example. Ideally with correct blending text should look equally "bold" regardless of background and foreground color. It is obvious white on black with naive blending is too weak, but the color on white text with GC blending is just as weak, while white on black is now as bold as color on white used to be. If I used a gamma of 1.6 it would look more balanced, but my screen has a gamma of either 2.4 or sRGB , so why does using the right value give the an unbalanced result? Anyway, on the API front. Forcing to autohinter is probably not acceptable. So we could enable stem darkening where native available, but then we need to know if what engine a face is using, or better yet specifically if the engine used right now on this face did stem darkening. Best regards `Allan ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
>> If the new FT_Face_Option() is present, FT can do stem darkening on >> (almost entirely) all outline fonts :) The toolkit just has to invoke >> the function on all FT_Faces to be rendered. > > But will stem darkening work with the bytecode interpreter? It won't until I implement it in the TrueType engine, and only for the v40 interpreter in backwards compatibility mode. I don't think the concept of stem darkening is compatible with the explicit glyph modifications on both axes that are possible in v40 native ClearType mode and v35. Turning on stem darkening currently triggers the autohinter for all outlines formats except .otf, where the font driver can do it natively. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
On Saturday 19 November 2016, Nikolaus Waxweiler wrote: > > Anyway from an API point of view, the easiest implementation would be if Qt > > could read on initialization if freetype can do stem darkening on all > > outline > > fonts. Since it can't do that currently, an alternative would be to be able > > to > > query it per face, and then carry the information on. > > If the new FT_Face_Option() is present, FT can do stem darkening on > (almost entirely) all outline fonts :) The toolkit just has to invoke > the function on all FT_Faces to be rendered. But will stem darkening work with the bytecode interpreter? Fredrik ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
>> Correct font rendering with linear alpha blending and gamma correction >> can make text look pale like reported in >> https://bugreports.qt.io/browse/QTBUG-41590 due to the way the math >> behind it works out. Stem darkening compensates for the paleness. > > Any idea why exactly? I'm not sure what you're asking. Do you mean why LAB+GC results in pale(r) text? The paleness is an expected side-effect of gamma correction on low-DPI screens. Have a look at https://www.freetype.org/image/BlendingExamples.png. All (grayscale) examples are composed onto the surface using linear alpha blending. Column 1 has no gamma correction, column 2 uses a gamma correction factor of 1.8. The result in column 2 is clean but paler text. The glyphs that FreeType outputs are really 8-bit alpha maps in linear space: a pixel that has zero coverage of a glyph is white (255), one with 100% coverage is black (0), one with 50% coverage is set to a value of 127, or a middle shade of gray. Since most monitors out there do not have a linear gamma curve, you need to bend your alpha map after you have composited onto a surface. The 50% coverage or 127 value in linear space maps to a value of around 180 or so on a standard sRGB surface, 127 would be much darker. So now you go and bump that 127 up to 180 -- tada, the pixel and by extension the entire glyph is now lighter, or paler. But also nice and clean. You can also have a look at ftview from the freetype2-demos package. It uses LAB+GC by default. Using LCD filtered rendering actually makes little difference to my own surprise (press 'A' and 'C' to switch between grayscale and LCD filtered rendering, respectively). Since 1) a pixel's chance of being 100% covered is much higher on HiDPI screens and 2) black is the same thing in linear space and all other gamma curves, this is primarily an issue on LoDPI screens, so 99% of screens out there. > Anyway from an API point of view, the easiest implementation would be if Qt > could read on initialization if freetype can do stem darkening on all outline > fonts. Since it can't do that currently, an alternative would be to be able > to > query it per face, and then carry the information on. If the new FT_Face_Option() is present, FT can do stem darkening on (almost entirely) all outline fonts :) The toolkit just has to invoke the function on all FT_Faces to be rendered. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
>> I'm working on FreeType and want to merge a new API (FT_Face_Option) >> that would allow setting LCD filter weights and stem darkening >> properties on a per-face basis. > > I'm fascinated but clueless ! https://www.freetype.org/freetype2/docs/text-rendering-general.html#experimental-stem-darkening-for-the-auto-hinter Correct font rendering with linear alpha blending and gamma correction can make text look pale like reported in https://bugreports.qt.io/browse/QTBUG-41590 due to the way the math behind it works out. Stem darkening compensates for the paleness. The new API is trying to make it practical for toolkits to opt into correct rendering of fonts by making it easy to toggle stem darkening (older toolkits without opt-in will get the same glyphs as before to keep backwards compatibility). No more bug reports about pale text! (Windows, macOS and Adobe's own font software render fonts correctly (read: compose glyphs correctly onto surfaces). macOS and I think Adobe software also use stem darkening to counteract paleness. The effect is most obvious on macOS. No toolkit on X11/Wayland does any of this currently. I want to change that. Stem darkening was introduced to FreeType by Adobe, by the way.) >> A side issue this is trying to solve is making the API thread-safer, > > The concept "thread-safer" amuses me. As far as I understand, FT is not by itself thread-safe, the developer has to use the API in a certain way to not blow things up. This API is supposed to be another stepping stone towards usefulness/pain-lesser-ness in a multithreading context. > I've (as ediosyncratic) reviewed; nothing struck me as obviously > problematic. I am not, however, a graphics expert. Thanks! :) ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
[Development] Font rendering on X11/Wayland: New FreeType API to toggle LCD filters and stem darkening on a per-font basis, would love a review
Hi! people in #qt-labs directed me here. I'm working on FreeType and want to merge a new API (FT_Face_Option) that would allow setting LCD filter weights and stem darkening properties on a per-face basis. The goal is to enable toolkits like Qt to finally turn on linear alpha blending and gamma correction on X11/Wayland for font rendering without users filing bugs like https://bugreports.qt.io/browse/QTBUG-41590. Stem darkening thickens glyphs depending on pixel size and the font design itself to prevent them from thinning out with LAB+GC. This would properly solve the above bug. A side issue this is trying to solve is making the API thread-safer, i.e. threads can now toggle stem darkening and modify LCD filter weights directly on their own FT_Face object without contending for a shared FT_Library or the font-driver-wide setting. I'd love to get feedback on the API before we make it official because I want to make sure it's actually useful in practice. The patches for FT are the top 3 commits at https://github.com/madig/freetype2/commits/stem-darkening-api. You can clone the repo somewhere and modify your compiler's include directives to look for FreeType there, then load the new library with `LD_PRELOAD=/somewhere/freetype2/objs/.libs/libfreetype.so some-application`. API usage examples are at https://github.com/madig/freetype2/commit/297b68621c020c8d6e61a04b8e91ac829a6bc13d#diff-9a8d509c02006aa497c68bcbcd32d505R3618 Best regards, Nikolaus ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development