-
Notifications
You must be signed in to change notification settings - Fork 44
Implement OVERLAP_SIMPLE / OVERLAP_COMPOUND #402
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
Comments
I petitioned @anthrotype to include that snippet in ufo2ft but he wondered if we break something with that. So, we asked Apple... and got a bit of a non-response. So. Yeah. Maybe we simply need to put it in and rely on scream testing? We certainly do it internally for our future VF releases. Or maybe we need to test for any overlaps before setting the flags, to not unnecessarily impact performance where not needed? Hm, hm, hm. |
My understanding (as I mentioned on the other thread) is that Apple assumes the flags are set for Variable Fonts. So it doesn't really matter to them either way. I asked the folks at Microsoft and they said that they essentially ignore the flag. So it is really just FreeType to worry about.
This would definitely be the most elegant approach, but brute force is so much more fun. 😆 |
Honestly I wasn't aware freetype produced such glitchy renderings of overlapping contours in VFs until reading this. The "known limitation" is also confirmed on this ft-devel thread https://www.mail-archive.com/freetype-devel@nongnu.org/msg11473.html IIUC, this has been like that for long time, but only recently a new 4x4 oversampling feature that mitigates this was added but not enabled by default for VFs for performance reasons. The latest FreeType is instead using the OVERLAP glyf flags to determine whether to enable the oversampling, thus shifting the responsibility of detecting overlaps on the font developer/compiler; probably because doing that at runtime would be even more expensive. I can understand why they may want to do that, however I am not sure if freetype can rely on those flags being set "correctly" by the font developer, at least for the current set of VFs out there. The Apple TrueType spec says those flags are required to support legacy environments like PostScript printers that only understand even-odd fill rule; they mean to say to the renderer that "this glyph contains overlapping contours or components; remove overlaps using non-zero winding to obtain simplified outlines that render the same when they are filled using even-odd rule". Only recently the OpenType spec made those flags public, but with a caveat that they are not required and only relevant for the apple platform. The OT spec also notes that their intent is to "avoid dropouts" and "ensure that non-zero-fill algorithm is used"; it does not mention the problem of inflated pixel coverage of overlapping paths. fontmake (via ufo2ft) never sets these flags for VFs currently, because my understanding was that they are "legacy" stuff for old Apple-only implementations. The fonttools mutator/instancer do set the flags only when creating static instances from VFs -- to work around the fill algorithm issues on Apple renderers mentioned above. Also I don't think any other font compiler out there sets the overlap flags when making VFs, for the same reasons. Now I am not saying we should ignore the issue. Actually thanks for bringing this up to my attention. |
time compexity of testing for intersections between contours or components is proportional to the square of the number of elements in a glyph as we need to test all pair combinations. Then we can have a new pre-processing filter, which is disabled by default (and also, it's never enabled if overlaps are being removed -- the default with statics), which detects the self-overlapping contours/components and adds tha lib key, so that the outlineCompiler can subsequently apply it when creating the TTGlyph. fonttools varLib will then set the flags on the default glyphs if any of the non-default glyph masters set them, as outlined in fonttools/fonttools#2059 |
In static fonts "either set this flag in the derived glyph data, or else should merge contours to remove overlap". Such strong language would never appear in the specifications for something insignificant. FreeType is just asking to be explicit about overlaps so that at least some variable glyphs or fonts do not suffer from slow rendering. Do we want to reward some variable fonts or just punish all of them? |
nobody is questioning that for static fonts overlaps should be removed, or that when dynamically generating static instances from a variable font one should set the flags for broader interoperability with old apple rasterizers that only do even-odd fill. |
I do not think that the inflated coverage problem is specific to FreeType. I wish I could test it on macOS with unflagged overlap in a static font. Unfortunately I do not have macOS and you say that it will show as even-odd fill. So our discussion remains hypothetical for the time being. |
it will show as even-odd fill, as this issue (and many similar) reported fonttools/fonttools#1281 Note that WOFF2 fonts strip those overlap flags (they cannot encode them in the transformed glyf table): google/woff2#123 Among the workarounds for the even-odd overlap issue above with static fonts, @Lorp suggested to add an empty fvar to trigger the Apple rasterizer into thinking the font is "variable", which everybody so far understands as often being "with overlaps" and as such not needing those legacy flags. |
Please understand my concern too. Why should FreeType waste CPU in variable glyphs without overlaps? |
@apodtele the issue for me is with static fonts made on the fly from variable fonts, as in FauxFoundry but also in printer drivers or anything exporting static content. For such fonts, the producer does not want to spend CPU cycles/coding time finding out whether there are overlaps in each glyph, but wants to express “there may be overlaps” for all glyphs. The producer also wants the full benefit of WOFF2 compression, so @anthrotype a dummy axis was necessary in the end, rather than an empty fvar table. So the fvar table is this (as I wrote here but with @behdad’s nameID fix): <fvar>
<Axis>
<AxisTag>AAAA</AxisTag>
<Flags>0x0</Flags>
<MinValue>0.0</MinValue>
<DefaultValue>0.0</DefaultValue>
<MaxValue>0.0</MaxValue>
<AxisNameID>0xFFFF</AxisNameID>
</Axis>
</fvar> |
@Lorp The inflated coverage artifact would not be visible in printers and they should indeed ignore the flags. Besides WOFF2 with transformed 'glyf', CFF2 cannot flag overlaps either. Those are all good arguments against OVERLAP_SIMPLE and OVERLAP_COMPOUND, but WOFF2 also supports null-trasformed 'glyf'. On my side is quadrupling of rendering time in FreeType to deal with overlaps which is not something to ignore. To fully appreciate the problem we need to know the cost on other platforms too. Don't you agree? So we are stuck until we have hard numbers from macOS: difference between flagged and removed overlaps, specifically. Windows might have a different algorithm, slower but immune to overlaps. |
I believe the artefacts appear very visibly in print, possibly via any path that transforms the TTF into a PostScript font (one would have to check 100s of actual printers to be sure). The artefacts definitely appear in PDFs with embedded fonts, at least using macOS Preview or other Apple system renderers. To be clear, these are not like the edge effects that overlaps sometimes cause, but real winding errors with significant problems that non-specialists notice immediately. WOFF2 with null-transformed 'glyf' is somewhat larger than transformed 'glyf', so it’s reasonable to want to avoid it especially when generating fonts on the fly for web delivery. The 4:1 slowdown in FreeType is serious, thanks for that figure. I agree that decisions by font makers should be made with all possible knowledge of their effects in rendering performance. |
So funny story. We recently received a new bug about strange overshoot artifacts showing up in macOS. Turns out that it struggles with paths that have coincident edges: microsoft/cascadia-code#362 And it appears that setting "OVERLAP_SIMPLE" does not have any impact on this rendering as far as I can tell. Fun! Anyway, I've submitted a bug report through Apple's feedback tool and we'll see what happens. |
I wrote a script to set overlap bits here: google/fonts#4405 (comment) Performance measurements on two Noto fonts:
The CJK is an extreme case in two respects, glyph and overlap count:
Edit: if you comment out the
|
It would be interesting to write a little program that rasterizes every glyph with FreeType, so we can measure the difference of marking all glyphs indiscriminately vs ones that actually overlap. |
Re: impact on compile time Those times are probably a small fraction of the overall compile times for the two projects in your environment? FWIW, it seems a shame to do full glyph set overlap detection computation at compile time when there are frequently large numbers of stable glyph definitions between compiles. Would be nice to serialize the data into sources. |
Yes, this is nothing.
I suppose this would be one way of doing it, but you'd always need to make sure the list is up to date 🤔 |
I think the easiest thing for now is that we add support for setting those glyf flags if the UFO glyph.lib contains the key "public.truetype.overlap" defined in https://unifiedfontobject.org/versions/ufo3/glyphs/glif/#publictruetypeoverlap This way the font developer can set them (manually or through some script) directly on the sources. Maybe later on we can also add a pre-processor filter that checks for overlaps and adds the lib key if not set and the glyph requires one. |
this is implemented now so I will close this |
I'm not sure if I missed a setting, but it appears that ufo2ft.compileVariableTTF doesn't implement the OVERLAP_SIMPLE / OVERLAP_COMPOUND flag that FreeType relies on to render overlapping paths correctly.
More information on the issue here: microsoft/cascadia-code#350
For Cascadia Code, I adapted this code in my build script to resolve this issue:
Is this functionality available in ufo2ft? Else, where would be the best place to implement something like this?
The text was updated successfully, but these errors were encountered: