Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Linux/FreeType + VariableTTF-specific] Some glyphs (e.g. a '4', or the bottom-right stem of lowercase 'u') look weird at certain sizes, due to mis-handling overlapping paths of variable font. Needs FreeType 2.10.3 and font flag OVERLAP_{SIMPLE, COMPOUND} #350

Closed
ronjouch opened this issue Aug 27, 2020 · 26 comments · Fixed by #352

Comments

@ronjouch
Copy link

Environment

Cascadia Code version number: 2008.25
Application used to display text: VS Code 1.48.2, Firefox 80.0, Kitty 0.18.3, everywhere
OS platform and version: Ubuntu 20.04.1
Screen resolution (i.e. 220dpi): I don't know

Steps to reproduce

Display a u at size 14.7

Expected behavior

u is good-looking

Actual behavior

u looks weird: the bottom right stem has sort of a glitch, where it overlaps to the inside part of the curve:

screenshot_cascadia-code-weird-u_2020-08-27-10:37:25

@ronjouch ronjouch changed the title Bottom-right stem of lowercase 'u' looks weird at size 14.7: chunky, a bit overlapping to the inside of the curve Bottom-right stem of lowercase 'u' looks weird at certain sizes: chunky, a bit overlapping to the inside of the curve Aug 27, 2020
@ronjouch
Copy link
Author

Here's another slightly bigger size looking funky:

screenshot_other-size_2020-08-27-10:40:59

@aaronbell
Copy link
Collaborator

