fix(pdf): codepoint-aware symbol fallback; footnote cells keep fallback (#72) - #74
Merged
Merged
Conversation
added 2 commits
June 20, 2026 12:38
…ck (#72) Two cases still emitted '?' despite the #52 Unicode fallback: (A) Non-BMP characters rendered as '??'. NeedsFallback/FontForChar/SplitFontRuns, the glyph encoder (EncodeTextAsGlyphIds/TrackCodePoints), and the WinAnsi escaper (EscapePdfString) all iterated UTF-16 code units, so a surrogate pair was treated as two characters — each half missing in every font, yielding two '?'. They now iterate Unicode codepoints: a non-BMP codepoint routes to the fallback font when covered, otherwise collapses to a single missing-glyph indicator — never '??'. (B) A footnote in a table cell disabled symbol fallback for the rest of the cell. #69's segment-based cell path (RenderCellSegments) wrapped and wrote segments directly, skipping ExpandSegmentsForFallback, so '=>'/'✓' next to a footnote regressed to base-font '?'. RenderCellSegments now runs the same fallback expansion as the body-text path. Body paragraphs were unaffected (they already go through WriteWrappedSegments). Adds PdfSymbolFallbackTests covering the single-missing-glyph behaviour for a non-BMP char, symbol fallback in footnote-bearing cells (arrow + check mark), and a plain-paragraph regression guard.
…ol-fallback # Conflicts: # CHANGELOG.md
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 #72.
Problem
Two cases still emitted
?despite the #52 Unicode fallback (both render correctly in the Avalonia preview, so they're PDF-renderer-specific):??.🛇(U+1F6C7) came out as two question marks — the UTF-16 surrogate pair was iterated as two code units, each half missing in every font.⇒/✓that renders via the fallback font in a plain cell regressed to?when the same cell also had afootnote:[…]. Cross-references did not trigger it; footnotes did.Root cause & fix
(A)
NeedsFallback/FontForChar/SplitFontRuns, the glyph encoder (EncodeTextAsGlyphIds/TrackCodePoints), and the WinAnsi escaper (EscapePdfString) all iteratedchar(UTF-16 code units). They now iterate Unicode codepoints via a sharedEnumerateCodePointshelper, so a non-BMP character is one unit: it routes to the fallback font when covered, otherwise collapses to a single missing-glyph indicator — never??.(B) #69's segment-based cell path (
RenderCellSegments) wrapped and wrote segments directly, skippingExpandSegmentsForFallback— the step the body-text path (WriteWrappedSegments) runs. It now runs the same fallback expansion, so a footnote no longer disables fallback for sibling runs. (Confirmed body paragraphs were never affected.)Before → after (literal base-font text from the repro)
Prohibited ?? sign→Prohibited ? sign? K [1]→K [1](the⇒now uses the embedded fallback font)Tests
Adds
PdfSymbolFallbackTests: the single-missing-glyph behaviour for a non-BMP char (never??), symbol fallback inside footnote-bearing cells (arrow + check mark), and a plain-paragraph regression guard for the #52 behaviour. Full Release suite green (0 failures, +4 tests); the 480 PDF/conformance/parity/font tests still pass.Related: #52 (prior glyph/fallback fix), #69 (the table-cell segment path that regressed B).