Es gibt eine Unmenge von Parametern, die wir einstellen können. Nötig sind zum Glück nur deren vier, und nur drei davon müssen wir in der Praxis anpassen: Die Seitengrösse, das Fontdictionary, und das X-Objektdictionary. Die Angaben können für alle Seiten, für Seitenbereiche oder für einzelne Seiten gemacht werden. Zunächst einmal aber eine Beschreibung der Parameter selbst:
Die Seitengrösse wird durch einen Dictionaryeintrag /MediaBox
eingestellt. Als Wert erhält dieser ein Array von Zahlen, welche den Bereich im Koordinatensystem beschreibt, der vom dargestellten Blatt Papier eingenommen wird.
Wie in den Notationsregeln erwähnt, schreibt man erst die X- und die Y-Koordinate der linken, unteren Ecke. Es ist Usus, hier zweimal null einzusetzen. Danach folgt die X- und die Y-Koordiante der rechten, oberen Ecke. Wenn wir vorher zweimal null eingesetzt haben, sind dies faktisch die Seitenbreite und -höhe in point.
Im Hallo Welt haben wir [0 0 595 842]
verwendet, was eine recht präzise Annäherung an A4-hoch ist. Wir können aber auch Dezimalbrüche verwenden, um eine genauere Annäherung zu erreichen: [0 0 595.276 841.89]
Eine Genauigkeit über die dritte Nachkommastelle hinaus schadet nicht, ist aber sinnlos. Auch Profimaschinen können nicht so präzise drucken, dass dies noch einen Unterschied machen würde. Ab der sechsten Nachkommastelle wird es definitiv sinnlos, da die meiste PDF Software nur die ersten fünf Nachkommastellen überhaupt auswertet.
Die von der Seite verwendeten Resourcen sind in einem Dictionaryeintrag /Resources
festgehalten. Es handelt sich dabei um ein Unterdictionary. Dieses kann wiederum verschiede Einträge enthalten, wovon drei für uns interessant sind:
Das /ProcSet
gibt grob an, welche Routinen für die Inhaltsdarstellung von diesem PDF verwendet werden. Diese sind in fünf Kategorien eingeteilt, von denen die Verwendeten in einem Array aufgezählt werden. Namentlich:
grundlegende Funktionen | |
/Text | Textdarstellung |
/ImageB | Graustufenbilder |
/ImageC | Farbbilder |
/ImageI | Bilder mit Farbpalette |
Ursprünglich war dies dazu gedacht, dass der Interpreter die entsprechenden Funktionen nur bei Bedarf laden muss. Inzwischen hat man diesen Ansatz aber aufgegeben, und ein PDF 1.4 kompatibler Interpreter sollte die Angabe ignorieren. Aus Kompatibilitätsgründen muss sie trotzdem geschrieben werden. Adobe empfiehlt inzwischen, einfach alle Kategorien zu aufzulisten, unabhängig vom tatsächlichen Inhalt der Datei.
/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
Die verwendeten Schriften müssen in einem Resourceneintrag /Font
aufgeführt werden. Dabei handelt es sich um ein Unterdictionary, in dem jede Schrift einen Eintrag hat. Als Name dient der künftig intern verwendete Schriftname; Usus ist ein F
, gefolgt von einer Nummer. Als Wert gibt man eine Referenz auf das Schriftobjekt an. Dieses enthält genauere Angaben. Zu den Schriftobjekten kommen wir im nächsten Kapitel.
Hier ein kleines Beispiel mit drei Schriften, die nacheinander in den Objekten 4 – 6 stehen:
/Font << /F1 4 0 R /F2 5 0 R /F3 6 0 R >>
X-Objekte sind zusätzliche Objekte, die in eine Seite eingebunden werden können. Am häufigsten braucht man sie zum Einbinden von Bildern. Wir werden im entsprechenden Kapitel darauf eingehen. Die X-Objekte müssen in einem Resourceneintrag /XObject
, welcher ein Unterdictionary enthält, gelistet sein. Ähnlich wie beim Fontdictionary enthält dieses Unterdictionary jeweils einen internen Namen gefolgt von einer Referenz auf das eigentliche X-Objekt.
/XObject << /I1 7 0 R >>
Enthält ein Dokument keine X-Objekte, so lässt man diesen Resourceneintrag einfach weg.
Wir wissen nun, wie wir die Seitenparameter angeben, aber nicht wo. Dies geschieht in den Seiten- und Seitenbereichsobjekten. Typischerweise gibt es ein Seitenbereichsobjekt, welches das gesamte Dokument abdeckt, und ein Seitenobjekt pro Einzelseite. Es können aber auch Unterbereiche definiert werden.
Sowohl Seiten- wie auch Seitenbereichsobjekte können /MediaBox
und /Resources
Einträge haben, wobei sie allenfalls übergeordnete Objekte übersteuern. So ist es recht leicht möglich, z.B. eine Seitengrösse für das gesamte Dokument vorzugeben, aber für einzelne Seiten oder Bereiche eine andere Grösse zu verwenden.
Pro Dokument hat es genau ein Katalogobjekt, welches ein indirektes Objekt und Dictionary ist. Es verweist auf das oberste Seitenbereichsobjekt (siehe unten). In der einfachsten Form hat es genau zwei Einträge:
/Type | immer /Catalog |
---|---|
/Pages | Referenz auf den obersten Seitenbereich |
Beispiel:
2 0 obj << /Type /Catalog /Pages 3 0 R >> endobj
Der /Root
Eintrag des Trailers muss auf das Katalogobjekt verweisen.
Dies sind immer indirekte Objekte und Dictionaries. Davon muss es mindestens eines geben, welches das gesamte Dokument umfasst. Dieses Seitenbereichsobjekt wird vom Katalogobjekt referenziert. Das Gesamtdokument, die allfälligen Unterbereiche und die Einzelseiten sind streng hierarchisch organisiert. Es kann also keine sich überschneidenden Unterbereiche geben.
Das Dictionary enthält die Seitenparameter für den Bereich. Diese müssen nicht angegeben werden, falls sie weiter oben oder unten in der Hierarchie schon definiert sind. Zusätzlich zu den Seitenparametern sind folgende Dictionaryeinträge nötig:
/Type | immer /Pages |
---|---|
/Kids | Array von Referenzen auf die direkt untergeordneten Seiten- und Seitenbereichsobjekte |
/Count | Anzahl der Einzelseiten (nicht Unterobjekte!) in diesem Bereich |
Für Unterbereiche kommt ein weiterer Eintrag hinzu:
/Parent | Referenz auf das übergeordnete Seitenbereichsobjekt |
---|
Hier ein kleines Beispiel für ein Seitenbereichsobjekt in einem Dokument mit drei Seiten und ohne Unterbereiche:
3 0 obj << /Type /Pages /MediaBox [0 0 595.276 841.89] /Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /Font << /F1 4 0 R >> >> /Kids [10 0 R 12 0 R 14 0 R] /Count 3 >> endobj
Auch dies sind immer indirekte Objekte und Dictionaries.
Das Seitenobjekt enthält die Seitenparameter für die Einzelseite. Diese müssen nicht angegeben werden, wenn sie bereits in einem übergeordneten Bereich definiert wurden. Zusätzlich sind folgende Dictionaryeinträge nötig:
/Type | immer /Page |
---|---|
/Parent | Referenz auf das übergeordnete Seitenbereichsobjekt |
/Contents | Referenz auf den Seiteninhalt |
Der /Contents
Eintrag kann weggelassen werden. In dem Fall gilt die Seite als Leerseite.
Hier zwei Beispiele für Pages-Objekte, wovon das erste die übergeordneten Seitenparameter übernimmt, während das zweite für diese Seite auf A4-quer umstellt:
10 0 obj << /Type /Page /Parent 3 0 R /Contents 11 0 R >> endobj
12 0 obj << /Type /Page /Parent 3 0 R /MediaBox [0 0 841.89 595.276] /Contents 13 0 R >> endobj
Diskussion