1 PDF Theory of Operation 2 ======================= 3 4 <!-- 5 PRE-GIT DOCUMENT VERSION HISTORY 6 2012-06-25 Steve VanDeBogart 7 * Original version 8 2015-01-14 Hal Canary. 9 * Add section "Using the PDF backend" 10 * Markdown formatting 11 --> 12 13 14 Internally, SkPDFDocument and SkPDFDevice represents PDF documents and 15 pages. This document describes how the backend operates, but **these 16 interfaces are not part of the public API and are subject to perpetual 17 change.** 18 19 See [Using Skia's PDF Backend](../../user/sample/pdf) to find out how 20 to use SkPDF as a client calling Skia's public API. 21 22 * * * 23 24 ### Contents ### 25 26 * [Typical usage of the PDF backend](#Typical_usage_of_the_PDF_backend) 27 * [PDF Objects and Document Structure](#PDF_Objects_and_Document_Structure) 28 * [PDF drawing](#PDF_drawing) 29 * [Interned objects](#Interned_objects) 30 * [Graphic States](#Graphic_States) 31 * [Clip and Transform](#Clip_and_Transform) 32 * [Generating a content stream](#Generating_a_content_stream) 33 * [Drawing details](#Drawing_details) 34 + [Layers](#Layers) 35 + [Fonts](#Fonts) 36 + [Shaders](#Shaders) 37 + [Xfer modes](#Xfer_modes) 38 * [Known issues](#Known_issues) 39 40 41 <span id="Typical_usage_of_the_PDF_backend">Typical usage of the PDF backend</span> 42 ----------------------------------------------------------------------------------- 43 44 SkPDFDevice is the main interface to the PDF backend. This child of 45 SkDevice can be set on an SkCanvas and drawn to. Once drawing to 46 the canvas is complete (SkDocument::onEndPage() is called), the 47 device's content and resouces are added to the SkPDFDocument that owns 48 the device. A new SkPDFDevice should be created for each page or 49 layer desired in the document. After all the pages have been added to 50 the document, `SkPDFDocument::onClose()` is called to finish 51 serializing the PDF file. 52 53 54 <span id="PDF_Objects_and_Document_Structure">PDF Objects and Document Structure</span> 55 --------------------------------------------------------------------------------------- 56 57 ![PDF Logical Document Structure](/dev/design/PdfLogicalDocumentStructure.png) 58 59 **Background**: The PDF file format has a header, a set of objects and 60 then a footer that contains a table of contents for all of the objects 61 in the document (the cross-reference table). The table of contents 62 lists the specific byte position for each object. The objects may have 63 references to other objects and the ASCII size of those references is 64 dependent on the object number assigned to the referenced object; 65 therefore we can't calculate the table of contents until the size of 66 objects is known, which requires assignment of object numbers. The 67 document uses SkWStream::bytesWritten() to query the offsets of each 68 object and build the cross-reference table. 69 70 Furthermore, PDF files can support a *linearized* mode, where objects 71 are in a specific order so that pdf-viewers can more easily retrieve 72 just the objects they need to display a specific page, i.e. by 73 byte-range requests over the web. Linearization also requires that all 74 objects used or referenced on the first page of the PDF have object 75 numbers before the rest of the objects. Consequently, before 76 generating a linearized PDF, all objects, their sizes, and object 77 references must be known. Skia has no plans to implement linearized 78 PDFs. 79 80 %PDF-1.4 81 objects... 82 xref 83 0 31 % Total number of entries in the table of contents. 84 0000000000 65535 f 85 0000210343 00000 n 86 87 0000117055 00000 n 88 trailer 89 <</Size 31 /Root 1 0 R>> 90 startxref 91 210399 % Byte offset to the start of the table of contents. 92 %%EOF 93 94 The the virtual class SkPDFObject are used to 95 manage the needs of the file format. Any object that will represent a 96 PDF object must inherit from SkPDFObject and implement the methods to 97 generate the binary representation and report any other SkPDFObjects 98 used as resources. SkPDFTypes.h defines most of the basic PDF object 99 types: bool, int, scalar, string, name, array, dictionary, and stream. 100 (A stream is a dictionary containing at least a Length entry followed 101 by the data of the stream.) 102 103 Streams are now handled in a slightly different way. The SkPDFStreamOut() 104 function compresses and serializes the binary data immediately instead of 105 creating a new object. 106 107 All of these PDF object types except the stream type can be used in 108 both a direct and an indirect fashion, i.e. an array can have an int 109 or a dictionary as an inline entry, which does not require an object 110 number. The stream type, cannot be inlined and must be referred to 111 with an object reference. Most of the time, other objects types can be 112 referred to with an object reference, but there are specific rules in 113 the PDF specification that requires an inline reference in some place 114 or an indirect reference in other places. All indirect objects must 115 have an object number assigned. 116 117 * **bools**: `true` `false` 118 * **ints**: `42` `0` `-1` 119 * **scalars**: `0.001` 120 * **strings**: `(strings are in parentheses or byte encoded)` `<74657374>` 121 * **name**: `/Name` `/Name#20with#20spaces` 122 * **array**: `[/Foo 42 (arrays can contain multiple types)]` 123 * **dictionary**: `<</Key1 (value1) /key2 42>>` 124 * **indirect object**: 125 `5 0 obj 126 (An indirect string. Indirect objects have an object number and a 127 generation number, Skia always uses generation 0 objects) 128 endobj` 129 * **object reference**: `5 0 R` 130 * **stream**: `<</Length 56>> 131 stream 132 ...stream contents can be arbitrary, including binary... 133 endstream` 134 135 Indirect objects are either: 136 137 - Serialized as soon as they are needed, and a new SkPDFIndirectReference is 138 returned, or 139 140 - Serialized later, but reserve a document-unique SkPDFIndirectReference to 141 allow other objects to refer to it. 142 143 Example document: 144 145 %PDF-1.4 146 2 0 obj << 147 /Type /Catalog 148 /Pages 1 0 R 149 >> 150 endobj 151 3 0 obj << 152 /Type /Page 153 /Parent 1 0 R 154 /Resources <> 155 /MediaBox [0 0 612 792] 156 /Contents 4 0 R 157 >> 158 endobj 159 4 0 obj <> stream 160 endstream 161 endobj 162 1 0 obj << 163 /Type /Pages 164 /Kids [3 0 R] 165 /Count 1 166 >> 167 endobj 168 xref 169 0 5 170 0000000000 65535 f 171 0000000236 00000 n 172 0000000009 00000 n 173 0000000062 00000 n 174 0000000190 00000 n 175 trailer 176 <</Size 5 /Root 2 0 R>> 177 startxref 178 299 179 %%EOF 180 181 182 <span id="PDF_drawing">PDF drawing</span> 183 ----------------------------------------- 184 185 Most drawing in PDF is specified by the text of a stream, referred to 186 as a content stream. The syntax of the content stream is different 187 than the syntax of the file format described above and is much closer 188 to PostScript in nature. The commands in the content stream tell the 189 PDF interpreter to draw things, like a rectangle (`x y w h re`), an 190 image, or text, or to do meta operations like set the drawing color, 191 apply a transform to the drawing coordinates, or clip future drawing 192 operations. The page object that references a content stream has a 193 list of resources that can be used in the content stream using the 194 dictionary name to reference the resources. Resources are things like 195 font objects, images objects, graphic state objects (a set of meta 196 operations like miter limit, line width, etc). Because of a mismatch 197 between Skia and PDFs support for transparency (which will be 198 explained later), SkPDFDevice records each drawing operation into an 199 internal structure (ContentEntry) and only when the content stream is 200 needed does it flatten that list of structures into the final content 201 stream. 202 203 4 0 obj << 204 /Type /Page 205 /Resources << 206 /Font <</F1 9 0 R>> 207 /XObject <</Image1 22 0 R /Image2 73 0 R>> 208 >> 209 /Content 5 0 R 210 >> endobj 211 212 5 0 obj <</Length 227>> stream 213 % In the font specified in object 9 and a height 214 % of 12 points, at (72, 96) draw Hello World. 215 BT 216 /F1 12 Tf 217 72 96 Td 218 (Hello World) Tj 219 ET 220 % Draw a filled rectange. 221 200 96 72 72 re B 222 ... 223 endstream 224 endobj 225 226 <span id="Interned_objects">Interned objects</span> 227 --------------------------------------------------- 228 229 There are a number of high level PDF objects (like fonts, graphic 230 states, etc) that are likely to be referenced multiple times in a 231 single PDF. To ensure that there is only one copy of each object, 232 the SkPDFDocument holds on to a mapping from type-specific keys onto the 233 SkPDFIndirectReference for these objects. 234 235 <span id="Graphic_States">Graphic States</span> 236 ----------------------------------------------- 237 238 PDF has a number of parameters that affect how things are drawn. The 239 ones that correspond to drawing options in Skia are: color, alpha, 240 line cap, line join type, line width, miter limit, and xfer/blend mode 241 (see later section for xfer modes). With the exception of color, these 242 can all be specified in a single pdf object, represented by the 243 SkPDFGraphicState class. A simple command in the content stream can 244 then set the drawing parameters to the values specified in that 245 graphic state object. PDF does not allow specifying color in the 246 graphic state object, instead it must be specified directly in the 247 content stream. Similarly the current font and font size are set 248 directly in the content stream. 249 250 6 0 obj << 251 /Type /ExtGState 252 /CA 1 % Opaque - alpha = 1 253 /LC 0 % Butt linecap 254 /LJ 0 % Miter line-join 255 /LW 2 % Line width of 2 256 /ML 6 % Miter limit of 6 257 /BM /Normal % Blend mode is normal i.e. source over 258 >> 259 endobj 260 261 <span id="Clip_and_Transform">Clip and Transform</span> 262 ------------------------------------------------------- 263 264 Similar to Skia, PDF allows drawing to be clipped or 265 transformed. However, there are a few caveats that affect the design 266 of the PDF backend. PDF does not support perspective transforms 267 (perspective transform are treated as identity transforms). Clips, 268 however, have more issues to cotend with. PDF clips cannot be directly 269 unapplied or expanded. i.e. once an area has been clipped off, there 270 is no way to draw to it. However, PDF provides a limited depth stack 271 for the PDF graphic state (which includes the drawing parameters 272 mentioned above in the Graphic States section as well as the clip and 273 transform). Therefore to undo a clip, the PDF graphic state must be 274 pushed before the clip is applied, then popped to revert to the state 275 of the graphic state before the clip was applied. 276 277 As the canvas makes drawing calls into SkPDFDevice, the active 278 transform, clip region, and clip stack are stored in a ContentEntry 279 structure. Later, when the ContentEntry structures are flattened into 280 a valid PDF content stream, the transforms and clips are compared to 281 decide on an efficient set of operations to transition between the 282 states needed. Currently, a local optimization is used, to figure out 283 the best transition from one state to the next. A global optimization 284 could improve things by more effectively using the graphics state 285 stack provided in the PDF format. 286 287 <span id="Generating_a_content_stream">Generating a content stream</span> 288 ------------------------------------------------------------------------- 289 290 For each draw call on an SkPDFDevice, a new ContentEntry is created, 291 which stores the matrix, clip region, and clip stack as well as the 292 paint parameters. Most of the paint parameters are bundled into an 293 SkPDFGraphicState (interned) with the rest (color, font size, etc) 294 explicitly stored in the ContentEntry. After populating the 295 ContentEntry with all the relevant context, it is compared to the the 296 most recently used ContentEntry. If the context matches, then the 297 previous one is appended to instead of using the new one. In either 298 case, with the context populated into the ContentEntry, the 299 appropriate draw call is allowed to append to the content stream 300 snippet in the ContentEntry to affect the core of the drawing call, 301 i.e. drawing a shape, an image, text, etc. 302 303 When all drawing is complete, SkPDFDocument::onEndPage() will call 304 SkPDFDevice::content() to request the complete content stream for the 305 page. The first thing done is to apply the initial transform specified 306 in part in the constructor, this transform takes care of changing the 307 coordinate space from an origin in the lower left (PDF default) to the 308 upper left (Skia default) as well as any translation or scaling 309 requested by the user (i.e. to achieve a margin or scale the 310 canvas). Next (well almost next, see the next section), a clip is 311 applied to restrict drawing to the content area (the part of the page 312 inside the margins) of the page. Then, each ContentEntry is applied to 313 the content stream with the help of a helper class, GraphicStackState, 314 which tracks the state of the PDF graphics stack and optimizes the 315 output. For each ContentEntry, commands are emitted to the final 316 content entry to update the clip from its current state to the state 317 specified in the ContentEntry, similarly the Matrix and drawing state 318 (color, line joins, etc) are updated, then the content entry fragment 319 (the actual drawing operation) is appended. 320 321 <span id="Drawing_details">Drawing details</span> 322 ------------------------------------------------- 323 324 Certain objects have specific properties that need to be dealt 325 with. Images, layers (see below), and fonts assume the standard PDF 326 coordinate system, so we have to undo any flip to the Skia coordinate 327 system before drawing these entities. We don't currently support 328 inverted paths, so filling an inverted path will give the wrong result 329 ([issue 241](https://bug.skia.org/241)). PDF doesn't draw zero length 330 lines that have butt of square caps, so that is emulated. 331 332 ### <span id="Layers">Layers</span> ### 333 334 PDF has a higher level object called a form x-object (form external 335 object) that is basically a PDF page, with resources and a content 336 stream, but can be transformed and drawn on an existing page. This is 337 used to implement layers. SkPDFDevice has a method, 338 makeFormXObjectFromDevice(), which uses the SkPDFDevice::content() 339 method to construct a form x-object from the the 340 device. SkPDFDevice::drawDevice() works by creating a form x-object of 341 the passed device and then drawing that form x-object in the root 342 device. There are a couple things to be aware of in this process. As 343 noted previously, we have to be aware of any flip to the coordinate 344 system - flipping it an even number of times will lead to the wrong 345 result unless it is corrected for. The SkClipStack passed to drawing 346 commands includes the entire clip stack, including the clipping 347 operations done on the base layer. Since the form x-object will be 348 drawn as a single operation onto the base layer, we can assume that 349 all of those clips are in effect and need not apply them within the 350 layer. 351 352 ### <span id="Fonts">Fonts</span> ### 353 354 There are many details for dealing with fonts, so this document will 355 only talk about some of the more important ones. A couple short 356 details: 357 358 * We can't assume that an arbitrary font will be available at PDF view 359 time, so we embed all fonts in accordance with modern PDF 360 guidelines. 361 * Most fonts these days are TrueType fonts, so this is where most of 362 the effort has been concentrated. 363 * Because Skia may only be given a glyph-id encoding of the text to 364 render and there is no perfect way to reverse the encoding, the 365 PDF backend always uses the glyph-id encoding of the text. 366 367 #### *Type1/Type3 fonts* #### 368 369 Linux supports Type1 fonts, but Windows and Mac seem to lack the 370 functionality required to extract the required information from the 371 font without parsing the font file. When a non TrueType font is used 372 any any platform (except for Type1 on Linux), it is encoded as a Type3 373 font. In this context, a Type3 font is an array of form x-objects 374 (content streams) that draw each glyph of the font. No hinting or 375 kerning information is included in a Type3 font, just the shape of 376 each glyph. Any font that has the do-not embed copy protection bit set 377 will also get embedded as a Type3 font. From what I understand, shapes 378 are not copyrightable, but programs are, so by stripping all the 379 programmatic information and only embedding the shape of the glyphs we 380 are honoring the do-not embed bit as much as required by law. 381 382 PDF only supports an 8-bit encoding for Type1 or Type3 fonts. However, 383 they can contain more than 256 glyphs. The PDF backend handles this by 384 segmenting the glyphs into groups of 255 (glyph id 0 is always the 385 unknown glyph) and presenting the font as multiple fonts, each with up 386 to 255 glyphs. 387 388 #### *Font subsetting* #### 389 390 Many fonts, especially fonts with CJK support are fairly large, so it 391 is desirable to subset them. Chrome uses the SFNTLY package to provide 392 subsetting support to Skia for TrueType fonts. 393 394 ### <span id="Shaders">Shaders</span> ### 395 396 Skia has two types of predefined shaders, image shaders and gradient 397 shaders. In both cases, shaders are effectively positioned absolutely, 398 so the initial position and bounds of where they are visible is part 399 of the immutable state of the shader object. Each of the Skia's tile 400 modes needs to be considered and handled explicitly. The image shader 401 we generate will be tiled, so tiling is handled by default. To support 402 mirroring, we draw the image, reversed, on the appropriate axis, or on 403 both axes plus a fourth in the vacant quadrant. For clamp mode, we 404 extract the pixels along the appropriate edge and stretch the single 405 pixel wide/long image to fill the bounds. For both x and y in clamp 406 mode, we fill the corners with a rectangle of the appropriate 407 color. The composed shader is then rotated or scaled as appropriate 408 for the request. 409 410 Gradient shaders are handled purely mathematically. First, the matrix 411 is transformed so that specific points in the requested gradient are 412 at pre-defined locations, for example, the linear distance of the 413 gradient is always normalized to one. Then, a type 4 PDF function is 414 created that achieves the desired gradient. A type 4 function is a 415 function defined by a resticted postscript language. The generated 416 functions clamp at the edges so if the desired tiling mode is tile or 417 mirror, we hav to add a bit more postscript code to map any input 418 parameter into the 0-1 range appropriately. The code to generate the 419 postscript code is somewhat obtuse, since it is trying to generate 420 optimized (for space) postscript code, but there is a significant 421 number of comments to explain the intent. 422 423 ### <span id="Xfer_modes">Xfer modes</span> ### 424 425 PDF supports some of the xfer modes used in Skia directly. For those, 426 it is simply a matter of setting the blend mode in the graphic state 427 to the appropriate value (Normal/SrcOver, Multiply, Screen, Overlay, 428 Darken, Lighten, !ColorDOdge, ColorBurn, HardLight, SoftLight, 429 Difference, Exclusion). Aside from the standard SrcOver mode, PDF does 430 not directly support the porter-duff xfer modes though. Most of them 431 (Clear, SrcMode, DstMode, DstOver, SrcIn, DstIn, SrcOut, DstOut) can 432 be emulated by various means, mostly by creating form x-objects out of 433 part of the content and drawing it with a another form x-object as a 434 mask. I have not figured out how to emulate the following modes: 435 SrcATop, DstATop, Xor, Plus. 436 437 At the time of writing [2012-06-25], I have a [CL outstanding to fix a 438 misunderstanding I had about the meaning of some of the emulated 439 modes](https://codereview.appspot.com/4631078/). 440 I will describe the system with this change applied. 441 442 First, a bit of terminology and definition. When drawing something 443 with an emulated xfer mode, what's already drawn to the device is 444 called the destination or Dst, and what's about to be drawn is the 445 source or Src. Src (and Dst) can have regions where it is transparent 446 (alpha equals zero), but it also has an inherent shape. For most kinds 447 of drawn objects, the shape is the same as where alpha is not 448 zero. However, for things like images and layers, the shape is the 449 bounds of the item, not where the alpha is non-zero. For example, a 450 10x10 image, that is transparent except for a 1x1 dot in the center 451 has a shape that is 10x10. The xfermodes gm test demonstrates the 452 interaction between shape and alpha in combination with the port-duff 453 xfer modes. 454 455 The clear xfer mode removes any part of Dst that is within Src's 456 shape. This is accomplished by bundling the current content of the 457 device (Dst) into a single entity and then drawing that with the 458 inverse of Src's shape used as a mask (we want Dst where Src 459 isn't). The implementation of that takes a couple more steps. You may 460 have to refer back to [the content stream section](#Generating_a_content_stream). For any draw call, a 461 ContentEntry is created through a method called 462 SkPDFDevice::setUpContentEntry(). This method examines the xfer modes 463 in effect for that drawing operation and if it is an xfer mode that 464 needs emulation, it creates a form x-object from the device, 465 i.e. creates Dst, and stores it away for later use. This also clears 466 all of that existing ContentEntry's on that device. The drawing 467 operation is then allowed to proceed as normal (in most cases, see 468 note about shape below), but into the now empty device. Then, when the 469 drawing operation in done, a complementary method is 470 called,SkPDFDevice::finishContentEntry(), which takes action if the 471 current xfer mode is emulated. In the case of Clear, it packages what 472 was just drawn into another form x-object, and then uses the Src form 473 x-object, an invert function, and the Dst form x-object to draw Dst 474 with the inverse shape of Src as a mask. This works well when the 475 shape of Src is the same as the opaque part of the drawing, since PDF 476 uses the alpha channel of the mask form x-object to do masking. When 477 shape doesn't match the alpha channel, additional action is 478 required. The drawing routines where shape and alpha don't match, set 479 state to indicate the shape (always rectangular), which 480 finishContentEntry uses. The clear xfer mode is a special case; if 481 shape is needed, then Src isn't used, so there is code to not bother 482 drawing Src if shape is required and the xfer mode is clear. 483 484 SrcMode is clear plus Src being drawn afterward. DstMode simply omits 485 drawing Src. DstOver is the same as SrcOver with Src and Dst swapped - 486 this is accomplished by inserting the new ContentEntry at the 487 beginning of the list of ContentEntry's in setUpContentEntry instead 488 of at the end. SrcIn, SrcOut, DstIn, DstOut are similar to each, the 489 difference being an inverted or non-inverted mask and swapping Src and 490 Dst (or not). SrcIn is SrcMode with Src drawn with Dst as a 491 mask. SrcOut is like SrcMode, but with Src drawn with an inverted Dst 492 as a mask. DstIn is SrcMode with Dst drawn with Src as a 493 mask. Finally, DstOut is SrcMode with Dst draw with an inverted Src as 494 a mask. 495 496 <span id="Known_issues">Known issues</span> 497 ------------------------------------------- 498 499 * [issue 249](https://bug.skia.org/249) 500 SrcAtop Xor, and Plus xfer modes are not supported. 501 * [issue 240](https://bug.skia.org/240) 502 drawVerticies is not implemented. 503 * [issue 244](https://bug.skia.org/244) 504 Mostly, only TTF fonts are *directly* supported. 505 (User metrics show that almost all fonts are truetype.) 506 * [issue 260](https://bug.skia.org/260) 507 Page rotation is accomplished by specifying a different 508 size page instead of including the appropriate rotation 509 annotation. 510 511 * * * 512 513