Repository navigation
slides: an embedded font is declared with the weights it has (#850) - #851
Merged
Merged
Conversation
Build size
Updated: |
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.
Fixes #850.
"+ Embed font file…" declared every embedded face
font-weight: normal. A variable font covering 100–900 then matched only weight 400, so Bold drew the 400 instance thickened by the browser (faux bold) instead of the font's own bold. A static bold file got faux bold on top of its bold.What it does
When a font is embedded,
embedFontnow writes the weight and style the file states intodoc.fonts(newslides/src/fontmeta.ts):fvarwght range, e.g.100 900. A font with no wght axis gets its OS/2usWeightClass. The OS/2 italic bit givesstyle: italic.DecompressionStream('deflate').WOFF2: measured by rendering
All of a WOFF2's tables sit in one brotli stream, and no browser accepts brotli in
DecompressionStream(Chrome 149 and 156 both refuse it). Only the table directory is readable, and it says whetherfvaris present.For a variable WOFF2, the range is measured instead:
1 1000descriptor and drawn on a canvas at weights 1, 100, 200 … 1000;An axis end that falls between two hundreds reads as the outer one. The range can come out wider than the font, never narrower. Wider costs nothing, since the font clamps; narrower would bring faux bold back. The shell's own Instrument Sans measures
400 700, which matches itsfvar.Known gap
A static WOFF2's weight lives inside the brotli stream, so it can't be read. It stays unstated, as before.
Evidence
Test fonts: our own design, MIT, 4 KB in total, in
scripts/fixtures/fonts/with the generator that rebuilds them. A single bar glyph whose stem and advance grow with wght, so a rendered weight can be measured. Variable TTF/WOFF/WOFF2 with a wght axis of 100–900, plus a static TTF/WOFF2 with weight 700 and the italic bit set.test-slides-font-weight.ts(validate-slides): 12/12.{}, never a throw.fvarcompressed, so the inflate path runs.test-slides-font-weight-browser.mjs(ci-slides): 10/10 on bundled Chromium 149 and on Chrome 156.doc.fonts.100 900: weight 700 is 1.55x the width of 400, which is the font's own bold.normal: weight 700 is 1.00x the width of 400 (faux bold).On main's
embedFont: 5/10. Every embed row is red, with no weight written.Mutants, each confirmed applied and each build exited 0:
fvarreader offThe existing font rigs still pass:
test-slides-fonts25/25, and font-lifecycle.Shell: +1.7 KB compressed.
Decks that embedded a font before this change keep their entry. Re-embedding the font writes the weights.