Een pijl in een diagramlabel breekt de PDF-export niet meer (#1987) #1989
No reviewers
Labels
No labels
accepted
bug
declined
docs
duplicate
enhancement
good first issue
in-progress
needs-info
privacy
security
triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
LibreKAT/Ocideck!1989
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/pdf-svg-fontkeuze-1987"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Wat er misging
laag → hoogin een diagram- of grafieklabel liet de PDF-export afbreken metNull check operator used on a null value— dezelfde klasse fout die #1942 dichtzette, opnieuw geopend door #1968.Twee dingen samen:
1.
svgTypesettingkoos het symbolen-font zodra Roboto één teken miste. Nagemeten:laag → hoogКритик высокийКритик → высокий2.
NotoSansMath-subset.ttfheeft geen letters en geen spatie. Zijn laagste codepunt is U+2190. De SVG-lezer vanpackage:pdfzet alle tekst van een tekening met die ene snede, enTtfWriter.withCharsdoet voor de spatie een onvoorwaardelijkecharToGlyphIndexMap[32]!.Zelfs zonder die worp was de keuze verkeerd: elke letter van
laag → hoogin een wiskundefont is een leeg blokje. Vóór #1968 stond er een leesbaar label met één blokje op de plek van de pijl; erna was het hele document weg.Wat er verandert
De terugvalfonts zijn één geordende lijst.
fallbackFont+symbolFontzijnfallbackFontsgeworden. De vorige vorm gaf geen plek aan de vraag wélke snede een tekening krijgt, en wordt onhoudbaar bij elk font dat erbij komt.Inter staat in die lijst, tussen Roboto en het wiskundefont. Die zat al in de app als interfaceletter, dekt
→ ← ↑ ↓ ↔ ⇒ ✓ ✗ ★ ▪én alle letters, en kost dus geen byte extra, geen licentieregel en geen SBOM-wijziging.Een tekening krijgt de eerste snede die haar hélemaal kan zetten, of anders haar bron. Dat lijkt streng — waarom niet de best dekkende snede, en de rest een blokje? Omdat een ontbrekende glyph in
TtfWriter.withCharsníét betrouwbaar een blokje wordt. Nagemeten met Roboto:laag ⨁ ∮ hooga ⨁ ∮Ԁ ∮Ԁ ⨁ ∮Waar die grens ligt hangt af van hoeveel glyphs de subset verderop nog over heeft — niet na te bouwen, en bij de volgende versie van de bibliotheek mogelijk anders. Op zo'n grens valt geen regel te bouwen. Alles-of-de-bron is wél te beredeneren, en het is dezelfde afweging die er voor een onleesbare SVG al stond.
Waarom dit er ongezien doorheen kwam
De exporttests bouwden hun fonts met Roboto alleen, terwijl de app met drie fonts exporteert. De hele klasse fouten die uit de fontkeuze komt was daarmee onbereikbaar voor de test. Ze gebruiken nu dezelfde lijst en dezelfde volgorde als
loadPdfFallbackFontsin de schil.Eén bestaande test legde bovendien het foute gedrag vast: hij toetste wélk font gekozen werd (
fonts.fallback[1]) in plaats van of de gekozen snede het label kán zetten. Die is omgeschreven naar de eigenschap.Regressietests
☑) wordt gemeldMet eigen ogen bekeken
Een echte export met
→,✓,≤, een gedachtestreepje en krul-apostrofs in kop, alinea, grafiektitel, aslabels en legenda, gerasterd met QuickLook: alles staat er, niets is een blokje, enunsupportedCharactersis leeg.Poorten
make check-secretsgroen (gitleaks + trufflehog)make sastgroen (semgrep)make checkgroen behalvetest-goldenDie 23 golden-tests falen ook op een schone
origin/main— de twee lijsten met faalnamen zijn letterlijk identiek (diffleeg), en het gaat om sub-promille pixelverschillen (0.00%, 28px). Dat is vastgelegd als #1988 en staat los van deze PR.Bewaker
Geen bestandsformaat, geen opslag, geen nieuwe afhankelijkheid, geen uitgaand verkeer, geen publieke belofte — er komt zelfs geen bestand bij. Bewaker-stap expliciet overgeslagen.
Closes #1987
🤖 Generated with Claude Code