back

by raphlinus·3y ago·view on hn ↗
I'll give some context. Shaping is converting a string of unicode code points into a sequence of glyphs, each with an advance and also finer positioning. For typical Latin fonts, shaping is straightforward; each code point generally corresponds to one glyph, but sometimes there are ligatures ("fi" is often one glyph), and then there is kerning, usually placing pairs of glyphs such as AV closer together if there would be a gap between them. But for complex fonts such as Nastaliq (used in writing Urdu), the rules get a lot more complicated.

OpenType shaping is currently defined in terms of a whole bunch of rewrite rules, with some script-specific knowledge (such as reordering vowels in Indic) added in by the shaping engine. The original idea is that it would be declarative and fairly easy for font designers to work with, but in practice it's pretty clunky, and doesn't scale well as complexity goes up. It's also slow to evaluate on modern computers because sequence matching is very branchy, and it's not unusual to require dozens of passes.

A particularly striking example is hieroglyphics. These compose multiple elements together into a block, with rules not unlike CSS grid. Sometimes there's vertical stacking, sometimes horizontal, occasionally more complex interactions like nestling inside an L. It is possible to encode this into OpenType rules, but it's very much a hack - at heart you need to do fairly simple geometry calculations to add up the total widths and divide them proportionally, but think about writing that as a regex and you'll get some idea how it comes out.

This proposal replaces the OpenType shaping rules with a call into WASM, where you can do these sorts of calculations straightforwardly and in a single pass. It is another Turing complete language (as is OpenType shaping, as proved by Behdad a few years ago, and TrueType hints), but there are excellent off-the-shelf implementations and it's well known how to run it securely sandboxed.

Even for Latin, this kind of thing would be useful for making a font that looks like real handwriting, for example. You can fake that in OpenType to a certain extent, but it goes beyond what the format was designed to handle.

This is a first cut, as it only affects positioning of premade glyphs. One thing I'd like to see going forward is adjusting variation parameters. As an example, a typical Devanagari (Hindi) font has 6 or so different widths of "ि" depending on the width of the consonant cluster it composes with (so रि or ल्कि). With variation connected to shaping, you could have one glyph of variable width, and the shaping engine could just set the variation to the right value, and with greater precision to boot.

If I were designing a new font format from scratch, this is definitely the way I'd do it. I'm excited to see where it goes.

1 comments
> “The original idea is that it would be declarative and fairly easy for font designers to work with, but in practice it's pretty clunky, and doesn't scale well as complexity goes up.”

A sentence that also applies to CSS. Declarative systems for design tend to fail.

I dream of the day when baroque CSS layout rules can also be replaced with tiny WASM programs for computing the exact layout your application needs.