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
16class SkPdfFont;
17class SkPdfNativeObject;
18class SkPdfResourceDictionary;
19class SkPdfSoftMaskDictionary;
20
21/** \class SkPdfColorOperator
22 *   Operates on stroking or non-stroking properties.
23 */
24class 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
35public:
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
51public:
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.
59    SkPdfColorOperator() : fPattern(NULL), fColor(SK_ColorBLACK), fOpacity(1) {
60        NotOwnedString::init(&fColorSpace, "DeviceRGB");
61    }
62
63    void setColorSpace(NotOwnedString* colorSpace) {
64        fColorSpace = *colorSpace;
65        fPattern = NULL;
66    }
67
68    void setPatternColorSpace(SkPdfNativeObject* pattern) {
69        fColorSpace.fBuffer = (const unsigned char*)"Pattern";
70        fColorSpace.fBytes = 7;  // strlen("Pattern")
71        fPattern = pattern;
72    }
73
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 */
82struct 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/*
116clipping 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/*
129text 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/*
142line 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/*
149line 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/*
157line 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/*
165miter 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/*
174dash 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/*
184rendering 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/*
191stroke 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/*
202blend 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/*
213soft 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/*
228alpha 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/*
240alpha 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/*
252overprint          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/*
263overprint 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/*
271black 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/*
279undercolor 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/*
288transfer           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/*
296halftone           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/*
303flatness            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/*
312smoothness             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, ...
322    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