Repository navigation
feat: embed font via @font-face with pyftsubset subsetting - #8
Conversation
Resolve the configured font family using fc-match, subset it to only the glyphs used in the SVG frames via pyftsubset (if available), and embed the result as a base64 @font-face rule. Falls back to embedding the full font file when pyftsubset is not installed.
|
Closing as superseded for portable font embedding by the merged exact-font implementation. Automatic |
|
Thank you, @xav-ie, for proposing automatic font discovery, glyph subsetting, graceful tool fallback, and safer font-family handling. I closed this PR too early: the manual font-file option does not provide the automatic setup or file-size benefits you proposed. I have reopened it. We are completing automatic selection before capture so the browser and SVG use the same face, optional subsetting with full-font fallback, title glyph coverage, and font-family escaping. Your contribution will remain in the replacement branch history. I will link the tested replacement and coverage evidence here before closing this PR again. |
|
Thank you, @xav-ie, for proposing automatic font discovery and subsetting. The audit showed that explicit font files alone did not deliver those benefits. We reopened this PR and completed the missing behavior in PR 15. The merged repair provides:
A real installed-font CLI capture produces a 9,601-byte SVG with two WOFF2 subsets. Glyphs and advances match the selected faces. A separate real evaluation reduces the base64 font payload from 231,000 to 5,000 bytes. The final source passes 336 native race cases, 106 tape checks, and all eight hosted build and lint checks. Vet, lint, build, tidy, formatting, and pre-PR review also pass. Native rendering evidence covers macOS and Chrome. Linux and Windows native rendering remains unverified. The replacement preserves your original commits. We used an owned branch because the contributor fork rejected the authenticated LFS lock check. Thank you for identifying the setup and file-size improvements. |
Summary
fc-match, subset it to only the glyphs used in the SVG frames viapyftsubset(if available), and embed the result as a base64@font-facerulepyftsubsetis not installedSet FontFamily— the default comma-separated fallback stack is skipped to avoid a CSS@font-facename mismatchfc-matchfor clear error messages\,",{},;,<>, newlines)format()hints for woff2, woff, opentype, and truetypeTest plan
TestSVGGenerator_FontFaceEmbed— @font-face present/absent based on FontDataTestSVGGenerator_FontFormatHint— correct format hint for all MIME typesTestSVGGenerator_FontFamilyEscaping— all special characters escaped correctlyTestResolveFont_EarlyReturns— skips empty, monospace, comma-separated, and default font familyTestResolveFont_WithFcMatch— resolves real fonts, handles nonexistent gracefullygo test ./...)