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