Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: site/dev/design/pdftheory.md

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

Powered by Google App Engine
This is Rietveld 408576698