Text- und Grafik-Operatoren im PDF-Content-Stream
Jede Linie, jedes Wort und jedes Bild auf einer PDF-Seite wird durch eine kleine, klar definierte Operator-Sprache erzeugt. Dieser Artikel geht die zentralen Befehle durch – die Text-Operatoren, die Grafik-Operatoren und die Transformationen, die alles in Position bringen – mit Schaubild zur Transformationsmatrix und konkreten Code-Beispielen.
Was ein Content Stream ist
Ein Content Stream
ist ein Bytefolge im Body einer
PDF-Datei, die beschreibt, was auf einer Seite zu sehen ist.
Eine Seite ( /Page
) verweist über /Contents
auf einen oder mehrere solcher Streams. Der
Inhalt eines Content Streams besteht aus einer Folge sehr kurzer Operatoren
– einer kleinen, klar spezifizierten
Befehlssprache, die im wesentlichen seit den frühen Tagen von PDF
stabil ist und in ISO 32000-2
Abschnitt 7.8
definiert wird.
Wer einen Content Stream das erste Mal sieht, erkennt vier Eigenschaften
sehr schnell: Befehle sind kurz
(oft nur ein oder zwei
Buchstaben), sie stehen nach
ihren Argumenten (Postfix-Notation),
jeder Befehl steht auf einer eigenen Zeile
, und Streams sind
in der Datei in der Regel komprimiert
( FlateDecode
) –
sichtbar werden sie erst nach Dekompression, z. B. mit qpdf --qdf
.
Operator-Syntax: Postfix in Kleinbuchstaben
Die Operator-Sprache erinnert an PostScript, ist aber deutlich kleiner und deklarativ: Es gibt keine Schleifen, keine if-Konstrukte, keine Variablen. Alles ist eine Folge von Befehlen , jeder Befehl konsumiert Argumente, die unmittelbar davor stehen.
Eine Konvention der Spezifikation: Operatoren sind durchgängig kleingeschrieben
, wenn sie auf Strokes(Konturen) wirken, und großgeschrieben
für die Fill-Variante. s
schließt einen Pfad
und zeichnet ihn nach; S
zeichnet nur die Kontur ohne
Schließen; f
füllt einen Pfad; B
macht beides.
Diese kleine Konvention vereinfacht das Lesen.
Der Graphics-State und seine Stack-Operatoren (q/Q)
Operatoren wirken nicht direkt auf die Seite, sondern auf einen Graphics-State: einen Zustand mit Eigenschaften wie aktuelle Schrift, Strichbreite, Farbe, Text-Matrix und Transformationsmatrix. Die Spec spricht von CTM – der Current Transformation Matrix.
Zwei Operatoren machen den Graphics-State stack-fähig:
-
q(für „save" – kommt vom englischen quit-restoring , ist aber faktisch eine Push-Operation): sichert den aktuellen Graphics-State auf einem internen Stack. -
Q(für „restore"): stellt den zuletzt gesicherten Zustand wieder her und entfernt ihn vom Stack.
Das Muster ist immer dasselbe: lokale Änderungen zwischen q
und Q
einklammern, damit sie nichts
Nachfolgendes beeinflussen.
Text-Operatoren: BT, Tf, Td, Tj, Tm
Text wird auf einer PDF-Seite ausschließlich innerhalb von Text-Objekten
gezeichnet, eingeleitet durch BT
( Begin Text
) und beendet durch ET
( End Text
). Dazwischen gilt eine zusätzliche
Zustands-Schicht: die Text-Matrix
und der Text-State.
Die wichtigsten Text-Operatoren im Überblick
| Operator | Argumente | Wirkung |
|---|---|---|
BT
· ET
|
– | Beginn / Ende eines Text-Objekts. Außerhalb dieser Klammer sind Text-Operatoren ungültig. |
Tf
|
name size
|
Schrift wählen (über Resource Name /F1
u. a.) und Größe in Punkt setzen. |
Td
|
tx ty
|
Textposition relativ zur Zeilenstart-Position verschieben. |
Tm
|
a b c d e f
|
Text-Matrix setzen – legt Drehung, Scherung, Skalierung und Position des Texts fest. |
Tj
|
(string)
|
Zeichenkette zeichnen. |
TJ
|
[array]
|
Array aus Strings und Zahlen; Zahlen erzeugen Kerning-Verschiebungen. |
T*
|
– | In die nächste Zeile springen (auf Basis des Leading-Werts). |
Grafik-Operatoren: m, l, c, re, S, f
Linien, Kurven und Flächen werden über Pfad-Konstruktion und anschließendes Painten erzeugt. Pfad-Operatoren bauen einen Pfad auf; Paint-Operatoren realisieren ihn als sichtbares Stroke, Fill oder beides.
| Operator | Argumente | Wirkung |
|---|---|---|
m
|
x y
|
Pfad-Startpunkt setzen ( moveto ). |
l
|
x y
|
Linie vom aktuellen Punkt zu (x, y) ziehen ( lineto ). |
c
|
x1 y1 x2 y2 x3 y3
|
Kubische Bézier-Kurve mit zwei Kontrollpunkten zu (x3, y3). |
re
|
x y w h
|
Rechteck als geschlossenen Sub-Pfad anlegen (linke untere Ecke + Größe). |
h
|
– | Aktuellen Sub-Pfad schließen. |
S
|
– | Pfad als Kontur zeichnen (Stroke). |
f
|
– | Pfad füllen (Fill). |
B
|
– | Pfad füllen und Kontur zeichnen. |
n
|
– | Pfad ohne Zeichnen abschließen (z. B. für Clipping). |
Transformationen und die Matrix cm
Die wichtigste Brücke zwischen Operatoren und Seiten-Geometrie ist die Current Transformation Matrix, kurz CTM. Sie
legt fest, wie Koordinaten der nachfolgenden Operatoren in den
Seitenraum übersetzt werden. Der Operator cm
erweitert
die CTM um eine neue Transformation ( concatenate matrix
).
In PDF wird jede Transformation als 2D-Affintransformation in einer 3×3-Matrix dargestellt – die letzte Spalte ist immer fixiert. Sechs Zahlen a b c d e f reichen, um sie vollständig zu beschreiben:
0.866 0.5 -0.5 0.866 0 0 cm
. Translation in derselben
Matrix erfolgt über e
und f.Wer eine Drehung mit Verschiebung kombinieren möchte, fügt Translation
über e
und f
direkt in dieselbe Matrix ein. Wer
mehrere Transformationen hintereinander braucht, ruft mehrfach cm
auf – jeder Aufruf verkettet die neue Transformation
mit der bestehenden CTM (Matrix-Multiplikation, von rechts).
Marked Content: die Brücke zur Barrierefreiheit
Inhalte werden barrierefrei nutzbar, indem ihre Bedeutung über den Struktur-Baum einer PDF erschlossen wird. Verknüpft werden Struktur-Baum und Content Stream über Marked-Content-Sequenzen. Im Content Stream gibt es dafür drei Operatoren:
-
BDC– Begin marked-content with Dictionary : eröffnet einen markierten Bereich mit Tag (z. B./P) und einer Eigenschaft, die typischerweise eine MCID enthält. -
EMC– End Marked Content : schließt den zuletzt geöffneten Bereich. -
BMC– wieBDC, aber ohne Properties-Dictionary. Wird selten für Tagging verwendet.
Der Struktur-Baum verweist über die MCID auf genau diese Sequenz und
gibt ihr eine semantische Rolle (hier: einen Absatz, /P
).
Ohne diese Verbindung würden Reader und Assistive-Technologie zwar
sehen, dass dort Text gezeichnet wird – aber nicht, was er bedeutet.
Damit liegt die strukturelle Erklärung von Barrierefreiheit im
Format: Operator-Schicht zeichnet, Tag-Schicht bedeutet, Marked
Content verbindet.
Drei Missverständnisse über den Content Stream
„Text in einer PDF ist Unicode-Text."
In der Regel
nicht. Tj
und TJ
zeichnen Glyphen
, deren Bedeutung über die Schrift-Ressource
festgelegt ist. Erst der /ToUnicode
-Eintrag der Schrift
bringt eine zuverlässige Rückabbildung auf Unicode-Zeichen. Fehlt
dieser Eintrag, ist Text-Extraktion und Vorlesen unzuverlässig –
auch wenn die Datei optisch perfekt aussieht.
„Eine Drehung erreicht man mit einem einzigen Operator."
Es gibt keinen dedizierten Rotations-Operator. Drehung wird
ausschließlich über die Matrix cm
(oder für Text über Tm
) erreicht – mit den Werten cos α · sin α · -sin α · cos α · 0 · 0
.
„Tagging passiert nach dem Zeichnen, also nachträglich."
Korrekt ist: Tagging passiert parallel
zum Zeichnen –
im selben Content Stream, durch BDC
/ EMC
.
Nachträgliche Tagging-Tools rekonstruieren diese Klammerung
rückwärts, was selten so sauber gelingt wie eine gleich richtig
getaggte Erstausgabe.
Was du daraus mitnimmst
Drei Punkte, die das Lesen jedes Content Streams erleichtern:
- Postfix-Notation, kleine Operator-Sprache, kein Kontrollfluss. Jeder Befehl verbraucht die unmittelbar davor liegenden Argumente, endet die Zeile – und ändert entweder den Graphics-State oder zeichnet etwas.
- Alles, was kein Text ist, ist Pfad-Konstruktion + Painten.
Linien, Rechtecke und Kurven werden mit
m,l,coderreaufgebaut und mitS,foderBrealisiert. - Transformationen sind sechs Zahlen. Wer a b c d e f cm versteht, versteht Position, Skalierung, Rotation und Scherung in PDF. Translation steckt im letzten Zahlenpaar, Drehung im Rest.
Wer diese Schicht beherrscht, kann nicht nur PDF-Inhalte lesen, sondern auch gezielt schreiben – und versteht, was beim Tagging strukturell passieren muss, damit eine PDF aus Coding-Sicht tatsächlich barrierefrei wird.
Eigenes PDF-Tooling sauber bauen?
Wir begleiten Entwicklungsteams beim Aufbau eigener PDF-Pipelines – von der Operator-Ebene über sauberes Marked Content bis zum vollständigen Struktur-Baum nach PDF/UA. Workshops, Code-Reviews und Audits aus einer Hand.
Beratung oder Schulung anfragen
