Opacity, mixing, and what a press asks for
Declare a painting setting — opacity, blend mode, overprinting, halftone screen — then apply it to shapes by its name.
Summary
A highlighter lets the text below show through: the colour does not hide, it mixes. Sixteen ways of mixing exist here, the ones drawing software uses — multiply, lighten, difference — and each of them can be dialled down to half strength, or to a tenth, so a shape sits over the page rather than on top of it. The same setting states what a printing works asks for and no screen ever shows: whether an ink lies over the one already on the sheet or wipes it off, how fine the grid of dots is and which way it is turned, how colours the press cannot hold are brought into what it can, and the curve the tone is bent through on its way to the machine.
Technically
Written at the top level of a request, under
"graphics_states"
graphics_states declares each /ExtGState the document defines for itself, under the name a drawn shape applies it by: the opacity for filling, the one for stroking, the blend mode, the mask what it paints is seen through, what those opacities and that mask state, what the letters of one block of text do to each other where they overlap, the overprinting and what a component of zero means under it, the rendering intent and the black point, the stroke adjustment, how finely a curve and a gradient are laid down, the transfer curve, the halftone screen and where it is anchored. The dictionary is written once however many shapes apply it, and it lasts as long as the shape that named it and no longer. Only what it names is written: a state naming an opacity and nothing else leaves everything else as it stands.
Request schema
-
graphics_states— array, optional, empty by default. -
graphics_states[].name— string, required. The name items apply this state by. -
graphics_states[].state— object, required. -
state.fill_alpha— number from 0 to 1, optional. The opacity every fill is painted at: 0 lets everything through, 1 covers. -
state.stroke_alpha— number from 0 to 1, optional. The opacity every stroke is painted at. Fill and stroke are said apart: a shape half transparent outside and whole inside names both. -
state.blend_mode— string, optional. Sixteen values:normal,multiply,screen,overlay,darken,lighten,color_dodge,color_burn,hard_light,soft_light,difference,exclusion,hue,saturation,color,luminosity. The first twelve mix each channel on its own, the last four take a whole colour at a time. -
state.alpha_is_shape— boolean, optional. Whether the two opacities and the mask say how much of a point is covered rather than how opaque the paint on it is. A shape painted straight onto the page comes out the same either way. The two readings part inside a knockout group: false, an opacity of 0.4 wipes out what an earlier mark put down and paints four tenths of its colour instead; true, a coverage of 0.4 keeps six tenths of the earlier mark. -
state.text_knockout— boolean, optional. Whether the letters of one text object are composited as a single object: true, a letter laid over an earlier letter of the same text object knocks it out and the overlap is painted once; false, each letter is composited on its own and the overlap keeps both. Atextblock writes its letters as one text object, its shadow as another and, tagged, one text object per paragraph; atext_pathwrites each letter as a text object of its own. -
state.overprint— boolean, optional. Whether a stroke and a fill both leave the inks already on the sheet where they are, rather than wiping them off. Naming it besidestate.stroke_overprintorstate.fill_overprintis refused: the two say one thing twice. -
state.stroke_overprint— boolean, optional. Whether a stroke leaves the inks already on the sheet where they are. -
state.fill_overprint— boolean, optional. Whether a fill does. Name these two where a shape overprints on one side and not the other, andstate.overprintwhere it does on both. -
state.overprint_mode— string, optional. What a component of zero means while overprinting. Two values:erase_zero, every component laid down as it is given, so a zero wipes that ink off the sheet;keep_zero, a zero leaving that ink as it was found and only the other components laid down.keep_zerois what lets black type with no cyan, magenta or yellow overprint a coloured ground rather than knock a hole in it. -
state.rendering_intent— string, optional. How colours the destination cannot hold are brought into what it can. Four values:absolute_colorimetric, every colour kept exactly, white included, and what will not fit clipped;relative_colorimetric, every colour kept exactly but all of them moved so that the picture's white is the paper's white;saturation, colours kept vivid rather than exact, which is what a chart wants;perceptual, every colour moved, those that would fit included, so that the relations between them survive, which is what a photograph wants. -
state.black_point_compensation— string, optional. Whether a conversion takes the darkest tone of the source into account. Three values:reader, the reading software decides, which is what saying nothing does as well;on, the darkest tone is taken into account;off, it is left out. -
state.stroke_adjustment— boolean, optional. Whether a stroke too thin to cover a whole device pixel is widened to one rather than left to fade. It is what keeps a hairline rule even across a page. -
state.flatness— number from 0 to 100, optional. The furthest a curve laid down as straight segments may fall from the curve itself, in device pixels. 0 asks the device for its own; a smaller number is a smoother curve and more segments to lay down. A number outside that range is refused,400. -
state.smoothness— number from 0 to 1, optional. The largest error a gradient may be laid down with, as a fraction of the range of a colour component. A smaller number is a finer gradient and more of the device's time spent laying it down. A number outside that range is refused,400. -
state.mask— object, optional. A declared drawing composited apart from the page and read as a coverage rather than shown: where it lets everything through, what the state paints goes down whole; where it stops everything, nothing does. Four keys:state.mask.drawing— string, required. The name of the declared drawing the mask is made of.state.mask.read— string, optional,luminosityby default. What is read off that drawing:luminosity, how light it came out, white letting everything through and black stopping it; oralpha, how opaque it came out whatever colour it was painted in. A shape painted black at half opacity is dark and half clear, so the two answers differ.state.mask.space— string, optional, one ofgray,rgborcmyk. The device space the drawing is composited in, for a mask read by light. Absent composites it in the three lights.state.mask.backdrop— array of numbers, optional, one per component ofstate.mask.space. The colour everything outside the drawing's box counts as. Absent leaves it black, which for a mask read by light stops everything outside that box. A mask read by opacity ignores it.
-
state.transfer— optional. The curve the tone a colour asks for is bent through on its way to the device it is laid down on. The curve maps 0 to 1 onto itself and is read by the device alone: nothing of it shows on a display. Each curve is the same function object a gradient is built on. Three shapes:"page"— the curve the page began with, kept as it stands.{"every": {…}}— one curve, read for every process ink.{"per_ink": [{…}, {…}, {…}, {…}]}— four curves, in the order cyan, magenta, yellow, black.
-
state.halftone— optional. The screen a tone is laid down through. None of it shows on a display. Two shapes:{"every": {…}}— one screen, laid down through for every ink.{"per_ink": {"inks": […], "default": {…}}}—inks, an array with one entry per named ink, each with acolorant, the ink's name as the press knows it and as aseparationspace states it, and ascreen; anddefault, the screen every ink the list does not name is laid down through. Both are required insideper_ink.
-
A screen has four keys:
screen.frequency— number, required. How many cells to the inch the grid of dots runs to.screen.angle— number, required. How many degrees counterclockwise the grid is turned. Plates laid down through one angle print on top of one another, so a press turns each ink to its own.screen.spot— string, required. The shape a dot grows into as the tone darkens.screen.accurate— boolean, optional,falseby default. Whether the device is asked for the precise screening algorithm rather than the ordinary one.
-
screen.spottakes one of twenty-one values. Round dots:simple_dot,inverted_simple_dot,double_dot,inverted_double_dot,cosine_dot,double,inverted_double,round. Lines:line,line_x,line_y. Ovals:ellipse,ellipse_a,inverted_ellipse_a,ellipse_b,ellipse_c,inverted_ellipse_c. Angular shapes:square,cross,rhomboid,diamond. A name ending in a letter is a second, third or fourth oval shape; a name opening oninverted_grows out of the corners of the cell inwards rather than out of its middle. -
state.halftone_origin— array of two numbers, optional. The point the grid of dots is anchored at, in the coordinates in force where the state is applied: the grid is laid out from there on the device, and a later change of coordinates does not move it. The entry arrived with PDF 2.0, so a state naming it needs"version": "2.0", and a document stating an older one is refused,400. -
A
path,rect,textortext_pathitem applies a state through itsgraphics_statekey.
A whole request that creates a PDF
{
"version": "2.0",
"drawings": [
{
"name": "window",
"box": { "llx": 140, "lly": 660, "urx": 280, "ury": 750 },
"items": [
{
"type": "rect",
"rect": { "llx": 140, "lly": 660, "urx": 210, "ury": 750 },
"fill": [1, 1, 1]
}
]
}
],
"graphics_states": [
{
"name": "half",
"state": {
"mask": { "drawing": "window", "read": "alpha" },
"fill_alpha": 0.5,
"blend_mode": "multiply",
"alpha_is_shape": false,
"text_knockout": true,
"rendering_intent": "relative_colorimetric",
"black_point_compensation": "on",
"overprint_mode": "erase_zero",
"flatness": 1,
"smoothness": 0.02,
"transfer": "page",
"halftone": {
"every": { "frequency": 60, "angle": 45, "spot": "round" }
},
"halftone_origin": [12, 24]
}
}
],
"items": [
{
"type": "rect",
"rect": { "llx": 60, "lly": 700, "urx": 200, "ury": 790 },
"fill": [0.85, 0.15, 0.15]
},
{
"type": "rect",
"rect": { "llx": 140, "lly": 660, "urx": 280, "ury": 750 },
"fill": [0.15, 0.3, 0.85],
"graphics_state": "half"
}
]
}
Colour and how it is shown
The device the colours are stated for Which plate of a separated sheet a page is The device one page's colours are stated for Declaring colour beyond red, green and blue What a page's bare numbers mean A colour sliding into another A cell repeated to fill a shape The space a page mixes its colours in
Where to go next
Every JSON key of a request, in one page The other forty-one settings of a request