Skip to content

fix(deps): fontkit comes from npm again, and a variable face in a WOFF or a WOFF2 is read as the sfnt inside it - #485

Merged
sidorares merged 1 commit into
masterfrom
fix/fontkit-from-npm
Sep 30, 2026
Merged

sidorares merged 1 commit into
masterfrom
fix/fontkit-from-npm

Conversation

@sidorares

Copy link
Copy Markdown
Owner

8.17.2 never reached npm, and nothing merged since 8.17.1 is published. #479 named fontkit by the URL of a fork's release tarball, and npm 12 fetches no URL or git dependency unless told to: allow-remote and allow-git default to none. The publish job upgrades npm and failed in npm ci with EALLOWREMOTE. The test jobs install with the npm their Node ships, so CI was green. An application on npm 12 could not have installed that version either, which I reproduced with npm 12.1.0 against a packed master.

That was my recommendation in #479 and it was wrong: I tried the tarball with npm 11 and Bun, not with the npm the publish job uses.

What this does

fontkit is ^2.0.4 from npm again, and the lockfile is 8.17.1's for it.

What the fork was for is done here instead. fontkit cuts an instance of a variable font by reading the file again as a plain sfnt, which a WOFF or a WOFF2 is not. So a variable face that arrives in a container is handed to fontkit as the sfnt inside it, built by the new lib/text/sfnt.js: a WOFF's tables as fontkit inflates them, a WOFF2's as it decompresses them, with glyf and loca written back from the transformed streams. It is done once, when the face is opened, 10 ms for Geist's 70 KB WOFF2. A static face stays in its container, and a container that cannot be taken apart stays too and refuses at variation, as before #479.

CI has a publishable job that does what the publish job does up to the upload, with the newest npm, and then installs the packed tarball into an empty project.

The loca guard from #479 stays: it is about static WOFF2 faces and does not depend on which fontkit is installed.

Verification

  • The tests fix(text): a variable font is instantiated out of a WOFF or a WOFF2, where the first weight off the file's default threw #479 added pass unchanged but for one assertion, against fontkit 2.0.4: every glyph of an instance out of the .woff and the .woff2 fixture equals the sfnt's, at three weights.
  • test/sfnt.test.js: the sfnt made of a WOFF is the original, table for table. The one made of a WOFF2 has every table but glyf, loca and head byte for byte, and every glyph reads the same. The two faces used have composite, hinted and empty glyphs between them, and a test says so.
  • Outside the suite, 16 containers were rebuilt and compared with fontTools' own reading of the same file, glyph by glyph: coordinates, on-curve flags, contour ends, instructions, component records, boxes, the overlap flag, and every other table's bytes. Geist with 975 glyphs, Mada with 292 composites of 529, Source Sans Pro with 1974 hinted glyphs, CFF and CFF2 flavours, and a WOFF2 with an untransformed glyf.
  • Through react-x11-components' <Html> with this lib/ and fontkit 2.0.4: all 728 characters of Geist's variable WOFF2 at eight weights, each matched to an instance of the rebuilt face.
  • With npm 12.1.0: npm ci, npm publish --dry-run, and an install of the packed tarball into an empty project all pass.

npm test: 1449 pass, 10 skipped, none fail.

After this

8.17.2 cannot be published from its tag, whose commit has the URL. Merging this and then the release PR, #484, publishes 8.17.3 with everything since 8.17.1.

@sidorares
sidorares merged commit b5d5320 into master Sep 30, 2026
7 checks passed
@sidorares
sidorares deleted the fix/fontkit-from-npm branch September 30, 2026 21:41
sidorares pushed a commit that referenced this pull request Sep 30, 2026
🤖 I have created a release *beep* *boop*
---


## [8.17.3](v8.17.2...v8.17.3)
(2026-09-30)


### Bug Fixes

* **deps:** fontkit comes from npm again, and a variable face in a WOFF
or a WOFF2 is read as the sfnt inside it
([#485](#485))
([b5d5320](b5d5320))
* **svg:** an element that is display: none is not drawn, nor anything
in it ([#483](#483))
([3ece30b](3ece30b))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

1 participant