OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkPdfGraphicsState_DEFINED | 8 #ifndef SkPdfGraphicsState_DEFINED |
9 #define SkPdfGraphicsState_DEFINED | 9 #define SkPdfGraphicsState_DEFINED |
10 | 10 |
11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
12 #include "SkPaint.h" | 12 #include "SkPaint.h" |
13 #include "SkPdfConfig.h" | 13 #include "SkPdfConfig.h" |
14 #include "SkPdfUtils.h" | 14 #include "SkPdfUtils.h" |
| 15 #include "SkTDStackNester.h" |
15 | 16 |
16 class SkPdfAllocator; | 17 class SkPdfAllocator; |
17 class SkPdfFont; | 18 class SkPdfFont; |
18 class SkPdfDoc; | 19 class SkPdfDoc; |
19 class SkPdfNativeDoc; | 20 class SkPdfNativeDoc; |
20 class SkPdfNativeObject; | 21 class SkPdfNativeObject; |
21 class SkPdfResourceDictionary; | 22 class SkPdfResourceDictionary; |
22 class SkPdfSoftMaskDictionary; | 23 class SkPdfSoftMaskDictionary; |
23 #include "SkTypes.h" | |
24 | 24 |
25 | 25 /** \class SkPdfColorOperator |
26 // TODO(edisonn): move SkTDStackNester class in its own private file | |
27 | |
28 // Adobe limits it to 28, so 256 should be more than enough | |
29 #define MAX_NESTING 256 | |
30 | |
31 /** \class SkTDStackNester | |
32 * | |
33 * The difference between SkTDStackNester and SkTDStack is that: | |
34 * - SkTDStackNester uses new/delete to manage initializations | |
35 * - Supports nest/unnest which simulates a stack of stack. unnest will pop al
l the | |
36 * objects pushed since the last nest | |
37 */ | |
38 | |
39 template <typename T> class SkTDStackNester : SkNoncopyable { | |
40 public: | |
41 SkTDStackNester() : fCount(0), fTotalCount(0), fLocalCount(0) { | |
42 fInitialRec.fNext = NULL; | |
43 fRec = &fInitialRec; | |
44 | |
45 // fCount = kSlotCount; | |
46 } | |
47 | |
48 ~SkTDStackNester() { | |
49 Rec* rec = fRec; | |
50 while (rec != &fInitialRec) { | |
51 Rec* next = rec->fNext; | |
52 delete rec; | |
53 rec = next; | |
54 } | |
55 } | |
56 | |
57 int count() const { return fLocalCount; } | |
58 int depth() const { return fLocalCount; } | |
59 bool empty() const { return fLocalCount == 0; } | |
60 | |
61 int nests() { | |
62 return fNestingLevel; | |
63 } | |
64 | |
65 void nest() { | |
66 // We are are past max nesting levels, we will still continue to work, b
ut we might fail | |
67 // to properly ignore errors. Ideally it should only mean poor rendering
in exceptional | |
68 // cases | |
69 if (fNestingLevel >= 0 && fNestingLevel < MAX_NESTING) { | |
70 fNestings[fNestingLevel] = fLocalCount; | |
71 fLocalCount = 0; | |
72 } | |
73 fNestingLevel++; | |
74 } | |
75 | |
76 void unnest() { | |
77 SkASSERT(fNestingLevel > 0); | |
78 fNestingLevel--; | |
79 if (fNestingLevel >= 0 && fNestingLevel < MAX_NESTING) { | |
80 // TODO(edisonn): warn if fLocal > 0 | |
81 while (fLocalCount > 0) { | |
82 pop(); | |
83 } | |
84 fLocalCount = fNestings[fNestingLevel]; | |
85 } | |
86 } | |
87 | |
88 T* push() { | |
89 SkASSERT(fCount <= kSlotCount); | |
90 if (fCount == kSlotCount) { | |
91 Rec* rec = new Rec(); | |
92 rec->fNext = fRec; | |
93 fRec = rec; | |
94 fCount = 0; | |
95 } | |
96 ++fTotalCount; | |
97 ++fLocalCount; | |
98 return &fRec->fSlots[fCount++]; | |
99 } | |
100 | |
101 void push(const T& elem) { *this->push() = elem; } | |
102 | |
103 const T& index(int idx) const { | |
104 SkASSERT(fRec && fCount > idx); | |
105 return fRec->fSlots[fCount - idx - 1]; | |
106 } | |
107 | |
108 T& index(int idx) { | |
109 SkASSERT(fRec && fCount > idx); | |
110 return fRec->fSlots[fCount - idx - 1]; | |
111 } | |
112 | |
113 const T& top() const { | |
114 SkASSERT(fRec && fCount > 0); | |
115 return fRec->fSlots[fCount - 1]; | |
116 } | |
117 | |
118 T& top() { | |
119 SkASSERT(fRec && fCount > 0); | |
120 return fRec->fSlots[fCount - 1]; | |
121 } | |
122 | |
123 void pop(T* elem) { | |
124 if (elem) { | |
125 *elem = fRec->fSlots[fCount - 1]; | |
126 } | |
127 this->pop(); | |
128 } | |
129 | |
130 void pop() { | |
131 SkASSERT(fCount > 0 && fRec); | |
132 --fLocalCount; | |
133 --fTotalCount; | |
134 if (--fCount == 0) { | |
135 if (fRec != &fInitialRec) { | |
136 Rec* rec = fRec->fNext; | |
137 delete fRec; | |
138 fCount = kSlotCount; | |
139 fRec = rec; | |
140 } else { | |
141 SkASSERT(fTotalCount == 0); | |
142 } | |
143 } | |
144 } | |
145 | |
146 private: | |
147 enum { | |
148 kSlotCount = 64 | |
149 }; | |
150 | |
151 struct Rec; | |
152 friend struct Rec; | |
153 | |
154 struct Rec { | |
155 Rec* fNext; | |
156 T fSlots[kSlotCount]; | |
157 }; | |
158 Rec fInitialRec; | |
159 Rec* fRec; | |
160 int fCount, fTotalCount, fLocalCount; | |
161 int fNestings[MAX_NESTING]; | |
162 int fNestingLevel; | |
163 }; | |
164 | |
165 /** \class SkTDStackNester | |
166 * Operates on stroking or non-stroking properties. | 26 * Operates on stroking or non-stroking properties. |
167 */ | 27 */ |
168 class SkPdfColorOperator { | 28 class SkPdfColorOperator { |
169 | 29 |
170 /* | 30 /* |
171 color space name or array The current color space in which color value
s are to be interpreted | 31 color space name or array The current color space in which color value
s are to be interpreted |
172 (see Section 4.5, “Color Spaces”). There are
two separate color space | 32 (see Section 4.5, “Color Spaces”). There are
two separate color space |
173 parameters: one for stroking and one for all
other painting opera- | 33 parameters: one for stroking and one for all
other painting opera- |
174 tions. Initial value: DeviceGray. | 34 tions. Initial value: DeviceGray. |
175 */ | 35 */ |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 SkPdfGraphicsState fGraphicsState; | 365 SkPdfGraphicsState fGraphicsState; |
506 SkPdfNativeDoc* fPdfDoc; | 366 SkPdfNativeDoc* fPdfDoc; |
507 SkPdfAllocator* fTmpPageAllocator; | 367 SkPdfAllocator* fTmpPageAllocator; |
508 SkMatrix fOriginalMatrix; | 368 SkMatrix fOriginalMatrix; |
509 | 369 |
510 SkPdfContext(SkPdfNativeDoc* doc); | 370 SkPdfContext(SkPdfNativeDoc* doc); |
511 ~SkPdfContext(); | 371 ~SkPdfContext(); |
512 }; | 372 }; |
513 | 373 |
514 #endif // SkPdfGraphicsState_DEFINED | 374 #endif // SkPdfGraphicsState_DEFINED |
OLD | NEW |