bohoomil/fontconfig-ultimate

Add option to re-enable stem darkening

Closed this issue · 36 comments

I've found that the differences with FreeType 2.6.2 I was complaining about here were caused by the change upstream that disables stem darkening by default.

I've written a patch which adds a new option, INFINALITY_FT_STEM_DARKENING, which when set to true re-enables stem darkening. With that my fonts mostly look the same as they did before the 2.6.2 upgrade (apart from in Chrome, which I still need to investigate).

No idea if adding an option for this is the right thing to do, seemed better than just reverting the upstream change though ;)

Here's a newer version of the patch: stem-darkening.txt

Turns out that the stem darkening in the autofit module was added in 2.6.2, only the CFF module had it previously. The results produced by the autofit stem darkening look way too bold, so in the new version I've separated the options out into INFINALITY_FT_{CFF,AUTOFIT}_STEM_DARKENING.

With the CFF stem darkening enabled and the autofit disabled I've now got my fonts completely back to how they were in 2.6.1.

0xBRM commented

@aejsmith Can you show screenshots of the results produced by the autofit stem darkening and the new ones? Curious now.

@aejsmith Thank you for the contribution. I believe @mviikki16 or @goddesse will kindly look into it and discuss the matter with you much better than I could. Besides, @mviikki16 has been working a lot with Infinality recently so I wouldn't like to get in the way and mess with the code without his knowledge. ;-)

@bohoomil The official code is on your hands so it's entirely up to you what goes in or out of it :-)

Initially I was also leaning on reverting the stem darkening upstream change and my old patch did just that. However, with old stem darkening i turned into l and I decided to follow upstream as I got used with the less contrasty but more accurate rendering.

I had a glance over the patch, it looks nice. I haven't yet tested it but seems to be the right way to have this additional flexibility available.

The patch looks logically correct and I've tested it and it properly does what it says without interfering with the default behavior for those who don't want stem darkening. It's small and unobtrusive enough that it will be easy to massage into working with future upstream changes to stem darkening whether it's a module option or what.

I would also recommend a patch to infinality_setting.sh with it off by default so people know it's there.

Thank you @mviikki16 and @goddesse. I'll update the package and change infinality-settings.sh appropriately (I was going to do this anyway).

Just one pedantic notice/suggestion/question:
The options in the ftinf_t structure were in alphabetical order, wouldn't it be nicer to have the new options fit the same pattern and maybe be renamed as stem_darkening_{autofit,cff} to be adjacent to each other. I know, this requires a bit of updating...

You mean like this:

int autofit_stem_darkening;
int cff_stem_darkening;

vs.

int stem_darkening_autofit;
int stem_darkening_cff;

If so, I'll do this, no problem.

diff --git a/src/base/ftinf.h b/src/base/ftinf.h index 384ed90..fbe1bd1 100644 --- a/src/base/ftinf.h +++ b/src/base/ftinf.h @@ -42,13 +42,13 @@ typedef struct ftinf_s { int global_embolden_y_value; int grayscale_filter_strength; int stem_alignment_strength; - int stem_darkening_autofit; - int stem_darkening_cff; int stem_fitting_strength; int stem_snapping_sliding_scale; int use_known_settings_on_selected_fonts; int use_various_tweaks; int windows_style_sharpening_strength; - int autofit_stem_darkening; - int cff_stem_darkening; } ftinf_t; Indeed, the struct will look as above but other changes are missing and needed.

OK, I'll do my best. Thank you!

Hmm, I couldn't update my comment to properly display the code so it's attached (but you got the idea the 1st time)

ftinf.txt

If you need help I can also do it although my target was @aejsmith, the original creator.

That's OK, I got the properly formatted in the mail. @aejsmith will certainly help if necessary, I believe. ;-)

Updated patch with the reordered/renamed settings: stem-darkening.txt

@CrisBRM The screenshots I posted on the Arch forums show the difference for CFF stem darkening, with and without. For the autofit stem darkening, here's some screenshots with and
without (look at the content of the Chrome window). To me CFF darkening looks OK but the autofit one doesn't look right (maybe it's just that I'm so used to how I had it looking before!)

@aejsmith,
I've applied your patch. How can these setting be changed ?

@perfect7gentleman Using the INFINALITY_FT_STEM_DARKENING_AUTOFIT and INFINALITY_FT_STEM_DARKENING_CFF environment variables, set them as you would any other Infinality environment variables. They default to false which is the upstream behaviour, set them to true to enable them.

i.e. export INFINALITY_FT_STEM_DARKENING_AUTOFIT=true ?

@perfect7gentleman Yes, you can use any of: 1, on, true, yes (in case independent manner)

Nice for infinality to have so much flexibility with settings. It clearly has potential to address anybody's preferences and, in my testing, it's a significant step up to vanilla freetype. However, there's still room to grow. To my eyes, the gold standard looks to be how Acrobat Reader renders fonts i.e. CoolType library (perfect balance with colour fringes). I updated poppler to run cairo backend with subpixel rendering and okular gives an improved view but it is still at some distance to the Acrobat :( While I didn't have enough time to experiment I can't seem to find the settings to replicate that, even with the current multitude of options. If anybody took (or will take a closer look to this issue) I'll be happy to add a new settings record with the magic variables.

with INFINALITY_FT_STEM_DARKENING_AUTOFIT=true fonts are some kind of blurred

0xBRM commented

@perfect7gentleman You can try INFINALITY_FT_STEM_DARKENING_CFF=true as well. If you don't like either, don't use them. That's why modularity is so good :]

