Repository navigation
fix(paint): draw a variable font at the CSS font-weight - #405
Merged
Merged
Conversation
A face of a font with an OpenType wght axis is now instanced at the requested weight (clamped to the axis range) through opentype.Face.SetVariation, which applies gvar outlines and HVAR/MVAR metrics, so measurement and painting agree. The default master keeps the unvaried path. The vector painter hands exporters the static instance (Font.Instance) so a PDF embeds the weight it drew. The bundled Inter and Lora regulars carry a wght axis too, so weights 100-599 now draw at their own weight instead of regular. render -file now uses the file's directory as base and file root, so a relative @font-face font beside it loads; an http(s) -base keeps local files out of reach. Bundles Outfit[wght].ttf (SIL OFL 1.1) as a test font. Closes #399 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Nov 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A variable font (OpenType
fvar/gvar) is drawn at the weight the page asks for instead of its default instance.Reference opened: the go-opentype/opentype source at the pinned version (
Face.SetVariation,Font.Axes,Font.Instance,advance.go/face.goapplyingHVAR/MVARdeltas). The variation machinery already exists in the lowest shared library, so no font code is added here. The OpenTypefvarspec text itself was not opened for this PR; the claims below rest on the library source and on the Chrome comparison.paint.Fonts.facefinds the style'swghtaxis (cached per style and per font), clamps the CSS weight to its range and callsSetVariationon the face, so glyph outlines and advances both follow the weight. The face cache is keyed by the clamped weight. The axis default keeps the unvaried path, so default-weight text costs the same as before.Fonts.glyphFont: the static instance (Font.Instance) for the weight, so the exported font is the one drawn, notRaleway-Thin.render -file: the CLI sent noFileRoot, so a relative orfile:@font-faceURL next to the file could never load (the second observation in the issue). It now uses the file's directory as the base and the file root. An explicithttp(s)-baseis left alone (a remote base must not reach local files).testdata/fonts/Outfit-wght.ttf(SIL OFL 1.1, licence file beside it), 110 KB,wght100..900.Behaviour change to note
The bundled Inter and Lora regulars carry a
wghtaxis themselves, sofont-weight100..599 now draws at that weight (Inter 300 is light, 500 is medium), as Chrome does, instead of always at regular. Bold (>= 600) still uses the bundled static bold.Evidence
engine.TestVariableFontWeights(ink grows with weight),paint.TestVariableFontWeightInstances/TestGlyphFontInstance,cmd/render.TestRunFileLoadsRelativeFont.@font-faceweight range): dark-pixel ink per paragraph, Chrome 991 / 2257 / 3262 / 3976, engine 610 / 1844 / 2814 / 3570, engine before the fix 1683 / 1720 / 1673 / 1729 (serif fallback, flat). Same monotonic progression, same glyph shapes by eye; the engine draws about 10-40 percent less ink (rasteriser coverage, not weight).Found, not fixed here
The CSS
fontshorthand is not parsed at all (font: 32px V, serifleaves the generic family and size), which also hides@font-facefamilies set that way. Filed as Refs #404 (stays open).Closes #399
Co-Authored-By: Claude Sonnet 5.5 noreply@anthropic.com
🤖 Generated with Claude Code