latex3 / luaotfload

OpenType font loader for LuaTeX
Other
59 stars 7 forks source link

Support OpenType variable fonts #120

Open stone-zeng opened 4 years ago

stone-zeng commented 4 years ago

Since HarfBuzz has already supported OpenType variable fonts, is it possible to provide APIs for it in luaotfload?

See https://github.com/wspr/fontspec/issues/321.

zauguin commented 4 years ago

We probably won't add this anytime soon. While HarfBuzz provides shaping for variable fonts, there are two steps missing: The variation has to be applied to the glyphs an for CFF fonts the CFF2 tables have to become CFF tables.

In the following I will only talk about OTF/CFF fonts and not about OTF/TTF fonts because I know more about their structure. For CFF fonts at least, applying the variation data would need some work but isn't particularly hard. We could do that, but it is not part of the traditional scope of luaotfload because we normally we just pass fonts unmodified.

Anyway the harder part is the conversion from CFF2 to CFF. This are the actual tables containing glyph data and variable fonts always have to use CFF2 while PDF only supports CFF. The problem with converting between them is that CFF tables do not allow overlapping curves (and PDF viewers show inconsistent behaviour when overlapping curves occur) while CFF2 curves are filled according to the non-zero winding rule. So converting between them requires removing overlap of arbitrary cubic bezier curves. That's hard and I don't know an algorithm to do this reliably without user-input.

malipivo commented 3 years ago

Michal Hoftich sent me a software tip. https://fonttools.readthedocs.io/en/latest/varLib/instancer.html https://rsms.me/fonttools-docs/varLib/mutator.html I tried it in Linux, it generates a new TTF file: $ fonttools varLib.mutator ./DecovarAlpha-VF.ttf BLDA=500 TRMK=500 This open-source tool is written in Python, in theory, it could be used for caching variable fonts.

zauguin commented 3 years ago

While this probably ill not be added for the HarfBuzz based shaper anytime soon, the traditional node shaper does support variable fonts with the latest release!

callegar commented 3 years ago

There seems to be still an issue in picking the correct default values for the font axes:

for instance

\documentclass[a4paper,12pt]{article}
\usepackage{fontspec}
\setmainfont{Source Serif 4 Variable}
\begin{document}
The quick brown fox jumps over the lazy dog.
\end{document}

fails, unless you add a

\defaultfontfeatures{RawFeature={+axis={wght=100}}}

before the \setmainfont.

zauguin commented 3 years ago

@callegar What you are observing is that the variable font support is only activated if either axis or instance is present. Defaults can be obtained by using the default instance name or just setting a dummy axis, e.g. \setmainfont[RawFeature={axis={something=else}}]{Source Serif 4 Variable} would give the default. This is done to avoid the overhead of variable font support for other fonts.

But I pushed an experiment which should enable this automatically for variable fonts. We'll have to see if that breaks anything.

callegar commented 3 years ago

@zauguin thanks, this clarifies. Looking forward to seeing the attempt at the automatic enablement of variable font support.