madig commented

@mviikki16 I don't think you can match or exceed what Adobe is doing until 1. Linear alpha blending and gamma correction (critical for minimizing color fringes) 2. Stem darkening for everything, even TrueType fonts.

@madig Matching Adobe's rendering would be already enough...1 can be a reason but not so sure about 2. Infinality is not that far off for TrueType fonts, not that much of a difference... However, Type 1 of which pdf have plenty of embedded fonts is atrociously bad, especially at small sizes...

madig commented

@mviikki16 2 is needed if you do 1, Adobe is doing it. alankila wrote a proof-of-concept hack for cairo's pixman, I updated it to work with 0.32.6 and possibly above: https://gist.github.com/madig/c7dca1e242ade375856e

Recompile pixman with it and do:

export LD_PRELOAD=~/somewhere/pixman-0.32.8/pixman/.libs/libpixman-1.so
export CAIRO_DEBUG=xrender-version=-1
some_application

in the terminal. This will trigger software rendering in apps using cairo (e.g. all GNOME3 apps). The result is something approximating linear alpha blending and gamma correction. Then you can turn stem darkening on and off in infinality and compare.

@madig Thanks! Did a test and there are differences as seen in the images attached. pix denotes the patched pixman and the setup you described, sdcff0/1 is for INFINALITY_FT_STEM_DARKENING_CFF off or on while adobe is Adobe's rendering in Acrobat.

sdcff1 does the trick for reducing the color fringes while pix helps offset somewhat the too harsh contrast.
adobe
snap_adobe
sdcff0
snap_sdcff0
sdcff0_pix
snap_sdcff0_pix
sdcff1
snap_sdcff1
sdcff1_pix
snap_sdcff1_pix

0xBRM commented

acrobat vs okular

To be fair, both could do better.

@CrisBRM For this comparison okular wouldn't be so far off but you need a patched poppler to enable cairo backend e.g. https://github.com/giddie/poppler-qt4-cairo-backend. Acrobat can't do wonders with dpi limits though...

0xBRM commented

@mviikki16 it was emerged with the Cairo use flag. Is that not enough? What do you mean by the DPI limits? (Since everything is DPI bound anyway)
Thanks for the patch set. I will check it out when I get home.

@CrisBRM It is obvious from the image that okular has no subpixel anti-aliasing enabled. Poppler does not do that by default, you must patch it and then check again.

With dpi limits I meant that there's only that much you can do. As you wrote, everything is limited by it and at ~100 dpi for you screen (assuming it's like mine) you can't expect miracles. Adobe's CoolType does a good job at it, for my eyes looks better than everything else i.e. ClearType, OS-X and even Infinality (which at certain cases like very small sizes and Type-1 fonts has issues).

madig commented

Which LCD filter did you use? It must be normalized and color-balanced. Try the default or light one.

@madig Good you mentioned! I thought I've used the "push" default one, color-balanced but not normalized. I've tried changing the filter with the environment variable and I got identical rendering, even a filter like "100 100 100 100 100" while it messes up UI fonts the pdf renders the same. Clearly, at some level a custom filter is set overriding Infinality's filter settings. This requires some debugging..

Cairo as used by poppler will default to FT_LCD_FILTER_LEGACY and this causes most problems. When forcing it to use FT_LCD_FILTER_DEFAULT the results are much better

sdcff0
snap_sdcff0_upd
sdcff1
snap_sdcff1_upd

sdcff1 results in way too bold fonts, perhaps an updated pixman might reduce this somewhat but in other parts of the documents the effects are even more pronounced, not really an option to turn this on.

Perhaps the Infinality patch should be updated to replace the legacy filter options (there is also FT_LCD_FILTER_LEGACY1) with the default to take care of cases where old filters are used. To cover all options the 3 tap light filter (FT_LCD_FILTER_LIGHT) would need its Infinality variant to allow customization in all cases...

As clarification, FT_LCD_FILTER_DEFAULT from above is not freetype's built-in default but, finally, it is allowing the custom Infinality preset version (8, 24, 56, 24, 8 as used above) to be enabled. When any other filter options are selected then the Infinality filter is ignored.

I attached an update fixing this Cairo issue by ignoring the legacy requests and using the default filter instead. A light filter option is also included. No built-in setting uses it but can be set from environment.

Speaking of environment, in my testing I found rather cumbersome the INFINALITY_FT prefix and replaced it with FT as the names are long enough anyway...
The active/default built-in setting is now selected with FT_DEFAULT.
Filter parameters are taken from FT_LCD_FILTER and FT_LCD_FILTER_LIGHT (while FT_FILTER_PARAMS was still left as option for 1st one).

inf_update.txt

inf_rename.txt

The reference is the current 03-infinality-2.6.2-2015.12.05.patch made by @bohoomil. (it also adds the two STEM_DARKENING additions as I already had those in my code)

0xBRM commented

@mviikki16 What cairo method call did you use to call LCD_FILTER_DEFAULT and LCD_FILTER_LIGHT? Did you patch Cairo yourself or is there something other than the now deprecated cairo_font_options_set_lcd_filter()?

I did not modify cairo calls, the update is as described and included in the patch above, legacy filter settings are ignored being replaced with the default ones (when infinality patch is selected). You can see the specific change at the end of inf_update.txt (@@ -381,8 +405,14 @@).

The functionality is available in the recent upgrade.

@bohoomil Thanks, looks good!