commontype-standard / commontype

Annotated OpenType Specification
Other
23 stars 1 forks source link

Cubic Beziers in glyf table #38

Open simoncozens opened 4 years ago

simoncozens commented 4 years ago

Easiest way to do this:

Things to think about:

behdad commented 4 years ago

Okay I opened https://github.com/OpenType/opentype-next/issues/7 Just closed that one and copying my comment here.

behdad commented 4 years ago

Suggesting that we move cubics-for-glyf discussion here.

I see two ways:

Use flag bit 7 to add cubics in, without bumping any version or major bump. glyf table has its version in head table's glyphDataFormat; not sure if any software checks that. That might be good if they don't check if we choose the semi-backward-compatible way (more about that below).

Given that glyf table was the common thread we inherited from TrueType and has not changed in 30ish years, changing it drastically constitutes a new font format, so we might as well address many other issues at the same time, in particular: 1. 16bit GIDs, and 2. add versatile component reuse (including variations), particularly without consuming GIDs necessarily.

NorbertLindenberg commented 4 years ago

Do the cubic curves have to live in the glyf table, or could they be in a new table, say cube? The second option would allow a gradual transition, where fonts provide both cube and glyf tables, implementations that know about cube would prefer it, but others would still have glyf as a fallback. Yes, related data in other tables, such as for hinting, needs to be considered too.

behdad commented 4 years ago

Just want to leave this about cu2qu algorithm here, because it is relevant. I'll comment on the relevance later. https://github.com/googlefonts/cu2qu/issues/10

simoncozens commented 4 years ago

The nice thing about (ab)using bit 7 in the glyf table is that you get the potential to use cubic and quadratic curves in the same glyph. This may however create more potential for confusion than it is worth...

Lorp commented 4 years ago

Here is the messy Twitter thread where some discussion took place on 2020-09-16. Twitter makes it very difficult to follow the whole discussion.

Lorp commented 4 years ago

Coincidentally that afternoon I published a build of Samsa that handles an experimental version of TrueType: Samsa Cubic. Versions of MutatorSans as quadratic (standards compliant) and cubic (non-compliant) are included for convenient comparison.

The experimental “ttf-cubic” format is identical to TrueType, except:

Design goals for ttf-cubic:

Follow these instructions if you want to make one:

  1. Obtain cubic UFO font sources with .designspace that already makes a working variable font
  2. Replace "curve" with "qcurve" in all .glif files — this fools fontmake that the font is quadratic, so no cu2qu
  3. Run fontmake -o variable -m your.designspace on the .designspace as normal
  4. Overwrite the first 4 bytes of the file with "CUBE" — this tells Samsa to treat the curves as cubic
  5. Make the extension "ttf-cubic"

Remember the only environment that supports ttf-cubic is Samsa!

Note that there is nothing specifically relating to variable fonts in ttf-cubic, although currently Samsa does not handle static fonts.

If anyone has other prototype font/table formats that they would like to try out in Samsa, please let me know.

Lorp commented 4 years ago

Using bit 7 on every cubic off-curve point is safe, I think. To retain the benefits of sequences of smooth curves in cubic and quadratic, to avoid recoding existing fonts, and interpreting usefully all combinations of off-curve, on curve and bit7, we can allow cubics to be optionally defined by one off-curve point defining both tangents like a quadratic, its two mathematical control points at the same position.

Some examples (the 0 and 1 below represent bit 7):

Bit 7 set for an on-curve point is an error, or ignored for this table version.

Too complicated? One option might be to keep to one curve order per contour, so just one flag needed, which could be stolen from the endPts array (limiting point ids to max 32767 instead of 65535).