Add support for variable fonts#997
Conversation
- Parse font-variation-settings CSS property - Auto-map font-weight/stretch/style to variation axes - Apply variations during text shaping via rustybuzz - Add FontVariationSettings to presentation attributes for CSS cascade 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
The ``typos'' seem to be outside my PR |
Just for info, there is already a |
|
Looks good, but we need some tests. Which also means we have to find and add a free variable font here.
Not sure about "auto-mapping". Afaik a font can have a variation axis with any range. Meanwhile your code sets |
|
Thanks for the review! I've added tests using https://fonts.google.com/specimen/Roboto+Flex, a variable font with 13 axes (OFL 1.1 licensed). Tests added (14 total):
Regarding the wdth auto-mapping (50-200%): The hardcoded percentages are the CSS standard values per https://drafts.csswg.org/css-fonts-4/#font-stretch-prop. When applied to fonts with different axis ranges (Roboto Flex's wdth is 25-151), the font engine clamps to the supported range. This matches browser behavior. For example, font-stretch: ultra-expanded (200%) on Roboto Flex gets clamped to 151 by rustybuzz/ttf-parser. This is expected - it means "as expanded as this font supports." Moving parse_font_variation_settings to svgtypes: Happy to do this in a follow-up if you'd like, though as you noted it's not critical. |
Added 14 tests for font-variation-settings using a subsetted Roboto Flex variable font (OFL 1.1 licensed). The font preserves all 13 variation axes including wght, wdth, slnt, opsz, GRAD, and parametric axes. Tests cover: - Explicit font-variation-settings (wght, wdth, slnt, opsz, GRAD, XTRA) - Multiple axes combined - Auto-mapping from font-weight/stretch/style to variation axes - Priority behavior (explicit settings override auto-mapping) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ec6c295 to
3d47ff4
Compare
|
I compared the output with the browser output for specific axis values ... and it does not match ... investigating ... |
|
Tests look good. Thanks! And I guess we could iron-out auto-mapping later, if someone would fine any issues. Matching at least the Chrome output is preferable. |
|
the output difference is as of yet unresolved, I have rendering the test svgs with chrome and firefox result in narrow output while rendering them to png with rust or c harfbuzz implementations give the much less narrow output. while the paremeter definitly has an influence, it just seems to be much less pronounced than with the browsers ... |
- Add `font-optical-sizing` CSS property support (auto/none) - When `font-optical-sizing: auto` (default), automatically set the `opsz` axis to match font size for variable fonts that support it - Fix variable font outline extraction to properly apply variations - Regenerate names.rs using codegen after adding FontOpticalSizing attribute - Update test reference images with correct variable font rendering The key fix ensures that font variations (wdth, wght, opsz, etc.) are applied consistently during both text shaping and glyph outline extraction, so both letter positioning AND letter shapes reflect the variation settings. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
found and fixed ... font-optical-sizing support was missing ... this is set to see here for demo 49771e2#diff-644028718b75197f20d9637b7b96a77a7ee893aa8505860075af643503d053e4 |
|
@LaurenzV looks good to me. |
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Thanks, sorry for the delay, I'll try to take a second look very soon. |
Move `variations`, `font_optical_sizing`, and `hinting` fields from `PositionedGlyph` to `Span` struct since these values are uniform for all glyphs within a span. Benefits: - Reduces memory by not duplicating Vec<FontVariation> per glyph - Cleaner data model: span-level properties at span level - Minor perf improvement: needs_variations check once per span Based on PR linebender#997 review feedback. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move variations and font_optical_sizing from PositionedGlyph to Span (these are uniform per span, reducing memory and simplifying the API) - Add cached has_opsz_axis check to only bypass outline cache when needed (fixes issue where cache was rarely used due to auto opsz default) - Use rb_font.tables().fvar instead of re-parsing font with ttf_parser - Remove unnecessary log::debug! messages - Remove empty --drop-tables flag from README Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Thanks! |
|
@oetiker I'm going to try to make a release soon. Any hints as to if this is a breaking change or not? I'm checking if we should do a major or minor release. |
|
@wmedrano the variable font support changes the way variable fonts are handled. Before this, if you used a variable font, there was no way to controll it, but it did render somehow ... so if you relied on that behavior, then you will be in trouble ... all other fonts are not affected. |
|
if you are talking about #1009 then the visual differences to be expected are displayed in the PR ... if it has any other side effects, I do not know, but it does successfully run the testsuite. |
|
Ack. It is not an API breaking change, just a visual change. Seems like we should do a major version release anyways because tiny-skia is re-exported as part of resvg API and tiny-skia had a major version bump. |
Uh oh!
There was an error while loading. Please reload this page.