Add auto font install support#246
Draft
jonmmease wants to merge 12 commits intojonmmease/fontsource-installfrom
Draft
Add auto font install support#246jonmmease wants to merge 12 commits intojonmmease/fontsource-installfrom
jonmmease wants to merge 12 commits intojonmmease/fontsource-installfrom
Conversation
Add a new crate for downloading and caching font files from the Fontsource catalog (which includes Google Fonts and other open-source fonts). Features include: - HTTP-based font file download with Fontsource API integration - LRU-evicting disk cache with configurable size limit - File-level locking for safe concurrent access - Font metadata caching and validation
- Add fontsource dependency to vl-convert-rs - Add FONTSOURCE_CACHE global, font registration, install_font(), and configure_font_cache() functions in text module - Re-export install_font and configure_font_cache from crate root - Add AutoInstallFonts enum and auto_install_fonts config field to VlConverterConfig (dormant until auto-download is implemented)
Python bindings: - Add install_font() and install_font_asyncio() functions - Add auto_install_fonts and font_cache_size_mb to configure_converter() - Add AutoInstallFonts type and ConverterConfig updates to .pyi stubs CLI: - Add --install-font flag for explicit font installation - Add --auto-install-fonts flag (strict/best-effort modes) - Pass auto_install_fonts config through build_converter to all commands
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
617b385 to
ed148bb
Compare
The AutoInstallFonts enum, --auto-install-fonts CLI flag, and auto_install_fonts Python parameter are moved to PR2 where the actual auto-download logic lives. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ed148bb to
29c9209
Compare
Remove font-subset from Cargo.lock (PR3-only dependency) and fix rustfmt formatting in Python bindings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add extract module for parsing font-family strings from Vega specs and resolving them against system fonts and the Fontsource catalog: - CSS font-family string parser handling quoted/unquoted names - Vega spec traversal extracting fonts from axes, titles, marks, legends, transforms, and config - First-font resolution classifying fonts as available, downloadable, generic, or unavailable - FontForHtml type for tracking font source (Google vs other)
Add AutoInstallFonts enum and configuration to converter, CLI, Python bindings, and type stubs. Moved from PR1 where it was a no-op. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
29c9209 to
d437728
Compare
- Make extract::is_available pub, remove duplicated is_available_in_fontdb - Strict mode now returns hard errors on download failures and API errors - Network errors distinguished from "not in catalog" in error messages - Replace unreachable!() for Off with return Ok(vec![]) - Change maybe_compile_vl_with_auto_fonts to return Option instead of nested Result - Add auto-font hooks to all 4 scenegraph methods (vega/vegalite × json/msgpack) - Add missing config keys: config.font, config.mark.font, header variants, axisDiscrete/Point/Quantitative/Temporal - Fix axis/legend/title encode traversal to iterate all states (not just update) - Case-insensitive generic family matching (Sans-Serif → Generic) - Python type stubs use Literal["off", "strict", "best-effort"] - Add comments: allow_http_access independence, FontForHtml scaffolding, doc separator - Add 9 new tests for config keys, encode states, and case-insensitive generics Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
903179c to
116d812
Compare
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.
Summary
Add automatic font preprocessing during rendering. When enabled,
vl-convertparses the compiled Vega spec to find referenced fonts, checks them against the local fontdb, and can download missing fonts from Fontsource before rendering.This is the second of three PRs in the font management stack:
vl-convert-fontsourcecrate and explicitinstall_font()APIMotivation
Even with explicit
install_font(), users still have to manually identify referenced fonts and preinstall them. That is error-prone and especially painful for themes/config-driven fonts.This PR separates two independent concerns:
auto_install_fonts(bool) controls whether missing fonts may be downloaded from Fontsourcemissing_fontscontrols what happens when referenced fonts are unavailable (fallback,warn,error)Behavior Matrix
auto_install_fontsmissing_fontsfalsefallbackfalsewarnfalseerrortruefallbacktruewarntrueerrorGeneric CSS families (
serif,sans-serif, etc.) are treated as generic fallbacks and are never flagged as missing.Changes
New module:
vl-convert-rs/src/extract.rsfont-familyparser (named vs generic entries)resolve_first_fontsclassification (Available,NeedsDownload,Generic,Unavailable) using first-font semanticsCore library:
vl-convert-rs/src/converter.rsauto_install_fonts: boolmissing_fonts: MissingFontsPolicy(Fallback,Warn,Error)preprocess_fontspipeline that handles:missing_fontsauto_install_fonts=false,missing_fonts=error) with no Fontsource API accessmaybe_compile_vl_with_preprocessed_fontsmaybe_preprocess_vega_fontsVec<FontForHtml>as scaffolding for PR Add font embedding to HTML export and vegalite_fonts/vega_fonts API #247CLI:
vl-convert/src/main.rs--auto-install-fonts(bool flag)--missing-fonts <fallback|warn|error>Python bindings:
vl-convert-python/src/lib.rs+vl_convert.pyiconfigure_converter(auto_install_fonts: bool | None = None, missing_fonts: Literal["fallback", "warn", "error"] | None = None)get_converter_config()now reports:auto_install_fonts: boolmissing_fonts: "fallback" | "warn" | "error"Commits
0809967feat: add font extraction and resolution modulee24910efeat: add auto font download to converterd437728feat: add auto_install_fonts plumbing to PR212d80fefix: address 13 code review recommendations for auto-fontsdc280efrefactor: split behavior intoauto_install_fonts+missing_fontspolicyReview Tour
Tier 1 — Start here:
vl-convert-rs/src/extract.rs— font-family parsing, Vega traversal, and first-font resolution logicTier 2 — Integration behavior:
vl-convert-rs/src/converter.rs—MissingFontsPolicy,preprocess_fonts, and conversion-path hooksTier 3 — User-facing APIs:
vl-convert/src/main.rs— CLI options + converter wiringvl-convert-python/src/lib.rs— Python config parsing/serializationvl-convert-python/vl_convert.pyi— updated typing surfaceTesting
Locally run:
cargo check -p vl-convert-rs -p vl-convert-python -p vl-convert(Full test suites are expected to run in CI.)