Hi. What is interesting is that you can see on the 4 that it appears that the diagonal stroke is extending past the horizontal one. I'm guessing that you've installed the variable font version (since what you're observing happens where different strokes overlap). Did you install the OTF or TTF version?

However, I am not able to repro the issue that you're observing on Windows or Mac, which makes me suspect that it has something to do with how ubuntu is interpreting the font.

@ronjouch
Copy link
Author

ronjouch commented Aug 27, 2020

@aaronbell thanks for the fast feedback.

What is interesting is that you can see on the 4 that it appears that the diagonal stroke is extending past the horizontal one.

Indeed 👍.

I'm guessing that you've installed the variable font version (since what you're observing happens where different strokes overlap).

What do you mean by "the variable font version"?

Did you install the OTF or TTF version?

I had installed the TTF version. And, lo and behold, the OTF version doesn't exhibit the issue! Here's a screenshot of the OTF version at the same size as the initial screenshot (14.7), the problem is gone (but now descenders for y g j are cut, gah 😄, maybe this is my terminal's problem, though)

screenshot_otf_2020-08-27-12:40:51

However, I am not able to repro the issue that you're observing on Windows or Mac, which makes me suspect that it has something to do with how ubuntu is interpreting the font.

Not just Ubuntu, though, I see the same thing on my Arch Linux machine (and I will confirm it's gone switching to OTF). So, maybe a bug in a common rendering library? Which one is responsible for this exactly? FreeType? Harfbuzz?

@ronjouch ronjouch changed the title Bottom-right stem of lowercase 'u' looks weird at certain sizes: chunky, a bit overlapping to the inside of the curve [linux-specific, TTF-specific] Bottom-right stem of lowercase 'u' looks weird at certain sizes: chunky, a bit overlapping to the inside of the curve Aug 27, 2020
@aaronbell
Copy link
Collaborator

In the 2008.25 package, there are static OTFs (each weight is a separate .otf) and TTFs, both variable (all styles are contained within one .ttf file) and static (each weight is a separate .ttf).

When you installed the TTF version, did you install CascadiaCode.ttf or CascadiaCode-Regular.ttf?

@ronjouch
Copy link
Author

ronjouch commented Aug 27, 2020

In the 2008.25 package, there are static OTFs (each weight is a separate .otf) and TTFs, both variable (all styles are contained within one .ttf file) and static (each weight is a separate .ttf).

When you installed the TTF version, did you install CascadiaCode.ttf or CascadiaCode-Regular.ttf?

@aaronbell my initial report was with the variable TTF (all styles in one .ttf). After a rm -rf ~/.local/share/fonts/Saja* && fc-cache -fv followed by an install of static Cascadia_Code_Regular.ttf + Cascadia_Code_Bold.ttf, things look good (as good as when I installed OTF Regular+Bold, in my previous post):

screenshot_ttf-static_2020-08-27-13:04:43

→ Yes, the problem is specific to the variable TTF (all styles are contained within one .ttf file).

What could explain this?

@aaronbell
Copy link
Collaborator

It is probably an issue with FreeType's method of dealing with variable fonts, or fonts that have overlapping paths within one glyph (normally these overlaps are removed, but for variable fonts it is useful to preserve them).

Which version of FreeType are you running? According to the FreeType page you should be running 2.9 at minimum for proper Variable font support.

@ronjouch
Copy link
Author

ronjouch commented Aug 27, 2020

Which version of FreeType are you running? According to the FreeType page you should be running 2.9 at minimum for proper Variable font support.

@aaronbell I'm running the libfreetype6 2.10.1 package shipping as part of Ubuntu 20.04. Do you suggest I report this as a potential FreeType bug?

@aaronbell
Copy link
Collaborator

From what I can tell, that package doesn't look like it has the most up-to-date version of FreeType. Can you try upgrading to the latest? If the latest still shows the issue, then yeah, it should be reported.

@ronjouch
Copy link
Author

From what I can tell, that package doesn't look like it has the most up-to-date version of FreeType. Can you try upgrading to the latest? If the latest still shows the issue, then yeah, it should be reported.

@aaronbell no and yes. No because in a non-rolling-release Linux (like Ubuntu), you never upgrade such a core package out of major versions, that's a recipe for a broken system. That being said, yes because my home machine runs Arch (which is a rolling release currently shipping the latest freetype 2.10.2) and exhibits the problem. Will file a bug upstream and closing this one. Thanks for all the guidance.

@ronjouch ronjouch changed the title [linux-specific, TTF-specific] Bottom-right stem of lowercase 'u' looks weird at certain sizes: chunky, a bit overlapping to the inside of the curve [linux + VariableTTF-specific] Some glyphs (e.g. a '4', or the bottom-right stem of lowercase 'u') looks weird at certain sizes, maybe due to mis-handling overlapping paths of variable font Aug 27, 2020
@ronjouch
Copy link
Author

@aaronbell FYI, as I'm preparing the FreeType bug report:

  • (Broken multi-font bundle) ftview -d 1024x768x24 30 CascadiaCode-2008.25/ttf/CascadiaCode.ttf
    screenshot_cascadia-1-bad-ttfBundle_2020-08-27-19:07:37
  • (Good single font) ftview -d 1024x768x24 30 CascadiaCode-2008.25/ttf/static/CascadiaCode-Regular.ttf:
    screenshot_cascadia-2-ok-singleRegular_2020-08-27-19:06:58
  • A looping GIF animating between both:
    cascadia-code-animation

@ronjouch
Copy link
Author

@aaronbell
Copy link
Collaborator

Thank you!

@apodtele
Copy link

FreeType will handle overlapping contours in the next release but it will require OVELAP_SIMPLE or OVERLAP_COMPOUND set. We understand that those flags are optional in variation fonts but oversampling quadruples the rendering time. Buyer beware.

@ronjouch
Copy link
Author

ronjouch commented Aug 28, 2020

FreeType will handle overlapping contours in the next release but it will require OVELAP_SIMPLE or OVERLAP_COMPOUND set. We understand that those flags are optional in variation fonts but oversampling quadruples the rendering time. Buyer beware.

Thanks @apodtele . @aaronbell, Alexei also posted a few more details on the FreeType bug that should be of interest to you. Quoting them here:

You correctly identified the issue: overlapping contours can produce pixels with inflated coverage because FreeType normally integrates the coverage. To mitigate the artefacts, oversampling is necessary (increase resolution 4x4 and average the results).

We implemented this recently but it quadruples the rendering time. Only glyphs with explicit OVERLAP_SIMPLE or OVERLAP_COMPOUND would be subject to oversampling.

Those flags are required in static fonts with overlaps. CascadiaCode just removes the overlaps in the static fonts, which is even better alternative. The flags are optional in variation fonts however but not all variation fonts have overlaps. We stopped short of enabling oversampling for all variation fonts.

Alexei also comments about OVERLAP_SIMPLE and OVERLAP_COMPOUND in the OpenType
specs
:

On one hand in variable fonts, "use of this flag is not required in OpenType". On the other hand in static fonts, "either set this flag in the derived glyph data, or else should merge contours to remove overlap". Hopefully, the next version of the specs will recommend these flags in variation fonts just to be consistent.

It will be hard to change the current practice before the specs mature. So it is a long road ahead with some discussions to be had.

@aaronbell, can you build me a pre-release version of CascadiaCode with one of the OVERLAP_ flags set? I'll test it with the latest git version of FreeType.

Side note: over at the FreeType bug I'm also asking what's the path forward for distribution packagers.

@ronjouch ronjouch reopened this Aug 28, 2020
@ronjouch ronjouch changed the title [linux + VariableTTF-specific] Some glyphs (e.g. a '4', or the bottom-right stem of lowercase 'u') looks weird at certain sizes, maybe due to mis-handling overlapping paths of variable font [Linux/FreeType + VariableTTF-specific] Some glyphs (e.g. a '4', or the bottom-right stem of lowercase 'u') look weird at certain sizes, due to mis-handling overlapping paths of variable font. Needs FreeType 2.10.3 and font flag OVERLAP_{SIMPLE, COMPOUND} Aug 28, 2020
@aaronbell
Copy link
Collaborator

Thanks for the investigation and info on this. It appears that the python library that we're using to build the Variable font doesn't automatically implement the OVERLAP_SIMPLE or OVERLAP_COMPOUND flag where it should be. AFAIK, this isn't a problem in the Mac / Windows rasterizers, but seems that it is in FreeType. I'll investigate further.

@aaronbell
Copy link
Collaborator

aaronbell commented Aug 28, 2020

@ronjouch Can you test the attached font?
[removed]

(BTW, this font does not contain hinting, which may cause other unexpected changes, but I wanted to see if my fix actually resolved the overlap issue)

@ronjouch
Copy link
Author

ronjouch commented Aug 28, 2020

Can you test the attached font? [removed]

(BTW, this font does not contain hinting, which may cause other unexpected changes, but I wanted to see if my fix actually resolved the overlap issue)

@aaronbell (cc @apodtele) problem fixed if using that font and FreeType 2.10.2+p53+g6730854c3 (but not FreeType 2.10.2 stable). For completeness, what flag/changes did you use to produce this build?

Proof: screenshots of ftview -d 1024x768x24 30 CascadiaCodeTEST.ttf,

  1. With FreeType 2.10.2 stable: broken, with artifacts:
    screenshot_cascadiacodeTEST-freetype2102stable_2020-08-28-12:31:34
  2. With FreeType 2.10.2+p53+g6730854c3: fixed, no artifacts:
    screenshot_cascadiacodeTEST-freetype2102+p53+g6730854c3_2020-08-28-12:32:37
  3. A GIF animating between both:
    screenshot_cascadiacodeTEST-animation

@apodtele
Copy link

I think that the root of the problem is in the rasterizer implementation

  • Microsoft rasterizer is based on 4x4 oversampling for anti-aliasing which is likely slower but handles overlaps naturally. Microsoft even omitted these flags in the earlier versions of specification.
  • Apple rasterizer is probably based on integration, which is likely faster but does not handle overlaps well. Hence they care about the OVERLAP_SIMPLE or OVERLAP_COMPOUND flags but probably give in and do oversampling on top of integration for all variable fonts. This is just a guess and they might have a fast algorithm to detect overlaps.
  • FreeType is certainly based on integration. We would like to be explicit about oversampling by setting the flags because it quadruples the rendering time. We did not investigate if detecting overlaps is plausible.

Thus this is an active area...

@aaronbell
Copy link
Collaborator

aaronbell commented Aug 28, 2020

Thank you for your help! For this test version of the font I adapted @chrissimpkins's code from here to the build process. This forces the OVERLAP_SIMPLE or OVERLAP_COMPOUND flags to be applied to all glyphs if simple or compound, respectively.

Perhaps a bit of a brute force approach, but it solves the problem.

@aaronbell
Copy link
Collaborator

@apodtele My understanding aligns with yours—for variable fonts, MacOS acts as if the OVERLAP_SIMPLE and OVERLAP_COMPOUND flags are present, even if not actually set in font.

Seems that FreeType is the only rasterizer that actually cares if the flags are present in a variable font.

@apodtele
Copy link

Ideally, only glyphs with overlaps should have these flags set. I wonder what @madig is doing.

Would you like to bring this up on freetype-devel? I honestly have no idea how prevalent the overlaps in variable fonts. I would like to see overlap-free variable fonts if it is practical.

@aaronbell
Copy link
Collaborator

aaronbell commented Aug 28, 2020

If this is any indication he's putting it everywhere 😆 .

Overlaps are actually extremely common in variable font development. For example, at extreme heavy weights, glyphs often have greater amount of overlap than they do at the extreme light end. If overlaps were removed in such a situation, it would be impossible to preserve master compatibility. So preserving outline overlaps is a necessity.

From what I have found, it sounds like this issue has already been raised several times on the FreeType mailing list, so I wouldn't be adding anything more to the discussion 😄.

@madig
Copy link
Contributor

madig commented Aug 28, 2020

Seems that FreeType is the only rasterizer that actually cares if the flags are present in a variable font.

macOS < 10.16 cares, too.

I honestly have no idea how prevalent the overlaps in variable fonts. I would like to see overlap-free variable fonts if it is practical.

The usual (most common) open-source pipeline to make VFs is based on ufo2ft, which currently doesn't do anything, so there are unlikely to be many VFs with those flags set...

@apodtele
Copy link

If you agree with setting the flags explicitly, we are on the same page and the specs will catch up eventually by recommending these flags. Implying the overlaps in all variable fonts seems to be an overkill unless I miss something. That is what needs to be discussed in a larger community.

@madig
Copy link
Contributor

madig commented Aug 28, 2020

If you agree with setting the flags explicitly

Sure, even if this is to work around an InDesign bug.

That is what needs to be discussed in a larger community.

Use this community: googlefonts/ufo2ft#402, it's the only one I care about ☺

@ronjouch
Copy link
Author

On the distro packaging side, I filed Arch FS#67746 - [ttf-cascadia-code] Some glyphs show artifacts due lack of overlap support in FreeType 2.10.2, where I suggest they switch to packaging the static fonts (with the caveat of increased disk space) until the font is patched with OVERLAY flags and a stable FreeType release supports them.

DHowett pushed a commit that referenced this issue Sep 14, 2020
This commit modifies the build script to add "OVERLAP_SIMPLE" to normal
glyphs and "OVERLAP_COMPOUND" to component glyphs. 

Under FreeType, "overlapping contours can produce pixels with inflated
coverage because FreeType normally integrates the coverage. To mitigate
the artefacts, oversampling is necessary (increase resolution 4x4 and
average the results)" ([mailinglist quote]). FreeType relies on the
"OVERLAP_SIMPLE" and "OVERLAP_COMPOUND" flags to be set to know when
this oversampling should take place. 

At current, Cascadia does not contain either of these two flags. This
fix will add one or the other to every glyph in Cascadia (depending on
type of glyph), thus resolving the issue. Once the ufo2ft library adds
functionality to address this issue, the build script modification can
be removed. 

The addition of these flags has no impact on the behavior of the font in
Mac or Windows environments. 

Closes #350
Closes #355 - switches contour order to resolve interpolation error at wght 300

[mailinglist quote]: https://savannah.nongnu.org/bugs/index.php?59026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants