PDF ist kein Dokumentenformat in der Art, wie es Word oder RTF sind. Diese Formate speichern eine Sequenz von Inhalten, die ein Renderer im Moment der Anzeige interpretiert, sodass die Ausgabe von den zufällig vorhandenen Schriftarten und Layout-Engines abhängt. PDF speichert das Ergebnis dieses Prozesses: präzise Rendering-Anweisungen, Schriftartenprogramme, komprimierte Bildströme und einen Objektgraphen, der sie zu einer in sich geschlossenen Beschreibung jeder Seite zusammenfasst. Die Datei enthält genügend Informationen, um jede Seite auf jedem konformen Renderer identisch zu reproduzieren. Dies ist sowohl ihr Hauptentwurfsziel als auch die Quelle der meisten Komplexitäten, auf die Sie stoßen, wenn Sie versuchen, eine solche Datei programmgesteuert zu generieren, zu parsen oder zu ändern
Das Objektmodell
Jedes PDF ist eine Sammlung nummerierter Objekte. Ein Objekt kann ein boolescher Wert, eine Ganzzahl, eine reelle Zahl, ein Name, ein String, ein Array, ein Wörterbuch, ein Stream oder Null sein. Fast alles Interessante ist ein Wörterbuch, das heißt eine Menge von Schlüssel-Wert-Paaren, bei denen die Schlüssel Namen sind und die Werte jeder andere Objekttyp sein können, einschließlich Referenzen auf andere Objekte anhand von Nummer und Generationszahl. Ein Stream ist ein Wörterbuch, gefolgt von einer Bytesequenz, typischerweise komprimiert
Das Katalog-Wörterbuch ist die Wurzel. Es verweist auf den Seitenbaum, der die Seiten-Wörterbücher eher in einer balancierten Baumstruktur als in einer flachen Liste organisiert, sodass das Navigieren zur Seite 5.000 eines 10.000-seitigen Dokuments nicht erfordert, jeden vorhergehenden Seitendeskriptor zu durchlaufen. Jedes Seiten-Wörterbuch referenziert seine Content-Streams (eine oder mehrere Sequenzen von Seitenbeschreibungs-Operatoren), sein Ressourcen-Wörterbuch (das wiederum Schriftdeskriptoren, Farbräume und Bild-XObjects referenziert) und seine Media-Box (den Koordinatenraum, in dem sich die Seite befindet). Der Koordinatenursprung liegt in der unteren linken Ecke, wobei die positive Y-Achse nach oben verläuft, in Einheiten von 1/72 Zoll
Am Ende der Datei befindet sich die Kreuzreferenztabelle, die jede Objektnummer ihrem Byte-Offset in der Datei zuordnet. Dies ermöglicht den wahlfreien Zugriff: Ein Viewer liest zuerst die Kreuzreferenztabelle und springt dann direkt zu den Objekten, die er benötigt. PDF 1.5 führte Kreuzreferenzströme ein, die die Tabelle in ein Stream-Objekt komprimieren und zusammengehörige Objekte in Objektströmen packen, was die Dateigröße für Dokumente mit vielen kleinen Objekten spürbar reduziert
Content-Streams und das Grafikmodell
Der visuelle Inhalt einer Seite befindet sich in einem oder mehreren Content-Streams. Jeder Stream ist eine Folge von PDF-Operatoren, die mit ihren Operanden durchsetzt sind. Der Textoperator BT beginnt ein Textobjekt, Tf wählt eine Schriftart und Größe aus dem Ressourcen-Wörterbuch, Td positioniert den Textcursor, Tj oder TJ zeichnet einen String und ET schließt das Textobjekt. Vektorgrafiken folgen einem ähnlichen Muster: m setzt einen Pfadstartpunkt, l hängt ein Liniensegment an, c hängt eine Bezier-Kurve an, und f oder S füllt oder strichelt den Pfad
Der Grafikstatus regelt alles, was zwischen den Operatoren passiert: aktuelle Transformationsmatrix, Linienbreite, Farbraum, Füllfarbe, Strichfarbe und den Beschneidungspfad. Operatoren wie q und Q schieben den Grafikstatus auf einen Stack und holen ihn wieder herunter. So implementiert PDF lokale Koordinatentransformationen und temporäre Statusüberschreibungen, ohne den Kontext um sie herum zu beeinflussen. Form-XObjects verallgemeinern dies: ein in sich geschlossener Content-Stream mit einem eigenen Ressourcen-Wörterbuch, der an beliebigen Positionen und in beliebigen Skalierungen mit einem einzigen Do-Operator auf eine Seite gezeichnet werden kann
Schrifteinbettung und Textextraktion
PDF kann Schriften beim Namen nennen und sich darauf verlassen, dass der Viewer etwas Entsprechendes ersetzt, aber in der Praxis muss jedes Dokument, das Sie teilen möchten, die Schriftdaten einbetten. Eine in einem PDF eingebettete Type 1- oder TrueType/OpenType-Schrift trägt ein Schriftdeskriptor-Wörterbuch, das auf einen Schriftdateistrom verweist. Bei TrueType-Schriften enthält dieser Stream das binäre Schriftprogramm; bei Type 1 sind es die PFB-Daten. Das Subsetting (Untergruppenbildung), was jeder seriöse PDF-Generator tut, entfernt Glyphen, die vom Dokument nicht referenziert werden, und hält so die Dateigrößen selbst bei großen Unicode-Schriften überschaubar
Bei der Textextraktion schlägt die Schrifteinbettung zurück. Die visuelle Darstellung eines Zeichens wird durch eine Glyphe im eingebetteten Schriftprogramm bestimmt. Der Unicode-Wert dieses Zeichens wird durch einen ToUnicode-CMap-Stream bestimmt, der an das Schrift-Wörterbuch angehängt ist. Wenn die ToUnicode-CMap fehlt oder falsch ist, kann ein PDF-Viewer Text lesbar rendern, ihn aber nicht als sinnvollen Unicode extrahieren, weshalb das Kopieren und Einfügen aus einigen PDFs Müll erzeugt. Tagged PDF (ISO 32000 §14.8) fügt eine zweite Ebene hinzu: einen logischen Strukturbaum, der Seiteninhalt auf dokumentensemantische Rollen wie Absätze, Überschriften und Tabellenzellen abbildet. Screenreader und Reflow-Engines verwenden den Strukturbaum anstelle der rohen Content-Stream-Reihenfolge, was erklärt, warum ein visuell gut gestaltetes PDF dennoch unzugänglich sein kann, wenn das Tagging fehlt oder falsch ist
Inkrementelle Updates und digitale Signaturen
Wenn Sie Änderungen an einem bestehenden PDF speichern, ohne es von Grund auf neu zu schreiben, werden die neuen Objekte nach dem ursprünglichen Dateikörper angehängt, zusammen mit einem neuen Kreuzreferenzabschnitt und einem neuen Trailer-Wörterbuch. Der aktualisierte Trailer verweist auf die neuen Kreuzreferenzdaten, und ersetzte Objekte bleiben in der Datei, werden aber einfach nicht durch die neue Kreuzreferenzkette referenziert. Dies ist ein inkrementelles Update, und es hat zwei wesentliche Konsequenzen
Erstens wächst die Datei mit jedem Speicherzyklus. Ein Dokument, das wiederholt bearbeitet und gespeichert wird, sammelt Schichten veralteter Objekte an. Werkzeuge wie QPDF können eine Datei linearisieren oder komprimieren-und-neu-schreiben, um diesen Platz zurückzugewinnen, aber der Standard ist Akkumulation. Zweitens hängen digitale Signaturen für ihr Integritätsmodell von inkrementellen Updates ab. Eine ISO 32000-Signatur deckt einen Bytebereich der Datei ab, typischerweise alles außer dem Platzhalter für den Signaturwert selbst. Alle Änderungen nach dem Signieren, die als zusätzliche inkrementelle Updates erscheinen, sind für einen überprüfenden Reader als Modifikationen sichtbar, die nach dem Signieren vorgenommen wurden, was genau der Prüfpfad (Audit Trail) ist, den Sie möchten. Dies bedeutet jedoch auch, dass bestimmte Änderungen, wie das Hinzufügen einer Genehmigungssignatur oder das Ausfüllen von Formularfeldern, durch den Standard ausdrücklich zugelassen sind, ohne die ursprüngliche Signatur ungültig zu machen, vorausgesetzt, die Änderungen entsprechen den Berechtigungseinstellungen des Dokuments (ISO 32000-2 §12.7.6). Eine Änderung, die außerhalb dieser Berechtigungen liegt, wird als nicht autorisiert gekennzeichnet. Diese Unterscheidung richtig zu treffen ist wichtig, wenn Sie Dokumente generieren, die später gegengezeichnet werden sollen
Konformitätsstufen und die ISO 32000-Abstammungslinie
PDF begann 1993 als proprietäres Adobe-Format, übernahm das Bildmodell von PostScript und sammelte über fünfzehn Versionen hinweg Funktionen an: Verschlüsselung in 1.1, interaktive Formulare in 1.2, digitale Signaturen und logische Struktur in 1.3, Transparenz in 1.4, Objektströme in 1.5, AES-Verschlüsselung in 1.6. Adobe reichte PDF 1.7 im Jahr 2007 bei der ISO ein, und ISO 32000-1:2008 war das Ergebnis. ISO 32000-2:2020 deckt PDF 2.0 ab, welches mehrere unzureichend spezifizierte Bereiche straffte, die AES-256-Schlüsselableitung überarbeitete (Revision 6 ersetzt Revision 5) und explizite Unterstützung für assoziierte Dateien und Rich Media hinzufügte
Die Substandards leiten sich von derselben Basis ab. PDF/A (ISO 19005) tauscht Funktionen gegen Archivierungsstabilität ein: keine Verschlüsselung, keine externen Inhaltsabhängigkeiten, alle Schriften eingebettet, geräteunabhängige Farbräume, XMP-Metadaten erforderlich. PDF/A-1 basiert auf PDF 1.4, PDF/A-2 auf PDF 1.7, PDF/A-3 erlaubt eingebettete Dateien jeden Formats. PDF/X (ISO 15930) ist die Teilmenge für die Druckproduktion: Output Intents, Anschnitt- und Endformat-Rahmen (Bleed and Trim Boxes), keine Transparenz in älteren Konformitätsstufen. PDF/UA (ISO 14289) schreibt Tagged-Strukturen, Unicode-Zuordnungen und Sprach-Metadaten für Barrierefreiheit vor. Dies sind keine konkurrierenden Formate; es handelt sich um Sätze zusätzlicher Einschränkungen zusätzlich zum Kern-PDF, und eine einzelne Datei kann mehr als einem gleichzeitig entsprechen, vorausgesetzt, die Einschränkungen stehen nicht in Konflikt zueinander
Für jeden, der Code schreibt, welcher PDFs generiert oder verarbeitet, ist die praktische Basislinie ISO 32000-2 mit besonderem Augenmerk auf die Abschnitte, die das Kreuzreferenzmodell (§7.5), den Grafikstatus (§8.4), Textstatus-Operatoren (§9.3), Schriftdeskriptoren und ToUnicode (§9.6 und §9.10), interaktive Formulare (§12.7) und digitale Signaturen (§12.8) abdecken. Der Standard ist lang, aber die meiste programmatische PDF-Arbeit berührt immer wieder einen schmalen Bereich davon. Das Verständnis des Objektmodells und des Kreuzreferenzmechanismus ist der Einstiegspunkt; alles andere ist von dort aus Spezialisierung