Learning Drawing a page

Graphics state

1.4 §4.31.7 §8.4

The painting operators take only geometry. S strokes the current path without being told a color or a width: it uses whatever the graphics state holds at that moment. The graphics state is the reader's current settings for transformation, clip, color, line style, font and opacity. Operators like rg, w and cm each change one setting, which stays in effect until something changes it again. The model comes from PostScript, where q and Q are called gsave and grestore.

0 0 1 RG 4 w               % blue, 4 wide, from here on
72 700 m 272 700 l S       % a blue line
q
1 0 0 RG [6 3] 0 d         % red and dashed, until Q
1 0 0 1 0 -40 cm           % and moved down 40
72 700 m 272 700 l S       % a red dashed line, drawn at y = 660
Q
72 620 m 272 620 l S       % blue and solid again, still 4 wide

What it holds

The spec splits the parameters in two. Device-independent ones affect what you see on any output. Device-dependent ones fine-tune a particular printer or screen, and most files never set them.

KindParameterSet withInitial value
Device-independentCurrent transformation matrix (CTM)cmDefault user space: 1/72-inch units, y up
Clipping pathW W*The whole page
Color space, stroking and nonstrokingCS cs, or G g RG rg K kDeviceGray
Color, stroking and nonstrokingSC SCN sc scn G g RG rg K kBlack
Text state: font and size, spacing, scaling, leading, rendering mode, riseTf Tc Tw Tz TL Tr Ts; /FontNo font; scaling 100, the rest 0
Line width, cap, join, miter limit, dashw J j M d; /LW /LC /LJ /ML /D1, butt, miter, 10, solid
Rendering intentri; /RIRelativeColorimetric
Stroke adjustment/SAOff
Transparency: blend mode, soft mask, alpha, alpha source 1.4/BM /SMask /CA /ca /AISNormal, None, 1, off
Device-dependentOverprint and overprint mode/OP /op /OPMOff, 0
Black generation, undercolor removal/BG /BG2 /UCR /UCR2The device's own
Transfer function, halftone/TR /TR2 /HTThe device's own
Flatness, smoothnessi; /FL /SM1; the device's own

Names with a slash are keys in an ExtGState dictionary.

The graphics state stack

q pushes a copy of the whole graphics state onto a stack, and Q pops the most recent copy and makes it current again. Pairs nest. They must balance within a content stream, or across a page's /Contents array taken together, and they can't appear inside BT … ET.

A clip can only get smaller, so Q is the only way back to a larger one. cm only ever multiplies onto the CTM, so writers wrap it in q … Q rather than undo it with the inverse matrix.

Parameters without an operator: ExtGState

About half the parameters have no operator of their own. They are set from a graphics state parameter dictionary, a named entry in the /ExtGState resources, applied with gs (PDF 1.2). A dictionary changes only the parameters it has keys for. Some keys repeat an operator: /LW is w, and /Font [font size] is Tf. The rest are the only way to set overprint, transparency, stroke adjustment and the device-dependent parameters.

% Resources: /ExtGState << /GS0 << /LW 2 /LC 1 /OP true /op true >> >>
q
/GS0 gs                    % the same as "2 w 1 J", plus overprint, which no operator sets
72 600 200 100 re S
Q

What starts fresh, and what carries over

  • Each page starts from the initial values. Nothing set on one page carries over to the next. Within a page, a /Contents array is read as one stream, so the state carries across the joins.
  • A form XObject inherits the state at its Do. Do saves the state as q would, multiplies the form's /Matrix onto the CTM, clips to its /BBox, runs its content stream, then restores the state as Q would. A form that never sets a color paints in the caller's color, and nothing it sets leaks out.
  • Text state is part of the graphics state; the text matrix isn't. The font, spacing and rendering mode outlast ET. The text matrix exists only inside a text object and is reset by every BT.
  • The current path isn't part of it either. A path has to be painted, or ended with n, before any state operator can run.

Read: 1.4 §4.31.7 §8.4 Form XObjects: 1.4 §4.91.7 §8.10

Gotcha when adding to an existing page: its content may end with a cm, a clip or a color still in effect, and anything you append is drawn under it. Wrap the original first: add a stream holding q before it in /Contents and one holding Q after it. If the original leaves some q unmatched, close each with an extra Q. Or turn the original content into a form XObject and paint it with Do, which saves and restores the state for you.
Q1. Which of these is not saved and restored by q and Q?
The clipping pathThe text matrixThe fill colorThe font set with Tf
Check
Q2. A form XObject's content stream never sets a fill color. What color do its fills come out in?
Black, the initial valueWhatever fill color was current at its DoThe color named in its /ResourcesNone: unset fills aren't painted
Check
Q3. Which of these can only be set through an ExtGState dictionary and gs?
Line widthFill colorFont and sizeOverprint
Check
Reset3 questions

Section references such as 1.4 §3.4 1.7 §7.5 are to the Adobe PDF Reference, third edition (PDF 1.4) and ISO 32000-1:2008 (PDF 1.7). Where to get them: PDF specifications.