Waarom de tekst in een PDF niet echt tekst is
In een oogopslag
Sectie met titel “In een oogopslag”Wanneer je een PDF leest, zie je woorden. Het bestand bevat geen woorden. Het bevat instructies om vormen op coördinaten te schilderen, en die vormen lijken toevallig op letters. De kloof tussen wat een PDF tekent en wat ze betekent is de reden dat een pagina er foutloos kan uitzien en toch als onzin geëxtraheerd wordt. Deze pagina gaat over die kloof, en over de kleine, afzonderlijke afbeelding die ze dicht.
Waarom dit belangrijk is
Sectie met titel “Waarom dit belangrijk is”Alles wat je met een PDF doet als tekst — haar selecteren, kopiëren, doorzoeken,
indexeren voor terugvinden, hardop voorlezen met een schermlezer — is afhankelijk
van het terugwinnen van tekens die het bestand nooit rechtstreeks heeft
opgeslagen. Als dat terugwinnen mislukt, is de mislukking onzichtbaar. De pagina
wordt nog steeds weergegeven. Niemand merkt het tot iemand een alinea in een
e-mail kopieert en □□□□ krijgt, of een contract van 400 pagina’s doorzoekt naar
een clausule die er duidelijk staat en niets vindt.
Dat is een dure categorie bug, juist omdat ze elke visuele controle overleeft. Er is niets te zien. Het document oogt gezaghebbend en is, voor machinale doeleinden, stom.
De korte versie
Sectie met titel “De korte versie”- Een PDF tekent glyphs — visuele vormen die via numerieke codes uit een font worden gekozen — geen Unicode-tekens.
- Dezelfde vorm kan verschillende tekens betekenen, en hetzelfde teken kan door verschillende glyphs worden getekend. Uiterlijk en betekenis zijn van nature ontkoppeld.
- Om tekst er weer uit te krijgen, draait een reader het toonpad omgekeerd: code
naar teken. De
/ToUnicode-CMap van het font is de opzoektabel voor die omgekeerde stap (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). - Geen
/ToUnicode, of een verkeerde, betekent verminkt kopiëren-en-plakken en mislukt zoeken — terwijl de pagina nog steeds pixelperfect is. - Dit is het betekenisprobleem. Of de glyph er goed uitziet is het afzonderlijke
uiterlijkprobleem dat behandeld wordt in
Fonts: the hard part. NextPDF zendt een
correcte
/ToUnicodeuit zodat de rondgang getrouw is.
Hoe NextPDF dit aanpakt
Sectie met titel “Hoe NextPDF dit aanpakt”Begin met hoe tekst überhaupt op de pagina komt. Een content stream zegt niet
“schrijf het woord file.” Het selecteert een font en geeft vervolgens een
string van codes door aan een tekstoperator
(Spec: ISO 32000-2, §9ISO 32000-2 §9). Elke code is een index — een
positie in een font-programma — en het font verandert die index in een
glyph-omtrek en schildert die. De code 70 is niet het teken F. Het is “slot
70 in dit font”, en slot 70 bevat toevallig een F-vormige kromme. Kies een
ander font en slot 70 zou een sneeuwvlok kunnen zijn.
Een code betekent dus alleen iets ten opzichte van de encoding van het font. Voor een simpel font is die encoding ruwweg één byte per glyph. Voor de schriften die duizenden glyphs nodig hebben — CJK, of welk volledig-Unicode-document dan ook — is dat niet genoeg ruimte, en grijpt de PDF naar een composite (Type 0) font (Spec: ISO 32000-2, §9.7ISO 32000-2 §9.7). Een composite font leest multibyte-codes via een CMap, verandert ze in CID’s (character identifiers), en beeldt CID’s af op glyphs. Het is een elegante indirectie die één font een enorme glyph-set laat adresseren. Het is ook nog een plek waar het spoor van “wat wordt getoond” naar “wat het betekent” kan doodlopen.
Draai het nu om. Om tekst te extraheren, neemt een reader de codes die hij in de content stream aantreft en moet hij tekens terugwinnen (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). De encoding die de glyph tekende ging teken naar glyph; extractie heeft glyphcode naar teken nodig, en die richting is niet gegarandeerd inverteerbaar. Een subset-font kan zijn glyphs hernummerd hebben. De CID’s van een composite font kunnen privé zijn. De vorm op de pagina draagt geen inherente Unicode-betekenis.
De oplossing is de omgekeerde afbeelding naast het font mee te leveren. Die
afbeelding is de /ToUnicode-CMap: voor elke code die het document gebruikt,
legt ze de Unicode-waarde (of -waarden) vast waarvoor die code staat. Daarmee is
extractie een schone opzoeking. Zonder haar moet een reader gokken op basis van
font-encodings en heuristieken — en gokken is precies waar fi een vraagteken
wordt.
- Your charactersThe Unicode text you set, for example the word 'file'.
- Encoding → codesThe font's encoding turns characters into numeric codes; a composite font routes them through a CMap to CIDs.
- Codes → glyphsEach code selects a glyph outline, which is painted to the page. This is the part you see.
- Extraction reverses itA reader reads the codes back and looks each one up in /ToUnicode to recover Unicode.
- Text againWith a correct /ToUnicode, copy, search, indexing, and screen readers all get the original characters back.
NextPDF schrijft de omgekeerde afbeelding vanzelfsprekend. Wanneer het een
composite font inbedt, zendt het de CIDFontType2-afstammeling, de
Type0-ouder en een /ToUnicode-CMap uit zodat codes terug naar Unicode worden
opgelost — het encodingwerk dat beschreven wordt in
Fonts: the hard part. Wat het hier waard is
om apart te zetten is het waarom: de /ToUnicode-stream gaat er niet over de
pagina er goed uit te laten zien. De glyphs zien er zonder haar al goed uit. Het is
het enige artefact dat de tekst extraheerbaar houdt.
Praktisch voorbeeld
Sectie met titel “Praktisch voorbeeld”De beroemdste plek waar dit aan de oppervlakte komt, is de fi-ligatuur.
Veel fonts tekenen f en i als één gecombineerde glyph, omdat de punt van de
i botst met de haak van de f. Op de pagina is het één vorm, getekend door één
code. De vraag is wat er gebeurt als je haar kopieert.
% A /ToUnicode entry that maps the single ligature code to TWO characters,% so selecting the 'fi' glyph copies out as 'f' then 'i' — not one mystery box.1 beginbfchar<0085> <00660069> % code 0x85 -> U+0066 'f' U+0069 'i'endbfcharDie ene regel is het verschil tussen een zoekopdracht naar “file” die wel
overeenkomt en een zoekopdracht naar “file” die stilletjes elk voorkomen mist dat
met de ligatuur is weergegeven. Beeld de ligatuurcode af op de tekenreeks f +
i van twee tekens, en het woord is doorzoekbaar en kopieerbaar. Laat haar
ongekoppeld, en de pagina toont nog steeds perfect file terwijl de tekst stil
niets zegt dat een machine kan lezen.
Daarom kan “fi” als één teken of als twee worden geëxtraheerd, en daarom is het
verschil niet willekeurig — het is wat de /ToUnicode-afbeelding ook maar
opgedragen kreeg te zeggen. Een correcte afbeelding ontleedt de ligatuur terug in
haar tekens. NextPDF zendt precies dat soort regel uit, zodat een ligatuur op de
pagina twee gewone letters op het klembord is.
Veelvoorkomend misverstand
Sectie met titel “Veelvoorkomend misverstand”De valkuil, benoemd: “de tekst wordt weergegeven, dus de tekst is in orde.”
Weergave en extractie zijn verschillende mechanismen die verschillende gegevens
lezen. Weergave volgt het code-naar-glyphpad en is wat je ogen controleren.
Extractie volgt het code-naar-tekenpad via /ToUnicode en is wat elke machinale
consument controleert. Een document kan het eerste glansrijk doorstaan en het
tweede volledig falen, want naar zijn constructie is er niets visueels dat het
verraadt.
Een tweede, subtielere valkuil: aannemen dat een glyph “vanzelfsprekend” weet welk teken hij is. Dat doet hij niet. Een glyph is een vorm met een index. De afbeelding terug naar een teken is aanvullende informatie die de producent moet leveren. Als de producent haar nooit heeft geschreven, kan geen enkele reader haar getrouw terugwinnen — hij kan alleen gokken.
Limieten en grenzen
Sectie met titel “Limieten en grenzen”| Edition | Availability |
|---|---|
| Core | NextPDF emits a correct /ToUnicode CMap for the fonts it embeds, including the ligature and composite-font cases, so the documents it produces are searchable and copyable. |
| Pro | Not in this edition |
| Enterprise | Not in this edition |
Een /ToUnicode-afbeelding kan alleen informatie dragen die het bronfont
daadwerkelijk blootlegt. Waar een glyph geen bepaalbaar teken heeft — een puur
decoratief teken, een private-use-symbool zonder Unicode-toewijzing — kan geen
enkele afbeelding betekenis verzinnen die er nooit was. NextPDF zendt de
waarheidsgetrouwe afbeelding uit die het kan afleiden; het fabriceert geen tekens
om een gat te vullen.
Deze pagina gaat over de documenten die NextPDF schrijft. Het is geen
reparatietool voor willekeurige binnenkomende PDF’s waarvan de /ToUnicode al
afwezig of fout is; tekst uit die documenten terugwinnen is een afzonderlijk,
heuristisch probleem. En getrouwe extractie is noodzakelijk voor toegankelijkheid
maar niet het geheel ervan — leesvolgorde, tags en alternatieve tekst worden
behandeld in
What makes a PDF accessible.
Mini-FAQ
Sectie met titel “Mini-FAQ”Waarom kopieert dezelfde PDF goed in de ene reader en slecht in de andere?
Verschillende readers vallen verschillend terug wanneer /ToUnicode ontbreekt.
Sommige gokken op basis van de ingebouwde encoding van het font en boffen bij
veelvoorkomende Latijnse tekst; andere niet. Een correcte /ToUnicode haalt de
loterij weg — elke conforme reader krijgt dezelfde tekens.
Is dit hetzelfde als het font dat niet is ingebed?
Nee. Inbedding gaat over uiterlijk — of de glyph schildert zonder dat het font
geïnstalleerd is. /ToUnicode gaat over betekenis — of de code terug op een
teken wordt afgebeeld. Een font kan perfect zijn ingebed en toch geen bruikbare
/ToUnicode hebben, wat de niet-doorzoekbaar-maar-mooi-mislukking is.
Heeft extractie ooit meer dan één teken per code nodig?
Ja — de ligatuurcasus is precies dat: één code wordt afgebeeld op twee tekens. Een
/ToUnicode-regel kan een enkele code afbeelden op een korte reeks, en zo komen
ligaturen, en sommige samengestelde vormen, terug als hun samenstellende letters.
Gerelateerde documentatie
Sectie met titel “Gerelateerde documentatie”- Fonts: the hard part — het zusterstuk over de uiterlijkkant: inbedding, subsetting, en hoe de encoding wordt opgebouwd. Deze pagina is de betekeniskant van dezelfde medaille.
- What makes a PDF accessible — getrouwe tekst is één ingrediënt; leesvolgorde, tags en alt-tekst zijn de rest.
- What a PDF actually is — het
objectmodel waarbinnen de fonts, encodings en
/ToUnicode-streams leven.
Verklarende woordenlijst
Sectie met titel “Verklarende woordenlijst”- Glyph — een visuele vorm in een font (een omtrek). Wat een PDF werkelijk schildert. Een glyph heeft een index maar geen inherente tekenbetekenis.
- Teken — een eenheid van geschreven taal, geïdentificeerd door een Unicode-codepunt. Wat je bedoelt, en wat extractie probeert terug te winnen.
- Code — de numerieke waarde in een content stream die een glyph uit het huidige font selecteert. Geen Unicode-teken; alleen betekenisvol ten opzichte van het font.
- CID — een character identifier die een composite font gebruikt om een glyph binnen een grote set te adresseren; een tussenstap tussen code en glyph.
- Composite (Type 0) font — een font dat multibyte-codes via een CMap leest om CID’s en glyphs te bereiken, gebruikt wanneer één font duizenden glyphs moet adresseren.
/ToUnicode— de CMap-stream die de codes die een document gebruikt terugbeeldt op Unicode-waarden; wat PDF-tekst doorzoekbaar, kopieerbaar en toegankelijk maakt.- Ligatuur — een enkele glyph die twee of meer letters als één vorm tekent
(bijvoorbeeld
fi); haar/ToUnicode-regel ontleedt haar terug in haar tekens.