BT /F1 12 Tf 72 720 Td (Hello) Tj ET means, this guide explains exactly that.
Understanding content streams is essential for: debugging PDF rendering issues; building PDF generation tools; analysing malicious PDFs; understanding why text extraction sometimes produces wrong results; and working with low-level PDF manipulation. The content stream model is also how all PDF accessibility, layer, and graphics state machinery works — marked content sequences, graphics state saves/restores, and XObject references are all content stream constructs.Content stream syntax and operator categories
72 720 Td means "move text position to (72, 720) using operator Td".
Text operators — The BT (Begin Text) / ET (End Text) pair brackets all text painting operations:
- /F1 12 Tf — Select font named F1 at 12pt
- 72 720 Td — Move text position to x=72, y=720
- (Hello world) Tj — Paint string "Hello world"
- [(Hello) -250 (world)] TJ — Paint string with kerning adjustments (negative = tighter)
- 0 1 Tc Tw — Set character spacing and word spacing
Path operators — For vector graphics:
- m — Move to (start new subpath)
- l — Line to
- c / v / y — Bezier curves (cubic, with first/last handle on current point)
- re — Rectangle (shorthand for four line operations)
- S / s — Stroke path / close and stroke
- f / F / f* — Fill path (nonzero / nonzero / even-odd winding rule)
- B / b — Fill and stroke / close, fill and stroke
- n / W / W* — No paint (end path without painting) / clip to path
Graphics state operators:
- q / Q — Save / restore graphics state (push/pop the state stack)
- cm — Concatenate matrix (modify current transformation matrix)
- w — Line width
- J / j / M — Line cap / join / miter limit
- d — Dash pattern
- gs — Set graphics state parameters from a named ExtGState resource
Colour operators:
- CS / cs — Set stroke / fill colour space
- SC / sc — Set stroke / fill colour values
- G / g — Set grey stroke / fill (shorthand for DeviceGray)
- RG / rg — Set RGB stroke / fill
- K / k — Set CMYK stroke / fill
- ri — Rendering intent
XObject operator:
- /Im0 Do — Draw (invoke) named XObject Im0 from the resource dictionaryThe graphics state stack
q saves the current state and Q restores the most recently saved state.
The graphics state includes:
- CTM (Current Transformation Matrix) — A 6-element matrix [a b c d e f] mapping user-space coordinates to device coordinates. Initially maps PDF user units (1/72 inch) to device pixels.
- Clipping path — The current clip region; only content within this path is rendered.
- Stroke colour — Used by S, s, B, b operators
- Fill colour — Used by f, F, f*, B, b operators
- Line width, cap, join, dash — Control stroke appearance
- Font and font size — Set by Tf
- Text state — Character spacing (Tc), word spacing (Tw), horizontal scaling (Tz), leading (TL), text rise (Ts), text rendering mode (Tr 0–7 — fill, stroke, fill+stroke, invisible, etc.)
- Alpha (opacity) — The current alpha constant for transparency compositing
- Blend mode — How painted content composites with what is behind it
The q/Q pattern is used extensively for temporary state changes: change colour, paint content, restore the previous colour. Without Q, changes accumulate and affect subsequent operations unexpectedly — a common source of content stream bugs.Reading and debugging content streams
qpdf --qdf --object-streams=disable input.pdf output.qdf produces a human-readable PDF with all streams decompressed and objects on individual lines.
Python with pikepdf:
import pikepdf
pdf = pikepdf.open("input.pdf")
page = pdf.pages[0]
stream = page["/Contents"]
print(stream.read_bytes().decode("latin-1"))
pdftk: pdftk input.pdf output output.pdf uncompress decompresses content streams.
Common content stream problems:
Unbalanced q/Q — Every q must have a matching Q. Unbalanced saves/restores cause rendering state to leak between operations, producing unexpected colours, transforms, or clip regions on subsequent objects or pages.
Missing resource references — If the content stream references /F1 but the page's /Resources /Font dictionary has no /F1 entry, the viewer may substitute a default font or produce an error.
Coordinate system confusion — PDF's default coordinate origin is bottom-left, with y increasing upward. Most document formats (HTML, Word) use top-left origin with y increasing downward. Content streams generated by tools that use screen coordinates may appear flipped. The cm operator or a reflected CTM can re-orient the coordinate system.
Text extraction order — Text operators in the content stream are not required to appear in reading order. They may be placed in any order for rendering efficiency. Screen readers and text extraction tools must sort by position or rely on the structure tree to determine reading order.