edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 1 | #ifndef __DEFINED__SkPdfBasics |
| 2 | #define __DEFINED__SkPdfBasics |
| 3 | |
edisonn@google.com | 131d4ee | 2013-06-26 17:48:12 +0000 | [diff] [blame] | 4 | #include "SkCanvas.h" |
| 5 | #include "SkPaint.h" |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 6 | #include "SkPdfConfig.h" |
edisonn@google.com | 131d4ee | 2013-06-26 17:48:12 +0000 | [diff] [blame] | 7 | |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 8 | #include <iostream> |
| 9 | #include <cstdio> |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 10 | #include <map> |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 11 | #include <stack> |
| 12 | |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 13 | class SkPdfFont; |
| 14 | class SkPdfDoc; |
edisonn@google.com | 131d4ee | 2013-06-26 17:48:12 +0000 | [diff] [blame] | 15 | class SkPdfObject; |
| 16 | class SkPdfResourceDictionary; |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 17 | |
edisonn@google.com | 571c70b | 2013-07-10 17:09:50 +0000 | [diff] [blame] | 18 | class SkNativeParsedPDF; |
edisonn@google.com | 2ccc3af | 2013-07-23 17:43:18 +0000 | [diff] [blame] | 19 | class SkPdfAllocator; |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 20 | |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 21 | // TODO(edisonn): better class design. |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 22 | struct SkPdfColorOperator { |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 23 | |
| 24 | /* |
| 25 | color space name or array The current color space in which color values are to be interpreted |
| 26 | (see Section 4.5, “Color Spaces”). There are two separate color space |
| 27 | parameters: one for stroking and one for all other painting opera- |
| 28 | tions. Initial value: DeviceGray. |
| 29 | */ |
| 30 | |
| 31 | // TODO(edisonn): implement the array part too |
edisonn@google.com | 571c70b | 2013-07-10 17:09:50 +0000 | [diff] [blame] | 32 | // does not own the char* |
edisonn@google.com | 2ccc3af | 2013-07-23 17:43:18 +0000 | [diff] [blame] | 33 | NotOwnedString fColorSpace; |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 34 | |
| 35 | |
| 36 | /* |
| 37 | color (various) The current color to be used during painting operations (see Section |
| 38 | 4.5, “Color Spaces”). The type and interpretation of this parameter |
| 39 | depend on the current color space; for most color spaces, a color |
| 40 | value consists of one to four numbers. There are two separate color |
| 41 | parameters: one for stroking and one for all other painting opera- |
| 42 | tions. Initial value: black. |
| 43 | */ |
| 44 | |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 45 | SkColor fColor; |
| 46 | double fOpacity; // ca or CA |
| 47 | // TODO(edisonn): add here other color space options. |
| 48 | |
| 49 | void setRGBColor(SkColor color) { |
| 50 | // TODO(edisonn): ASSERT DeviceRGB is the color space. |
| 51 | fColor = color; |
| 52 | } |
| 53 | // TODO(edisonn): double check the default values for all fields. |
edisonn@google.com | 2ccc3af | 2013-07-23 17:43:18 +0000 | [diff] [blame] | 54 | SkPdfColorOperator() : fColor(SK_ColorBLACK), fOpacity(1) { |
| 55 | NotOwnedString::init(&fColorSpace); |
| 56 | } |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 57 | |
| 58 | void applyGraphicsState(SkPaint* paint) { |
edisonn@google.com | 96ba3aa | 2013-07-28 20:04:35 +0000 | [diff] [blame] | 59 | paint->setColor(SkColorSetA(fColor, (U8CPU)(fOpacity * 255))); |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 60 | } |
| 61 | }; |
| 62 | |
| 63 | // TODO(edisonn): better class design. |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 64 | struct SkPdfGraphicsState { |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 65 | // TODO(edisonn): deprecate and remove these! |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 66 | double fCurPosX; |
| 67 | double fCurPosY; |
| 68 | |
| 69 | double fCurFontSize; |
| 70 | bool fTextBlock; |
| 71 | SkPdfFont* fSkFont; |
| 72 | SkPath fPath; |
| 73 | bool fPathClosed; |
| 74 | |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 75 | |
| 76 | |
| 77 | double fTextLeading; |
| 78 | double fWordSpace; |
| 79 | double fCharSpace; |
| 80 | |
| 81 | SkPdfResourceDictionary* fResources; |
| 82 | |
| 83 | |
| 84 | // TODO(edisonn): move most of these in canvas/paint? |
| 85 | // we could have some in canvas (matrixes?), |
| 86 | // some in 2 paints (stroking paint and non stroking paint) |
| 87 | |
| 88 | // TABLE 4.2 Device-independent graphics state parameters |
| 89 | /* |
| 90 | * CTM array The current transformation matrix, which maps positions from user |
| 91 | coordinates to device coordinates (see Section 4.2, “Coordinate Sys- |
| 92 | tems”). This matrix is modified by each application of the coordi- |
| 93 | nate transformation operator, cm. Initial value: a matrix that |
| 94 | transforms default user coordinates to device coordinates. |
| 95 | */ |
| 96 | SkMatrix fCTM; |
| 97 | |
| 98 | /* |
| 99 | clipping path (internal) The current clipping path, which defines the boundary against |
| 100 | which all output is to be cropped (see Section 4.4.3, “Clipping Path |
| 101 | Operators”). Initial value: the boundary of the entire imageable |
| 102 | portion of the output page. |
| 103 | */ |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 104 | // Clip that is applied after the drawing is done!!! |
| 105 | bool fHasClipPathToApply; |
| 106 | SkPath fClipPath; |
| 107 | |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 108 | SkPdfColorOperator fStroking; |
| 109 | SkPdfColorOperator fNonStroking; |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 110 | |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 111 | /* |
| 112 | text state (various) A set of nine graphics state parameters that pertain only to the |
| 113 | painting of text. These include parameters that select the font, scale |
| 114 | the glyphs to an appropriate size, and accomplish other effects. The |
| 115 | text state parameters are described in Section 5.2, “Text State |
| 116 | Parameters and Operators.” |
| 117 | */ |
| 118 | |
| 119 | // TODO(edisonn): add SkPdfTextState class. remove these two existing fields |
| 120 | SkMatrix fMatrixTm; |
| 121 | SkMatrix fMatrixTlm; |
| 122 | |
| 123 | |
| 124 | /* |
| 125 | line width number The thickness, in user space units, of paths to be stroked (see “Line |
| 126 | Width” on page 152). Initial value: 1.0. |
| 127 | */ |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 128 | double fLineWidth; |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 129 | |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 130 | |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 131 | /* |
| 132 | line cap integer A code specifying the shape of the endpoints for any open path that |
| 133 | is stroked (see “Line Cap Style” on page 153). Initial value: 0, for |
| 134 | square butt caps. |
| 135 | */ |
| 136 | // TODO (edisonn): implement defaults - page 153 |
| 137 | int fLineCap; |
| 138 | |
| 139 | /* |
| 140 | line join integer A code specifying the shape of joints between connected segments |
| 141 | of a stroked path (see “Line Join Style” on page 153). Initial value: 0, |
| 142 | for mitered joins. |
| 143 | */ |
| 144 | // TODO (edisonn): implement defaults - page 153 |
| 145 | int fLineJoin; |
| 146 | |
| 147 | /* |
| 148 | miter limit number The maximum length of mitered line joins for stroked paths (see |
| 149 | “Miter Limit” on page 153). This parameter limits the length of |
| 150 | “spikes” produced when line segments join at sharp angles. Initial |
| 151 | value: 10.0, for a miter cutoff below approximately 11.5 degrees. |
| 152 | */ |
| 153 | // TODO (edisonn): implement defaults - page 153 |
| 154 | double fMiterLimit; |
| 155 | |
| 156 | /* |
| 157 | dash pattern array and A description of the dash pattern to be used when paths are |
| 158 | number stroked (see “Line Dash Pattern” on page 155). Initial value: a solid |
| 159 | line. |
| 160 | */ |
| 161 | SkScalar fDashArray[256]; // TODO(edisonn): allocate array? |
| 162 | int fDashArrayLength; |
| 163 | SkScalar fDashPhase; |
| 164 | |
| 165 | |
| 166 | /* |
| 167 | rendering intent name The rendering intent to be used when converting CIE-based colors |
| 168 | to device colors (see “Rendering Intents” on page 197). Default |
| 169 | value: RelativeColorimetric. |
| 170 | */ |
| 171 | // TODO(edisonn): seems paper only. Verify. |
| 172 | |
| 173 | /* |
| 174 | stroke adjustment boolean (PDF 1.2) A flag specifying whether to compensate for possible ras- |
| 175 | terization effects when stroking a path with a line width that is |
| 176 | small relative to the pixel resolution of the output device (see Sec- |
| 177 | tion 6.5.4, “Automatic Stroke Adjustment”). Note that this is con- |
| 178 | sidered a device-independent parameter, even though the details of |
| 179 | its effects are device-dependent. Initial value: false. |
| 180 | */ |
| 181 | // TODO(edisonn): stroke adjustment low priority. |
| 182 | |
| 183 | |
| 184 | /* |
| 185 | blend mode name or array (PDF 1.4) The current blend mode to be used in the transparent |
| 186 | imaging model (see Sections 7.2.4, “Blend Mode,” and 7.5.2, “Spec- |
| 187 | ifying Blending Color Space and Blend Mode”). This parameter is |
| 188 | implicitly reset to its initial value at the beginning of execution of a |
| 189 | transparency group XObject (see Section 7.5.5, “Transparency |
| 190 | Group XObjects”). Initial value: Normal. |
| 191 | */ |
edisonn@google.com | e878e72 | 2013-07-29 19:10:58 +0000 | [diff] [blame^] | 192 | SkXfermode::Mode fBlendModes[256]; |
| 193 | int fBlendModesLength; |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 194 | |
| 195 | /* |
| 196 | soft mask dictionary (PDF 1.4) A soft-mask dictionary (see “Soft-Mask Dictionaries” on |
| 197 | or name page 445) specifying the mask shape or mask opacity values to be |
| 198 | used in the transparent imaging model (see “Source Shape and |
| 199 | Opacity” on page 421 and “Mask Shape and Opacity” on page 443), |
| 200 | or the name None if no such mask is specified. This parameter is |
| 201 | implicitly reset to its initial value at the beginning of execution of a |
| 202 | transparency group XObject (see Section 7.5.5, “Transparency |
| 203 | Group XObjects”). Initial value: None. |
| 204 | */ |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 205 | SkBitmap fSMask; |
| 206 | |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 207 | |
| 208 | /* |
| 209 | alpha constant number (PDF 1.4) The constant shape or constant opacity value to be used |
| 210 | in the transparent imaging model (see “Source Shape and Opacity” |
| 211 | on page 421 and “Constant Shape and Opacity” on page 444). |
| 212 | There are two separate alpha constant parameters: one for stroking |
| 213 | and one for all other painting operations. This parameter is implic- |
| 214 | itly reset to its initial value at the beginning of execution of a trans- |
| 215 | parency group XObject (see Section 7.5.5, “Transparency Group |
| 216 | XObjects”). Initial value: 1.0. |
| 217 | */ |
| 218 | double fAphaConstant; |
| 219 | |
| 220 | /* |
| 221 | alpha source boolean (PDF 1.4) A flag specifying whether the current soft mask and alpha |
| 222 | constant parameters are to be interpreted as shape values (true) or |
| 223 | opacity values (false). This flag also governs the interpretation of |
| 224 | the SMask entry, if any, in an image dictionary (see Section 4.8.4, |
| 225 | “Image Dictionaries”). Initial value: false. |
| 226 | */ |
| 227 | bool fAlphaSource; |
| 228 | |
| 229 | |
| 230 | // TODO(edisonn): Device-dependent seem to be required only on the actual physical printer? |
| 231 | // TABLE 4.3 Device-dependent graphics state parameters |
| 232 | /* |
| 233 | overprint boolean (PDF 1.2) A flag specifying (on output devices that support the |
| 234 | overprint control feature) whether painting in one set of colorants |
| 235 | should cause the corresponding areas of other colorants to be |
| 236 | erased (false) or left unchanged (true); see Section 4.5.6, “Over- |
| 237 | print Control.” In PDF 1.3, there are two separate overprint param- |
| 238 | eters: one for stroking and one for all other painting operations. |
| 239 | Initial value: false. |
| 240 | */ |
| 241 | |
| 242 | |
| 243 | /* |
| 244 | overprint mode number (PDF 1.3) A code specifying whether a color component value of 0 |
| 245 | in a DeviceCMYK color space should erase that component (0) or |
| 246 | leave it unchanged (1) when overprinting (see Section 4.5.6, “Over- |
| 247 | print Control”). Initial value: 0. |
| 248 | */ |
| 249 | |
| 250 | |
| 251 | /* |
| 252 | black generation function (PDF 1.2) A function that calculates the level of the black color |
| 253 | or name component to use when converting RGB colors to CMYK (see Sec- |
| 254 | tion 6.2.3, “Conversion from DeviceRGB to DeviceCMYK”). Initial |
| 255 | value: installation-dependent. |
| 256 | */ |
| 257 | |
| 258 | |
| 259 | /* |
| 260 | undercolor removal function (PDF 1.2) A function that calculates the reduction in the levels of |
| 261 | or name the cyan, magenta, and yellow color components to compensate for |
| 262 | the amount of black added by black generation (see Section 6.2.3, |
| 263 | “Conversion from DeviceRGB to DeviceCMYK”). Initial value: in- |
| 264 | stallation-dependent. |
| 265 | */ |
| 266 | |
| 267 | |
| 268 | /* |
| 269 | transfer function, (PDF 1.2) A function that adjusts device gray or color component |
| 270 | array, or name levels to compensate for nonlinear response in a particular out- |
| 271 | put device (see Section 6.3, “Transfer Functions”). Initial value: |
| 272 | installation-dependent. |
| 273 | */ |
| 274 | |
| 275 | |
| 276 | /* |
| 277 | halftone dictionary, (PDF 1.2) A halftone screen for gray and color rendering, specified |
| 278 | stream, or name as a halftone dictionary or stream (see Section 6.4, “Halftones”). |
| 279 | Initial value: installation-dependent. |
| 280 | */ |
| 281 | |
| 282 | |
| 283 | /* |
| 284 | flatness number The precision with which curves are to be rendered on the output |
| 285 | device (see Section 6.5.1, “Flatness Tolerance”). The value of this |
| 286 | parameter gives the maximum error tolerance, measured in output |
| 287 | device pixels; smaller numbers give smoother curves at the expense |
| 288 | of more computation and memory use. Initial value: 1.0. |
| 289 | */ |
| 290 | |
| 291 | |
| 292 | /* |
| 293 | smoothness number (PDF 1.3) The precision with which color gradients are to be ren- |
| 294 | dered on the output device (see Section 6.5.2, “Smoothness Toler- |
| 295 | ance”). The value of this parameter gives the maximum error |
| 296 | tolerance, expressed as a fraction of the range of each color compo- |
| 297 | nent; smaller numbers give smoother color transitions at the |
| 298 | expense of more computation and memory use. Initial value: |
| 299 | installation-dependent. |
| 300 | */ |
| 301 | |
| 302 | |
| 303 | |
| 304 | |
| 305 | |
| 306 | |
| 307 | |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 308 | SkPdfGraphicsState() { |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 309 | fCurPosX = 0.0; |
| 310 | fCurPosY = 0.0; |
| 311 | fCurFontSize = 0.0; |
| 312 | fTextBlock = false; |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 313 | fCTM = SkMatrix::I(); |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 314 | fMatrixTm = SkMatrix::I(); |
| 315 | fMatrixTlm = SkMatrix::I(); |
| 316 | fPathClosed = true; |
| 317 | fLineWidth = 0; |
| 318 | fTextLeading = 0; |
| 319 | fWordSpace = 0; |
| 320 | fCharSpace = 0; |
| 321 | fHasClipPathToApply = false; |
| 322 | fResources = NULL; |
| 323 | fSkFont = NULL; |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 324 | fLineCap = 0; |
| 325 | fLineJoin = 0; |
| 326 | fMiterLimit = 10.0; |
| 327 | fAphaConstant = 1.0; |
| 328 | fAlphaSource = false; |
| 329 | fDashArrayLength = 0; |
| 330 | fDashPhase = 0; |
edisonn@google.com | e878e72 | 2013-07-29 19:10:58 +0000 | [diff] [blame^] | 331 | fBlendModesLength = 1; |
| 332 | fBlendModes[0] = SkXfermode::kSrc_Mode; // PDF: Normal Blend mode |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 333 | } |
| 334 | |
edisonn@google.com | a0cefa1 | 2013-07-28 18:34:14 +0000 | [diff] [blame] | 335 | // TODO(edisonn): make two functons instead, stroking and non stoking, avoid branching |
| 336 | void applyGraphicsState(SkPaint* paint, bool stroking); |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 337 | }; |
| 338 | |
| 339 | // TODO(edisonn): better class design. |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 340 | // TODO(edisonn): could we remove it? |
| 341 | // TODO(edisonn): rename to SkPdfInlineImage |
| 342 | struct SkPdfInlineImage { |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 343 | std::map<std::string, std::string> fKeyValuePairs; |
| 344 | std::string fImageData; |
| 345 | }; |
| 346 | |
| 347 | // TODO(edisonn): better class design. |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 348 | // TODO(edisonn): rename to SkPdfContext |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 349 | struct PdfContext { |
| 350 | std::stack<SkPdfObject*> fObjectStack; |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 351 | std::stack<SkPdfGraphicsState> fStateStack; |
| 352 | SkPdfGraphicsState fGraphicsState; |
edisonn@google.com | 571c70b | 2013-07-10 17:09:50 +0000 | [diff] [blame] | 353 | SkNativeParsedPDF* fPdfDoc; |
edisonn@google.com | 2ccc3af | 2013-07-23 17:43:18 +0000 | [diff] [blame] | 354 | // TODO(edisonn): the allocator, could be freed after the page is done drawing. |
| 355 | SkPdfAllocator* fTmpPageAllocator; |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 356 | SkMatrix fOriginalMatrix; |
| 357 | |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 358 | SkPdfInlineImage fInlineImage; |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 359 | |
edisonn@google.com | 2ccc3af | 2013-07-23 17:43:18 +0000 | [diff] [blame] | 360 | PdfContext(SkNativeParsedPDF* doc); |
| 361 | ~PdfContext(); |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 362 | }; |
| 363 | |
edisonn@google.com | 3aac1f9 | 2013-07-02 22:42:53 +0000 | [diff] [blame] | 364 | // TODO(edisonn): temporary code, to report how much of the PDF we actually think we rendered. |
| 365 | // TODO(edisonn): rename to SkPdfResult |
edisonn@google.com | b857a0c | 2013-06-25 20:45:40 +0000 | [diff] [blame] | 366 | enum PdfResult { |
| 367 | kOK_PdfResult, |
| 368 | kPartial_PdfResult, |
| 369 | kNYI_PdfResult, |
| 370 | kIgnoreError_PdfResult, |
| 371 | kError_PdfResult, |
| 372 | kUnsupported_PdfResult, |
| 373 | |
| 374 | kCount_PdfResult |
| 375 | }; |
| 376 | |
| 377 | #endif // __DEFINED__SkPdfBasics |