blob: 7ed1fd3c6ab692479c00189e924bb5134b0cdb31 [file] [log] [blame]
edisonn@google.comb857a0c2013-06-25 20:45:40 +00001#ifndef __DEFINED__SkPdfBasics
2#define __DEFINED__SkPdfBasics
3
edisonn@google.com131d4ee2013-06-26 17:48:12 +00004#include "SkCanvas.h"
5#include "SkPaint.h"
edisonn@google.com3aac1f92013-07-02 22:42:53 +00006#include "SkPdfConfig.h"
edisonn@google.com3aa35552013-08-14 18:26:20 +00007#include "SkPdfUtils.h"
edisonn@google.com131d4ee2013-06-26 17:48:12 +00008
edisonn@google.com063d7072013-08-16 15:05:08 +00009//#include "SkTDStack.h"
edisonn@google.comb857a0c2013-06-25 20:45:40 +000010
edisonn@google.comb857a0c2013-06-25 20:45:40 +000011class SkPdfFont;
12class SkPdfDoc;
edisonn@google.com3aa35552013-08-14 18:26:20 +000013class SkPdfNativeObject;
edisonn@google.com131d4ee2013-06-26 17:48:12 +000014class SkPdfResourceDictionary;
edisonn@google.com4ef4bed2013-07-29 22:14:45 +000015class SkPdfSoftMaskDictionary;
edisonn@google.comb857a0c2013-06-25 20:45:40 +000016
edisonn@google.com3aa35552013-08-14 18:26:20 +000017class SkPdfNativeDoc;
edisonn@google.com2ccc3af2013-07-23 17:43:18 +000018class SkPdfAllocator;
edisonn@google.com3aac1f92013-07-02 22:42:53 +000019
edisonn@google.com063d7072013-08-16 15:05:08 +000020// TODO(edisonn): move this class in iclude/core?
21// Ref objects can't be dealt unless we use a specific class initialization
22// The difference between SkTDStackNew and SkTDStack is that SkTDStackNew uses new/delete
23// to be a manage c++ stuff (like initializations)
24#include "SkTypes.h"
25template <typename T> class SkTDStackNew : SkNoncopyable {
26public:
27 SkTDStackNew() : fCount(0), fTotalCount(0) {
28 fInitialRec.fNext = NULL;
29 fRec = &fInitialRec;
30
31 // fCount = kSlotCount;
32 }
33
34 ~SkTDStackNew() {
35 Rec* rec = fRec;
36 while (rec != &fInitialRec) {
37 Rec* next = rec->fNext;
38 delete rec;
39 rec = next;
40 }
41 }
42
43 int count() const { return fTotalCount; }
44 int depth() const { return fTotalCount; }
45 bool empty() const { return fTotalCount == 0; }
46
47 T* push() {
48 SkASSERT(fCount <= kSlotCount);
49 if (fCount == kSlotCount) {
50 Rec* rec = new Rec();
51 rec->fNext = fRec;
52 fRec = rec;
53 fCount = 0;
54 }
55 ++fTotalCount;
56 return &fRec->fSlots[fCount++];
57 }
58
59 void push(const T& elem) { *this->push() = elem; }
60
61 const T& index(int idx) const {
62 SkASSERT(fRec && fCount > idx);
63 return fRec->fSlots[fCount - idx - 1];
64 }
65
66 T& index(int idx) {
67 SkASSERT(fRec && fCount > idx);
68 return fRec->fSlots[fCount - idx - 1];
69 }
70
71 const T& top() const {
72 SkASSERT(fRec && fCount > 0);
73 return fRec->fSlots[fCount - 1];
74 }
75
76 T& top() {
77 SkASSERT(fRec && fCount > 0);
78 return fRec->fSlots[fCount - 1];
79 }
80
81 void pop(T* elem) {
82 if (elem) {
83 *elem = fRec->fSlots[fCount - 1];
84 }
85 this->pop();
86 }
87
88 void pop() {
89 SkASSERT(fCount > 0 && fRec);
90 --fTotalCount;
91 if (--fCount == 0) {
92 if (fRec != &fInitialRec) {
93 Rec* rec = fRec->fNext;
94 delete fRec;
95 fCount = kSlotCount;
96 fRec = rec;
97 } else {
98 SkASSERT(fTotalCount == 0);
99 }
100 }
101 }
102
103private:
104 enum {
105 kSlotCount = 64
106 };
107
108 struct Rec;
109 friend struct Rec;
110
111 struct Rec {
112 Rec* fNext;
113 T fSlots[kSlotCount];
114 };
115 Rec fInitialRec;
116 Rec* fRec;
117 int fCount, fTotalCount;
118};
119
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000120// TODO(edisonn): better class design.
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000121class SkPdfColorOperator {
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000122
123 /*
124 color space name or array The current color space in which color values are to be interpreted
125 (see Section 4.5, “Color Spaces”). There are two separate color space
126 parameters: one for stroking and one for all other painting opera-
127 tions. Initial value: DeviceGray.
128 */
129
130 // TODO(edisonn): implement the array part too
edisonn@google.com571c70b2013-07-10 17:09:50 +0000131 // does not own the char*
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000132// TODO(edisonn): remove this public, let fields be private
133// TODO(edisonn): make color space an enum!
134public:
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000135 NotOwnedString fColorSpace;
edisonn@google.com3aa35552013-08-14 18:26:20 +0000136 SkPdfNativeObject* fPattern;
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000137
138 /*
139 color (various) The current color to be used during painting operations (see Section
140 4.5, “Color Spaces”). The type and interpretation of this parameter
141 depend on the current color space; for most color spaces, a color
142 value consists of one to four numbers. There are two separate color
143 parameters: one for stroking and one for all other painting opera-
144 tions. Initial value: black.
145 */
146
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000147 SkColor fColor;
148 double fOpacity; // ca or CA
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000149
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000150 // TODO(edisonn): add here other color space options.
151
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000152public:
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000153 void setRGBColor(SkColor color) {
154 // TODO(edisonn): ASSERT DeviceRGB is the color space.
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000155 fPattern = NULL;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000156 fColor = color;
157 }
158 // TODO(edisonn): double check the default values for all fields.
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000159 SkPdfColorOperator() : fPattern(NULL), fColor(SK_ColorBLACK), fOpacity(1) {
160 NotOwnedString::init(&fColorSpace, "DeviceRGB");
161 }
162
163 void setColorSpace(NotOwnedString* colorSpace) {
164 fColorSpace = *colorSpace;
165 fPattern = NULL;
166 }
167
edisonn@google.com3aa35552013-08-14 18:26:20 +0000168 void setPatternColorSpace(SkPdfNativeObject* pattern) {
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000169 fColorSpace.fBuffer = (const unsigned char*)"Pattern";
170 fColorSpace.fBytes = 7; // strlen("Pattern")
171 fPattern = pattern;
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000172 }
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000173
174 void applyGraphicsState(SkPaint* paint) {
edisonn@google.com96ba3aa2013-07-28 20:04:35 +0000175 paint->setColor(SkColorSetA(fColor, (U8CPU)(fOpacity * 255)));
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000176 }
177};
178
179// TODO(edisonn): better class design.
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000180struct SkPdfGraphicsState {
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000181 // TODO(edisonn): deprecate and remove these!
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000182 double fCurPosX;
183 double fCurPosY;
184
185 double fCurFontSize;
186 bool fTextBlock;
187 SkPdfFont* fSkFont;
188 SkPath fPath;
189 bool fPathClosed;
190
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000191 double fTextLeading;
192 double fWordSpace;
193 double fCharSpace;
194
195 SkPdfResourceDictionary* fResources;
196
197
198 // TODO(edisonn): move most of these in canvas/paint?
199 // we could have some in canvas (matrixes?),
200 // some in 2 paints (stroking paint and non stroking paint)
201
202// TABLE 4.2 Device-independent graphics state parameters
203/*
204 * CTM array The current transformation matrix, which maps positions from user
205 coordinates to device coordinates (see Section 4.2, “Coordinate Sys-
206 tems”). This matrix is modified by each application of the coordi-
207 nate transformation operator, cm. Initial value: a matrix that
208 transforms default user coordinates to device coordinates.
209 */
210 SkMatrix fCTM;
211
edisonn@google.com0f901902013-08-07 11:56:16 +0000212 SkMatrix fContentStreamMatrix;
213
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000214/*
215clipping path (internal) The current clipping path, which defines the boundary against
216 which all output is to be cropped (see Section 4.4.3, “Clipping Path
217 Operators”). Initial value: the boundary of the entire imageable
218 portion of the output page.
219 */
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000220 // Clip that is applied after the drawing is done!!!
221 bool fHasClipPathToApply;
222 SkPath fClipPath;
223
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000224 SkPdfColorOperator fStroking;
225 SkPdfColorOperator fNonStroking;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000226
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000227/*
228text state (various) A set of nine graphics state parameters that pertain only to the
229 painting of text. These include parameters that select the font, scale
230 the glyphs to an appropriate size, and accomplish other effects. The
231 text state parameters are described in Section 5.2, “Text State
232 Parameters and Operators.”
233 */
234
235 // TODO(edisonn): add SkPdfTextState class. remove these two existing fields
236 SkMatrix fMatrixTm;
237 SkMatrix fMatrixTlm;
238
239
240/*
241line width number The thickness, in user space units, of paths to be stroked (see “Line
242 Width” on page 152). Initial value: 1.0.
243 */
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000244 double fLineWidth;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000245
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000246
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000247/*
248line cap integer A code specifying the shape of the endpoints for any open path that
249 is stroked (see “Line Cap Style” on page 153). Initial value: 0, for
250 square butt caps.
251 */
252 // TODO (edisonn): implement defaults - page 153
253 int fLineCap;
254
255/*
256line join integer A code specifying the shape of joints between connected segments
257 of a stroked path (see “Line Join Style” on page 153). Initial value: 0,
258 for mitered joins.
259 */
260 // TODO (edisonn): implement defaults - page 153
261 int fLineJoin;
262
263/*
264miter limit number The maximum length of mitered line joins for stroked paths (see
265 “Miter Limit” on page 153). This parameter limits the length of
266 “spikes” produced when line segments join at sharp angles. Initial
267 value: 10.0, for a miter cutoff below approximately 11.5 degrees.
268 */
269 // TODO (edisonn): implement defaults - page 153
270 double fMiterLimit;
271
272/*
273dash pattern array and A description of the dash pattern to be used when paths are
274 number stroked (see “Line Dash Pattern” on page 155). Initial value: a solid
275 line.
276 */
277 SkScalar fDashArray[256]; // TODO(edisonn): allocate array?
278 int fDashArrayLength;
279 SkScalar fDashPhase;
280
281
282/*
283rendering intent name The rendering intent to be used when converting CIE-based colors
284 to device colors (see “Rendering Intents” on page 197). Default
285 value: RelativeColorimetric.
286 */
287 // TODO(edisonn): seems paper only. Verify.
288
289/*
290stroke adjustment boolean (PDF 1.2) A flag specifying whether to compensate for possible ras-
291 terization effects when stroking a path with a line width that is
292 small relative to the pixel resolution of the output device (see Sec-
293 tion 6.5.4, “Automatic Stroke Adjustment”). Note that this is con-
294 sidered a device-independent parameter, even though the details of
295 its effects are device-dependent. Initial value: false.
296 */
297 // TODO(edisonn): stroke adjustment low priority.
298
299
300/*
301blend mode name or array (PDF 1.4) The current blend mode to be used in the transparent
302 imaging model (see Sections 7.2.4, “Blend Mode,” and 7.5.2, “Spec-
303 ifying Blending Color Space and Blend Mode”). This parameter is
304 implicitly reset to its initial value at the beginning of execution of a
305 transparency group XObject (see Section 7.5.5, “Transparency
306 Group XObjects”). Initial value: Normal.
307 */
edisonn@google.come878e722013-07-29 19:10:58 +0000308 SkXfermode::Mode fBlendModes[256];
309 int fBlendModesLength;
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000310
311/*
312soft mask dictionary (PDF 1.4) A soft-mask dictionary (see “Soft-Mask Dictionaries” on
313 or name page 445) specifying the mask shape or mask opacity values to be
314 used in the transparent imaging model (see “Source Shape and
315 Opacity” on page 421 and “Mask Shape and Opacity” on page 443),
316 or the name None if no such mask is specified. This parameter is
317 implicitly reset to its initial value at the beginning of execution of a
318 transparency group XObject (see Section 7.5.5, “Transparency
319 Group XObjects”). Initial value: None.
320 */
edisonn@google.com4ef4bed2013-07-29 22:14:45 +0000321 SkPdfSoftMaskDictionary* fSoftMaskDictionary;
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000322 // TODO(edisonn): make sMask private, add setter and getter, ref/unref/..., at the moment we most likely leask
323 SkBitmap* fSMask;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000324
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000325
326/*
327alpha constant number (PDF 1.4) The constant shape or constant opacity value to be used
328 in the transparent imaging model (see “Source Shape and Opacity”
329 on page 421 and “Constant Shape and Opacity” on page 444).
330 There are two separate alpha constant parameters: one for stroking
331 and one for all other painting operations. This parameter is implic-
332 itly reset to its initial value at the beginning of execution of a trans-
333 parency group XObject (see Section 7.5.5, “Transparency Group
334 XObjects”). Initial value: 1.0.
335 */
336 double fAphaConstant;
337
338/*
339alpha source boolean (PDF 1.4) A flag specifying whether the current soft mask and alpha
340 constant parameters are to be interpreted as shape values (true) or
341 opacity values (false). This flag also governs the interpretation of
342 the SMask entry, if any, in an image dictionary (see Section 4.8.4,
343 “Image Dictionaries”). Initial value: false.
344 */
345 bool fAlphaSource;
346
347
348// TODO(edisonn): Device-dependent seem to be required only on the actual physical printer?
349// TABLE 4.3 Device-dependent graphics state parameters
350/*
351overprint boolean (PDF 1.2) A flag specifying (on output devices that support the
352 overprint control feature) whether painting in one set of colorants
353 should cause the corresponding areas of other colorants to be
354 erased (false) or left unchanged (true); see Section 4.5.6, “Over-
355 print Control.” In PDF 1.3, there are two separate overprint param-
356 eters: one for stroking and one for all other painting operations.
357 Initial value: false.
358 */
359
360
361/*
362overprint mode number (PDF 1.3) A code specifying whether a color component value of 0
363 in a DeviceCMYK color space should erase that component (0) or
364 leave it unchanged (1) when overprinting (see Section 4.5.6, “Over-
365 print Control”). Initial value: 0.
366 */
367
368
369/*
370black generation function (PDF 1.2) A function that calculates the level of the black color
371 or name component to use when converting RGB colors to CMYK (see Sec-
372 tion 6.2.3, “Conversion from DeviceRGB to DeviceCMYK”). Initial
373 value: installation-dependent.
374 */
375
376
377/*
378undercolor removal function (PDF 1.2) A function that calculates the reduction in the levels of
379 or name the cyan, magenta, and yellow color components to compensate for
380 the amount of black added by black generation (see Section 6.2.3,
381 “Conversion from DeviceRGB to DeviceCMYK”). Initial value: in-
382 stallation-dependent.
383 */
384
385
386/*
387transfer function, (PDF 1.2) A function that adjusts device gray or color component
388 array, or name levels to compensate for nonlinear response in a particular out-
389 put device (see Section 6.3, “Transfer Functions”). Initial value:
390 installation-dependent.
391 */
392
393
394/*
395halftone dictionary, (PDF 1.2) A halftone screen for gray and color rendering, specified
396 stream, or name as a halftone dictionary or stream (see Section 6.4, “Halftones”).
397 Initial value: installation-dependent.
398 */
399
400
401/*
402flatness number The precision with which curves are to be rendered on the output
403 device (see Section 6.5.1, “Flatness Tolerance”). The value of this
404 parameter gives the maximum error tolerance, measured in output
405 device pixels; smaller numbers give smoother curves at the expense
406 of more computation and memory use. Initial value: 1.0.
407 */
408
409
410/*
411smoothness number (PDF 1.3) The precision with which color gradients are to be ren-
412 dered on the output device (see Section 6.5.2, “Smoothness Toler-
413 ance”). The value of this parameter gives the maximum error
414 tolerance, expressed as a fraction of the range of each color compo-
415 nent; smaller numbers give smoother color transitions at the
416 expense of more computation and memory use. Initial value:
417 installation-dependent.
418 */
419
420
421
422
423
424
425
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000426 SkPdfGraphicsState() {
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000427 fCurPosX = 0.0;
428 fCurPosY = 0.0;
429 fCurFontSize = 0.0;
430 fTextBlock = false;
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000431 fCTM = SkMatrix::I();
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000432 fMatrixTm = SkMatrix::I();
433 fMatrixTlm = SkMatrix::I();
434 fPathClosed = true;
435 fLineWidth = 0;
436 fTextLeading = 0;
437 fWordSpace = 0;
438 fCharSpace = 0;
439 fHasClipPathToApply = false;
440 fResources = NULL;
441 fSkFont = NULL;
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000442 fLineCap = 0;
443 fLineJoin = 0;
444 fMiterLimit = 10.0;
445 fAphaConstant = 1.0;
446 fAlphaSource = false;
447 fDashArrayLength = 0;
448 fDashPhase = 0;
edisonn@google.come878e722013-07-29 19:10:58 +0000449 fBlendModesLength = 1;
450 fBlendModes[0] = SkXfermode::kSrc_Mode; // PDF: Normal Blend mode
edisonn@google.com91ce6982013-08-05 20:45:40 +0000451 fSMask = NULL;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000452 }
453
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000454 // TODO(edisonn): make two functons instead, stroking and non stoking, avoid branching
455 void applyGraphicsState(SkPaint* paint, bool stroking);
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000456};
457
458// TODO(edisonn): better class design.
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000459// TODO(edisonn): rename to SkPdfContext
edisonn@google.com33f11b62013-08-14 21:35:27 +0000460class SkPdfContext {
461public:
edisonn@google.com063d7072013-08-16 15:05:08 +0000462 SkTDStackNew<SkPdfNativeObject*> fObjectStack;
463 SkTDStackNew<SkPdfGraphicsState> fStateStack;
edisonn@google.com3aac1f92013-07-02 22:42:53 +0000464 SkPdfGraphicsState fGraphicsState;
edisonn@google.com33f11b62013-08-14 21:35:27 +0000465 SkPdfNativeDoc* fPdfDoc;
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000466 // TODO(edisonn): the allocator, could be freed after the page is done drawing.
467 SkPdfAllocator* fTmpPageAllocator;
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000468 SkMatrix fOriginalMatrix;
469
edisonn@google.com3aa35552013-08-14 18:26:20 +0000470 SkPdfContext(SkPdfNativeDoc* doc);
471 ~SkPdfContext();
edisonn@google.comb857a0c2013-06-25 20:45:40 +0000472};
473
474#endif // __DEFINED__SkPdfBasics