Warum der Text in einem PDF kein echter Text ist
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Wenn Sie ein PDF lesen, sehen Sie Wörter. Die Datei enthält keine Wörter. Sie enthält Anweisungen, Formen an Koordinaten zu zeichnen, und die Formen sehen zufällig wie Buchstaben aus. Die Kluft zwischen dem, was ein PDF zeichnet, und dem, was es bedeutet, ist der Grund, warum eine Seite makellos aussehen und trotzdem als Unsinn herauskopiert werden kann. Auf dieser Seite geht es um diese Kluft und um die kleine, separate Zuordnung, die sie schließt.
Warum das wichtig ist
Abschnitt betitelt „Warum das wichtig ist“Alles, was Sie mit einem PDF als Text tun — es markieren, kopieren,
durchsuchen, für die Suche indizieren, mit einem Screenreader vorlesen lassen —
hängt davon ab, Zeichen wiederherzustellen, die die Datei nie direkt gespeichert
hat. Wenn diese Wiederherstellung scheitert, ist das Scheitern unsichtbar. Die
Seite wird trotzdem gerendert. Niemand bemerkt es, bis jemand einen Absatz in
eine E-Mail kopiert und □□□□ erhält oder einen 400-seitigen Vertrag nach einer
Klausel durchsucht, die klar darin steht, und nichts findet.
Das ist eine teure Fehlerklasse gerade deshalb, weil sie jede visuelle Prüfung übersteht. Es gibt nichts zu sehen. Das Dokument wirkt verbindlich und ist, für maschinelle Zwecke, stumm.
Die Kurzfassung
Abschnitt betitelt „Die Kurzfassung“- Ein PDF zeichnet Glyphen — visuelle Formen, die durch numerische Codes in eine Schrift ausgewählt werden — keine Unicode-Zeichen.
- Dieselbe Form kann unterschiedliche Zeichen bedeuten, und dasselbe Zeichen kann durch unterschiedliche Glyphen gezeichnet werden. Erscheinungsbild und Bedeutung sind konstruktionsbedingt entkoppelt.
- Um Text wieder herauszubekommen, durchläuft ein Reader den Darstellungspfad
rückwärts: vom Code zum Zeichen. Die
/ToUnicode-CMap der Schrift ist die Nachschlagetabelle für diesen Rückwärtsschritt (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). - Keine
/ToUnicodeoder eine falsche bedeutet verstümmeltes Kopieren/Einfügen und gescheiterte Suche — bei einer Seite, die weiterhin pixelgenau ist. - Das ist das Bedeutungsproblem. Ob die Glyphe richtig aussieht, ist das
separate Erscheinungsbildproblem, das in
Schriften: der schwierige Teil behandelt
wird. NextPDF gibt eine korrekte
/ToUnicodeaus, sodass der Hin- und Rückweg zuverlässig ist.
Wie NextPDF es angeht
Abschnitt betitelt „Wie NextPDF es angeht“Beginnen Sie damit, wie Text überhaupt auf die Seite gelangt. Ein Content-Stream
sagt nicht „schreibe das Wort file“. Er wählt eine Schrift und übergibt dann
eine Zeichenkette aus Codes an einen Textdarstellungsoperator
(Spec: ISO 32000-2, §9ISO 32000-2 §9). Jeder Code ist ein Index — eine
Position in einem Schriftprogramm —, und die Schrift verwandelt diesen Index in
eine Glyphenkontur und zeichnet sie. Der Code 70 ist nicht das Zeichen F. Er
ist „Slot 70 in dieser Schrift“, und Slot 70 enthält zufällig eine
F-förmige Kurve. Wählen Sie eine andere Schrift, und Slot 70 könnte eine
Schneeflocke sein.
Ein Code bedeutet also nur etwas relativ zur Kodierung seiner Schrift. Bei einer einfachen Schrift ist diese Kodierung in etwa ein Byte pro Glyphe. Für die Schriftsysteme, die Tausende von Glyphen benötigen — CJK oder jedes vollständige Unicode-Dokument —, ist das nicht genug Platz, und das PDF greift zu einer zusammengesetzten (Type-0-)Schrift (Spec: ISO 32000-2, §9.7ISO 32000-2 §9.7). Eine zusammengesetzte Schrift liest Mehrbyte-Codes durch eine CMap, verwandelt sie in CIDs (Zeichenkennungen) und bildet CIDs auf Glyphen ab. Es ist eine elegante Indirektion, die einer Schrift erlaubt, einen enormen Glyphensatz zu adressieren. Es ist auch eine weitere Stelle, an der die Spur von „was gezeigt wird“ zu „was es bedeutet“ kalt werden kann.
Lassen Sie es nun rückwärts laufen. Um Text zu extrahieren, nimmt ein Reader die Codes, die er im Content-Stream findet, und muss Zeichen wiederherstellen (Spec: ISO 32000-2, §9.10ISO 32000-2 §9.10). Die Kodierung, die die Glyphe gezeichnet hat, ging vom Zeichen zur Glyphe; die Extraktion benötigt vom Glyphen-Code zum Zeichen, und diese Richtung ist nicht garantiert umkehrbar. Eine Subset-Schrift kann ihre Glyphen neu nummeriert haben. Die CIDs einer zusammengesetzten Schrift können privat sein. Die Form auf der Seite trägt keine inhärente Unicode-Bedeutung.
Die Lösung besteht darin, die Rückwärtszuordnung zusammen mit der Schrift
mitzuliefern. Diese Zuordnung ist die /ToUnicode-CMap: für jeden Code, den
das Dokument verwendet, hält sie den oder die Unicode-Werte fest, für die dieser
Code steht. Mit ihr ist die Extraktion ein sauberes Nachschlagen. Ohne sie bleibt
einem Reader nur, aus Schriftkodierungen und Heuristiken zu raten — und Raten ist
genau die Stelle, an der aus fi ein Fragezeichen wird.
- 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 schreibt die Rückwärtszuordnung als Selbstverständlichkeit. Wenn es eine
zusammengesetzte Schrift einbettet, gibt es die CIDFontType2-Nachkommenschrift,
das Type0-Elterndictionary und eine /ToUnicode-CMap aus, sodass Codes wieder
nach Unicode aufgelöst werden — die Kodierungsarbeit, die in
Schriften: der schwierige Teil beschrieben
ist. Der Punkt, den es hier wert ist herauszustellen, ist das Warum: Der
/ToUnicode-Stream geht nicht darum, die Seite richtig aussehen zu lassen. Die
Glyphen sehen schon ohne ihn richtig aus. Er ist das einzige Artefakt, das den
Text extrahierbar hält.
Praktisches Beispiel
Abschnitt betitelt „Praktisches Beispiel“Die bekannteste Stelle, an der das zutage tritt, ist die fi-Ligatur. Viele
Schriften zeichnen f und i als eine kombinierte Glyphe, weil der Punkt des
i mit dem Haken des f kollidiert. Auf der Seite ist es eine Form, gezeichnet
durch einen Code. Die Frage ist, was passiert, wenn Sie sie kopieren.
% 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'endbfcharDieser eine Eintrag ist der Unterschied zwischen einer Suche nach „file“, die
trifft, und einer Suche nach „file“, die jedes mit der Ligatur gerenderte
Vorkommen stillschweigend verfehlt. Bilden Sie den Ligatur-Code auf die
Zwei-Zeichen-Folge f + i ab, und das Wort ist durchsuchbar und kopierbar.
Lassen Sie es unzugeordnet, und die Seite zeigt weiterhin perfekt file, während
der Text leise nichts sagt, was eine Maschine lesen kann.
Das ist der Grund, warum „fi“ als ein Zeichen oder als zwei extrahiert werden
kann, und warum der Unterschied nicht zufällig ist — es ist, was auch immer der
/ToUnicode-Zuordnung aufgetragen wurde zu sagen. Eine korrekte Zuordnung zerlegt
die Ligatur wieder in ihre Zeichen. NextPDF gibt genau diese Art von Eintrag aus,
sodass eine Ligatur auf der Seite zwei gewöhnliche Buchstaben in der
Zwischenablage sind.
Häufiges Missverständnis
Abschnitt betitelt „Häufiges Missverständnis“Die Falle, benannt: „Der Text wird gerendert, also ist der Text in Ordnung.“
Rendering und Extraktion sind unterschiedliche Mechanismen, die unterschiedliche
Daten lesen. Rendering folgt dem Pfad vom Code zur Glyphe und ist das, was Ihre
Augen prüfen. Die Extraktion folgt dem Pfad vom Code zum Zeichen über
/ToUnicode und ist das, was jeder maschinelle Konsument prüft. Ein Dokument kann
das Erste mit Bravour bestehen und das Zweite vollständig verfehlen, weil es
konstruktionsbedingt nichts Visuelles gibt, das es verrät.
Eine zweite, subtilere Falle: anzunehmen, eine Glyphe „wisse offensichtlich“, welches Zeichen sie ist. Das tut sie nicht. Eine Glyphe ist eine Form mit einem Index. Die Zuordnung zurück zu einem Zeichen ist zusätzliche Information, die der Erzeuger bereitstellen muss. Wenn der Erzeuger sie nie geschrieben hat, kann kein Reader sie zuverlässig wiederherstellen — er kann nur raten.
Grenzen und Abgrenzungen
Abschnitt betitelt „Grenzen und Abgrenzungen“| Edition | Availability |
|---|---|
| Core | NextPDF gibt eine korrekte /ToUnicode-CMap für die Schriften aus, die es einbettet, einschließlich der Ligatur- und Fälle zusammengesetzter Schriften, sodass die von ihm erzeugten Dokumente durchsuchbar und kopierbar sind. |
| Pro | Not in this edition |
| Enterprise | Not in this edition |
Eine /ToUnicode-Zuordnung kann nur Information tragen, die die Quellschrift
tatsächlich offenlegt. Wo eine Glyphe kein bestimmbares Zeichen hat — eine rein
dekorative Marke, ein Symbol aus dem Private-Use-Bereich ohne Unicode-Zuordnung —,
kann keine Zuordnung Bedeutung erfinden, die nie da war. NextPDF gibt die
wahrheitsgemäße Zuordnung aus, die es ableiten kann; es erfindet keine Zeichen, um
eine Lücke zu füllen.
Auf dieser Seite geht es um die Dokumente, die NextPDF schreibt. Es ist kein
Reparaturwerkzeug für beliebige eingehende PDFs, deren /ToUnicode bereits fehlt
oder falsch ist; Text aus diesen wiederherzustellen ist ein separates,
heuristisches Problem. Und eine zuverlässige Extraktion ist für die
Barrierefreiheit notwendig, aber nicht das Ganze davon — Lesereihenfolge, Tags
und Alternativtext werden in
Was ein PDF barrierefrei macht
behandelt.
Mini-FAQ
Abschnitt betitelt „Mini-FAQ“Warum kopiert sich dasselbe PDF in einem Reader gut und in einem anderen
schlecht?
Unterschiedliche Reader weichen unterschiedlich aus, wenn /ToUnicode fehlt.
Einige raten aus der eingebauten Kodierung der Schrift und haben bei gängigem
lateinischem Text Glück; andere nicht. Eine korrekte /ToUnicode beseitigt die
Lotterie — jeder konforme Reader erhält dieselben Zeichen.
Ist das dasselbe wie eine nicht eingebettete Schrift?
Nein. Beim Einbetten geht es um das Erscheinungsbild — ob die Glyphe ohne die
installierte Schrift gezeichnet wird. Bei /ToUnicode geht es um die Bedeutung
— ob der Code wieder auf ein Zeichen abgebildet wird. Eine Schrift kann perfekt
eingebettet sein und dennoch keine brauchbare /ToUnicode haben, was das
unsuchbar-aber-hübsch-Versagen ist.
Braucht die Extraktion jemals mehr als ein Zeichen pro Code?
Ja — der Ligaturfall ist genau das: Ein Code wird auf zwei Zeichen abgebildet.
Ein /ToUnicode-Eintrag kann einen einzelnen Code auf eine kurze Folge abbilden,
und so kommen Ligaturen und einige zusammengesetzte Formen als ihre einzelnen
Buchstaben zurück.
Verwandte Dokumente
Abschnitt betitelt „Verwandte Dokumente“- Schriften: der schwierige Teil — das Begleitstück zur Erscheinungsbildseite: Einbettung, Subsetting und wie die Kodierung aufgebaut wird. Diese Seite ist die Bedeutungsseite derselben Medaille.
- Was ein PDF barrierefrei macht — zuverlässiger Text ist eine Zutat; Lesereihenfolge, Tags und Alternativtext sind der Rest.
- Was ein PDF wirklich ist — das
Objektmodell, in dem die Schriften, Kodierungen und
/ToUnicode-Streams leben.
Glossar
Abschnitt betitelt „Glossar“- Glyphe — eine visuelle Form in einer Schrift (eine Kontur). Das, was ein PDF tatsächlich zeichnet. Eine Glyphe hat einen Index, aber keine inhärente Zeichenbedeutung.
- Zeichen — eine Einheit geschriebener Sprache, identifiziert durch einen Unicode-Codepunkt. Das, was Sie meinen, und das, was die Extraktion wiederherzustellen versucht.
- Code — der numerische Wert in einem Content-Stream, der eine Glyphe aus der aktuellen Schrift auswählt. Kein Unicode-Zeichen; nur relativ zur Schrift bedeutungsvoll.
- CID — eine Zeichenkennung, die eine zusammengesetzte Schrift verwendet, um eine Glyphe innerhalb eines großen Satzes zu adressieren; ein Zwischenschritt zwischen Code und Glyphe.
- Zusammengesetzte (Type-0-)Schrift — eine Schrift, die Mehrbyte-Codes durch eine CMap liest, um CIDs und Glyphen zu erreichen, verwendet, wenn eine Schrift Tausende von Glyphen adressieren muss.
/ToUnicode— der CMap-Stream, der die von einem Dokument verwendeten Codes wieder auf Unicode-Werte abbildet; was PDF-Text durchsuchbar, kopierbar und barrierefrei macht.- Ligatur — eine einzelne Glyphe, die zwei oder mehr Buchstaben als eine Form
zeichnet (zum Beispiel
fi); ihr/ToUnicode-Eintrag zerlegt sie wieder in ihre Zeichen.