Skip to content

Conversation

LaurenzV
Copy link
Collaborator

@LaurenzV LaurenzV commented Aug 16, 2025

This PR is still in-progress and aims to add some initial support for variable fonts. Initial because the aim is not to give the user full control over setting custom variation coordinates (this could be good future work, but probably makes more sense to implement in conjunction with the planned font object). The aim is to automatically select a correct instance based on the wght (font weight), wdth (font stretch), and ital/slnt (italic) axes, which I think should over 95%+ of the use cases.

It also adds support for embedding CFF2 fonts in PDFs by converting them to a TTF font, which is not the best approach (better would be to convert to CFF), but it should do the job. CFF2 fonts are pretty rare (less than 1% of variable fonts), but based on past issues it seems like some systems do use some CFF2-based Noto fonts, so this is definitely worth fixing.

Fixes #185 (tracking support for specifying variable font axes is probably worth opening a new issue for).

Example:

#for (font, d_text) in (
    ("Cantarell", "I love using variable fonts!"),
    ("Noto Sans CJK SC", "我太喜欢使用可变字体了!"),
    ("Roboto", "I love using variable fonts!"),
) {
    [= #font]
    for i in range(100, 900, step: 100) {
        text(weight: i, font: font)[#d_text \ ]
    }
}

Result:
test.pdf

TODOs:

  • Properly hook up the wdth and slant/italic axes.
  • Bulk test with maany fonts to ensure it works as expected.
  • Fix or find a workaround for the pixglyph bug that makes CFF2 fonts render as black rectangles in PNG export.
  • Investigate whether the code leads to regressions in SVG rendering, where variable fonts are currently not supported.
  • Add test cases
  • Clean up code + documentation

@khaledhosny
Copy link

The aim is to automatically select a correct instance based on the wght (font weight), wdth (font stretch), and ital/slnt (italic) axes, which I think should over 95%+ of the use cases.

Maybe add opsz to the mix.

@LaurenzV
Copy link
Collaborator Author

I might be wrong, but I was assuming that opsz, similar to hinting, is to improve the rendering at certain font sizes. Does it really make sense to use that when exporting to PDF?

@khaledhosny
Copy link

I might be wrong, but I was assuming that opsz, similar to hinting, is to improve the rendering at certain font sizes. Does it really make sense to use that when exporting to PDF?

Optical Size is a totally different concept. Hinting is about pixels, but optical size is about adapting the design for the intended font size. The most widely used typeface with optical sizes is probably Computer Modern (no opsz axis of course). A font designed for 5pt will have less contrast and wider spacing, while a font designed for, say, 120pt will have much more contrast and more compact spacing.

@LaurenzV
Copy link
Collaborator Author

I see, thanks!

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

Successfully merging this pull request may close these issues.

Support variable fonts
2 participants