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

[varLib.mutator] Overlapping contours on old versions of Safari #1281

Closed
m4rc1e opened this issue Jun 26, 2018 · 28 comments
Closed

[varLib.mutator] Overlapping contours on old versions of Safari #1281

m4rc1e opened this issue Jun 26, 2018 · 28 comments

Comments

@m4rc1e
Copy link
Contributor

m4rc1e commented Jun 26, 2018

Google Fonts has just released their first VF font, MarkaziText. VarLib's mutator has been used to serve static instances to browsers which do not support variable fonts. Unfortunately, users who still use older versions of Safari are reporting the classic OS X winding problem.

@garretrieger says that half of all users of Safari are using an outdated version. We could potentially solve this issue by removing overlaps on the mutated instances.

@behdad
Copy link
Member

behdad commented Jun 26, 2018

See #730

@behdad
Copy link
Member

behdad commented Jun 26, 2018

cc @Lorp

@Lorp
Copy link

Lorp commented Jun 26, 2018

Note that this overlap issue still affects current Safari Version 11.1.1 (13605.2.8). In fact the bug is deep inside macOS. I believe these fonts are problematic in all apps that use the system renderer.

Thanks for the pointer to the "bit 6 hack", @behdad. Please remember that this causes the font to be rejected by OT sanitizer code built into Chrome and Firefox.

Another hack that works is to add a dummy fvar table in the font (e.g. a single custom axis with min, max & default = 0) and no gvar table. I have not seen any side-effects.

Great that Google Fonts has released a VF font :)

cc @twardoch

@behdad
Copy link
Member

behdad commented Jun 26, 2018

Thanks for the pointer to the "bit 6 hack", @behdad. Please remember that this causes the font to be rejected by OT sanitizer code built into Chrome and Firefox.

Ugh... @khaledhosny can you fix OTS please?

Another hack that works is to add a dummy fvar table in the font (e.g. a single custom axis with min, max & default = 0) and no gvar table. I have not seen any side-effects.

Umm. That's ugly but maybe not a big deal. I wonder what tools will consider the font a varfont by just seeing fvar.

Great that Google Fonts has released a VF font :)

@garretrieger
Copy link
Contributor

Looks like this is was already recently fixed in OTS. Font with the bit flipped works on the latest Chrome/FF. However fails on FF 59 and below and Chrome 63 and below.

@khaledhosny
Copy link
Collaborator

khaledhosny commented Jun 26, 2018

Ugh... @khaledhosny can you fix OTS please?

I already did, last year khaledhosny/ots@353c7f8.

@anthrotype
Copy link
Member

anthrotype commented Aug 9, 2018

We could potentially solve this issue by removing overlaps on the mutated instances.

our fonttools/skia-pathops can be used to remove overlaps of the mutated instances. It works on quadratic curves as well, and supports the fonttools pen protocol.
We could add an option to fonttools mutator to use that (provided pathops is installed).

@jenskutilek
Copy link
Collaborator

our fonttools/skia-pathops can be used to remove overlaps of the mutated instances. It works on quadratic curves as well, and supports the fonttools pen protocol.
We could add an option to fonttools mutator to use that (provided pathops is installed).

Removing overlaps might get ugly if the font has TT instructions ...

@anthrotype
Copy link
Member

should we add an options to fontTools.varLib.mutator to set that flag?

@anthrotype
Copy link
Member

I meant the OVERLAP_SIMPLE flag for glyf contour points that @jenskutilek added with #1316

@chrissimpkins
Copy link
Member

#1518 adds support for setting Bit 6 (OVERLAP_SIMPLE) of the first flag byte of all glyphs with contour definitions to 1 with varLib.mutator.instanatiateVariableFont.

@Lorp
Copy link

Lorp commented Feb 24, 2019

I was going to advise Microsoft to update the glyf table spec, explicitly allowing bit 6, but I’m pleased to see that it’s official already :) Thx @PeterCon @robmck-ms
screenshot 2019-02-24 at 15 01 13

@khaledhosny
Copy link
Collaborator

I believe this is fixed now.

@Lorp
Copy link

Lorp commented Jun 10, 2019

Note that woff2_compress currently sets OVERLAP_SIMPLE to zero. This is undesirable! See woff2 issue #20.

@anthrotype anthrotype reopened this Jun 10, 2019
@anthrotype
Copy link
Member

