feat(pdf): extend Unicode fallback to a font chain with Symbola (#75) - #76
Merged
Conversation
The single DejaVu Sans fallback (#52) covered text plus common arrows/dingbats but not SMP symbol blocks, so e.g. U+1F6C7 still rendered as '?' even after #72 fixed the surrogate-pair handling — diverging from the Avalonia preview (which uses system fallback). The fallback is now an ordered chain: primary embedded -> DejaVu Sans -> Symbola. FontForCodePoint already consulted FallbackCandidates in order, so this adds Symbola (public domain, George Douros v8.00) as the second resource. Each codepoint routes to the first font in the chain with a glyph, so symbols DejaVu lacks but Symbola covers (U+1F6C7, U+1F6AB, U+26D4, U+29B8, …) now render instead of '?'. DejaVu stays the general/text fallback; Symbola is consulted only for glyphs DejaVu lacks and, like DejaVu, is subset + embedded only when used, so documents without such symbols are unchanged. A genuinely uncovered codepoint still collapses to a single missing-glyph indicator (#72). NOTICES.md gains the Symbola attribution (and the previously-missing DejaVu entry in the PDF section). Adds PdfFallbackChainTests (SMP symbols via Symbola, chain ordering, on-demand embedding) and repoints the #72 non-BMP test to a codepoint no bundled font covers. Also makes the cross-target PDF consistency check compare object counts rather than byte length: embedded fonts are Flate-compressed and Deflate output differs between .NET runtimes, so total size is not comparable (the unicode fixture now embeds Symbola).
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 #75.
Problem
The PDF renderer embedded DejaVu Sans as its single Unicode fallback (#52) — the right primary choice (general text + common arrows/dingbats). But DejaVu doesn't cover the SMP symbol blocks, so e.g.
🛇(U+1F6C7 🛇) still rendered as a single?even after #72 fixed surrogate-pair handling. The Avalonia preview shows these via system fallback, so preview and PDF disagreed.Fix
The fallback is now an ordered chain:
primary embedded → DejaVu Sans → Symbola.FontForCodePointalready consulted the fallback candidates in order, so this adds Symbola (public domain, George Douros v8.00) as the second resource. Each codepoint routes to the first font in the chain that has a glyph:?, matching the preview.??.Why DejaVu-first (not "Symbola for everything")
Per the issue's explicit ask, this is additive — DejaVu remains primary. Routing common symbols through Symbola would change glyph metrics (→ wrapping/layout) across many existing documents, pull the larger Symbola subset into common docs, and use a less text-fitted glyph design — for a consistency gain that only applies when a single document mixes a DejaVu-only and a Symbola-only symbol.
Attribution
NOTICES.mdgains the Symbola entry (public domain) and the previously-missing DejaVu entry in the PDF section. License/provenance verified from the font's name table ("Unicode Fonts for Ancient Scripts; George Douros; 2015 … Symbola is not a merchandise").Size
Symbola.ttfadds 2.19 MB to the repo /AdocNet.Converters.Pdfpackage (accepted for full coverage). Output PDFs include only the subset actually used.Tests
PdfFallbackChainTests(new): SMP symbols render via Symbola (no?); the chain consults DejaVu before Symbola (both embedded when both are needed); Symbola is absent when no glyph needs it.MultiTargetConsistencyTests+ConsistencyHarness) now compares PDF object counts rather than byte length — embedded fonts are Flate-compressed and Deflate output differs between .NET runtimes (theunicodefixture now embeds Symbola), so total size isn't comparable; object count is a deterministic structural check.Full Release suite green (0 failures; +3 tests). Related: #52 (DejaVu fallback), #72 (codepoint-aware fallback).