A workaround for using problematic typefaces in Typst — fonttools subset --unicodes='*'

OpenType is a complex standard. Some type designers didn’t set proper metadata for their typefaces, which is problematic for Typst.

The problem

Resource Han Rounded SC is an example. Typst loads it without any error or warning, but can’t render it reliably.

#set page(height: auto, width: auto)
#set text(font: "Resource Han Rounded SC")
123
桑之未落,其叶沃若。
#lorem(5)

When exporting to PDF, it looks fine:

When exporting to PNG, all characters become tofus:

When exporting to SVG, it’s all white:

I’m not sure about the exact cause, but I guess it relates to the mapping between characters and glyphs.
To be compatible with various platforms, OpenType specifies multiple mapping formats. Resource Han Rounded SC may set the correct mappings for only some of these formats.

Workaround

The fontTools project provides an open source Python library and CLI tool for manipulating fonts. Its subcommand fonttools subset can generate subsets of fonts (the generated font covers only a subset of characters).

The important thing here is that fonttools subset rewrites the character-glyph mappings.
If we tell it to keep all characters (--unicodes="*"), then this command is equivalent to normalizing the mappings.

fonttools subset ResourceHanRoundedSC-Regular.ttf \
  --output-file=fixed.ttf --unicodes="*"

Now Typst can render fixed.ttf when exporting to PDF/PNG/SVG.

Note that the command above also performs size-reduction optimizations. If you don’t want that, see the full example in docs.

Additional info for reproduction

1 Like