[skrifa] support interpreter-version 35
With this change, font rendering appears to be essentially identical to freetype.
Chromium compiled with this patch (and a small skia patch to use InterpreterVersion::from_environment):
Firefox:
There are some small differences but they might be caused by a different component.
I've not added any tests. Let me know if/how this should be tested.
Closes #1215
It might also be necessary to round the font size somewhere. Otherwise fonts with fractional pixel sizes in chromium don't render correctly.
I was able to fix the aforementioned issue by rounding font sizes when the interpreter version is 35. This makes chromium render text with fractional pixel sizes like firefox, that is, there is a hard jump at .5 and everything between x-0.5 and x+0.5 renders the same.
I believe that FreeType performs this rounding and that it does not depend on the interpreter version, but without interpreter-version=35 I could not easily spot the difference whereas interpreter-version=35 makes it obvious.
Thank you for taking this on! I won’t be able to do a thorough review until next week but, at a glance, the code looks good and I don’t foresee any issues with landing this in some form.
I just wanted to provide another data point for this: I just encountered a font that actually renders wrongly if hinting is disabled! If I don't enable hinting, the characters look like this, completely garbled:
With the current hinting mechanism, they look slightly better but still wrong:
With your patch, they look correct:
So this would definitely be nice having. :)
For others, who arrive here looking for solution how to make font rendering beautiful again in Chrome 136+, now that the flags used to disable Fontation have been deprecated - you can still use google-chrome --disable-features=FontationsLinuxSystemFonts
This disables fontation and falls back to freetype so FREETYPE_PROPERTIES="truetype:interpreter-version=35" is respected again.
I just wanted to provide another data point for this: I just encountered a font that actually renders wrongly if hinting is disabled! If I don't enable hinting, the characters look like this, completely garbled:
I believe this is #1303. For Skia/Chrome, we check the result of the require_interpreter() method and set the hinting target to Mono when that returns true. The result is very similar to the v35 interpreter.
Ah interesting, will try that!
EDIT: Okay, can confirm that this fixes it, thanks for the hint!
For others, who arrive here looking for solution how to make font rendering beautiful again in Chrome 136+, now that the flags used to disable Fontation have been deprecated - you can still use
google-chrome --disable-features=FontationsLinuxSystemFonts
Note that this option is removed after 139.0.7258 https://chromiumdash.appspot.com/commit/2fc1ae192a45eb6f1716e232dd1626317f8d299e We no longer intend to carry the FreeType support.
See https://crbug.com/349952802 and reasoning in https://developer.chrome.com/blog/memory-safety-fonts#why_replace_freetype
Then lot's hope this PR gets reviewed and merged until then.
I'll be out of the office during August so ideally that would happen before then.
yes please
@drott, moving on from freetype is certainly good idea but don't leave us hanging here :)
Ping
It looks like this is still failing CI for the reason I mentioned above. I've made a PR to your PR which should fix it.
I've merged your change but I don't think that is what has kept this PR from being reviewed.
I don't think that is what has kept this PR from being reviewed
Apologies, will ask internally.
https://issuetracker.google.com/issues/415076053 is marked WontFix, which I take to mean Chrome doesn't intend to work on this. Given that is there still a reason to land this?
https://github.com/googlefonts/fontations/issues/1215 is still open. I believe various API consumers in the Rust text ecosystem also want this hinting style (e.g. https://github.com/dfrg/swash/issues/96).
This PR doesn't seem to introduce that much new code to test; it seems to be a few new branches in what is already a straight port of FreeType code. How much would it cost in code review time and ongoing maintenance burden?
https://issuetracker.google.com/issues/415076053 is marked WontFix, which I take to mean Chrome doesn't intend to work on this. Given that is there still a reason to land this?
Doesn't it automatically fix it for chrome when it lands in fontations?
How much would it cost in code review time and ongoing maintenance burden?
Little but not zero is probably fair?
Doesn't it automatically fix it for chrome when it lands in fontations?
I am under the impression Chrome would need code to activate it before it would do anything.
https://issuetracker.google.com/issues/415076053 is marked WontFix, which I take to mean Chrome doesn't intend to work on this. Given that is there still a reason to land this?
It looks like the reason that issue was closed was because the author did not provide a justification for honoring FREETYPE_PROPERTIES=truetype:interpreter-version=35:
we no longer honor FREETYPE_PROPERTIES= - however, we do still take into account FontConfig rendering settings that are configured on the system.
What is the specific rendering issue you're trying to address with the FREETYPE_PROPERTIES environment variable? I suggest to file a specific issue for that.
I am under the impression Chrome would need code to activate it before it would do anything.
Skia needs to call the function to load the interpreter version from the environment.
https://github.com/googlefonts/fontations/issues/1215 is still open. I believe various API consumers in the Rust text ecosystem also want this hinting style (e.g. https://github.com/dfrg/swash/issues/96).
Vscode has also reverted the switch to fontations on their end due to the changed font rendering (linked above). So it's not just other rust code but also downstream from chromium.
Electron due to chromium is also affected ofc, thats why I run slack and signal-desktop with --disable-features=FontationsLinuxSystemFonts as well
Both the vscode and swash issues seem unrelated to the v35 interpreter. In the vscode case, this appears to be lack of support for embedded bitmaps. For swash, there is no way to request the monochrome hinting target and we don’t have a bi-level scanline converter with dropout control.
Ping
Could you please review this? It's only +234 −53 so it should not be that much work. The code is almost a 1-to-1 copy of the corresponding freetype code and can mostly be checked by comparing the two sources.
It would be one thing if you had said from the start that you don't want this. But instead you encouraged people that this is something that you supported.
I just don't want to have to have to recompile chromium just to get back the font rendering that I've enjoyed for the past 15 years.
Yes, please