Yeah, also the fontTools WOFF2 encoder in fontTools.ttLib.woff2 doesn't keep these OVERLAP glyf flags.
However, I believe this is a limitation of the current WOFF2 specification that only encodes the oncurve-ness of a glyph point and throws away any extra flags.
See "5.2. Decoding of variable-length X and Y coordinates" chapter in https://www.w3.org/TR/WOFF2/#triplet_decoding

I guess we could have an option that sets those flags on all glyphs when compressing WOFF2 fonts.

@anthrotype
Copy link
Member

I guess we could have an option that sets those flags on all glyphs when compressing WOFF2 fonts.

but we can't, because the format doesn't allow it. The only workaround if one wants to preserve those flags is to not transform the glyf table when compressing the font with WOFF2.

@anthrotype
Copy link
Member

another way to fix this is have the fonttools instancer run skia-pathops to remove the overlaps so that the OVERALP flags are no longer necessary.

@anthrotype
Copy link
Member

... however, as @jenskutilek already noted above, removing the overlaps will also invalidate any TrueType hinting that may be present in the instance font.

@robmck-ms
Copy link
Contributor

We TT Hint all of our fonts, and really enjoy that those hints still work when a VF is instanced, so it'd be great to keep the hints somehow.

@Lorp
Copy link

Lorp commented Jun 10, 2019

I’m reverting to my earlier solution of an empty fvar table to trick Apple to switch renderer :)

@anthrotype
Copy link
Member

an empty fvar table to trick Apple to switch renderer

ha! that's a good trick :)
Probably better than having the glyf table un-transformed in woff2 (with the penalty of bigger file size). An empty fvar is only a few bytes.

@chrissimpkins
Copy link
Member

chrissimpkins commented Jun 11, 2019

Btw, this issue was broader than old Safari versions as the title of this thread suggests when we looked at it in #1518 with static *.ttf fonts that were instantiated from VF's. It also affected (at least) Chrome on macOS at that time. I don't recall whether we looked into other browsers. I didn't document others in the PR, so I am guessing not.

@Lorp
Copy link

Lorp commented Jun 11, 2019

@chrissimpkins, yes indeed, I should not have specified Safari. It is in fact all native rendering on macOS, so you see the problem in TextEdit and even in Finder font quick view if your A exhibits the problem.

Unfortunately Apple has blocked my fvar trick! Safari is rejecting fonts with a present but empty fvar table :( This seems to be new (because I tried the trick successfully many months ago), so I guess a recent Safari update can be blamed. I hope other browser vendors do not follow Apple!

There may be other non-empty fvar hacks that pass Apple validation. I’ll post updates here.

@robmck-ms
Copy link
Contributor

I worry a bit about the empty fvar trick because that might cause other effects which may be unintuitive or not obvious. e.g. would Windows Chrome switch to render those fonts with freetype (possibly invoking ttfautohint, which I've found produces poor results on fonts with overlaps).

@Lorp
Copy link

Lorp commented Jun 13, 2019

I can confirm that the following tiny fvar table (36 bytes uncompressed) survives WOFF2 compression AND passes Safari validation on macOS 10.14, thus successfully nudging macOS to handle overlaps correctly in WOFF2’d non-variable TrueTypes:

  <fvar>

    <Axis>
      <AxisTag>wwww</AxisTag>
      <Flags>0x0</Flags>
      <MinValue>0.0</MinValue>
      <DefaultValue>0.0</DefaultValue>
      <MaxValue>0.0</MaxValue>
      <AxisNameID>0</AxisNameID>
    </Axis>

  </fvar>

Using axis tag wwww (= 0x77777777) to optimize compression :) The AxisNameID of 0 is perhaps risky, so keeping to spec and using 256 along with a name table update would be sensible.

Good point, Rob, about a specific downside to this platform-specific hack. In our environment we control how to serve the fonts, so we can deliver unmodified static TTF/WOFF2s for Windows Chrome and minimal-fvar versions for Mac.

@behdad
Copy link
Member

behdad commented Jun 13, 2019

NameID 0xFFFF please.

@anthrotype
Copy link
Member

As of #1639, you can now compress (and decompress) WOFF2 without glyf transformation. Up to you to decide whether to use the trick suggested by @Lorp above (adding a dummy fvar table) or just compress as un-transformed WOFF2.
I think we can close this now.

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

No branches or pull requests

10 participants