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

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

Issue 2295373002: documentation: update PDF design doc (Closed)
Patch Set: bungeman Created 4 years, 3 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 PDF Theory of Operation 1 PDF Theory of Operation
2 ======================= 2 =======================
3 3
4 <!-- 4 <!--
5 PRE-GIT DOCUMENT VERSION HISTORY 5 PRE-GIT DOCUMENT VERSION HISTORY
6 2012-06-25 Steve VanDeBogart 6 2012-06-25 Steve VanDeBogart
7 * Original version 7 * Original version
8 2015-01-14 Hal Canary. 8 2015-01-14 Hal Canary.
9 * Add section "Using the PDF backend" 9 * Add section "Using the PDF backend"
10 * Markdown formatting 10 * Markdown formatting
(...skipping 12 matching lines...) Expand all
23 23
24 ### Contents ### 24 ### Contents ###
25 25
26 * [Typical usage of the PDF backend](#Typical_usage_of_the_PDF_backend) 26 * [Typical usage of the PDF backend](#Typical_usage_of_the_PDF_backend)
27 * [PDF Objects and Document Structure](#PDF_Objects_and_Document_Structure) 27 * [PDF Objects and Document Structure](#PDF_Objects_and_Document_Structure)
28 * [PDF drawing](#PDF_drawing) 28 * [PDF drawing](#PDF_drawing)
29 * [Interned objects](#Interned_objects) 29 * [Interned objects](#Interned_objects)
30 * [Graphic States](#Graphic_States) 30 * [Graphic States](#Graphic_States)
31 * [Clip and Transform](#Clip_and_Transform) 31 * [Clip and Transform](#Clip_and_Transform)
32 * [Generating a content stream](#Generating_a_content_stream) 32 * [Generating a content stream](#Generating_a_content_stream)
33 * [Margins and content area](#Margins_and_content_area)
34 * [Drawing details](#Drawing_details) 33 * [Drawing details](#Drawing_details)
35 + [Layers](#Layers) 34 + [Layers](#Layers)
36 + [Fonts](#Fonts) 35 + [Fonts](#Fonts)
37 + [Shaders](#Shaders) 36 + [Shaders](#Shaders)
38 + [Xfer modes](#Xfer_modes) 37 + [Xfer modes](#Xfer_modes)
39 * [Known issues](#Known_issues) 38 * [Known issues](#Known_issues)
40 39
41 <a name="Typical_usage_of_the_PDF_backend"></a> 40 <a name="Typical_usage_of_the_PDF_backend"></a>
42 Typical usage of the PDF backend 41 Typical usage of the PDF backend
43 -------------------------------- 42 --------------------------------
44 43
45 SkPDFDevice is the main interface to the PDF backend. This child of 44 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 45 SkDevice can be set on an SkPDFCanvas and drawn to. Once drawing is
47 care and feeding than SkDevice. Once drawing is complete, the device 46 complete, the device's content and resouces are added to the
48 should be added to an SkPDFDocument as a page of the desired PDF. A 47 SkPDFDocument that owns the device. A new SkPDFDevice should be
49 new SkPDFDevice should be created for each page desired in the 48 created for each page or layer desired in the document. After all the
50 document. After all the pages have been added to the document, 49 pages have been added to the document, `SkPDFDocument::onClose()` is
51 `SkPDFDocument::emitPDF()` can be called to get a PDF file. One of the 50 called to finish the PDF file.
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 <!--?prettify lang=cc?-->
58
59 SkPDFCanon canon;
60 SkAutoUnref<SkPDFDevice> pdfDevice(
61 SkPDFDevice::Create(SkISize::Make(width, height), 72.0f, &canon));
62
63 SkCanvas canvas(pdfDevice);
64 draw_content(&canvas);
65
66 SkPDFDocument doc;
67 doc.appendPage(dev);
68 doc.emitPDF(&pdf_stream);
69 51
70 <a name="PDF_Objects_and_Document_Structure"></a> 52 <a name="PDF_Objects_and_Document_Structure"></a>
71 PDF Objects and Document Structure 53 PDF Objects and Document Structure
72 ---------------------------------- 54 ----------------------------------
73 55
74 ![PDF Logical Document Structure](/dev/design/PdfLogicalDocumentStructure.png) 56 ![PDF Logical Document Structure](/dev/design/PdfLogicalDocumentStructure.png)
75 57
76 **Background**: The PDF file format has a header, a set of objects and 58 **Background**: The PDF file format has a header, a set of objects and
77 then a footer that contains a table of contents for all of the objects 59 then a footer that contains a table of contents for all of the objects
78 in the document (the cross-reference table). The table of contents 60 in the document (the cross-reference table). The table of contents
79 lists the specific byte position for each object. The objects may have 61 lists the specific byte position for each object. The objects may have
80 references to other objects and the ASCII size of those references is 62 references to other objects and the ASCII size of those references is
81 dependent on the object number assigned to the referenced object; 63 dependent on the object number assigned to the referenced object;
82 therefore we can’t calculate the table of contents until the size of 64 therefore we can’t calculate the table of contents until the size of
83 objects is known, which requires assignment of object 65 objects is known, which requires assignment of object numbers. The
84 numbers. 66 document uses SkWStream::bytesWritten() to query the offsets of each
67 object and build the cross-reference table.
85 68
86 Furthermore, PDF files can support a *linearized* mode, where objects 69 Furthermore, PDF files can support a *linearized* mode, where objects
87 are in a specific order so that pdf-viewers can more easily retrieve 70 are in a specific order so that pdf-viewers can more easily retrieve
88 just the objects they need to display a specific page, i.e. by 71 just the objects they need to display a specific page, i.e. by
89 byte-range requests over the web. Linearization also requires that all 72 byte-range requests over the web. Linearization also requires that all
90 objects used or referenced on the first page of the PDF have object 73 objects used or referenced on the first page of the PDF have object
91 numbers before the rest of the objects. Consequently, before 74 numbers before the rest of the objects. Consequently, before
92 generating a linearized PDF, all objects, their sizes, and object 75 generating a linearized PDF, all objects, their sizes, and object
93 references must be known. Skia has no plans to implement linearized 76 references must be known. Skia has no plans to implement linearized
94 PDFs. 77 PDFs.
95 78
96 <!-- <del>At this point, linearized PDFs are not generated. The
97 framework to generate them is in place, but the final bits of code
98 have not been written.</del> -->
99
100 %PDF-1.4 79 %PDF-1.4
101 …objects... 80 …objects...
102 xref 81 xref
103 0 31 % Total number of entries in the table of contents. 82 0 31 % Total number of entries in the table of contents.
104 0000000000 65535 f 83 0000000000 65535 f
105 0000210343 00000 n 84 0000210343 00000 n
106 … 85 …
107 0000117055 00000 n 86 0000117055 00000 n
108 trailer 87 trailer
109 <</Size 31 /Root 1 0 R>> 88 <</Size 31 /Root 1 0 R>>
110 startxref 89 startxref
111 210399 % Byte offset to the start of the table of contents. 90 210399 % Byte offset to the start of the table of contents.
112 %%EOF 91 %%EOF
113 92
114 The class SkPDFCatalog and the virtual class SkPDFObject are used to 93 The class SkPDFObjNumMap and the virtual class SkPDFObject are used to
115 manage the needs of the file format. Any object that will represent a 94 manage the needs of the file format. Any object that will represent a
116 PDF object must inherit from SkPDFObject and implement the methods to 95 PDF object must inherit from SkPDFObject and implement the methods to
117 generate the binary representation and report any other SkPDFObjects 96 generate the binary representation and report any other SkPDFObjects
118 used as resources. SkPDFTypes.h defines most of the basic PDF objects 97 used as resources. SkPDFTypes.h defines most of the basic PDF objects
tomhudson 2016/09/01 19:11:58 Nit: object shouldn't be plural here.
hal.canary 2016/09/28 18:18:28 Done.
119 types: bool, int, scalar, string, name, array, dictionary, and object 98 types: bool, int, scalar, string, name, array, dictionary, and stream.
120 reference. The stream type is defined in SkPDFStream.h. A stream is a 99 A stream is a
121 dictionary containing at least a Length entry followed by the data of 100 dictionary containing at least a Length entry followed by the data of
122 the stream. All of these types except the stream type can be used in 101 the stream. All of these types except the stream type can be used in
123 both a direct and an indirect fashion, i.e. an array can have an int 102 both a direct and an indirect fashion, i.e. an array can have an int
tomhudson 2016/09/01 19:11:58 Nit: this isn't clear at all. Most of the rest of
hal.canary 2016/09/28 18:18:28 Acknowledged.
124 or a dictionary as an inline entry, which does not require an object 103 or a dictionary as an inline entry, which does not require an object
125 number. The stream type, cannot be inlined and must be referred to 104 number. The stream type, cannot be inlined and must be referred to
126 with an object reference. Most of the time, other objects types can be 105 with an object reference. Most of the time, other objects types can be
127 referred to with an object reference, but there are specific rules in 106 referred to with an object reference, but there are specific rules in
128 the PDF specification that requires an inline reference in some place 107 the PDF specification that requires an inline reference in some place
129 or an indirect reference in other places. All indirect objects must 108 or an indirect reference in other places. All indirect objects must
130 have an object number assigned. 109 have an object number assigned.
131 110
132 * **bools**: `true` `false` 111 * **bools**: `true` `false`
133 * **ints**: `42` `0` `-1` 112 * **ints**: `42` `0` `-1`
134 * **scalars**: `0.001` 113 * **scalars**: `0.001`
135 * **strings**: `(strings are in parentheses or byte encoded)` `<74657374>` 114 * **strings**: `(strings are in parentheses or byte encoded)` `<74657374>`
136 * **name**: `/Name` `/Name#20with#20spaces` 115 * **name**: `/Name` `/Name#20with#20spaces`
137 * **array**: `[/Foo 42 (arrays can contain multiple types)]` 116 * **array**: `[/Foo 42 (arrays can contain multiple types)]`
138 * **dictionary**: `<</Key1 (value1) /key2 42>>` 117 * **dictionary**: `<</Key1 (value1) /key2 42>>`
139 * **indirect object**: 118 * **indirect object**:
140 `5 0 obj 119 `5 0 obj
141 (An indirect string. Indirect objects have an object number and a 120 (An indirect string. Indirect objects have an object number and a
142 generation number, Skia always uses generation 0 objects) 121 generation number, Skia always uses generation 0 objects)
143 endobj` 122 endobj`
144 * **object reference**: `5 0 R` 123 * **object reference**: `5 0 R`
145 * **stream**: `<</Length 56>> 124 * **stream**: `<</Length 56>>
146 stream 125 stream
147 ...stream contents can be arbitrary, including binary... 126 ...stream contents can be arbitrary, including binary...
148 endstream` 127 endstream`
149 128
150 The PDF backend requires all indirect objects used in a PDF to be 129 The PDF backend requires all indirect objects used in a PDF to be
151 added to the SkPDFCatalog of the SkPDFDocument. The catalog is 130 added to the SkPDFObjNumMap of the SkPDFDocument. The catalog is
152 responsible for assigning object numbers and generating the table of 131 responsible for assigning object numbers and generating the table of
153 contents required at the end of PDF files. In some sense, generating a 132 contents required at the end of PDF files. In some sense, generating a
154 PDF is a three step process. In the first step all the objects and 133 PDF is a three step process. In the first step all the objects and
155 references among them are created (mostly done by SkPDFDevice). In the 134 references among them are created (mostly done by SkPDFDevice). In the
156 second step, object numbers are assigned and SkPDFCatalog is informed 135 second step, SkPDFObjNumMap assigns and remembers object numbers.
157 of the file offset of each indirect object. Finally, in the third 136 Finally, in the third
158 step, the header is printed, each object is printed, and then the 137 step, the header is printed, each object is printed, and then the
159 table of contents and trailer are printed. SkPDFDocument takes care of 138 table of contents and trailer are printed. SkPDFDocument takes care of
160 collecting all the objects from the various SkPDFDevice instances, 139 collecting all the objects from the various SkPDFDevice instances,
161 adding them to an SkPDFCatalog, iterating through the objects once to 140 adding them to an SkPDFObjNumMap, iterating through the objects once to
162 set their file positions, and iterating again to generate the final 141 set their file positions, and iterating again to generate the final
163 PDF. 142 PDF.
164 143
144 As an optimization, many leaf nodes in the direct graph of indirect
145 objects can be assigned object numbers and serialized early.
146
165 %PDF-1.4 147 %PDF-1.4
166 2 0 obj << 148 2 0 obj <<
167 /Type /Catalog 149 /Type /Catalog
168 /Pages 1 0 R 150 /Pages 1 0 R
169 >> 151 >>
170 endobj 152 endobj
171 3 0 obj << 153 3 0 obj <<
172 /Type /Page 154 /Type /Page
173 /Parent 1 0 R 155 /Parent 1 0 R
174 /Resources <> 156 /Resources <>
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 Interned objects 229 Interned objects
248 ---------------- 230 ----------------
249 231
250 There are a number of high level PDF objects (like fonts, graphic 232 There are a number of high level PDF objects (like fonts, graphic
251 states, etc) that are likely to be referenced multiple times in a 233 states, etc) that are likely to be referenced multiple times in a
252 single PDF. To ensure that there is only one copy of each object 234 single PDF. To ensure that there is only one copy of each object
253 instance these objects an implemented with an 235 instance these objects an implemented with an
254 [interning pattern](http://en.wikipedia.org/wiki/String_interning). 236 [interning pattern](http://en.wikipedia.org/wiki/String_interning).
255 As such, the classes representing these objects (like 237 As such, the classes representing these objects (like
256 SkPDFGraphicState) have private constructors and static methods to 238 SkPDFGraphicState) have private constructors and static methods to
257 retrieve an instance of the class. Internally, the class has a list of 239 retrieve an instance of the class.
258 unique instances that it consults before returning a new instance of 240
259 the class. If the requested instance already exists, the existing one 241 The SkPDFCanon object owns the interned objects. For obvious reasons,
260 is returned. For obvious reasons, the returned instance should not be 242 the returned instance should not be modified. A mechanism to ensure
261 modified. A mechanism to ensure that interned classes are immutable is 243 that interned classes are immutable is needed. See [issue
262 needed. See [issue 2683](https://bug.skia.org/2683). 244 2683](https://bug.skia.org/2683).
263 245
264 <a name="Graphic_States"></a> 246 <a name="Graphic_States"></a>
265 Graphic States 247 Graphic States
266 -------------- 248 --------------
267 249
268 PDF has a number of parameters that affect how things are drawn. The 250 PDF has a number of parameters that affect how things are drawn. The
269 ones that correspond to drawing options in Skia are: color, alpha, 251 ones that correspond to drawing options in Skia are: color, alpha,
270 line cap, line join type, line width, miter limit, and xfer/blend mode 252 line cap, line join type, line width, miter limit, and xfer/blend mode
271 (see later section for xfer modes). With the exception of color, these 253 (see later section for xfer modes). With the exception of color, these
272 can all be specified in a single pdf object, represented by the 254 can all be specified in a single pdf object, represented by the
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 SkPDFGraphicState (interned) with the rest (color, font size, etc) 307 SkPDFGraphicState (interned) with the rest (color, font size, etc)
326 explicitly stored in the ContentEntry. After populating the 308 explicitly stored in the ContentEntry. After populating the
327 ContentEntry with all the relevant context, it is compared to the the 309 ContentEntry with all the relevant context, it is compared to the the
328 most recently used ContentEntry. If the context matches, then the 310 most recently used ContentEntry. If the context matches, then the
329 previous one is appended to instead of using the new one. In either 311 previous one is appended to instead of using the new one. In either
330 case, with the context populated into the ContentEntry, the 312 case, with the context populated into the ContentEntry, the
331 appropriate draw call is allowed to append to the content stream 313 appropriate draw call is allowed to append to the content stream
332 snippet in the ContentEntry to affect the core of the drawing call, 314 snippet in the ContentEntry to affect the core of the drawing call,
333 i.e. drawing a shape, an image, text, etc. 315 i.e. drawing a shape, an image, text, etc.
334 316
335 When all drawing is complete, SkPDFDocument::emitPDF() will call 317 When all drawing is complete, SkPDFDocument::onEndPage() will call
336 SkPDFDevice::content() to request the complete content stream for the 318 SkPDFDevice::content() to request the complete content stream for the
337 page. The first thing done is to apply the initial transform specified 319 page. The first thing done is to apply the initial transform specified
338 in part in the constructor, this transform takes care of changing the 320 in part in the constructor, this transform takes care of changing the
339 coordinate space from an origin in the lower left (PDF default) to the 321 coordinate space from an origin in the lower left (PDF default) to the
340 upper left (Skia default) as well as any translation or scaling 322 upper left (Skia default) as well as any translation or scaling
341 requested by the user (i.e. to achieve a margin or scale the 323 requested by the user (i.e. to achieve a margin or scale the
342 canvas). Next (well almost next, see the next section), a clip is 324 canvas). Next (well almost next, see the next section), a clip is
343 applied to restrict drawing to the content area (the part of the page 325 applied to restrict drawing to the content area (the part of the page
344 inside the margins) of the page. Then, each ContentEntry is applied to 326 inside the margins) of the page. Then, each ContentEntry is applied to
345 the content stream with the help of a helper class, GraphicStackState, 327 the content stream with the help of a helper class, GraphicStackState,
346 which tracks the state of the PDF graphics stack and optimizes the 328 which tracks the state of the PDF graphics stack and optimizes the
347 output. For each ContentEntry, commands are emitted to the final 329 output. For each ContentEntry, commands are emitted to the final
348 content entry to update the clip from its current state to the state 330 content entry to update the clip from its current state to the state
349 specified in the ContentEntry, similarly the Matrix and drawing state 331 specified in the ContentEntry, similarly the Matrix and drawing state
350 (color, line joins, etc) are updated, then the content entry fragment 332 (color, line joins, etc) are updated, then the content entry fragment
351 (the actual drawing operation) is appended. 333 (the actual drawing operation) is appended.
352 334
353 <a name="Margins_and_content_area"></a>
354 Margins and content area
355 ------------------------
356
357 The above procedure does not permit drawing in the margins. This is
358 done in order to contain any rendering problems in WebKit. In order to
359 support headers and footers, which are drawn in the margin, a second
360 set of ContentEntry’s are maintained. The
361 methodSkPDFDevice::setDrawingArea() selects which set of
362 ContentEntry’s are drawn into. Then, in the SkPDFDevice::content()
363 method, just before the clip to the content area is applied the margin
364 ContentEntry's are played back.
365
366 <!-- TODO(halcanary): update this documentation. -->
367
368 <a name="Drawing_details"></a> 335 <a name="Drawing_details"></a>
369 Drawing details 336 Drawing details
370 --------------- 337 ---------------
371 338
372 Certain objects have specific properties that need to be dealt 339 Certain objects have specific properties that need to be dealt
373 with. Images, layers (see below), and fonts assume the standard PDF 340 with. Images, layers (see below), and fonts assume the standard PDF
374 coordinate system, so we have to undo any flip to the Skia coordinate 341 coordinate system, so we have to undo any flip to the Skia coordinate
375 system before drawing these entities. We don’t currently support 342 system before drawing these entities. We don’t currently support
376 inverted paths, so filling an inverted path will give the wrong result 343 inverted paths, so filling an inverted path will give the wrong result
377 ([issue 241](https://bug.skia.org/241)). PDF doesn’t draw zero length 344 ([issue 241](https://bug.skia.org/241)). PDF doesn’t draw zero length
378 lines that have butt of square caps, so that is emulated. 345 lines that have butt of square caps, so that is emulated.
379 346
380 <a name="Layers"></a> 347 <a name="Layers"></a>
381 ### Layers ### 348 ### Layers ###
382 349
383 PDF has a higher level object called a form x-object (form external 350 PDF has a higher level object called a form x-object (form external
384 object) that is basically a PDF page, with resources and a content 351 object) that is basically a PDF page, with resources and a content
385 stream, but can be transformed and drawn on an existing page. This is 352 stream, but can be transformed and drawn on an existing page. This is
386 used to implement layers. SkDevice has a method, 353 used to implement layers. SkPDFDevice has a method,
387 createFormXObjectFromDevice, which uses the SkPDFDevice::content() 354 makeFormXObjectFromDevice(), which uses the SkPDFDevice::content()
388 method to construct a form x-object from the the 355 method to construct a form x-object from the the
389 device. SkPDFDevice::drawDevice() works by creating a form x-object of 356 device. SkPDFDevice::drawDevice() works by creating a form x-object of
390 the passed device and then drawing that form x-object in the root 357 the passed device and then drawing that form x-object in the root
391 device. There are a couple things to be aware of in this process. As 358 device. There are a couple things to be aware of in this process. As
392 noted previously, we have to be aware of any flip to the coordinate 359 noted previously, we have to be aware of any flip to the coordinate
393 system - flipping it an even number of times will lead to the wrong 360 system - flipping it an even number of times will lead to the wrong
394 result unless it is corrected for. The SkClipStack passed to drawing 361 result unless it is corrected for. The SkClipStack passed to drawing
395 commands includes the entire clip stack, including the clipping 362 commands includes the entire clip stack, including the clipping
396 operations done on the base layer. Since the form x-object will be 363 operations done on the base layer. Since the form x-object will be
397 drawn as a single operation onto the base layer, we can assume that 364 drawn as a single operation onto the base layer, we can assume that
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 PDF only supports an 8-bit encoding for Type1 or Type3 fonts. However, 399 PDF only supports an 8-bit encoding for Type1 or Type3 fonts. However,
433 they can contain more than 256 glyphs. The PDF backend handles this by 400 they can contain more than 256 glyphs. The PDF backend handles this by
434 segmenting the glyphs into groups of 255 (glyph id 0 is always the 401 segmenting the glyphs into groups of 255 (glyph id 0 is always the
435 unknown glyph) and presenting the font as multiple fonts, each with up 402 unknown glyph) and presenting the font as multiple fonts, each with up
436 to 255 glyphs. 403 to 255 glyphs.
437 404
438 #### *Font subsetting* #### 405 #### *Font subsetting* ####
439 406
440 Many fonts, especially fonts with CJK support are fairly large, so it 407 Many fonts, especially fonts with CJK support are fairly large, so it
441 is desirable to subset them. Chrome uses the SFNTLY package to provide 408 is desirable to subset them. Chrome uses the SFNTLY package to provide
442 subsetting support to Skia for TrueType fonts. However, there is a 409 subsetting support to Skia for TrueType fonts.
443 conflict between font subsetting and interned objects. If the object
444 is immutable, how can it be subsetted? This conflict is resolved by
445 using a substitution mechanism in SkPDFCatalog. Font objects are still
446 interned, but the interned objects aren’t internally
447 populated. Subsetting starts while drawing text to an SkPDFDevice; a
448 bit set indicating which glyphs have been used is maintained. Later,
449 when SkPDFDocument::emitPDF() is rendering the PDF, it queries each
450 device (each page) for the set of fonts used and the glyphs used from
451 each font and combines the information. It then asks the interned
452 (unpopulated) font objects to create a populated instance with the
453 calculated subset of the font - this instance is not interned. The
454 subsetted instance is then set as a substitute for the interned font
455 object in the SkPDFCatalog. All future references to those fonts
456 within that document will refer to the subsetted instances, resulting
457 in a final PDF with exactly one instance of each used font that
458 includes only the glyphs used.
459
460 The substitution mechanism is a little complicated, but is needed to
461 support the use case of an SkPDFDevice being added to multiple
462 documents. If fonts were subsetted in-situ, concurrent PDF generation
463 would have to be explicitly handled. Instead, by giving each document
464 its own subsetted instance, there is no need to worry about concurrent
465 PDF generation. The substitution method is also used to support
466 optional stream compression. A stream can used by different documents
467 in both a compressed and uncompressed form, leading to the same
468 potential difficulties faced by the concurrent font use case.
469 410
470 <a name="Shaders"></a> 411 <a name="Shaders"></a>
471 ### Shaders ### 412 ### Shaders ###
472 413
473 Skia has two types of predefined shaders, image shaders and gradient 414 Skia has two types of predefined shaders, image shaders and gradient
474 shaders. In both cases, shaders are effectively positioned absolutely, 415 shaders. In both cases, shaders are effectively positioned absolutely,
475 so the initial position and bounds of where they are visible is part 416 so the initial position and bounds of where they are visible is part
476 of the immutable state of the shader object. Each of the Skia’s tile 417 of the immutable state of the shader object. Each of the Skia’s tile
477 modes needs to be considered and handled explicitly. The image shader 418 modes needs to be considered and handled explicitly. The image shader
478 we generate will be tiled, so tiling is handled by default. To support 419 we generate will be tiled, so tiling is handled by default. To support
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 Dst (or not). SrcIn is SrcMode with Src drawn with Dst as a 509 Dst (or not). SrcIn is SrcMode with Src drawn with Dst as a
569 mask. SrcOut is like SrcMode, but with Src drawn with an inverted Dst 510 mask. SrcOut is like SrcMode, but with Src drawn with an inverted Dst
570 as a mask. DstIn is SrcMode with Dst drawn with Src as a 511 as a mask. DstIn is SrcMode with Dst drawn with Src as a
571 mask. Finally, DstOut is SrcMode with Dst draw with an inverted Src as 512 mask. Finally, DstOut is SrcMode with Dst draw with an inverted Src as
572 a mask. 513 a mask.
573 514
574 <a name="Known_issues"></a> 515 <a name="Known_issues"></a>
575 Known issues 516 Known issues
576 ------------ 517 ------------
577 518
578 * [issue 241](https://bug.skia.org/241)
579 As previously noted, a boolean geometry library
580 would improve clip fidelity in some places, add supported for
581 inverted fill types, as well as simplify code.
582 This is fixed, but behind a flag until path ops is production ready.
583 * [issue 237](https://bug.skia.org/237) 519 * [issue 237](https://bug.skia.org/237)
584 SkMaskFilter is not supported. 520 SkMaskFilter is not supported.
585 * [issue 238](https://bug.skia.org/238) 521 * [issue 238](https://bug.skia.org/238)
586 SkColorFilter is not supported. 522 SkColorFilter is not supported.
587 * [issue 249](https://bug.skia.org/249) 523 * [issue 249](https://bug.skia.org/249)
588 SrcAtop Xor, and Plus xfer modes are not supported. 524 SrcAtop Xor, and Plus xfer modes are not supported.
589 * [issue 240](https://bug.skia.org/240) 525 * [issue 240](https://bug.skia.org/240)
590 drawVerticies is not implemented. 526 drawVerticies is not implemented.
591 * [issue 244](https://bug.skia.org/244) 527 * [issue 244](https://bug.skia.org/244)
592 Mostly, only TTF fonts are directly supported. (User metrics 528 Mostly, only TTF fonts are directly supported. (User metrics
tomhudson 2016/09/01 19:11:58 Nit: mostly only?
hal.canary 2016/09/28 18:18:28 Acknowledged.
593 show that almost all fonts are truetype. 529 show that almost all fonts are truetype.)
594 * [issue 260](https://bug.skia.org/260) 530 * [issue 260](https://bug.skia.org/260)
595 Page rotation is accomplished by specifying a different 531 Page rotation is accomplished by specifying a different
596 size page instead of including the appropriate rotation 532 size page instead of including the appropriate rotation
597 annotation. 533 annotation.
598 534
599 * * * 535 * * *
600 536
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698