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 #include "SkPdfRenderer.h" | 8 #include "SkPdfRenderer.h" |
9 | 9 |
10 #include "SkBitmapDevice.h" | 10 #include "SkBitmapDevice.h" |
11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
12 #include "SkDevice.h" | 12 #include "SkDevice.h" |
13 #include "SkForceLinking.h" | 13 #include "SkForceLinking.h" |
14 #include "SkGraphics.h" | 14 #include "SkGraphics.h" |
15 #include "SkImageDecoder.h" | 15 #include "SkImageDecoder.h" |
16 #include "SkImageEncoder.h" | 16 #include "SkImageEncoder.h" |
17 #include "SkOSFile.h" | 17 #include "SkOSFile.h" |
18 #include "SkPicture.h" | 18 #include "SkPicture.h" |
| 19 #include "SkPdfFont.h" |
| 20 #include "SkPdfGraphicsState.h" |
| 21 #include "SkPdfHeaders_autogen.h" |
| 22 #include "SkPdfMapper_autogen.h" |
| 23 #include "SkPdfNativeTokenizer.h" |
| 24 #include "SkPdfRenderer.h" |
| 25 #include "SkPdfReporter.h" |
| 26 #include "SkPdfUtils.h" |
19 #include "SkStream.h" | 27 #include "SkStream.h" |
20 #include "SkTypeface.h" | 28 #include "SkTypeface.h" |
21 #include "SkTArray.h" | 29 #include "SkTArray.h" |
22 #include "SkTDict.h" | 30 #include "SkTDict.h" |
23 | 31 |
24 #include "SkPdfGraphicsState.h" | 32 // TODO(edisonn): #ifdef these ones, as they are used only for debugging. |
25 #include "SkPdfNativeTokenizer.h" | |
26 #include "SkPdfReporter.h" | |
27 | |
28 extern "C" SkPdfContext* gPdfContext; | 33 extern "C" SkPdfContext* gPdfContext; |
29 extern "C" SkBitmap* gDumpBitmap; | 34 extern "C" SkBitmap* gDumpBitmap; |
30 extern "C" SkCanvas* gDumpCanvas; | 35 extern "C" SkCanvas* gDumpCanvas; |
31 | 36 |
32 | |
33 __SK_FORCE_IMAGE_DECODER_LINKING; | 37 __SK_FORCE_IMAGE_DECODER_LINKING; |
34 | 38 |
35 // TODO(edisonn): tool, show what objects were read at least, show the ones not
even read | 39 // TODO(edisonn): tool, show what objects were read during rendering - will help
to identify |
36 // keep for each object pos in file | 40 // features with incomplete implementation |
37 // plug in for VS? syntax coloring, show selected object ... from the text, or f
rom rendered x,y | 41 // TODO(edisonn): security - validate all the user input, all pdf! |
| 42 // TODO(edisonn): testability -add option to render without text, or only render
text |
38 | 43 |
39 // TODO(edisonn): security - validate all the user input, all pdf! | 44 // Helper macros to load variables from stack, and automatically check their typ
e. |
40 | |
41 // TODO(edisonn): put drawtext in #ifdefs, so comparations will ignore minor cha
nges in text positioning and font | |
42 // this way, we look more at other features and layout in diffs | |
43 | |
44 // TODO(edisonn): move trace dump in the get functions, and mapper ones too so i
t ghappens automatically | |
45 /* | |
46 #ifdef PDF_TRACE | |
47 SkString str; | |
48 pdfContext->fGraphicsState.fResources->native()->ToString(str); | |
49 printf("Print Tf Resources: %s\n", str.c_str()); | |
50 #endif | |
51 */ | |
52 | |
53 #include "SkPdfHeaders_autogen.h" | |
54 #include "SkPdfMapper_autogen.h" | |
55 #include "SkPdfRenderer.h" | |
56 | |
57 #include "SkPdfUtils.h" | |
58 | |
59 #include "SkPdfFont.h" | |
60 | |
61 /* | |
62 * TODO(edisonn): | |
63 * - all font types and all ppdf font features | |
64 * - word spacing | |
65 * - load font for baidu.pdf | |
66 * - load font for youtube.pdf | |
67 * - parser for pdf from the definition already available in pdfspec_autoge
n.py | |
68 * - all docs from ~/work | |
69 * - encapsulate native in the pdf api so the skpdf does not know anything about
native ... in progress | |
70 * - load gs/ especially smask and already known prop (skp) ... in progress | |
71 * - wrapper on classes for customizations? e.g. | |
72 * SkPdfPageObjectVanila - has only the basic loaders/getters | |
73 * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add custom
izations here | |
74 * need to find a nice object model for all this with constructors and factories | |
75 * - deal with inheritable automatically ? | |
76 * - deal with specific type in spec directly, add all dictionary types to known
types | |
77 */ | |
78 | |
79 #define EXPECT_OPERANDS(name,pdfContext,n) \ | 45 #define EXPECT_OPERANDS(name,pdfContext,n) \ |
80 bool __failed = pdfContext->fObjectStack.count() < n; \ | 46 bool __failed = pdfContext->fObjectStack.count() < n; \ |
81 SkPdfREPORTCODE(const char* __operator_name = name); \ | 47 SkPdfREPORTCODE(const char* __operator_name = name); \ |
82 SkPdfREPORTCODE((void)__operator_name); \ | 48 SkPdfREPORTCODE((void)__operator_name); \ |
83 SkPdfReportIf(pdfContext->fObjectStack.count() < n, kIgnoreError_SkPdfIssueS
everity, kStackOverflow_SkPdfIssue, "Not enought parameters.", NULL, pdfContext)
; \ | 49 SkPdfReportIf(pdfContext->fObjectStack.count() < n, \ |
| 50 kIgnoreError_SkPdfIssueSeverity, \ |
| 51 kStackOverflow_SkPdfIssue, \ |
| 52 "Not enought parameters.", NULL, pdfContext); \ |
84 SkDEBUGCODE(int __cnt = n); | 53 SkDEBUGCODE(int __cnt = n); |
85 | 54 |
86 #define POP_OBJ(pdfContext,name) \ | 55 #define POP_OBJ(pdfContext,name) \ |
87 SkDEBUGCODE(__cnt--); \ | 56 SkDEBUGCODE(__cnt--); \ |
88 SkASSERT(__cnt >= 0); \ | 57 SkASSERT(__cnt >= 0); \ |
89 SkPdfNativeObject* name = NULL; \ | 58 SkPdfNativeObject* name = NULL; \ |
90 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ | 59 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ |
91 if (pdfContext->fObjectStack.count() > 0) { \ | 60 if (pdfContext->fObjectStack.count() > 0) { \ |
92 name = pdfContext->fObjectStack.top(); \ | 61 name = pdfContext->fObjectStack.top(); \ |
93 pdfContext->fObjectStack.pop(); \ | 62 pdfContext->fObjectStack.pop(); \ |
94 } | 63 } |
95 | 64 |
96 // TODO(edisonn): make all pop function to use name##_obj | 65 // TODO(edisonn): make all pop function to use name##_obj |
97 #define POP_NUMBER(pdfContext,name) \ | 66 #define POP_NUMBER(pdfContext,name) \ |
98 SkDEBUGCODE(__cnt--); \ | 67 SkDEBUGCODE(__cnt--); \ |
99 SkASSERT(__cnt >= 0); \ | 68 SkASSERT(__cnt >= 0); \ |
100 double name = 0; \ | 69 double name = 0; \ |
101 SkPdfNativeObject* name##_obj = NULL; \ | 70 SkPdfNativeObject* name##_obj = NULL; \ |
102 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ | 71 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ |
103 if (pdfContext->fObjectStack.count() > 0) { \ | 72 if (pdfContext->fObjectStack.count() > 0) { \ |
104 name##_obj = pdfContext->fObjectStack.top(); \ | 73 name##_obj = pdfContext->fObjectStack.top(); \ |
105 pdfContext->fObjectStack.pop(); \ | 74 pdfContext->fObjectStack.pop(); \ |
106 if (!name##_obj || !name##_obj->isNumber()) { \ | 75 if (!name##_obj || !name##_obj->isNumber()) { \ |
107 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, __operato
r_name, name##_obj, SkPdfNativeObject::_kNumber_PdfObjectType, NULL);\ | 76 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ |
| 77 __operator_name, \ |
| 78 name##_obj, \ |
| 79 SkPdfNativeObject::_kNumber_PdfObjectType,
\ |
| 80 NULL);\ |
108 __failed = true;\ | 81 __failed = true;\ |
109 } else { \ | 82 } else { \ |
110 name = name##_obj->numberValue(); \ | 83 name = name##_obj->numberValue(); \ |
111 } \ | 84 } \ |
112 } | 85 } |
113 | 86 |
114 #define POP_INTEGER(pdfContext,name) \ | 87 #define POP_INTEGER(pdfContext,name) \ |
115 SkDEBUGCODE(__cnt--); \ | 88 SkDEBUGCODE(__cnt--); \ |
116 SkASSERT(__cnt >= 0); \ | 89 SkASSERT(__cnt >= 0); \ |
117 int64_t name = 0; \ | 90 int64_t name = 0; \ |
118 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ | 91 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ |
119 SkPdfNativeObject* name##_obj = NULL; \ | 92 SkPdfNativeObject* name##_obj = NULL; \ |
120 if (pdfContext->fObjectStack.count() > 0) { \ | 93 if (pdfContext->fObjectStack.count() > 0) { \ |
121 name##_obj = pdfContext->fObjectStack.top(); \ | 94 name##_obj = pdfContext->fObjectStack.top(); \ |
122 pdfContext->fObjectStack.pop(); \ | 95 pdfContext->fObjectStack.pop(); \ |
123 if (!name##_obj || !name##_obj->isInteger()) { \ | 96 if (!name##_obj || !name##_obj->isInteger()) { \ |
124 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, __operato
r_name, name##_obj, SkPdfNativeObject::kInteger_PdfObjectType, NULL);\ | 97 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ |
| 98 __operator_name, \ |
| 99 name##_obj, \ |
| 100 SkPdfNativeObject::kInteger_PdfObjectType,
\ |
| 101 NULL);\ |
125 __failed = true;\ | 102 __failed = true;\ |
126 } else { \ | 103 } else { \ |
127 name = name##_obj->intValue(); \ | 104 name = name##_obj->intValue(); \ |
128 } \ | 105 } \ |
129 } | 106 } |
130 | 107 |
131 #define POP_NUMBER_INTO(pdfContext,var) \ | 108 #define POP_NUMBER_INTO(pdfContext,var) \ |
132 SkDEBUGCODE(__cnt--); \ | 109 SkDEBUGCODE(__cnt--); \ |
133 SkASSERT(__cnt >= 0); \ | 110 SkASSERT(__cnt >= 0); \ |
134 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ | 111 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ |
135 if (pdfContext->fObjectStack.count() > 0) { \ | 112 if (pdfContext->fObjectStack.count() > 0) { \ |
136 SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ | 113 SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ |
137 pdfContext->fObjectStack.pop(); \ | 114 pdfContext->fObjectStack.pop(); \ |
138 if (!tmp || !tmp->isNumber()) { \ | 115 if (!tmp || !tmp->isNumber()) { \ |
139 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, __operato
r_name, tmp, SkPdfNativeObject::kInteger_PdfObjectType | SkPdfNativeObject::kRea
l_PdfObjectType, NULL);\ | 116 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ |
| 117 __operator_name, \ |
| 118 tmp, \ |
| 119 SkPdfNativeObject::kInteger_PdfObjectType
| \ |
| 120 SkPdfNativeObject::kReal_PdfObjectType
, \ |
| 121 NULL);\ |
140 __failed = true;\ | 122 __failed = true;\ |
141 } else { \ | 123 } else { \ |
142 var = tmp->numberValue(); \ | 124 var = tmp->numberValue(); \ |
143 } \ | 125 } \ |
144 } | 126 } |
145 | 127 |
146 | 128 |
147 #define POP_NAME(pdfContext,name) \ | 129 #define POP_NAME(pdfContext,name) \ |
148 SkDEBUGCODE(__cnt--); \ | 130 SkDEBUGCODE(__cnt--); \ |
149 SkASSERT(__cnt >= 0); \ | 131 SkASSERT(__cnt >= 0); \ |
150 SkPdfNativeObject* name = NULL; \ | 132 SkPdfNativeObject* name = NULL; \ |
151 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ | 133 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ |
152 if (pdfContext->fObjectStack.count() > 0) { \ | 134 if (pdfContext->fObjectStack.count() > 0) { \ |
153 SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ | 135 SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ |
154 pdfContext->fObjectStack.pop(); \ | 136 pdfContext->fObjectStack.pop(); \ |
155 if (!tmp || !tmp->isName()) { \ | 137 if (!tmp || !tmp->isName()) { \ |
156 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, __operato
r_name, tmp, SkPdfNativeObject::kName_PdfObjectType, NULL);\ | 138 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ |
| 139 __operator_name, \ |
| 140 tmp, \ |
| 141 SkPdfNativeObject::kName_PdfObjectType, \ |
| 142 NULL);\ |
157 __failed = true;\ | 143 __failed = true;\ |
158 } else { \ | 144 } else { \ |
159 name = tmp; \ | 145 name = tmp; \ |
160 } \ | 146 } \ |
161 } | 147 } |
162 | 148 |
163 #define POP_STRING(pdfContext,name) \ | 149 #define POP_STRING(pdfContext,name) \ |
164 SkDEBUGCODE(__cnt--); \ | 150 SkDEBUGCODE(__cnt--); \ |
165 SkASSERT(__cnt >= 0); \ | 151 SkASSERT(__cnt >= 0); \ |
166 SkPdfNativeObject* name = NULL; \ | 152 SkPdfNativeObject* name = NULL; \ |
167 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ | 153 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ |
168 if (pdfContext->fObjectStack.count() > 0) { \ | 154 if (pdfContext->fObjectStack.count() > 0) { \ |
169 SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ | 155 SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ |
170 pdfContext->fObjectStack.pop(); \ | 156 pdfContext->fObjectStack.pop(); \ |
171 if (!tmp || !tmp->isAnyString()) { \ | 157 if (!tmp || !tmp->isAnyString()) { \ |
172 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, __operato
r_name, tmp, SkPdfNativeObject::kString_PdfObjectType | SkPdfNativeObject::kHexS
tring_PdfObjectType, NULL);\ | 158 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ |
| 159 __operator_name, \ |
| 160 tmp, \ |
| 161 SkPdfNativeObject::kString_PdfObjectType |
\ |
| 162 SkPdfNativeObject::kHexString_PdfObjec
tType, \ |
| 163 NULL);\ |
173 __failed = true;\ | 164 __failed = true;\ |
174 } else { \ | 165 } else { \ |
175 name = tmp; \ | 166 name = tmp; \ |
176 } \ | 167 } \ |
177 } | 168 } |
178 | 169 |
179 #define POP_ARRAY(pdfContext,name) \ | 170 #define POP_ARRAY(pdfContext,name) \ |
180 SkDEBUGCODE(__cnt--); \ | 171 SkDEBUGCODE(__cnt--); \ |
181 SkASSERT(__cnt >= 0); \ | 172 SkASSERT(__cnt >= 0); \ |
182 SkPdfArray* name = NULL; \ | 173 SkPdfArray* name = NULL; \ |
183 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ | 174 __failed = __failed || pdfContext->fObjectStack.count() == 0; \ |
184 if (pdfContext->fObjectStack.count() > 0) { \ | 175 if (pdfContext->fObjectStack.count() > 0) { \ |
185 SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ | 176 SkPdfNativeObject* tmp = pdfContext->fObjectStack.top(); \ |
186 pdfContext->fObjectStack.pop(); \ | 177 pdfContext->fObjectStack.pop(); \ |
187 if (!tmp || !tmp->isArray()) { \ | 178 if (!tmp || !tmp->isArray()) { \ |
188 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, __operato
r_name, tmp, SkPdfNativeObject::kArray_PdfObjectType, NULL);\ | 179 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, \ |
| 180 __operator_name, \ |
| 181 tmp, \ |
| 182 SkPdfNativeObject::kArray_PdfObjectType, \ |
| 183 NULL);\ |
189 __failed = true;\ | 184 __failed = true;\ |
190 } else { \ | 185 } else { \ |
191 name = (SkPdfArray*)tmp; \ | 186 name = (SkPdfArray*)tmp; \ |
192 } \ | 187 } \ |
193 } | 188 } |
194 | 189 |
195 // TODO(edisonn): ability to turn on asserts for known good files | |
196 // log error - add name of function? location in file? | |
197 #define CHECK_PARAMETERS() \ | 190 #define CHECK_PARAMETERS() \ |
198 SkASSERT(__cnt == 0); \ | 191 SkASSERT(__cnt == 0); \ |
199 if (__failed) return kIgnoreError_SkPdfResult; | 192 if (__failed) return kIgnoreError_SkPdfResult; |
200 | 193 |
| 194 |
201 NotOwnedString strings_DeviceRGB; | 195 NotOwnedString strings_DeviceRGB; |
202 NotOwnedString strings_DeviceCMYK; | 196 NotOwnedString strings_DeviceCMYK; |
203 | 197 |
204 class StringsInit { | 198 class StringsInit { |
205 public: | 199 public: |
206 StringsInit() { | 200 StringsInit() { |
207 NotOwnedString::init(&strings_DeviceRGB, "DeviceRGB"); | 201 NotOwnedString::init(&strings_DeviceRGB, "DeviceRGB"); |
208 NotOwnedString::init(&strings_DeviceCMYK, "DeviceCMYK"); | 202 NotOwnedString::init(&strings_DeviceCMYK, "DeviceCMYK"); |
209 } | 203 } |
210 }; | 204 }; |
211 | 205 |
| 206 // TODO(edisonn): this will not work in chrome! Find another solution! |
212 StringsInit gStringsInit; | 207 StringsInit gStringsInit; |
213 | 208 |
214 // TODO(edisonn): Document PdfTokenLooper and subclasses. | 209 // TODO(edisonn): Document PdfTokenLooper and subclasses. |
215 class PdfTokenLooper { | 210 class PdfTokenLooper { |
216 protected: | 211 protected: |
217 PdfTokenLooper* fParent; | 212 PdfTokenLooper* fParent; |
218 SkPdfNativeTokenizer* fTokenizer; | 213 SkPdfNativeTokenizer* fTokenizer; |
219 SkPdfContext* fPdfContext; | 214 SkPdfContext* fPdfContext; |
220 SkCanvas* fCanvas; | 215 SkCanvas* fCanvas; |
221 | 216 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 }; | 268 }; |
274 | 269 |
275 // Utilities | 270 // Utilities |
276 static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color
= SK_ColorWHITE) { | 271 static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color
= SK_ColorWHITE) { |
277 bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); | 272 bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); |
278 | 273 |
279 bitmap->allocPixels(); | 274 bitmap->allocPixels(); |
280 bitmap->eraseColor(color); | 275 bitmap->eraseColor(color); |
281 } | 276 } |
282 | 277 |
283 // TODO(edisonn): synonyms? DeviceRGB and RGB ... | 278 // TODO(edisonn): synonyms? /DeviceRGB and /RGB mean the same thing. Context dep
endent. |
284 static int GetColorSpaceComponents(NotOwnedString& colorSpace) { | 279 static int GetColorSpaceComponents(NotOwnedString& colorSpace) { |
285 if (colorSpace.equals("DeviceCMYK")) { | 280 if (colorSpace.equals("DeviceCMYK")) { |
286 return 4; | 281 return 4; |
287 } else if (colorSpace.equals("DeviceGray") || | 282 } else if (colorSpace.equals("DeviceGray") || |
288 colorSpace.equals("CalGray") || | 283 colorSpace.equals("CalGray") || |
289 colorSpace.equals("Indexed")) { | 284 colorSpace.equals("Indexed")) { |
290 return 1; | 285 return 1; |
291 } else if (colorSpace.equals("DeviceRGB") || | 286 } else if (colorSpace.equals("DeviceRGB") || |
292 colorSpace.equals("CalRGB") || | 287 colorSpace.equals("CalRGB") || |
293 colorSpace.equals("Lab")) { | 288 colorSpace.equals("Lab")) { |
(...skipping 16 matching lines...) Expand all Loading... |
310 SkDoubleToScalar(1)); | 305 SkDoubleToScalar(1)); |
311 | 306 |
312 return matrix; | 307 return matrix; |
313 } | 308 } |
314 | 309 |
315 SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { | 310 SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) { |
316 double array[6]; | 311 double array[6]; |
317 | 312 |
318 // TODO(edisonn): security issue, ret if size() != 6 | 313 // TODO(edisonn): security issue, ret if size() != 6 |
319 if (pdfArray == NULL) { | 314 if (pdfArray == NULL) { |
320 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, "nu
ll array passed to build matrix", NULL, NULL); | 315 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, |
| 316 "null array passed to build matrix", NULL, NULL); |
321 return SkMatrix::I(); | 317 return SkMatrix::I(); |
322 } | 318 } |
323 | 319 |
324 if (pdfArray->size() != 6) { | 320 if (pdfArray->size() != 6) { |
325 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnexpectedArraySize_SkPdfI
ssue, "null array passed to build matrix", pdfArray, NULL); | 321 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnexpectedArraySize_SkPdfI
ssue, |
| 322 "null array passed to build matrix", pdfArray, NULL); |
326 return SkMatrix::I(); | 323 return SkMatrix::I(); |
327 } | 324 } |
328 | 325 |
329 for (int i = 0; i < 6; i++) { | 326 for (int i = 0; i < 6; i++) { |
330 const SkPdfNativeObject* elem = pdfArray->operator [](i); | 327 const SkPdfNativeObject* elem = pdfArray->operator [](i); |
331 if (elem == NULL || !elem->isNumber()) { | 328 if (elem == NULL || !elem->isNumber()) { |
332 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, ele
m, SkPdfNativeObject::_kNumber_PdfObjectType, NULL); | 329 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, ele
m, |
| 330 SkPdfNativeObject::_kNumber_PdfObjectType,
NULL); |
333 return SkMatrix::I(); | 331 return SkMatrix::I(); |
334 } | 332 } |
335 array[i] = elem->numberValue(); | 333 array[i] = elem->numberValue(); |
336 } | 334 } |
337 | 335 |
338 return SkMatrixFromPdfMatrix(array); | 336 return SkMatrixFromPdfMatrix(array); |
339 } | 337 } |
340 | 338 |
341 | 339 // TODO(edisonn): debug code, used to analyze rendering when we find bugs. |
342 extern "C" SkPdfNativeDoc* gDoc; | 340 extern "C" SkPdfNativeDoc* gDoc; |
343 SkBitmap* gDumpBitmap = NULL; | 341 SkBitmap* gDumpBitmap = NULL; |
344 SkCanvas* gDumpCanvas = NULL; | 342 SkCanvas* gDumpCanvas = NULL; |
345 char gLastKeyword[100] = ""; | 343 char gLastKeyword[100] = ""; |
346 int gLastOpKeyword = -1; | 344 int gLastOpKeyword = -1; |
347 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
,EI,Do,EX,"; | |
348 int gReadOp = 0; | 345 int gReadOp = 0; |
349 | 346 |
350 | |
351 #ifdef PDF_TRACE_DIFF_IN_PNG | 347 #ifdef PDF_TRACE_DIFF_IN_PNG |
| 348 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh
,EI,Do,EX,"; |
352 static bool hasVisualEffect(const char* pdfOp) { | 349 static bool hasVisualEffect(const char* pdfOp) { |
353 return true; | 350 return true; |
354 if (*pdfOp == '\0') return false; | 351 if (*pdfOp == '\0') return false; |
355 | 352 |
356 char markedPdfOp[100] = ","; | 353 char markedPdfOp[100] = ","; |
357 strcat(markedPdfOp, pdfOp); | 354 strcat(markedPdfOp, pdfOp); |
358 strcat(markedPdfOp, ","); | 355 strcat(markedPdfOp, ","); |
359 | 356 |
360 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); | 357 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); |
361 } | 358 } |
362 #endif // PDF_TRACE_DIFF_IN_PNG | 359 #endif // PDF_TRACE_DIFF_IN_PNG |
363 | 360 |
364 | |
365 | |
366 // TODO(edisonn): Pass SkPdfContext and SkCanvasd only with the define for instr
umentation. | 361 // TODO(edisonn): Pass SkPdfContext and SkCanvasd only with the define for instr
umentation. |
367 static bool readToken(SkPdfNativeTokenizer* fTokenizer, PdfToken* token) { | 362 static bool readToken(SkPdfNativeTokenizer* fTokenizer, PdfToken* token) { |
368 bool ret = fTokenizer->readToken(token); | 363 bool ret = fTokenizer->readToken(token); |
369 | 364 |
370 gReadOp++; | 365 gReadOp++; |
371 gLastOpKeyword++; | 366 gLastOpKeyword++; |
372 #ifdef PDF_TRACE_DIFF_IN_PNG | 367 #ifdef PDF_TRACE_DIFF_IN_PNG |
373 // TODO(edisonn): compare with old bitmap, and save only new bits are availa
ble, and save | 368 // TODO(edisonn): this code is used to make a step by step history of all th
e draw operations |
374 // the numbar and name of last operation, so the file name will reflect op t
hat changed. | 369 // so we could find the step where something is wrong. |
375 if (gLastKeyword[0] && hasVisualEffect(gLastKeyword)) { // TODO(edisonn): a
nd has dirty bits. | 370 if (gLastKeyword[0] && hasVisualEffect(gLastKeyword)) { |
376 gDumpCanvas->flush(); | 371 gDumpCanvas->flush(); |
377 | 372 |
378 SkBitmap bitmap; | 373 SkBitmap bitmap; |
379 setup_bitmap(&bitmap, gDumpBitmap->width(), gDumpBitmap->height()); | 374 setup_bitmap(&bitmap, gDumpBitmap->width(), gDumpBitmap->height()); |
380 | 375 |
381 memcpy(bitmap.getPixels(), gDumpBitmap->getPixels(), gDumpBitmap->getSiz
e()); | 376 memcpy(bitmap.getPixels(), gDumpBitmap->getPixels(), gDumpBitmap->getSiz
e()); |
382 | 377 |
383 SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); | 378 SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); |
384 SkCanvas canvas(device); | 379 SkCanvas canvas(device); |
385 | 380 |
(...skipping 11 matching lines...) Expand all Loading... |
397 const SkClipStack::Element* elem; | 392 const SkClipStack::Element* elem; |
398 double y = 0; | 393 double y = 0; |
399 int total = 0; | 394 int total = 0; |
400 while ((elem = iter.next()) != NULL) { | 395 while ((elem = iter.next()) != NULL) { |
401 total++; | 396 total++; |
402 y += 30; | 397 y += 30; |
403 | 398 |
404 switch (elem->getType()) { | 399 switch (elem->getType()) { |
405 case SkClipStack::Element::kRect_Type: | 400 case SkClipStack::Element::kRect_Type: |
406 canvas.drawRect(elem->getRect(), blueBorder); | 401 canvas.drawRect(elem->getRect(), blueBorder); |
407 canvas.drawText("Rect Clip", strlen("Rect Clip"), SkDoub
leToScalar(10), SkDoubleToScalar(y), blueBorder); | 402 canvas.drawText("Rect Clip", strlen("Rect Clip"), |
| 403 SkDoubleToScalar(10), SkDoubleToScalar(y
), blueBorder); |
408 break; | 404 break; |
409 case SkClipStack::Element::kPath_Type: | 405 case SkClipStack::Element::kPath_Type: |
410 canvas.drawPath(elem->getPath(), blueBorder); | 406 canvas.drawPath(elem->getPath(), blueBorder); |
411 canvas.drawText("Path Clip", strlen("Path Clip"), SkDoub
leToScalar(10), SkDoubleToScalar(y), blueBorder); | 407 canvas.drawText("Path Clip", strlen("Path Clip"), |
| 408 SkDoubleToScalar(10), SkDoubleToScalar(y
), blueBorder); |
412 break; | 409 break; |
413 case SkClipStack::Element::kEmpty_Type: | 410 case SkClipStack::Element::kEmpty_Type: |
414 canvas.drawText("Empty Clip!!!", strlen("Empty Clip!!!")
, SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder); | 411 canvas.drawText("Empty Clip!!!", strlen("Empty Clip!!!")
, |
| 412 SkDoubleToScalar(10), SkDoubleToScalar(y
), blueBorder); |
415 break; | 413 break; |
416 default: | 414 default: |
417 canvas.drawText("Unkown Clip!!!", strlen("Unkown Clip!!!
"), SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder); | 415 canvas.drawText("Unkown Clip!!!", strlen("Unkown Clip!!!
"), |
| 416 SkDoubleToScalar(10), SkDoubleToScalar(y
), blueBorder); |
418 break; | 417 break; |
419 } | 418 } |
420 } | 419 } |
421 | 420 |
422 y += 30; | 421 y += 30; |
423 str.printf("Number of clips in stack: %i", total); | 422 str.printf("Number of clips in stack: %i", total); |
424 canvas.drawText(str.c_str(), str.size(), SkDoubleToScalar(10), SkDou
bleToScalar(y), blueBorder); | 423 canvas.drawText(str.c_str(), str.size(), |
| 424 SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorde
r); |
425 } | 425 } |
426 | 426 |
427 const SkRegion& clipRegion = gDumpCanvas->getTotalClip(); | 427 const SkRegion& clipRegion = gDumpCanvas->getTotalClip(); |
428 SkPath clipPath; | 428 SkPath clipPath; |
429 if (clipRegion.getBoundaryPath(&clipPath)) { | 429 if (clipRegion.getBoundaryPath(&clipPath)) { |
430 SkPaint redBorder; | 430 SkPaint redBorder; |
431 redBorder.setColor(SK_ColorRED); | 431 redBorder.setColor(SK_ColorRED); |
432 redBorder.setStyle(SkPaint::kStroke_Style); | 432 redBorder.setStyle(SkPaint::kStroke_Style); |
433 canvas.drawPath(clipPath, redBorder); | 433 canvas.drawPath(clipPath, redBorder); |
434 } | 434 } |
435 | 435 |
436 canvas.flush(); | 436 canvas.flush(); |
437 | 437 |
438 SkString out; | 438 SkString out; |
439 | 439 |
440 // TODO(edisonn): get the image, and overlay on top of it, the clip , gr
afic state, teh stack, | 440 // TODO(edisonn): overlay on top of image inf about the clip , grafic st
ate, the stack |
441 // ... and other properties, to be able to debug th code easily | |
442 | 441 |
443 out.appendf("/usr/local/google/home/edisonn/log_view2/step-%i-%s.png", g
LastOpKeyword, gLastKeyword); | 442 out.appendf("/tmp/log_step_by_step/step-%i-%s.png", |
| 443 gLastOpKeyword, gLastKeyword); |
444 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG_Typ
e, 100); | 444 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG_Typ
e, 100); |
445 } | 445 } |
446 | 446 |
447 if (ret && token->fType == kKeyword_TokenType && token->fKeyword && token->f
KeywordLength > 0 && token->fKeywordLength < 100) { | 447 if (ret && token->fType == kKeyword_TokenType && |
| 448 token->fKeyword && token->fKeywordLength > 0 && token->fKeywordLengt
h < 100) { |
448 strncpy(gLastKeyword, token->fKeyword, token->fKeywordLength); | 449 strncpy(gLastKeyword, token->fKeyword, token->fKeywordLength); |
449 gLastKeyword[token->fKeywordLength] = '\0'; | 450 gLastKeyword[token->fKeywordLength] = '\0'; |
450 } else { | 451 } else { |
451 gLastKeyword[0] = '\0'; | 452 gLastKeyword[0] = '\0'; |
452 } | 453 } |
453 | |
454 #endif | 454 #endif |
455 | 455 |
456 return ret; | 456 return ret; |
457 } | 457 } |
458 | 458 |
459 | 459 // Signature for all the operations available in pdf. |
460 | |
461 typedef SkPdfResult (*PdfOperatorRenderer)(SkPdfContext*, SkCanvas*, PdfTokenLoo
per**); | 460 typedef SkPdfResult (*PdfOperatorRenderer)(SkPdfContext*, SkCanvas*, PdfTokenLoo
per**); |
462 | 461 |
| 462 // Map of string to function pointer for all known draw operations. |
463 SkTDict<PdfOperatorRenderer> gPdfOps(100); | 463 SkTDict<PdfOperatorRenderer> gPdfOps(100); |
464 | 464 |
465 | 465 // Temp code to measure what operands fail. |
466 template <typename T> class SkTDictWithDefaultConstructor : public SkTDict<T> { | 466 template <typename T> class SkTDictWithDefaultConstructor : public SkTDict<T> { |
467 public: | 467 public: |
468 SkTDictWithDefaultConstructor() : SkTDict<T>(10) {} | 468 SkTDictWithDefaultConstructor() : SkTDict<T>(10) {} |
469 }; | 469 }; |
470 | 470 |
471 SkTDictWithDefaultConstructor<int> gRenderStats[kCount_SkPdfResult]; | 471 SkTDictWithDefaultConstructor<int> gRenderStats[kCount_SkPdfResult]; |
472 | 472 |
473 const char* gRenderStatsNames[kCount_SkPdfResult] = { | 473 const char* gRenderStatsNames[kCount_SkPdfResult] = { |
474 "Success", | 474 "Success", |
475 "Partially implemented", | 475 "Partially implemented", |
476 "Not yet implemented", | 476 "Not yet implemented", |
477 "Ignore Error", | 477 "Ignore Error", |
478 "Error", | 478 "Error", |
479 "Unsupported/Unknown" | 479 "Unsupported/Unknown" |
480 }; | 480 }; |
481 | 481 |
482 static SkPdfResult DrawText(SkPdfContext* pdfContext, | 482 static SkPdfResult DrawText(SkPdfContext* pdfContext, |
483 const SkPdfNativeObject* _str, | 483 const SkPdfNativeObject* _str, |
484 SkCanvas* canvas) | 484 SkCanvas* canvas) |
485 { | 485 { |
486 | |
487 SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; | 486 SkPdfFont* skfont = pdfContext->fGraphicsState.fSkFont; |
488 if (skfont == NULL) { | 487 if (skfont == NULL) { |
489 skfont = SkPdfFont::Default(); | 488 skfont = SkPdfFont::Default(); |
490 } | 489 } |
491 | 490 |
492 if (_str == NULL || !_str->isAnyString()) { | 491 if (_str == NULL || !_str->isAnyString()) { |
493 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "DrawText", _
str, SkPdfNativeObject::_kAnyString_PdfObjectType, pdfContext); | 492 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, |
| 493 "DrawText", |
| 494 _str, |
| 495 SkPdfNativeObject::_kAnyString_PdfObjectType, |
| 496 pdfContext); |
494 return kIgnoreError_SkPdfResult; | 497 return kIgnoreError_SkPdfResult; |
495 } | 498 } |
496 const SkPdfString* str = (const SkPdfString*)_str; | 499 const SkPdfString* str = (const SkPdfString*)_str; |
497 | 500 |
498 SkUnencodedText binary(str); | 501 SkUnencodedText binary(str); |
499 | 502 |
500 SkDecodedText decoded; | 503 SkDecodedText decoded; |
501 | 504 |
502 if (skfont->encoding() == NULL) { | 505 if (skfont->encoding() == NULL) { |
503 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingEncoding_SkPdfIssue
, "draw text", _str, pdfContext); | 506 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingEncoding_SkPdfIssue
, |
| 507 "draw text", _str, pdfContext); |
504 return kNYI_SkPdfResult; | 508 return kNYI_SkPdfResult; |
505 } | 509 } |
506 | 510 |
507 skfont->encoding()->decodeText(binary, &decoded); | 511 skfont->encoding()->decodeText(binary, &decoded); |
508 | 512 |
509 SkPaint paint; | 513 SkPaint paint; |
510 // TODO(edisonn): when should fCurFont->GetFontSize() used? When cur is fCur
FontSize == 0? | 514 // TODO(edisonn): does size 0 mean anything special? |
511 // Or maybe just not call setTextSize at all? | |
512 if (pdfContext->fGraphicsState.fCurFontSize != 0) { | 515 if (pdfContext->fGraphicsState.fCurFontSize != 0) { |
513 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); | 516 paint.setTextSize(SkDoubleToScalar(pdfContext->fGraphicsState.fCurFontSi
ze)); |
514 } | 517 } |
515 | 518 |
| 519 // TODO(edisonn): implement font scaler |
516 // if (fCurFont && fCurFont->GetFontScale() != 0) { | 520 // if (fCurFont && fCurFont->GetFontScale() != 0) { |
517 // paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0))
; | 521 // paint.setTextScaleX(SkFloatToScalar(fCurFont->GetFontScale() / 100.0))
; |
518 // } | 522 // } |
519 | 523 |
520 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); | 524 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
521 | 525 |
522 skfont->drawText(decoded, &paint, pdfContext, canvas); | 526 skfont->drawText(decoded, &paint, pdfContext, canvas); |
523 | 527 |
524 return kOK_SkPdfResult; | 528 return kOK_SkPdfResult; |
525 } | 529 } |
526 | 530 |
527 // TODO(edisonn): create header files with declarations! | 531 // TODO(edisonn): create header files with declarations! |
528 SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper); | 532 SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper); |
529 SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper); | 533 SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper); |
530 SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper); | 534 SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper); |
531 SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper); | 535 SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper); |
532 | 536 |
533 // TODO(edisonn): perf!!! | 537 // TODO(edisonn): perf!!! |
534 | |
535 static SkColorTable* getGrayColortable() { | 538 static SkColorTable* getGrayColortable() { |
536 static SkColorTable* grayColortable = NULL; | 539 static SkColorTable* grayColortable = NULL; |
537 if (grayColortable == NULL) { | 540 if (grayColortable == NULL) { |
538 SkPMColor* colors = new SkPMColor[256]; | 541 SkPMColor* colors = new SkPMColor[256]; |
539 for (int i = 0 ; i < 256; i++) { | 542 for (int i = 0 ; i < 256; i++) { |
540 colors[i] = SkPreMultiplyARGB(255, i, i, i); | 543 colors[i] = SkPreMultiplyARGB(255, i, i, i); |
541 } | 544 } |
542 grayColortable = new SkColorTable(colors, 256); | 545 grayColortable = new SkColorTable(colors, 256); |
543 } | 546 } |
544 return grayColortable; | 547 return grayColortable; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 | 593 |
591 bitmap->setConfig(transparencyMask ? SkBitmap::kA8_Config : SkBitmap::kI
ndex8_Config, | 594 bitmap->setConfig(transparencyMask ? SkBitmap::kA8_Config : SkBitmap::kI
ndex8_Config, |
592 width, height); | 595 width, height); |
593 bitmap->setPixels(uncompressedStreamA8, transparencyMask ? NULL : getGra
yColortable()); | 596 bitmap->setPixels(uncompressedStreamA8, transparencyMask ? NULL : getGra
yColortable()); |
594 } | 597 } |
595 | 598 |
596 // TODO(edisonn): pass color space and context here? | 599 // TODO(edisonn): pass color space and context here? |
597 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "Color space N
YI", NULL, NULL); | 600 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "Color space N
YI", NULL, NULL); |
598 return bitmap; | 601 return bitmap; |
599 } | 602 } |
| 603 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
22, 444 to closest |
| 604 // skia format. |
600 | 605 |
601 // utils | 606 // This functions returns the image, it does not look at the smask. |
602 | 607 static SkBitmap* getImageFromObjectCore(SkPdfContext* pdfContext, |
603 // TODO(edisonn): add cache, or put the bitmap property directly on the PdfObjec
t | 608 SkPdfImageDictionary* image, bool transp
arencyMask) { |
604 // TODO(edisonn): deal with colorSpaces, we could add them to SkBitmap::Config | |
605 // TODO(edisonn): preserve A1 format that skia knows, + fast convert from 111, 2
22, 444 to closest | |
606 // skia format, through a table | |
607 | |
608 // this functions returns the image, it does not look at the smask. | |
609 | |
610 static SkBitmap* getImageFromObjectCore(SkPdfContext* pdfContext, SkPdfImageDict
ionary* image, bool transparencyMask) { | |
611 if (image == NULL || !image->hasStream()) { | 609 if (image == NULL || !image->hasStream()) { |
612 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", image, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); | 610 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", image, |
| 611 SkPdfNativeObject::_kStream_PdfObjectType, pdf
Context); |
613 return NULL; | 612 return NULL; |
614 } | 613 } |
615 | 614 |
616 int bpc = (int)image->BitsPerComponent(pdfContext->fPdfDoc); | 615 int bpc = (int)image->BitsPerComponent(pdfContext->fPdfDoc); |
617 int width = (int)image->Width(pdfContext->fPdfDoc); | 616 int width = (int)image->Width(pdfContext->fPdfDoc); |
618 int height = (int)image->Height(pdfContext->fPdfDoc); | 617 int height = (int)image->Height(pdfContext->fPdfDoc); |
619 SkString colorSpace("DeviceRGB"); | 618 SkString colorSpace("DeviceRGB"); |
620 | 619 |
621 bool indexed = false; | 620 bool indexed = false; |
622 SkPMColor colors[256]; | 621 SkPMColor colors[256]; |
623 int cnt = 0; | 622 int cnt = 0; |
624 | 623 |
625 if (image->isColorSpaceAName(pdfContext->fPdfDoc)) { | 624 if (image->isColorSpaceAName(pdfContext->fPdfDoc)) { |
626 colorSpace = image->getColorSpaceAsName(pdfContext->fPdfDoc); | 625 colorSpace = image->getColorSpaceAsName(pdfContext->fPdfDoc); |
627 } else if (image->isColorSpaceAArray(pdfContext->fPdfDoc)) { | 626 } else if (image->isColorSpaceAArray(pdfContext->fPdfDoc)) { |
628 SkPdfArray* array = image->getColorSpaceAsArray(pdfContext->fPdfDoc); | 627 SkPdfArray* array = image->getColorSpaceAsArray(pdfContext->fPdfDoc); |
629 if (array && array->size() == 4 && array->objAtAIndex(0)->isName("Indexe
d") && | 628 if (array && array->size() == 4 && array->objAtAIndex(0)->isName("Indexe
d") && |
630 (array->objAtAIndex(1)->isName("Devic
eRGB") || array->objAtAIndex(1)->isName("RGB")) && | 629 (array->objAtAIndex(1)->isName("Devic
eRGB") || |
| 630 array->objAtAIndex(1)->isName
("RGB")) && |
631 array->objAtAIndex(2)->isInteger() && | 631 array->objAtAIndex(2)->isInteger() && |
632 array->objAtAIndex(3)->isHexString() | 632 array->objAtAIndex(3)->isHexString() |
633 ) { | 633 ) { |
634 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "Color
space NYI", image, pdfContext); | 634 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "Color
space NYI", |
| 635 image, pdfContext); |
635 indexed = true; | 636 indexed = true; |
636 cnt = (int)array->objAtAIndex(2)->intValue() + 1; | 637 cnt = (int)array->objAtAIndex(2)->intValue() + 1; |
637 if (cnt > 256) { | 638 if (cnt > 256) { |
638 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "C
olor space feature NYI, cnt > 256", image, pdfContext); | 639 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, |
| 640 "Color space feature NYI, cnt > 256", image, pdfCont
ext); |
639 return NULL; | 641 return NULL; |
640 } | 642 } |
641 SkColorTable colorTable(cnt); | 643 SkColorTable colorTable(cnt); |
642 NotOwnedString data = array->objAtAIndex(3)->strRef(); | 644 NotOwnedString data = array->objAtAIndex(3)->strRef(); |
643 if (data.fBytes != (unsigned int)cnt * 3) { | 645 if (data.fBytes != (unsigned int)cnt * 3) { |
644 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_
SkPdfIssue, "Image color table mismatch color space specs", array, pdfContext); | 646 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_
SkPdfIssue, |
| 647 "Image color table mismatch color space specs", arra
y, pdfContext); |
645 return NULL; | 648 return NULL; |
646 } | 649 } |
647 for (int i = 0 ; i < cnt; i++) { | 650 for (int i = 0 ; i < cnt; i++) { |
648 colors[i] = SkPreMultiplyARGB(0xff, data.fBuffer[3 * i], data.fB
uffer[3 * i + 1], data.fBuffer[3 * i + 2]); | 651 colors[i] = SkPreMultiplyARGB(0xff, |
| 652 data.fBuffer[3 * i], |
| 653 data.fBuffer[3 * i + 1], |
| 654 data.fBuffer[3 * i + 2]); |
649 } | 655 } |
650 } | 656 } |
651 } | 657 } |
652 | 658 |
653 /* | 659 // TODO(edisonn): implement image masks. |
654 bool imageMask = image->imageMask(); | 660 /* bool imageMask = image->imageMask(); |
655 | |
656 if (imageMask) { | 661 if (imageMask) { |
657 if (bpc != 0 && bpc != 1) { | 662 if (bpc != 0 && bpc != 1) { |
658 // TODO(edisonn): report warning to be used in testing. | 663 // TODO(edisonn): report warning to be used in testing. |
659 return SkBitmap(); | 664 return SkBitmap(); |
660 } | 665 } |
661 bpc = 1; | 666 bpc = 1; |
662 } | 667 } |
663 */ | 668 */ |
664 | 669 |
665 const unsigned char* uncompressedStream = NULL; | 670 const unsigned char* uncompressedStream = NULL; |
666 size_t uncompressedStreamLength = 0; | 671 size_t uncompressedStreamLength = 0; |
667 | 672 |
668 SkPdfStream* stream = (SkPdfStream*)image; | 673 SkPdfStream* stream = (SkPdfStream*)image; |
669 | 674 |
670 if (!stream || !stream->GetFilteredStreamRef(&uncompressedStream, &uncompres
sedStreamLength) || | 675 if (!stream || !stream->GetFilteredStreamRef(&uncompressedStream, &uncompres
sedStreamLength) || |
671 uncompressedStream == NULL || uncompressedStreamLength == 0) { | 676 uncompressedStream == NULL || uncompressedStreamLength == 0) { |
672 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", stream, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); | 677 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", stream, |
| 678 SkPdfNativeObject::_kStream_PdfObjectType, pdf
Context); |
673 return NULL; | 679 return NULL; |
674 } | 680 } |
675 | 681 |
676 SkPdfStreamCommonDictionary* streamDict = (SkPdfStreamCommonDictionary*)stre
am; | 682 SkPdfStreamCommonDictionary* streamDict = (SkPdfStreamCommonDictionary*)stre
am; |
677 | 683 |
678 if (streamDict->has_Filter() && ((streamDict->isFilterAName(NULL) && | 684 if (streamDict->has_Filter() && |
679 streamDict->getFilterAsName(NULL).equa
ls("DCTDecode")) || | 685 ((streamDict->isFilterAName(NULL) && |
680 (streamDict->isFilterAArray(NULL) && | 686 streamDict->getFilterAsName(NULL).equals("DCTDecode")) || |
681 streamDict->getFilterAsArray(NULL)->si
ze() > 0 && | 687 (streamDict->isFilterAArray(NULL) && |
682 streamDict->getFilterAsArray(NULL)->ob
jAtAIndex(0)->isName() && | 688 streamDict->getFilterAsArray(NULL)->size() > 0 && |
683 streamDict->getFilterAsArray(NULL)->ob
jAtAIndex(0)->nameValue2().equals("DCTDecode")))) { | 689 streamDict->getFilterAsArray(NULL)->objAtAIndex(0)->isName() &
& |
| 690 streamDict->getFilterAsArray(NULL)->objAtAIndex(0)->nameValue2
() |
| 691 .equals("DCT
Decode")))) { |
684 SkBitmap* bitmap = new SkBitmap(); | 692 SkBitmap* bitmap = new SkBitmap(); |
685 SkImageDecoder::DecodeMemory(uncompressedStream, uncompressedStreamLengt
h, bitmap); | 693 SkImageDecoder::DecodeMemory(uncompressedStream, uncompressedStreamLengt
h, bitmap); |
686 return bitmap; | 694 return bitmap; |
687 } | 695 } |
688 | 696 |
689 | 697 // TODO(edisonn): assumes RGB for now, since it is the only one implemented |
690 | |
691 // TODO (edisonn): Fast Jpeg(DCTDecode) draw, or fast PNG(FlateDecode) draw
... | |
692 // PdfObject* value = resolveReferenceObject(pdfContext->fPdfDoc, | |
693 // obj.GetDictionary().GetKey(PdfNa
me("Filter"))); | |
694 // if (value && value->IsArray() && value->GetArray().GetSize() == 1) { | |
695 // value = resolveReferenceObject(pdfContext->fPdfDoc, | |
696 // &value->GetArray()[0]); | |
697 // } | |
698 // if (value && value->IsName() && value->GetName().GetName() == "DCTDecode")
{ | |
699 // SkStream stream = SkStream:: | |
700 // SkImageDecoder::Factory() | |
701 // } | |
702 | |
703 // TODO(edisonn): assumes RGB for now, since it is the only onwe implemented | |
704 if (indexed) { | 698 if (indexed) { |
705 SkBitmap* bitmap = new SkBitmap(); | 699 SkBitmap* bitmap = new SkBitmap(); |
706 bitmap->setConfig(SkBitmap::kIndex8_Config, width, height); | 700 bitmap->setConfig(SkBitmap::kIndex8_Config, width, height); |
707 SkColorTable* colorTable = new SkColorTable(colors, cnt); | 701 SkColorTable* colorTable = new SkColorTable(colors, cnt); |
708 bitmap->setPixels((void*)uncompressedStream, colorTable); | 702 bitmap->setPixels((void*)uncompressedStream, colorTable); |
709 return bitmap; | 703 return bitmap; |
710 } | 704 } |
711 | 705 |
712 int bytesPerLine = (int)(uncompressedStreamLength / height); | 706 int bytesPerLine = (int)(uncompressedStreamLength / height); |
713 #ifdef PDF_TRACE | 707 #ifdef PDF_TRACE |
714 if (uncompressedStreamLength % height != 0) { | 708 if (uncompressedStreamLength % height != 0) { |
715 printf("Warning uncompressedStreamLength modulo height != 0 !!!\n"); | 709 printf("Warning uncompressedStreamLength modulo height != 0 !!!\n"); |
716 } | 710 } |
717 #endif | 711 #endif |
718 | 712 |
719 SkBitmap* bitmap = transferImageStreamToBitmap( | 713 SkBitmap* bitmap = transferImageStreamToBitmap( |
720 (unsigned char*)uncompressedStream, uncompressedStreamLength, | 714 (unsigned char*)uncompressedStream, uncompressedStreamLength, |
721 (int)width, (int)height, bytesPerLine, | 715 (int)width, (int)height, bytesPerLine, |
722 (int)bpc, colorSpace, | 716 (int)bpc, colorSpace, |
723 transparencyMask); | 717 transparencyMask); |
724 | 718 |
725 return bitmap; | 719 return bitmap; |
726 } | 720 } |
727 | 721 |
728 static SkBitmap* getImageFromObject(SkPdfContext* pdfContext, SkPdfImageDictiona
ry* image, bool transparencyMask) { | 722 static SkBitmap* getImageFromObject(SkPdfContext* pdfContext, SkPdfImageDictiona
ry* image, |
| 723 bool transparencyMask) { |
729 if (!transparencyMask) { | 724 if (!transparencyMask) { |
730 if (!image->hasData(SkPdfNativeObject::kBitmap_Data)) { | 725 if (!image->hasData(SkPdfNativeObject::kBitmap_Data)) { |
731 SkBitmap* bitmap = getImageFromObjectCore(pdfContext, image, transpa
rencyMask); | 726 SkBitmap* bitmap = getImageFromObjectCore(pdfContext, image, transpa
rencyMask); |
732 image->setData(bitmap, SkPdfNativeObject::kBitmap_Data); | 727 image->setData(bitmap, SkPdfNativeObject::kBitmap_Data); |
733 } | 728 } |
734 return (SkBitmap*) image->data(SkPdfNativeObject::kBitmap_Data); | 729 return (SkBitmap*) image->data(SkPdfNativeObject::kBitmap_Data); |
735 } else { | 730 } else { |
736 return getImageFromObjectCore(pdfContext, image, transparencyMask); | 731 return getImageFromObjectCore(pdfContext, image, transparencyMask); |
737 } | 732 } |
738 } | 733 } |
739 | 734 |
740 static SkBitmap* getSmaskFromObject(SkPdfContext* pdfContext, SkPdfImageDictiona
ry* obj) { | 735 static SkBitmap* getSmaskFromObject(SkPdfContext* pdfContext, SkPdfImageDictiona
ry* obj) { |
741 SkPdfImageDictionary* sMask = obj->SMask(pdfContext->fPdfDoc); | 736 SkPdfImageDictionary* sMask = obj->SMask(pdfContext->fPdfDoc); |
742 | 737 |
743 if (sMask) { | 738 if (sMask) { |
744 return getImageFromObject(pdfContext, sMask, true); | 739 return getImageFromObject(pdfContext, sMask, true); |
745 } | 740 } |
746 | 741 |
747 // TODO(edisonn): implement GS SMask. Default to empty right now. | 742 // TODO(edisonn): implement GS SMask. Default to empty right now. |
748 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "implement GS
SMask. Default to empty right now.", obj, pdfContext); | 743 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, |
| 744 "implement GS SMask. Default to empty right now.", obj, pdfConte
xt); |
749 | 745 |
750 return pdfContext->fGraphicsState.fSMask; | 746 return pdfContext->fGraphicsState.fSMask; |
751 } | 747 } |
752 | 748 |
753 static SkPdfResult doXObject_Image(SkPdfContext* pdfContext, SkCanvas* canvas, S
kPdfImageDictionary* skpdfimage) { | 749 static SkPdfResult doXObject_Image(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 750 SkPdfImageDictionary* skpdfimage) { |
754 if (skpdfimage == NULL) { | 751 if (skpdfimage == NULL) { |
755 return kIgnoreError_SkPdfResult; | 752 return kIgnoreError_SkPdfResult; |
756 } | 753 } |
757 | 754 |
758 SkBitmap* image = getImageFromObject(pdfContext, skpdfimage, false); | 755 SkBitmap* image = getImageFromObject(pdfContext, skpdfimage, false); |
759 SkBitmap* sMask = getSmaskFromObject(pdfContext, skpdfimage); | 756 SkBitmap* sMask = getSmaskFromObject(pdfContext, skpdfimage); |
760 | 757 |
761 canvas->save(); | 758 canvas->save(); |
762 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); | 759 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); |
763 | 760 |
764 SkScalar z = SkIntToScalar(0); | 761 SkScalar z = SkIntToScalar(0); |
765 SkScalar one = SkIntToScalar(1); | 762 SkScalar one = SkIntToScalar(1); |
766 | 763 |
767 SkPoint from[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), SkPoint::Make
(one, one), SkPoint::Make(z, one)}; | 764 SkPoint from[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), |
768 SkPoint to[4] = {SkPoint::Make(z, one), SkPoint::Make(one, one), SkPoint::Ma
ke(one, z), SkPoint::Make(z, z)}; | 765 SkPoint::Make(one, one), SkPoint::Make(z, one)}; |
| 766 SkPoint to[4] = {SkPoint::Make(z, one), SkPoint::Make(one, one), |
| 767 SkPoint::Make(one, z), SkPoint::Make(z, z)}; |
769 SkMatrix flip; | 768 SkMatrix flip; |
770 SkAssertResult(flip.setPolyToPoly(from, to, 4)); | 769 SkAssertResult(flip.setPolyToPoly(from, to, 4)); |
771 SkMatrix solveImageFlip = pdfContext->fGraphicsState.fCTM; | 770 SkMatrix solveImageFlip = pdfContext->fGraphicsState.fCTM; |
772 solveImageFlip.preConcat(flip); | 771 solveImageFlip.preConcat(flip); |
773 canvas->setMatrix(solveImageFlip); | 772 canvas->setMatrix(solveImageFlip); |
774 | 773 |
775 #ifdef PDF_TRACE | 774 #ifdef PDF_TRACE |
776 SkPoint final[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), SkPoint::Mak
e(one, one), SkPoint::Make(z, one)}; | 775 SkPoint final[4] = {SkPoint::Make(z, z), SkPoint::Make(one, z), |
| 776 SkPoint::Make(one, one), SkPoint::Make(z, one)}; |
777 solveImageFlip.mapPoints(final, 4); | 777 solveImageFlip.mapPoints(final, 4); |
778 printf("IMAGE rect = "); | 778 printf("IMAGE rect = "); |
779 for (int i = 0; i < 4; i++) { | 779 for (int i = 0; i < 4; i++) { |
780 printf("(%f %f) ", SkScalarToDouble(final[i].x()), SkScalarToDouble(fina
l[i].y())); | 780 printf("(%f %f) ", SkScalarToDouble(final[i].x()), SkScalarToDouble(fina
l[i].y())); |
781 } | 781 } |
782 printf("\n"); | 782 printf("\n"); |
783 #endif // PDF_TRACE | 783 #endif // PDF_TRACE |
784 | 784 |
785 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0),
SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); | 785 SkRect dst = SkRect::MakeXYWH(SkDoubleToScalar(0.0), SkDoubleToScalar(0.0), |
| 786 SkDoubleToScalar(1.0), SkDoubleToScalar(1.0)); |
786 | 787 |
787 // TODO(edisonn): soft mask type? alpha/luminosity. | 788 // TODO(edisonn): soft mask type? alpha/luminosity. |
788 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "implement sof
t mask type", skpdfimage, pdfContext); | 789 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, |
| 790 "implement soft mask type", skpdfimage, pdfContext); |
789 | 791 |
790 SkPaint paint; | 792 SkPaint paint; |
791 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); | 793 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
792 | 794 |
793 if (!sMask || sMask->empty()) { | 795 if (!sMask || sMask->empty()) { |
794 canvas->drawBitmapRect(*image, dst, &paint); | 796 canvas->drawBitmapRect(*image, dst, &paint); |
795 } else { | 797 } else { |
796 canvas->saveLayer(&dst, &paint); | 798 canvas->saveLayer(&dst, &paint); |
797 canvas->drawBitmapRect(*image, dst, NULL); | 799 canvas->drawBitmapRect(*image, dst, NULL); |
798 SkPaint xfer; | 800 SkPaint xfer; |
799 // TODO(edisonn): is the blend mode specified already implicitly/explici
tly in pdf? | 801 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); |
800 xfer.setXfermodeMode(SkXfermode::kSrcOut_Mode); // SkXfermode::kSdtOut_M
ode | |
801 canvas->drawBitmapRect(*sMask, dst, &xfer); | 802 canvas->drawBitmapRect(*sMask, dst, &xfer); |
802 canvas->restore(); | 803 canvas->restore(); |
803 } | 804 } |
804 | 805 |
805 canvas->restore(); | 806 canvas->restore(); |
806 | 807 |
807 return kPartial_SkPdfResult; | 808 return kPartial_SkPdfResult; |
808 } | 809 } |
809 | 810 |
810 //TODO(edisonn): options for implementing isolation and knockout | 811 //TODO(edisonn): options for implementing isolation and knockout |
811 // 1) emulate them (current solution) | 812 // 1) emulate them (current solution) |
812 // PRO: simple | 813 // PRO: simple |
813 // CON: will need to use readPixels, which means serious perf issues | 814 // CON: will need to use readPixels, which means serious perf issues |
814 // 2) Compile a plan for an array of matrixes, compose the result at the end | 815 // 2) Compile a plan for an array of matrixes, compose the result at the end |
815 // PRO: might be faster then 1, no need to readPixels | 816 // PRO: might be faster then 1, no need to readPixels |
816 // CON: multiple drawings (but on smaller areas), pay a price at loading pdf
to compute a pdf draw plan | 817 // CON: multiple drawings (but on smaller areas), pay a price at loading pdf
to |
| 818 // compute a pdf draw plan |
817 // on average, a load with empty draw is 100ms on all the skps we have,
for complete sites | 819 // on average, a load with empty draw is 100ms on all the skps we have,
for complete sites |
818 // 3) support them natively in SkCanvas | 820 // 3) support them natively in SkCanvas |
819 // PRO: simple | 821 // PRO: simple |
820 // CON: we would still need to use a form of readPixels anyway, so perf migh
t be the same as 1) | 822 // CON: we would still need to use a form of readPixels anyway, so perf migh
t be the same as 1) |
821 // 4) compile a plan using pathops, and render once without any fancy rules with
backdrop | 823 // 4) compile a plan using pathops, and render once without any fancy rules with
backdrop |
822 // PRO: simple, fast | 824 // PRO: simple, fast |
823 // CON: pathops must be bug free first + time to compute new paths | 825 // CON: pathops must be bug free first + time to compute new paths |
824 // pay a price at loading pdf to compute a pdf draw plan | 826 // pay a price at loading pdf to compute a pdf draw plan |
825 // on average, a load with empty draw is 100ms on all the skps we have,
for complete sites | 827 // on average, a load with empty draw is 100ms on all the skps we have,
for complete sites |
826 // 5) for knockout, render the objects in reverse order, and add every object to
the clip, and any new draw will be cliped | 828 // 5) for knockout, render the objects in reverse order, and add every object to
the clip, and any |
| 829 // new draw will be cliped |
827 | 830 |
828 | 831 static void doGroup_before(SkPdfContext* pdfContext, SkCanvas* canvas, SkRect bb
ox, |
829 // TODO(edisonn): draw plan from point! - list of draw ops of a point, like a tr
ee! | 832 SkPdfTransparencyGroupDictionary* tgroup, bool page)
{ |
830 // TODO(edisonn): Minimal PDF to draw some points - remove everything that it is
not needed, save pdf uncompressed | |
831 | |
832 | |
833 | |
834 static void doGroup_before(SkPdfContext* pdfContext, SkCanvas* canvas, SkRect bb
ox, SkPdfTransparencyGroupDictionary* tgroup, bool page) { | |
835 SkRect bboxOrig = bbox; | 833 SkRect bboxOrig = bbox; |
836 SkBitmap backdrop; | 834 SkBitmap backdrop; |
837 bool isolatedGroup = tgroup->I(pdfContext->fPdfDoc); | 835 bool isolatedGroup = tgroup->I(pdfContext->fPdfDoc); |
838 // bool knockoutGroup = tgroup->K(pdfContext->fPdfDoc); | 836 // bool knockoutGroup = tgroup->K(pdfContext->fPdfDoc); |
839 SkPaint paint; | 837 SkPaint paint; |
840 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); | 838 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
841 canvas->saveLayer(&bboxOrig, isolatedGroup ? &paint : NULL); | 839 canvas->saveLayer(&bboxOrig, isolatedGroup ? &paint : NULL); |
842 } | 840 } |
843 | 841 |
844 // TODO(edisonn): non isolation implemented in skia | 842 // TODO(edisonn): non isolation should probably be implemented in skia |
845 //static void doGroup_after(SkPdfContext* pdfContext, SkCanvas* canvas, SkRect b
box, SkPdfTransparencyGroupDictionary* tgroup) { | 843 //static void doGroup_after(SkPdfContext* pdfContext, SkCanvas* canvas, SkRect b
box, |
| 844 // SkPdfTransparencyGroupDictionary* tgroup) { |
846 // if not isolated | 845 // if not isolated |
847 // canvas->drawBitmapRect(backdrop, bboxOrig, NULL); | 846 // canvas->drawBitmapRect(backdrop, bboxOrig, NULL); |
848 //} | 847 //} |
849 | 848 |
850 static SkPdfResult doXObject_Form(SkPdfContext* pdfContext, SkCanvas* canvas, Sk
PdfType1FormDictionary* skobj) { | 849 static SkPdfResult doXObject_Form(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 850 SkPdfType1FormDictionary* skobj) { |
851 if (!skobj || !skobj->hasStream()) { | 851 if (!skobj || !skobj->hasStream()) { |
852 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", skobj, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); | 852 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", skobj, |
| 853 SkPdfNativeObject::_kStream_PdfObjectType, pdf
Context); |
853 return kIgnoreError_SkPdfResult; | 854 return kIgnoreError_SkPdfResult; |
854 } | 855 } |
855 | 856 |
856 if (!skobj->has_BBox()) { | 857 if (!skobj->has_BBox()) { |
857 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingRequiredKey_SkPdfIs
sue, "BBox", skobj, pdfContext); | 858 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingRequiredKey_SkPdfIs
sue, "BBox", |
| 859 skobj, pdfContext); |
858 return kIgnoreError_SkPdfResult; | 860 return kIgnoreError_SkPdfResult; |
859 } | 861 } |
860 | 862 |
861 PdfOp_q(pdfContext, canvas, NULL); | 863 PdfOp_q(pdfContext, canvas, NULL); |
862 | 864 |
863 | 865 |
864 if (skobj->Resources(pdfContext->fPdfDoc)) { | 866 if (skobj->Resources(pdfContext->fPdfDoc)) { |
865 pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPd
fDoc); | 867 pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPd
fDoc); |
866 } | 868 } |
867 | 869 |
868 SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Current matrix"); | 870 SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Current matrix"); |
869 | 871 |
870 if (skobj->has_Matrix()) { | 872 if (skobj->has_Matrix()) { |
871 pdfContext->fGraphicsState.fCTM.preConcat(skobj->Matrix(pdfContext->fPdf
Doc)); | 873 pdfContext->fGraphicsState.fCTM.preConcat(skobj->Matrix(pdfContext->fPdf
Doc)); |
872 SkMatrix matrix = pdfContext->fGraphicsState.fCTM; | 874 SkMatrix matrix = pdfContext->fGraphicsState.fCTM; |
873 matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); | 875 matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); |
874 pdfContext->fGraphicsState.fMatrixTm = matrix; | 876 pdfContext->fGraphicsState.fMatrixTm = matrix; |
875 pdfContext->fGraphicsState.fMatrixTlm = matrix; | 877 pdfContext->fGraphicsState.fMatrixTlm = matrix; |
876 // TODO(edisonn) reset matrixTm and matricTlm also? | 878 // TODO(edisonn): text matrixes mosltly NYI |
877 } | 879 } |
878 | 880 |
879 SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Total matrix"); | 881 SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Total matrix"); |
880 pdfContext->fGraphicsState.fContentStreamMatrix = pdfContext->fGraphicsState
.fCTM; | 882 pdfContext->fGraphicsState.fContentStreamMatrix = pdfContext->fGraphicsState
.fCTM; |
881 | 883 |
882 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); | 884 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); |
883 | 885 |
884 SkRect bbox = skobj->BBox(pdfContext->fPdfDoc); | 886 SkRect bbox = skobj->BBox(pdfContext->fPdfDoc); |
885 canvas->clipRect(bbox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA
from settings. | 887 // TODO(edisonn): constants (AA) from settings. |
886 | 888 canvas->clipRect(bbox, SkRegion::kIntersect_Op, false); |
887 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. | |
888 // For this PdfContentsTokenizer needs to be extended. | |
889 | 889 |
890 // This is a group? | 890 // This is a group? |
891 if (skobj->has_Group()) { | 891 if (skobj->has_Group()) { |
892 SkPdfTransparencyGroupDictionary* tgroup = skobj->Group(pdfContext->fPdf
Doc); | 892 SkPdfTransparencyGroupDictionary* tgroup = skobj->Group(pdfContext->fPdf
Doc); |
893 doGroup_before(pdfContext, canvas, bbox, tgroup, false); | 893 doGroup_before(pdfContext, canvas, bbox, tgroup, false); |
894 } | 894 } |
895 | 895 |
896 SkPdfStream* stream = (SkPdfStream*)skobj; | 896 SkPdfStream* stream = (SkPdfStream*)skobj; |
897 | 897 |
898 SkPdfNativeTokenizer* tokenizer = | 898 SkPdfNativeTokenizer* tokenizer = |
899 pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageA
llocator); | 899 pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageA
llocator); |
900 if (tokenizer != NULL) { | 900 if (tokenizer != NULL) { |
901 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); | 901 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); |
902 looper.loop(); | 902 looper.loop(); |
903 delete tokenizer; | 903 delete tokenizer; |
904 } | 904 } |
905 | 905 |
906 // TODO(edisonn): should we restore the variable stack at the same state? | |
907 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | |
908 | |
909 if (skobj->has_Group()) { | 906 if (skobj->has_Group()) { |
910 canvas->restore(); | 907 canvas->restore(); |
911 } | 908 } |
912 | 909 |
913 PdfOp_Q(pdfContext, canvas, NULL); | 910 PdfOp_Q(pdfContext, canvas, NULL); |
914 return kPartial_SkPdfResult; | 911 return kPartial_SkPdfResult; |
915 } | 912 } |
916 | 913 |
917 | 914 static SkPdfResult doXObject_Pattern(SkPdfContext* pdfContext, SkCanvas* canvas, |
918 // TODO(edisonn): Extract a class like ObjWithStream | 915 SkPdfType1PatternDictionary* skobj) { |
919 static SkPdfResult doXObject_Pattern(SkPdfContext* pdfContext, SkCanvas* canvas,
SkPdfType1PatternDictionary* skobj) { | |
920 if (!skobj || !skobj->hasStream()) { | 916 if (!skobj || !skobj->hasStream()) { |
921 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", skobj, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); | 917 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", |
| 918 skobj, SkPdfNativeObject::_kStream_PdfObjectTy
pe, pdfContext); |
922 return kIgnoreError_SkPdfResult; | 919 return kIgnoreError_SkPdfResult; |
923 } | 920 } |
924 | 921 |
925 if (!skobj->has_BBox()) { | 922 if (!skobj->has_BBox()) { |
926 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingRequiredKey_SkPdfIs
sue, "BBox", skobj, pdfContext); | 923 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingRequiredKey_SkPdfIs
sue, "BBox", |
| 924 skobj, pdfContext); |
927 return kIgnoreError_SkPdfResult; | 925 return kIgnoreError_SkPdfResult; |
928 } | 926 } |
929 | 927 |
930 PdfOp_q(pdfContext, canvas, NULL); | 928 PdfOp_q(pdfContext, canvas, NULL); |
931 | 929 |
932 | 930 |
933 if (skobj->Resources(pdfContext->fPdfDoc)) { | 931 if (skobj->Resources(pdfContext->fPdfDoc)) { |
934 pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPd
fDoc); | 932 pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPd
fDoc); |
935 } | 933 } |
936 | 934 |
937 SkTraceMatrix(pdfContext->fGraphicsState.fContentStreamMatrix, "Current Cont
ent stream matrix"); | 935 SkTraceMatrix(pdfContext->fGraphicsState.fContentStreamMatrix, "Current Cont
ent stream matrix"); |
938 | 936 |
939 if (skobj->has_Matrix()) { | 937 if (skobj->has_Matrix()) { |
940 pdfContext->fGraphicsState.fContentStreamMatrix.preConcat(skobj->Matrix(
pdfContext->fPdfDoc)); | 938 pdfContext->fGraphicsState.fContentStreamMatrix.preConcat( |
| 939 skobj->Matrix(pdfContext->fPdfDoc)); |
941 } | 940 } |
942 | 941 |
943 SkTraceMatrix(pdfContext->fGraphicsState.fContentStreamMatrix, "Total Conten
t stream matrix"); | 942 SkTraceMatrix(pdfContext->fGraphicsState.fContentStreamMatrix, "Total Conten
t stream matrix"); |
944 | 943 |
945 canvas->setMatrix(pdfContext->fGraphicsState.fContentStreamMatrix); | 944 canvas->setMatrix(pdfContext->fGraphicsState.fContentStreamMatrix); |
946 pdfContext->fGraphicsState.fCTM = pdfContext->fGraphicsState.fContentStreamM
atrix; | 945 pdfContext->fGraphicsState.fCTM = pdfContext->fGraphicsState.fContentStreamM
atrix; |
947 | 946 |
948 SkRect bbox = skobj->BBox(pdfContext->fPdfDoc); | 947 SkRect bbox = skobj->BBox(pdfContext->fPdfDoc); |
949 canvas->clipRect(bbox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA
from settings. | 948 // TODO(edisonn): constants (AA) from settings. |
950 | 949 canvas->clipRect(bbox, SkRegion::kIntersect_Op, false); |
951 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. | |
952 // For this PdfContentsTokenizer needs to be extended. | |
953 | 950 |
954 SkPdfStream* stream = (SkPdfStream*)skobj; | 951 SkPdfStream* stream = (SkPdfStream*)skobj; |
955 | 952 |
956 SkPdfNativeTokenizer* tokenizer = | 953 SkPdfNativeTokenizer* tokenizer = |
957 pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageA
llocator); | 954 pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageA
llocator); |
958 if (tokenizer != NULL) { | 955 if (tokenizer != NULL) { |
959 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); | 956 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); |
960 looper.loop(); | 957 looper.loop(); |
961 delete tokenizer; | 958 delete tokenizer; |
962 } | 959 } |
963 | 960 |
964 // TODO(edisonn): should we restore the variable stack at the same state? | |
965 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | |
966 | |
967 PdfOp_Q(pdfContext, canvas, NULL); | 961 PdfOp_Q(pdfContext, canvas, NULL); |
968 return kPartial_SkPdfResult; | 962 return kPartial_SkPdfResult; |
969 } | 963 } |
970 | 964 |
971 | 965 // TODO(edisonn): PS NYI |
972 //static SkPdfResult doXObject_PS(SkPdfContext* pdfContext, SkCanvas* canvas, co
nst SkPdfNativeObject* obj) { | 966 //static SkPdfResult doXObject_PS(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 967 // const SkPdfNativeObject* obj) { |
973 // return kNYI_SkPdfResult; | 968 // return kNYI_SkPdfResult; |
974 //} | 969 //} |
975 | 970 |
976 SkPdfResult doType3Char(SkPdfContext* pdfContext, SkCanvas* canvas, const SkPdfN
ativeObject* skobj, SkRect bBox, SkMatrix matrix, double textSize) { | 971 SkPdfResult doType3Char(SkPdfContext* pdfContext, SkCanvas* canvas, const SkPdfN
ativeObject* skobj, |
| 972 SkRect bBox, SkMatrix matrix, double textSize) { |
977 if (!skobj || !skobj->hasStream()) { | 973 if (!skobj || !skobj->hasStream()) { |
978 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", skobj, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); | 974 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", skobj, |
| 975 SkPdfNativeObject::_kStream_PdfObjectType, pdf
Context); |
979 return kIgnoreError_SkPdfResult; | 976 return kIgnoreError_SkPdfResult; |
980 } | 977 } |
981 | 978 |
982 PdfOp_q(pdfContext, canvas, NULL); | 979 PdfOp_q(pdfContext, canvas, NULL); |
983 | 980 |
984 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 981 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
985 pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), Sk
DoubleToScalar(textSize)); | 982 pdfContext->fGraphicsState.fMatrixTm.preScale(SkDoubleToScalar(textSize), |
| 983 SkDoubleToScalar(textSize)); |
986 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrixTm
; | 984 pdfContext->fGraphicsState.fMatrixTlm = pdfContext->fGraphicsState.fMatrixTm
; |
987 | 985 |
988 pdfContext->fGraphicsState.fCTM = pdfContext->fGraphicsState.fMatrixTm; | 986 pdfContext->fGraphicsState.fCTM = pdfContext->fGraphicsState.fMatrixTm; |
989 pdfContext->fGraphicsState.fCTM.preScale(SkDoubleToScalar(1), SkDoubleToScal
ar(-1)); | 987 pdfContext->fGraphicsState.fCTM.preScale(SkDoubleToScalar(1), SkDoubleToScal
ar(-1)); |
990 | 988 |
991 SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Total matrix"); | 989 SkTraceMatrix(pdfContext->fGraphicsState.fCTM, "Total matrix"); |
992 | 990 |
993 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); | 991 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); |
994 | 992 |
995 SkRect rm = bBox; | 993 SkRect rm = bBox; |
996 pdfContext->fGraphicsState.fCTM.mapRect(&rm); | 994 pdfContext->fGraphicsState.fCTM.mapRect(&rm); |
997 | 995 |
998 SkTraceRect(rm, "bbox mapped"); | 996 SkTraceRect(rm, "bbox mapped"); |
999 | 997 |
1000 canvas->clipRect(bBox, SkRegion::kIntersect_Op, true); // TODO(edisonn): AA
from settings. | 998 // TODO(edisonn): constants (AA) from settings. |
1001 | 999 canvas->clipRect(bBox, SkRegion::kIntersect_Op, false); |
1002 // TODO(edisonn): iterate smart on the stream even if it is compressed, toke
nize it as we go. | |
1003 // For this PdfContentsTokenizer needs to be extended. | |
1004 | 1000 |
1005 SkPdfStream* stream = (SkPdfStream*)skobj; | 1001 SkPdfStream* stream = (SkPdfStream*)skobj; |
1006 | 1002 |
1007 SkPdfNativeTokenizer* tokenizer = | 1003 SkPdfNativeTokenizer* tokenizer = |
1008 pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageA
llocator); | 1004 pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageA
llocator); |
1009 if (tokenizer != NULL) { | 1005 if (tokenizer != NULL) { |
1010 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); | 1006 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); |
1011 looper.loop(); | 1007 looper.loop(); |
1012 delete tokenizer; | 1008 delete tokenizer; |
1013 } | 1009 } |
1014 | 1010 |
1015 // TODO(edisonn): should we restore the variable stack at the same state? | |
1016 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | |
1017 PdfOp_Q(pdfContext, canvas, NULL); | 1011 PdfOp_Q(pdfContext, canvas, NULL); |
1018 | 1012 |
1019 return kPartial_SkPdfResult; | 1013 return kPartial_SkPdfResult; |
1020 } | 1014 } |
1021 | 1015 |
| 1016 // The PDF could be corrupted so a dict refers recursively to the same dict, if
this happens |
| 1017 // we end up with a stack overflow and crash. |
1022 class CheckRecursiveRendering { | 1018 class CheckRecursiveRendering { |
1023 SkPdfNativeObject* fObj; | 1019 SkPdfNativeObject* fObj; |
1024 public: | 1020 public: |
1025 CheckRecursiveRendering(SkPdfNativeObject* obj) : fObj(obj) { | 1021 CheckRecursiveRendering(SkPdfNativeObject* obj) : fObj(obj) { |
1026 SkASSERT(!obj->inRendering()); | 1022 SkASSERT(!obj->inRendering()); |
1027 obj->startRendering(); | 1023 obj->startRendering(); |
1028 } | 1024 } |
1029 | 1025 |
1030 ~CheckRecursiveRendering() { | 1026 ~CheckRecursiveRendering() { |
1031 SkASSERT(fObj->inRendering()); | 1027 SkASSERT(fObj->inRendering()); |
1032 fObj->doneRendering(); | 1028 fObj->doneRendering(); |
1033 } | 1029 } |
1034 | 1030 |
1035 static bool IsInRendering(const SkPdfNativeObject* obj) { | 1031 static bool IsInRendering(const SkPdfNativeObject* obj) { |
1036 return obj->inRendering(); | 1032 return obj->inRendering(); |
1037 } | 1033 } |
1038 }; | 1034 }; |
1039 | 1035 |
1040 static SkPdfResult doXObject(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfNa
tiveObject* obj) { | 1036 static SkPdfResult doXObject(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfNa
tiveObject* obj) { |
1041 if (CheckRecursiveRendering::IsInRendering(obj)) { | 1037 if (CheckRecursiveRendering::IsInRendering(obj)) { |
1042 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kRecursiveReferencing_SkPdf
Issue, "Recursive reverencing is invalid in draw objects", obj, pdfContext); | 1038 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kRecursiveReferencing_SkPdf
Issue, |
| 1039 "Recursive reverencing is invalid in draw objects", obj, pdf
Context); |
1043 return kIgnoreError_SkPdfResult; | 1040 return kIgnoreError_SkPdfResult; |
1044 } | 1041 } |
1045 | 1042 |
1046 CheckRecursiveRendering checkRecursion(obj); | 1043 CheckRecursiveRendering checkRecursion(obj); |
1047 | 1044 |
1048 switch (pdfContext->fPdfDoc->mapper()->mapXObjectDictionary(obj)) | 1045 switch (pdfContext->fPdfDoc->mapper()->mapXObjectDictionary(obj)) |
1049 { | 1046 { |
1050 case kImageDictionary_SkPdfNativeObjectType: | 1047 case kImageDictionary_SkPdfNativeObjectType: |
1051 return doXObject_Image(pdfContext, canvas, (SkPdfImageDictionary*)ob
j); | 1048 return doXObject_Image(pdfContext, canvas, (SkPdfImageDictionary*)ob
j); |
1052 case kType1FormDictionary_SkPdfNativeObjectType: | 1049 case kType1FormDictionary_SkPdfNativeObjectType: |
1053 return doXObject_Form(pdfContext, canvas, (SkPdfType1FormDictionary*
)obj); | 1050 return doXObject_Form(pdfContext, canvas, (SkPdfType1FormDictionary*
)obj); |
1054 //case kObjectDictionaryXObjectPS_SkPdfNativeObjectType: | 1051 //case kObjectDictionaryXObjectPS_SkPdfNativeObjectType: |
1055 //return doXObject_PS(skxobj.asPS()); | 1052 //return doXObject_PS(skxobj.asPS()); |
1056 default: { | 1053 default: { |
1057 if (pdfContext->fPdfDoc->mapper()->mapType1PatternDictionary(obj) !=
kNone_SkPdfNativeObjectType) { | 1054 if (pdfContext->fPdfDoc->mapper()->mapType1PatternDictionary(obj) != |
| 1055 kNone_SkPdfNativeObjectType) { |
1058 SkPdfType1PatternDictionary* pattern = (SkPdfType1PatternDiction
ary*)obj; | 1056 SkPdfType1PatternDictionary* pattern = (SkPdfType1PatternDiction
ary*)obj; |
1059 return doXObject_Pattern(pdfContext, canvas, pattern); | 1057 return doXObject_Pattern(pdfContext, canvas, pattern); |
1060 } | 1058 } |
1061 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "doXOb
ject", obj, pdfContext); | 1059 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "doXOb
ject", |
| 1060 obj, pdfContext); |
1062 } | 1061 } |
1063 } | 1062 } |
1064 return kIgnoreError_SkPdfResult; | 1063 return kIgnoreError_SkPdfResult; |
1065 } | 1064 } |
1066 | 1065 |
1067 static SkPdfResult doPage(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfPageO
bjectDictionary* skobj) { | 1066 static SkPdfResult doPage(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1067 SkPdfPageObjectDictionary* skobj) { |
1068 if (!skobj || !skobj->isContentsAStream(pdfContext->fPdfDoc)) { | 1068 if (!skobj || !skobj->isContentsAStream(pdfContext->fPdfDoc)) { |
1069 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", skobj, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); | 1069 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", skobj, |
| 1070 SkPdfNativeObject::_kStream_PdfObjectType, pdf
Context); |
1070 return kNYI_SkPdfResult; | 1071 return kNYI_SkPdfResult; |
1071 } | 1072 } |
1072 | 1073 |
1073 SkPdfStream* stream = skobj->getContentsAsStream(pdfContext->fPdfDoc); | 1074 SkPdfStream* stream = skobj->getContentsAsStream(pdfContext->fPdfDoc); |
1074 | 1075 |
1075 if (!stream) { | 1076 if (!stream) { |
1076 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", skobj, SkPdfNativeObject::_kStream_PdfObjectType, pdfContext); | 1077 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Missing stre
am", |
| 1078 skobj, SkPdfNativeObject::_kStream_PdfObjectTy
pe, pdfContext); |
1077 return kIgnoreError_SkPdfResult; | 1079 return kIgnoreError_SkPdfResult; |
1078 } | 1080 } |
1079 | 1081 |
1080 pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPdfDoc
); | 1082 pdfContext->fGraphicsState.fResources = skobj->Resources(pdfContext->fPdfDoc
); |
1081 | 1083 |
1082 if (!pdfContext->fGraphicsState.fResources) { | 1084 if (!pdfContext->fGraphicsState.fResources) { |
1083 return kIgnoreError_SkPdfResult; // probably it is null because we have
not implemented yet inheritance | 1085 // It might be null because we have not implemented yet inheritance. |
| 1086 return kIgnoreError_SkPdfResult; |
1084 } | 1087 } |
1085 | 1088 |
1086 if (CheckRecursiveRendering::IsInRendering(skobj)) { | 1089 if (CheckRecursiveRendering::IsInRendering(skobj)) { |
1087 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kRecursiveReferencing_SkPdf
Issue, "Recursive reverencing is invalid in draw objects", skobj, pdfContext); | 1090 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kRecursiveReferencing_SkPdf
Issue, |
| 1091 "Recursive reverencing is invalid in draw objects", skobj, p
dfContext); |
1088 return kIgnoreError_SkPdfResult; | 1092 return kIgnoreError_SkPdfResult; |
1089 } | 1093 } |
1090 CheckRecursiveRendering checkRecursion(skobj); | 1094 CheckRecursiveRendering checkRecursion(skobj); |
1091 | 1095 |
1092 | 1096 |
1093 PdfOp_q(pdfContext, canvas, NULL); | 1097 PdfOp_q(pdfContext, canvas, NULL); |
1094 | 1098 |
1095 // TODO(edisonn): MediaBox can be inherited!!!! | 1099 // TODO(edisonn): MediaBox can be inherited!!!! |
1096 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "MediaBox inhe
ritance NYI", NULL, pdfContext); | 1100 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "MediaBox inhe
ritance NYI", |
1097 | 1101 NULL, pdfContext); |
1098 SkRect bbox = skobj->MediaBox(pdfContext->fPdfDoc); | 1102 SkRect bbox = skobj->MediaBox(pdfContext->fPdfDoc); |
1099 if (skobj->has_Group()) { | 1103 if (skobj->has_Group()) { |
1100 SkPdfTransparencyGroupDictionary* tgroup = skobj->Group(pdfContext->fPdf
Doc); | 1104 SkPdfTransparencyGroupDictionary* tgroup = skobj->Group(pdfContext->fPdf
Doc); |
1101 doGroup_before(pdfContext, canvas, bbox, tgroup, true); | 1105 doGroup_before(pdfContext, canvas, bbox, tgroup, true); |
1102 } else { | 1106 } else { |
1103 canvas->save(); | 1107 canvas->save(); |
1104 } | 1108 } |
1105 | 1109 |
1106 | 1110 |
1107 SkPdfNativeTokenizer* tokenizer = | 1111 SkPdfNativeTokenizer* tokenizer = |
1108 pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageA
llocator); | 1112 pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageA
llocator); |
1109 if (tokenizer != NULL) { | 1113 if (tokenizer != NULL) { |
1110 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); | 1114 PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas); |
1111 looper.loop(); | 1115 looper.loop(); |
1112 delete tokenizer; | 1116 delete tokenizer; |
1113 } | 1117 } |
1114 | 1118 |
1115 // TODO(edisonn): should we restore the variable stack at the same state? | |
1116 // There could be operands left, that could be consumed by a parent tokenize
r when we pop. | |
1117 canvas->restore(); | 1119 canvas->restore(); |
1118 PdfOp_Q(pdfContext, canvas, NULL); | 1120 PdfOp_Q(pdfContext, canvas, NULL); |
1119 return kPartial_SkPdfResult; | 1121 return kPartial_SkPdfResult; |
1120 } | 1122 } |
1121 | 1123 |
1122 SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper) { | 1124 SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper) { |
1123 // TODO(edisonn): create a new stack of parameters, so once we start a q, | |
1124 // it is not possible to see under the previous q? | |
1125 pdfContext->fStateStack.push(pdfContext->fGraphicsState); | 1125 pdfContext->fStateStack.push(pdfContext->fGraphicsState); |
1126 canvas->save(); | 1126 canvas->save(); |
1127 pdfContext->fObjectStack.nest(); | 1127 pdfContext->fObjectStack.nest(); |
1128 return kOK_SkPdfResult; | 1128 return kOK_SkPdfResult; |
1129 } | 1129 } |
1130 | 1130 |
1131 SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper) { | 1131 SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
looper) { |
1132 if (pdfContext->fStateStack.count() > 0) { | 1132 if (pdfContext->fStateStack.count() > 0) { |
1133 pdfContext->fGraphicsState = pdfContext->fStateStack.top(); | 1133 pdfContext->fGraphicsState = pdfContext->fStateStack.top(); |
1134 pdfContext->fStateStack.pop(); | 1134 pdfContext->fStateStack.pop(); |
1135 canvas->restore(); | 1135 canvas->restore(); |
1136 | 1136 |
1137 if (pdfContext->fObjectStack.nests() == 0) { | 1137 if (pdfContext->fObjectStack.nests() == 0) { |
1138 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kStackNestingOverflow_S
kPdfIssue, "stack nesting overflow (q/Q)", NULL, pdfContext); | 1138 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kStackNestingOverflow_S
kPdfIssue, |
| 1139 "stack nesting overflow (q/Q)", NULL, pdfContext); |
1139 return kIgnoreError_SkPdfResult; | 1140 return kIgnoreError_SkPdfResult; |
1140 } else { | 1141 } else { |
1141 pdfContext->fObjectStack.unnest(); | 1142 pdfContext->fObjectStack.unnest(); |
1142 } | 1143 } |
1143 } else { | 1144 } else { |
1144 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kStackOverflow_SkPdfIssue,
"stack overflow (q/Q)", NULL, pdfContext); | 1145 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kStackOverflow_SkPdfIssue, |
| 1146 "stack overflow (q/Q)", NULL, pdfContext); |
1145 return kIgnoreError_SkPdfResult; | 1147 return kIgnoreError_SkPdfResult; |
1146 } | 1148 } |
1147 | 1149 |
1148 return kOK_SkPdfResult; | 1150 return kOK_SkPdfResult; |
1149 } | 1151 } |
1150 | 1152 |
1151 static SkPdfResult PdfOp_cm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 1153 static SkPdfResult PdfOp_cm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1152 EXPECT_OPERANDS("cm", pdfContext, 6); | 1154 EXPECT_OPERANDS("cm", pdfContext, 6); |
1153 POP_NUMBER(pdfContext, f); | 1155 POP_NUMBER(pdfContext, f); |
1154 POP_NUMBER(pdfContext, e); | 1156 POP_NUMBER(pdfContext, e); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1227 PdfOp_TL(pdfContext, canvas, looper); | 1229 PdfOp_TL(pdfContext, canvas, looper); |
1228 | 1230 |
1229 SkPdfReal* vtx = pdfContext->fPdfDoc->createReal(tx); | 1231 SkPdfReal* vtx = pdfContext->fPdfDoc->createReal(tx); |
1230 pdfContext->fObjectStack.push(vtx); | 1232 pdfContext->fObjectStack.push(vtx); |
1231 | 1233 |
1232 SkPdfReal* vty = pdfContext->fPdfDoc->createReal(ty); | 1234 SkPdfReal* vty = pdfContext->fPdfDoc->createReal(ty); |
1233 pdfContext->fObjectStack.push(vty); | 1235 pdfContext->fObjectStack.push(vty); |
1234 | 1236 |
1235 SkPdfResult ret = PdfOp_Td(pdfContext, canvas, looper); | 1237 SkPdfResult ret = PdfOp_Td(pdfContext, canvas, looper); |
1236 | 1238 |
1237 // TODO(edisonn): delete all the objects after rendering was complete, in th
is way pdf is rendered faster | |
1238 // and the cleanup can happen while the user looks at the image | |
1239 | |
1240 return ret; | 1239 return ret; |
1241 } | 1240 } |
1242 | 1241 |
1243 static SkPdfResult PdfOp_Tm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 1242 static SkPdfResult PdfOp_Tm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1244 EXPECT_OPERANDS("Tm", pdfContext, 6); | 1243 EXPECT_OPERANDS("Tm", pdfContext, 6); |
1245 POP_NUMBER(pdfContext, f); | 1244 POP_NUMBER(pdfContext, f); |
1246 POP_NUMBER(pdfContext, e); | 1245 POP_NUMBER(pdfContext, e); |
1247 POP_NUMBER(pdfContext, d); | 1246 POP_NUMBER(pdfContext, d); |
1248 POP_NUMBER(pdfContext, c); | 1247 POP_NUMBER(pdfContext, c); |
1249 POP_NUMBER(pdfContext, b); | 1248 POP_NUMBER(pdfContext, b); |
1250 POP_NUMBER(pdfContext, a); | 1249 POP_NUMBER(pdfContext, a); |
1251 CHECK_PARAMETERS(); | 1250 CHECK_PARAMETERS(); |
1252 | 1251 |
1253 double array[6]; | 1252 double array[6]; |
1254 array[0] = a; | 1253 array[0] = a; |
1255 array[1] = b; | 1254 array[1] = b; |
1256 array[2] = c; | 1255 array[2] = c; |
1257 array[3] = d; | 1256 array[3] = d; |
1258 array[4] = e; | 1257 array[4] = e; |
1259 array[5] = f; | 1258 array[5] = f; |
1260 | 1259 |
1261 SkMatrix matrix = SkMatrixFromPdfMatrix(array); | 1260 SkMatrix matrix = SkMatrixFromPdfMatrix(array); |
1262 matrix.postConcat(pdfContext->fGraphicsState.fCTM); | 1261 matrix.postConcat(pdfContext->fGraphicsState.fCTM); |
1263 matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); | 1262 matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); |
1264 | 1263 |
1265 // TODO(edisonn): Text positioning. | 1264 // TODO(edisonn): NYI - Text positioning. |
1266 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "Text position
ing not implemented for 2+ chars", NULL, pdfContext); | 1265 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, |
| 1266 "Text positioning not implemented for 2+ chars", NULL, pdfContex
t); |
1267 | 1267 |
1268 pdfContext->fGraphicsState.fMatrixTm = matrix; | 1268 pdfContext->fGraphicsState.fMatrixTm = matrix; |
1269 pdfContext->fGraphicsState.fMatrixTlm = matrix;; | 1269 pdfContext->fGraphicsState.fMatrixTlm = matrix;; |
1270 | 1270 |
1271 return kPartial_SkPdfResult; | 1271 return kPartial_SkPdfResult; |
1272 } | 1272 } |
1273 | 1273 |
1274 //— T* Move to the start of the next line. This operator has the same effect as
the code | 1274 //— T* Move to the start of the next line. This operator has the same effect as
the code |
1275 //0 Tl Td | 1275 //0 Tl Td |
1276 //where Tl is the current leading parameter in the text state | 1276 //where Tl is the current leading parameter in the text state |
1277 static SkPdfResult PdfOp_T_star(SkPdfContext* pdfContext, SkCanvas* canvas, PdfT
okenLooper** looper) { | 1277 static SkPdfResult PdfOp_T_star(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1278 PdfTokenLooper** looper) { |
1278 SkPdfReal* zero = pdfContext->fPdfDoc->createReal(0.0); | 1279 SkPdfReal* zero = pdfContext->fPdfDoc->createReal(0.0); |
1279 SkPdfReal* tl = pdfContext->fPdfDoc->createReal(pdfContext->fGraphicsState.f
TextLeading); | 1280 SkPdfReal* tl = pdfContext->fPdfDoc->createReal(pdfContext->fGraphicsState.f
TextLeading); |
1280 | 1281 |
1281 pdfContext->fObjectStack.push(zero); | 1282 pdfContext->fObjectStack.push(zero); |
1282 pdfContext->fObjectStack.push(tl); | 1283 pdfContext->fObjectStack.push(tl); |
1283 | 1284 |
1284 SkPdfResult ret = PdfOp_Td(pdfContext, canvas, looper); | 1285 SkPdfResult ret = PdfOp_Td(pdfContext, canvas, looper); |
1285 | 1286 |
1286 return ret; | 1287 return ret; |
1287 } | 1288 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 pdfContext->fGraphicsState.fPathClosed = false; | 1410 pdfContext->fGraphicsState.fPathClosed = false; |
1410 } | 1411 } |
1411 | 1412 |
1412 EXPECT_OPERANDS("re", pdfContext, 4); | 1413 EXPECT_OPERANDS("re", pdfContext, 4); |
1413 POP_NUMBER(pdfContext, height); | 1414 POP_NUMBER(pdfContext, height); |
1414 POP_NUMBER(pdfContext, width); | 1415 POP_NUMBER(pdfContext, width); |
1415 POP_NUMBER(pdfContext, y); | 1416 POP_NUMBER(pdfContext, y); |
1416 POP_NUMBER(pdfContext, x); | 1417 POP_NUMBER(pdfContext, x); |
1417 CHECK_PARAMETERS(); | 1418 CHECK_PARAMETERS(); |
1418 | 1419 |
1419 pdfContext->fGraphicsState.fPath.addRect(SkDoubleToScalar(x), SkDoubleToScal
ar(y), | 1420 pdfContext->fGraphicsState.fPath.addRect(SkDoubleToScalar(x), |
1420 SkDoubleToScalar(x + width), SkDoub
leToScalar(y + height)); | 1421 SkDoubleToScalar(y), |
| 1422 SkDoubleToScalar(x + width), |
| 1423 SkDoubleToScalar(y + height)); |
1421 | 1424 |
1422 pdfContext->fGraphicsState.fCurPosX = x; | 1425 pdfContext->fGraphicsState.fCurPosX = x; |
1423 pdfContext->fGraphicsState.fCurPosY = y + height; | 1426 pdfContext->fGraphicsState.fCurPosY = y + height; |
1424 | 1427 |
1425 return kOK_SkPdfResult; | 1428 return kOK_SkPdfResult; |
1426 } | 1429 } |
1427 | 1430 |
1428 static SkPdfResult PdfOp_h(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 1431 static SkPdfResult PdfOp_h(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1429 pdfContext->fGraphicsState.fPath.close(); | 1432 pdfContext->fGraphicsState.fPath.close(); |
1430 return kOK_SkPdfResult; | 1433 return kOK_SkPdfResult; |
1431 } | 1434 } |
1432 | 1435 |
1433 static SkPdfResult PdfOp_fillAndStroke(SkPdfContext* pdfContext, SkCanvas* canva
s, bool fill, bool stroke, bool close, bool evenOdd) { | 1436 static SkPdfResult PdfOp_fillAndStroke(SkPdfContext* pdfContext, SkCanvas* canva
s, |
| 1437 bool fill, bool stroke, bool close, bool
evenOdd) { |
1434 SkPath path = pdfContext->fGraphicsState.fPath; | 1438 SkPath path = pdfContext->fGraphicsState.fPath; |
1435 | 1439 |
1436 if (close) { | 1440 if (close) { |
1437 path.close(); | 1441 path.close(); |
1438 } | 1442 } |
1439 | 1443 |
1440 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); | 1444 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); |
1441 | 1445 |
1442 SkPaint paint; | 1446 SkPaint paint; |
1443 | 1447 |
1444 SkPoint line[2]; | 1448 SkPoint line[2]; |
1445 if (fill && !stroke && path.isLine(line)) { | 1449 if (fill && !stroke && path.isLine(line)) { |
1446 paint.setStyle(SkPaint::kStroke_Style); | 1450 paint.setStyle(SkPaint::kStroke_Style); |
1447 | 1451 |
1448 // TODO(edisonn): implement this with patterns | 1452 // TODO(edisonn): implement this with patterns |
1449 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); | 1453 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
1450 paint.setStrokeWidth(SkDoubleToScalar(0)); | 1454 paint.setStrokeWidth(SkDoubleToScalar(0)); |
1451 | 1455 |
1452 canvas->drawPath(path, paint); | 1456 canvas->drawPath(path, paint); |
1453 } else { | 1457 } else { |
1454 if (fill) { | 1458 if (fill) { |
1455 if (strncmp((char*)pdfContext->fGraphicsState.fNonStroking.fColorSpa
ce.fBuffer, "Pattern", strlen("Pattern")) == 0 && | 1459 if (strncmp((char*)pdfContext->fGraphicsState.fNonStroking.fColorSpa
ce.fBuffer, |
| 1460 "Pattern", strlen("Pattern")) == 0 && |
1456 pdfContext->fGraphicsState.fNonStroking.fPattern != NULL) { | 1461 pdfContext->fGraphicsState.fNonStroking.fPattern != NULL) { |
1457 | 1462 |
1458 // TODO(edisonn): we can use a shader here, like imageshader to
draw fast. ultimately, | 1463 // TODO(edisonn): we can use a shader here, like imageshader to
draw fast. |
1459 // if this is not possible, and we are in rasper mode, and the c
ells don't intersect, we could even have multiple cpus. | |
1460 | 1464 |
1461 PdfOp_q(pdfContext, canvas, NULL); | 1465 PdfOp_q(pdfContext, canvas, NULL); |
1462 | 1466 |
1463 if (evenOdd) { | 1467 if (evenOdd) { |
1464 path.setFillType(SkPath::kEvenOdd_FillType); | 1468 path.setFillType(SkPath::kEvenOdd_FillType); |
1465 } | 1469 } |
1466 canvas->clipPath(path); | 1470 canvas->clipPath(path); |
1467 | 1471 |
1468 if (pdfContext->fPdfDoc->mapper()->mapType1PatternDictionary(pdf
Context->fGraphicsState.fNonStroking.fPattern) != kNone_SkPdfNativeObjectType) { | 1472 if (pdfContext->fPdfDoc |
1469 SkPdfType1PatternDictionary* pattern = (SkPdfType1PatternDic
tionary*)pdfContext->fGraphicsState.fNonStroking.fPattern; | 1473 ->mapper() |
| 1474 ->mapType1PatternDictionary(pdfContext->fGraphicsS
tate |
| 1475 .fNonStrokin
g |
| 1476 .fPattern) |
| 1477 != kNone_SkPdfNativeObj
ectType) { |
| 1478 SkPdfType1PatternDictionary* pattern |
| 1479 = (SkPdfType1PatternDictionary*)pdfContext->fGraphic
sState |
| 1480 .fNonStrok
ing |
| 1481 .fPattern; |
1470 | 1482 |
1471 // TODO(edisonn): constants | 1483 // TODO(edisonn): make PaintType constants |
1472 // TODO(edisonn): colored | |
1473 if (pattern->PaintType(pdfContext->fPdfDoc) == 1) { | 1484 if (pattern->PaintType(pdfContext->fPdfDoc) == 1) { |
1474 // TODO(edisonn): don't use abs, iterate as asked, if th
e cells intersect | 1485 // TODO(edisonn): don't use abs, iterate as asked, if th
e cells intersect |
1475 // it will change the result iterating in reverse | 1486 // it will change the result iterating in reverse |
| 1487 // remove then the following bounds.sort(); |
1476 int xStep = abs((int)pattern->XStep(pdfContext->fPdfDoc)
); | 1488 int xStep = abs((int)pattern->XStep(pdfContext->fPdfDoc)
); |
1477 int yStep = abs((int)pattern->YStep(pdfContext->fPdfDoc)
); | 1489 int yStep = abs((int)pattern->YStep(pdfContext->fPdfDoc)
); |
1478 | 1490 |
1479 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfI
ssue, "paterns x/y step is forced to positive number", pattern, pdfContext); | 1491 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfI
ssue, |
| 1492 "paterns x/y step is forced to positive numb
er", |
| 1493 pattern, pdfContext); |
1480 | 1494 |
1481 SkRect bounds = path.getBounds(); | 1495 SkRect bounds = path.getBounds(); |
1482 | |
1483 // TODO(edisonn): xstep and ystep can be negative, and w
e need to iterate in reverse | |
1484 // TODO(edisonn): don't do that! | |
1485 bounds.sort(); | 1496 bounds.sort(); |
1486 | 1497 |
1487 SkScalar x; | 1498 SkScalar x; |
1488 SkScalar y; | 1499 SkScalar y; |
1489 | 1500 |
1490 y = bounds.top(); | 1501 y = bounds.top(); |
1491 int totalx = 0; | 1502 int totalx = 0; |
1492 int totaly = 0; | 1503 int totaly = 0; |
1493 while (y < bounds.bottom()) { | 1504 while (y < bounds.bottom()) { |
1494 x = bounds.left(); | 1505 x = bounds.left(); |
1495 totalx = 0; | 1506 totalx = 0; |
1496 | 1507 |
1497 while (x < bounds.right()) { | 1508 while (x < bounds.right()) { |
1498 doXObject(pdfContext, canvas, pattern); | 1509 doXObject(pdfContext, canvas, pattern); |
1499 | 1510 |
1500 pdfContext->fGraphicsState.fContentStreamMatrix.
preTranslate(SkIntToScalar(xStep), SkIntToScalar(0)); | 1511 pdfContext->fGraphicsState.fContentStreamMatrix.
preTranslate( |
| 1512 SkIntToScalar(xStep), SkIntToScalar(0)); |
1501 totalx += xStep; | 1513 totalx += xStep; |
1502 x += SkIntToScalar(xStep); | 1514 x += SkIntToScalar(xStep); |
1503 } | 1515 } |
1504 pdfContext->fGraphicsState.fContentStreamMatrix.preT
ranslate(SkIntToScalar(-totalx), SkIntToScalar(0)); | 1516 pdfContext->fGraphicsState.fContentStreamMatrix.preT
ranslate( |
| 1517 SkIntToScalar(-totalx), SkIntToScalar(0)); |
1505 | 1518 |
1506 pdfContext->fGraphicsState.fContentStreamMatrix.preT
ranslate(SkIntToScalar(0), SkIntToScalar(-yStep)); | 1519 pdfContext->fGraphicsState.fContentStreamMatrix.preT
ranslate( |
| 1520 SkIntToScalar(0), SkIntToScalar(-yStep)); |
1507 totaly += yStep; | 1521 totaly += yStep; |
1508 y += SkIntToScalar(yStep); | 1522 y += SkIntToScalar(yStep); |
1509 } | 1523 } |
1510 pdfContext->fGraphicsState.fContentStreamMatrix.preTrans
late(SkIntToScalar(0), SkIntToScalar(totaly)); | 1524 pdfContext->fGraphicsState.fContentStreamMatrix.preTrans
late( |
| 1525 SkIntToScalar(0), SkIntToScalar(totaly)); |
1511 } | 1526 } |
1512 } | 1527 } |
1513 | 1528 |
1514 // apply matrix | |
1515 // get xstep, y step, bbox ... for cliping, and bos of the path | |
1516 | |
1517 PdfOp_Q(pdfContext, canvas, NULL); | 1529 PdfOp_Q(pdfContext, canvas, NULL); |
1518 } else { | 1530 } else { |
1519 paint.setStyle(SkPaint::kFill_Style); | 1531 paint.setStyle(SkPaint::kFill_Style); |
1520 if (evenOdd) { | 1532 if (evenOdd) { |
1521 path.setFillType(SkPath::kEvenOdd_FillType); | 1533 path.setFillType(SkPath::kEvenOdd_FillType); |
1522 } | 1534 } |
1523 | 1535 |
1524 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); | 1536 pdfContext->fGraphicsState.applyGraphicsState(&paint, false); |
1525 | 1537 |
1526 canvas->drawPath(path, paint); | 1538 canvas->drawPath(path, paint); |
1527 } | 1539 } |
1528 } | 1540 } |
1529 | 1541 |
1530 if (stroke) { | 1542 if (stroke) { |
1531 if (false && strncmp((char*)pdfContext->fGraphicsState.fNonStroking.
fColorSpace.fBuffer, "Pattern", strlen("Pattern")) == 0) { | 1543 if (false && strncmp((char*)pdfContext->fGraphicsState.fNonStroking.
fColorSpace.fBuffer, |
| 1544 "Pattern", strlen("Pattern")) == 0) { |
1532 // TODO(edisonn): implement Pattern for strokes | 1545 // TODO(edisonn): implement Pattern for strokes |
1533 paint.setStyle(SkPaint::kStroke_Style); | 1546 paint.setStyle(SkPaint::kStroke_Style); |
1534 | 1547 |
1535 paint.setColor(SK_ColorGREEN); | 1548 paint.setColor(SK_ColorGREEN); |
1536 | 1549 |
1537 path.setFillType(SkPath::kWinding_FillType); // reset it, just
in case it messes up the stroke | 1550 // reset it, just in case it messes up the stroke |
| 1551 path.setFillType(SkPath::kWinding_FillType); |
1538 canvas->drawPath(path, paint); | 1552 canvas->drawPath(path, paint); |
1539 } else { | 1553 } else { |
1540 paint.setStyle(SkPaint::kStroke_Style); | 1554 paint.setStyle(SkPaint::kStroke_Style); |
1541 | 1555 |
1542 pdfContext->fGraphicsState.applyGraphicsState(&paint, true); | 1556 pdfContext->fGraphicsState.applyGraphicsState(&paint, true); |
1543 | 1557 |
1544 path.setFillType(SkPath::kWinding_FillType); // reset it, just
in case it messes up the stroke | 1558 // reset it, just in case it messes up the stroke |
| 1559 path.setFillType(SkPath::kWinding_FillType); |
1545 canvas->drawPath(path, paint); | 1560 canvas->drawPath(path, paint); |
1546 } | 1561 } |
1547 } | 1562 } |
1548 } | 1563 } |
1549 | 1564 |
1550 pdfContext->fGraphicsState.fPath.reset(); | 1565 pdfContext->fGraphicsState.fPath.reset(); |
1551 // todo zoom ... other stuff ? | 1566 // TODO(edisonn): implement scale/zoom |
1552 | 1567 |
1553 if (pdfContext->fGraphicsState.fHasClipPathToApply) { | 1568 if (pdfContext->fGraphicsState.fHasClipPathToApply) { |
1554 #ifndef PDF_DEBUG_NO_CLIPING | 1569 #ifndef PDF_DEBUG_NO_CLIPING |
1555 canvas->clipPath(pdfContext->fGraphicsState.fClipPath, SkRegion::kInters
ect_Op, true); | 1570 canvas->clipPath(pdfContext->fGraphicsState.fClipPath, SkRegion::kInters
ect_Op, true); |
1556 #endif | 1571 #endif |
1557 } | 1572 } |
1558 | 1573 |
1559 //pdfContext->fGraphicsState.fClipPath.reset(); | 1574 //pdfContext->fGraphicsState.fClipPath.reset(); |
1560 pdfContext->fGraphicsState.fHasClipPathToApply = false; | 1575 pdfContext->fGraphicsState.fHasClipPathToApply = false; |
1561 | 1576 |
(...skipping 10 matching lines...) Expand all Loading... |
1572 } | 1587 } |
1573 | 1588 |
1574 static SkPdfResult PdfOp_F(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 1589 static SkPdfResult PdfOp_F(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1575 return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false); | 1590 return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false); |
1576 } | 1591 } |
1577 | 1592 |
1578 static SkPdfResult PdfOp_f(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 1593 static SkPdfResult PdfOp_f(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1579 return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false); | 1594 return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false); |
1580 } | 1595 } |
1581 | 1596 |
1582 static SkPdfResult PdfOp_f_star(SkPdfContext* pdfContext, SkCanvas* canvas, PdfT
okenLooper** looper) { | 1597 static SkPdfResult PdfOp_f_star(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1598 PdfTokenLooper** looper) { |
1583 return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, true); | 1599 return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, true); |
1584 } | 1600 } |
1585 | 1601 |
1586 static SkPdfResult PdfOp_B(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 1602 static SkPdfResult PdfOp_B(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1587 return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, false); | 1603 return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, false); |
1588 } | 1604 } |
1589 | 1605 |
1590 static SkPdfResult PdfOp_B_star(SkPdfContext* pdfContext, SkCanvas* canvas, PdfT
okenLooper** looper) { | 1606 static SkPdfResult PdfOp_B_star(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1607 PdfTokenLooper** looper) { |
1591 return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, true); | 1608 return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, true); |
1592 } | 1609 } |
1593 | 1610 |
1594 static SkPdfResult PdfOp_b(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 1611 static SkPdfResult PdfOp_b(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1595 return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, false); | 1612 return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, false); |
1596 } | 1613 } |
1597 | 1614 |
1598 static SkPdfResult PdfOp_b_star(SkPdfContext* pdfContext, SkCanvas* canvas, PdfT
okenLooper** looper) { | 1615 static SkPdfResult PdfOp_b_star(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1616 PdfTokenLooper** looper) { |
1599 return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, true); | 1617 return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, true); |
1600 } | 1618 } |
1601 | 1619 |
1602 static SkPdfResult PdfOp_n(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 1620 static SkPdfResult PdfOp_n(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1603 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); | 1621 canvas->setMatrix(pdfContext->fGraphicsState.fCTM); |
1604 if (pdfContext->fGraphicsState.fHasClipPathToApply) { | 1622 if (pdfContext->fGraphicsState.fHasClipPathToApply) { |
1605 #ifndef PDF_DEBUG_NO_CLIPING | 1623 #ifndef PDF_DEBUG_NO_CLIPING |
1606 canvas->clipPath(pdfContext->fGraphicsState.fClipPath, SkRegion::kInters
ect_Op, true); | 1624 canvas->clipPath(pdfContext->fGraphicsState.fClipPath, SkRegion::kInters
ect_Op, true); |
1607 #endif | 1625 #endif |
1608 } | 1626 } |
(...skipping 10 matching lines...) Expand all Loading... |
1619 SkMatrix matrix = pdfContext->fGraphicsState.fCTM; | 1637 SkMatrix matrix = pdfContext->fGraphicsState.fCTM; |
1620 matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); | 1638 matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1)); |
1621 pdfContext->fGraphicsState.fMatrixTm = matrix; | 1639 pdfContext->fGraphicsState.fMatrixTm = matrix; |
1622 pdfContext->fGraphicsState.fMatrixTlm = matrix; | 1640 pdfContext->fGraphicsState.fMatrixTlm = matrix; |
1623 | 1641 |
1624 return kPartial_SkPdfResult; | 1642 return kPartial_SkPdfResult; |
1625 } | 1643 } |
1626 | 1644 |
1627 static SkPdfResult PdfOp_ET(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 1645 static SkPdfResult PdfOp_ET(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1628 if (!pdfContext->fGraphicsState.fTextBlock) { | 1646 if (!pdfContext->fGraphicsState.fTextBlock) { |
1629 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "ET
without BT", NULL, pdfContext); | 1647 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "ET
without BT", NULL, |
| 1648 pdfContext); |
1630 | 1649 |
1631 return kIgnoreError_SkPdfResult; | 1650 return kIgnoreError_SkPdfResult; |
1632 } | 1651 } |
1633 // TODO(edisonn): anything else to be done once we are done with draw text?
Like restore stack? | 1652 // TODO(edisonn): anything else to be done once we are done with draw text?
Like restore stack? |
1634 return kOK_SkPdfResult; | 1653 return kOK_SkPdfResult; |
1635 } | 1654 } |
1636 | 1655 |
1637 static SkPdfResult skpdfGraphicsStateApplyFontCore(SkPdfContext* pdfContext, con
st SkPdfNativeObject* fontName, double fontSize) { | 1656 static SkPdfResult skpdfGraphicsStateApplyFontCore(SkPdfContext* pdfContext, |
| 1657 const SkPdfNativeObject* font
Name, double fontSize) { |
1638 #ifdef PDF_TRACE | 1658 #ifdef PDF_TRACE |
1639 printf("font name: %s\n", fontName->nameValue2().c_str()); | 1659 printf("font name: %s\n", fontName->nameValue2().c_str()); |
1640 #endif | 1660 #endif |
1641 | 1661 |
1642 if (!pdfContext->fGraphicsState.fResources->Font(pdfContext->fPdfDoc)) { | 1662 if (!pdfContext->fGraphicsState.fResources->Font(pdfContext->fPdfDoc)) { |
1643 // TODO(edisonn): try to recover and draw it any way? | 1663 // TODO(edisonn): try to recover and draw it any way? |
1644 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingFont_SkPdfIssue, "N
o font", fontName, pdfContext); | 1664 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingFont_SkPdfIssue, |
| 1665 "No font", fontName, pdfContext); |
1645 return kIgnoreError_SkPdfResult; | 1666 return kIgnoreError_SkPdfResult; |
1646 } | 1667 } |
1647 | 1668 |
1648 SkPdfNativeObject* objFont = pdfContext->fGraphicsState.fResources->Font(pdf
Context->fPdfDoc)->get(fontName); | 1669 SkPdfNativeObject* objFont |
| 1670 = pdfContext->fGraphicsState.fResources->Font(pdfContext->fPdfDoc)->
get(fontName); |
1649 objFont = pdfContext->fPdfDoc->resolveReference(objFont); | 1671 objFont = pdfContext->fPdfDoc->resolveReference(objFont); |
1650 if (kNone_SkPdfNativeObjectType == pdfContext->fPdfDoc->mapper()->mapFontDic
tionary(objFont)) { | 1672 if (kNone_SkPdfNativeObjectType == pdfContext->fPdfDoc->mapper()->mapFontDic
tionary(objFont)) { |
1651 // TODO(edisonn): try to recover and draw it any way? | 1673 // TODO(edisonn): try to recover and draw it any way? |
1652 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kInvalidFont_SkPdfIssue, "I
nvalid font", objFont, pdfContext); | 1674 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kInvalidFont_SkPdfIssue, |
| 1675 "Invalid font", objFont, pdfContext); |
1653 return kIgnoreError_SkPdfResult; | 1676 return kIgnoreError_SkPdfResult; |
1654 } | 1677 } |
1655 | 1678 |
1656 SkPdfFontDictionary* fd = (SkPdfFontDictionary*)objFont; | 1679 SkPdfFontDictionary* fd = (SkPdfFontDictionary*)objFont; |
1657 | 1680 |
1658 SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(pdfContext->fPdfDoc, fd
); | 1681 SkPdfFont* skfont = SkPdfFont::fontFromPdfDictionary(pdfContext->fPdfDoc, fd
); |
1659 | 1682 |
1660 if (skfont) { | 1683 if (skfont) { |
1661 pdfContext->fGraphicsState.fSkFont = skfont; | 1684 pdfContext->fGraphicsState.fSkFont = skfont; |
1662 } | 1685 } |
(...skipping 15 matching lines...) Expand all Loading... |
1678 return skpdfGraphicsStateApplyFontCore(pdfContext, fontName, fontSize); | 1701 return skpdfGraphicsStateApplyFontCore(pdfContext, fontName, fontSize); |
1679 } | 1702 } |
1680 | 1703 |
1681 static SkPdfResult PdfOp_Tj(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 1704 static SkPdfResult PdfOp_Tj(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1682 EXPECT_OPERANDS("Tj", pdfContext, 1); | 1705 EXPECT_OPERANDS("Tj", pdfContext, 1); |
1683 POP_STRING(pdfContext, str); | 1706 POP_STRING(pdfContext, str); |
1684 CHECK_PARAMETERS(); | 1707 CHECK_PARAMETERS(); |
1685 | 1708 |
1686 if (!pdfContext->fGraphicsState.fTextBlock) { | 1709 if (!pdfContext->fGraphicsState.fTextBlock) { |
1687 // TODO(edisonn): try to recover and draw it any way? | 1710 // TODO(edisonn): try to recover and draw it any way? |
1688 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "Tj
without BT", NULL, pdfContext); | 1711 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "Tj
without BT", NULL, |
| 1712 pdfContext); |
1689 return kIgnoreError_SkPdfResult; | 1713 return kIgnoreError_SkPdfResult; |
1690 } | 1714 } |
1691 | 1715 |
1692 SkPdfResult ret = DrawText(pdfContext, str, canvas); | 1716 SkPdfResult ret = DrawText(pdfContext, str, canvas); |
1693 | 1717 |
1694 return ret; | 1718 return ret; |
1695 } | 1719 } |
1696 | 1720 |
1697 static SkPdfResult PdfOp_quote(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTo
kenLooper** looper) { | 1721 static SkPdfResult PdfOp_quote(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1722 PdfTokenLooper** looper) { |
1698 if (!pdfContext->fGraphicsState.fTextBlock) { | 1723 if (!pdfContext->fGraphicsState.fTextBlock) { |
1699 // TODO(edisonn): try to recover and draw it any way? | 1724 // TODO(edisonn): try to recover and draw it any way? |
1700 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "' w
ithout BT", NULL, pdfContext); | 1725 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, |
| 1726 "' without BT", NULL, pdfContext); |
1701 return kIgnoreError_SkPdfResult; | 1727 return kIgnoreError_SkPdfResult; |
1702 } | 1728 } |
1703 | 1729 |
1704 PdfOp_T_star(pdfContext, canvas, looper); | 1730 PdfOp_T_star(pdfContext, canvas, looper); |
1705 // Do not pop, and push, just transfer the param to Tj | 1731 // Do not pop, and push, just transfer the param to Tj |
1706 return PdfOp_Tj(pdfContext, canvas, looper); | 1732 return PdfOp_Tj(pdfContext, canvas, looper); |
1707 } | 1733 } |
1708 | 1734 |
1709 static SkPdfResult PdfOp_doublequote(SkPdfContext* pdfContext, SkCanvas* canvas,
PdfTokenLooper** looper) { | 1735 static SkPdfResult PdfOp_doublequote(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1736 PdfTokenLooper** looper) { |
1710 if (!pdfContext->fGraphicsState.fTextBlock) { | 1737 if (!pdfContext->fGraphicsState.fTextBlock) { |
1711 // TODO(edisonn): try to recover and draw it any way? | 1738 // TODO(edisonn): try to recover and draw it any way? |
1712 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "\"
without BT", NULL, pdfContext); | 1739 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, |
| 1740 "\" without BT", NULL, pdfContext); |
1713 return kIgnoreError_SkPdfResult; | 1741 return kIgnoreError_SkPdfResult; |
1714 } | 1742 } |
1715 | 1743 |
1716 EXPECT_OPERANDS("\"", pdfContext, 3); | 1744 EXPECT_OPERANDS("\"", pdfContext, 3); |
1717 POP_OBJ(pdfContext, str); | 1745 POP_OBJ(pdfContext, str); |
1718 POP_OBJ(pdfContext, ac); | 1746 POP_OBJ(pdfContext, ac); |
1719 POP_OBJ(pdfContext, aw); | 1747 POP_OBJ(pdfContext, aw); |
1720 CHECK_PARAMETERS(); | 1748 CHECK_PARAMETERS(); |
1721 | 1749 |
1722 pdfContext->fObjectStack.push(aw); | 1750 pdfContext->fObjectStack.push(aw); |
1723 PdfOp_Tw(pdfContext, canvas, looper); | 1751 PdfOp_Tw(pdfContext, canvas, looper); |
1724 | 1752 |
1725 pdfContext->fObjectStack.push(ac); | 1753 pdfContext->fObjectStack.push(ac); |
1726 PdfOp_Tc(pdfContext, canvas, looper); | 1754 PdfOp_Tc(pdfContext, canvas, looper); |
1727 | 1755 |
1728 pdfContext->fObjectStack.push(str); | 1756 pdfContext->fObjectStack.push(str); |
1729 PdfOp_quote(pdfContext, canvas, looper); | 1757 PdfOp_quote(pdfContext, canvas, looper); |
1730 | 1758 |
1731 return kPartial_SkPdfResult; | 1759 return kPartial_SkPdfResult; |
1732 } | 1760 } |
1733 | 1761 |
1734 static SkPdfResult PdfOp_TJ(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 1762 static SkPdfResult PdfOp_TJ(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1735 EXPECT_OPERANDS("Tf", pdfContext, 1); | 1763 EXPECT_OPERANDS("Tf", pdfContext, 1); |
1736 POP_ARRAY(pdfContext, array); | 1764 POP_ARRAY(pdfContext, array); |
1737 CHECK_PARAMETERS(); | 1765 CHECK_PARAMETERS(); |
1738 | 1766 |
1739 if (!pdfContext->fGraphicsState.fTextBlock) { | 1767 if (!pdfContext->fGraphicsState.fTextBlock) { |
1740 // TODO(edisonn): try to recover and draw it any way? | 1768 // TODO(edisonn): try to recover and draw it any way? |
1741 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "TJ
without BT", NULL, pdfContext); | 1769 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "TJ
without BT", NULL, |
| 1770 pdfContext); |
1742 return kIgnoreError_SkPdfResult; | 1771 return kIgnoreError_SkPdfResult; |
1743 } | 1772 } |
1744 | 1773 |
1745 if (!array->isArray()) { | 1774 if (!array->isArray()) { |
1746 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, array,
SkPdfNativeObject::kArray_PdfObjectType, pdfContext); | 1775 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, array, |
| 1776 SkPdfNativeObject::kArray_PdfObjectType, pdfCo
ntext); |
1747 return kIgnoreError_SkPdfResult; | 1777 return kIgnoreError_SkPdfResult; |
1748 } | 1778 } |
1749 | 1779 |
1750 for( int i=0; i<static_cast<int>(array->size()); i++ ) | 1780 for( int i=0; i<static_cast<int>(array->size()); i++ ) |
1751 { | 1781 { |
1752 if (!(*array)[i]) { | 1782 if (!(*array)[i]) { |
1753 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "element
[i] is null, no element should be null", array, SkPdfNativeObject::_kAnyString_P
dfObjectType || SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext); | 1783 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, |
| 1784 "element [i] is null, no element should be
null", |
| 1785 array, |
| 1786 SkPdfNativeObject::_kAnyString_PdfObjectTy
pe || |
| 1787 SkPdfNativeObject::_kNumber_PdfObj
ectType, |
| 1788 pdfContext); |
1754 } else if( (*array)[i]->isAnyString()) { | 1789 } else if( (*array)[i]->isAnyString()) { |
1755 SkPdfNativeObject* obj = (*array)[i]; | 1790 SkPdfNativeObject* obj = (*array)[i]; |
1756 DrawText(pdfContext, obj, canvas); | 1791 DrawText(pdfContext, obj, canvas); |
1757 } else if ((*array)[i]->isNumber()) { | 1792 } else if ((*array)[i]->isNumber()) { |
1758 double dx = (*array)[i]->numberValue(); | 1793 double dx = (*array)[i]->numberValue(); |
1759 SkMatrix matrix; | 1794 SkMatrix matrix; |
1760 matrix.setAll(SkDoubleToScalar(1), | 1795 matrix.setAll(SkDoubleToScalar(1), |
1761 SkDoubleToScalar(0), | 1796 SkDoubleToScalar(0), |
1762 // TODO(edisonn): use writing mode, vertical/horizonta
l. | 1797 // TODO(edisonn): use writing mode, vertical/horizonta
l. |
1763 SkDoubleToScalar(-dx), // amount is substracted!!! | 1798 SkDoubleToScalar(-dx), // amount is substracted!!! |
1764 SkDoubleToScalar(0), | 1799 SkDoubleToScalar(0), |
1765 SkDoubleToScalar(1), | 1800 SkDoubleToScalar(1), |
1766 SkDoubleToScalar(0), | 1801 SkDoubleToScalar(0), |
1767 SkDoubleToScalar(0), | 1802 SkDoubleToScalar(0), |
1768 SkDoubleToScalar(0), | 1803 SkDoubleToScalar(0), |
1769 SkDoubleToScalar(1)); | 1804 SkDoubleToScalar(1)); |
1770 | 1805 |
1771 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); | 1806 pdfContext->fGraphicsState.fMatrixTm.preConcat(matrix); |
1772 } else { | 1807 } else { |
1773 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "wrong ty
pe", (*array)[i], SkPdfNativeObject::kArray_PdfObjectType || SkPdfNativeObject::
_kNumber_PdfObjectType, pdfContext); | 1808 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "wrong ty
pe", (*array)[i], |
| 1809 SkPdfNativeObject::kArray_PdfObjectType || |
| 1810 SkPdfNativeObject::_kNumber_PdfObj
ectType, |
| 1811 pdfContext); |
1774 } | 1812 } |
1775 } | 1813 } |
1776 return kPartial_SkPdfResult; // TODO(edisonn): Implement fully DrawText bef
ore returing OK. | 1814 return kPartial_SkPdfResult; // TODO(edisonn): Implement fully DrawText bef
ore returing OK. |
1777 } | 1815 } |
1778 | 1816 |
1779 static SkPdfResult PdfOp_CS_cs(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdf
ColorOperator* colorOperator) { | 1817 static SkPdfResult PdfOp_CS_cs(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1818 SkPdfColorOperator* colorOperator) { |
1780 EXPECT_OPERANDS("CS/cs", pdfContext, 1); | 1819 EXPECT_OPERANDS("CS/cs", pdfContext, 1); |
1781 POP_NAME(pdfContext, name); | 1820 POP_NAME(pdfContext, name); |
1782 CHECK_PARAMETERS(); | 1821 CHECK_PARAMETERS(); |
1783 | 1822 |
1784 //Next, get the ColorSpace Dictionary from the Resource Dictionary: | 1823 //Next, get the ColorSpace Dictionary from the Resource Dictionary: |
1785 SkPdfDictionary* colorSpaceResource = pdfContext->fGraphicsState.fResources-
>ColorSpace(pdfContext->fPdfDoc); | 1824 SkPdfDictionary* colorSpaceResource |
| 1825 = pdfContext->fGraphicsState.fResources->ColorSpace(pdfContext->fPdf
Doc); |
1786 | 1826 |
1787 SkPdfNativeObject* colorSpace = colorSpaceResource ? pdfContext->fPdfDoc->re
solveReference(colorSpaceResource->get(name)) : name; | 1827 SkPdfNativeObject* colorSpace |
| 1828 = colorSpaceResource ? pdfContext->fPdfDoc |
| 1829 ->resolveReference(colorSpaceResour
ce->get(name)) : |
| 1830 name; |
1788 | 1831 |
1789 if (colorSpace == NULL) { | 1832 if (colorSpace == NULL) { |
1790 colorOperator->fColorSpace = name->strRef(); | 1833 colorOperator->fColorSpace = name->strRef(); |
1791 } else { | 1834 } else { |
1792 #ifdef PDF_TRACE | 1835 #ifdef PDF_TRACE |
1793 printf("CS = %s\n", colorSpace->toString(0, 0).c_str()); | 1836 printf("CS = %s\n", colorSpace->toString(0, 0).c_str()); |
1794 #endif // PDF_TRACE | 1837 #endif // PDF_TRACE |
1795 if (colorSpace->isName()) { | 1838 if (colorSpace->isName()) { |
1796 colorOperator->fColorSpace = colorSpace->strRef(); | 1839 colorOperator->fColorSpace = colorSpace->strRef(); |
1797 } else if (colorSpace->isArray()) { | 1840 } else if (colorSpace->isArray()) { |
1798 int cnt = colorSpace->size(); | 1841 int cnt = colorSpace->size(); |
1799 if (cnt == 0) { | 1842 if (cnt == 0) { |
1800 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_
SkPdfIssue, "color space has length 0", colorSpace, pdfContext); | 1843 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_
SkPdfIssue, |
| 1844 "color space has length 0", colorSpace, pdfContext); |
1801 return kIgnoreError_SkPdfResult; | 1845 return kIgnoreError_SkPdfResult; |
1802 } | 1846 } |
1803 SkPdfNativeObject* type = colorSpace->objAtAIndex(0); | 1847 SkPdfNativeObject* type = colorSpace->objAtAIndex(0); |
1804 type = pdfContext->fPdfDoc->resolveReference(type); | 1848 type = pdfContext->fPdfDoc->resolveReference(type); |
1805 | 1849 |
1806 if (type->isName("ICCBased")) { | 1850 if (type->isName("ICCBased")) { |
1807 if (cnt != 2) { | 1851 if (cnt != 2) { |
1808 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSi
zes_SkPdfIssue, "ICCBased color space must have an array with 2 elements", color
Space, pdfContext); | 1852 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSi
zes_SkPdfIssue, |
| 1853 "ICCBased color space must have an array with 2
elements", |
| 1854 colorSpace, pdfContext); |
1809 return kIgnoreError_SkPdfResult; | 1855 return kIgnoreError_SkPdfResult; |
1810 } | 1856 } |
1811 SkPdfNativeObject* prop = colorSpace->objAtAIndex(1); | 1857 SkPdfNativeObject* prop = colorSpace->objAtAIndex(1); |
1812 prop = pdfContext->fPdfDoc->resolveReference(prop); | 1858 prop = pdfContext->fPdfDoc->resolveReference(prop); |
1813 #ifdef PDF_TRACE | 1859 #ifdef PDF_TRACE |
1814 printf("ICCBased prop = %s\n", prop->toString(0, 0).c_str()); | 1860 printf("ICCBased prop = %s\n", prop->toString(0, 0).c_str()); |
1815 #endif // PDF_TRACE | 1861 #endif // PDF_TRACE |
1816 // TODO(edisonn): hack | 1862 // TODO(edisonn): hack |
1817 if (prop && prop->isDictionary() && prop->get("N") && prop->get
("N")->isInteger() && prop->get("N")->intValue() == 3) { | 1863 if (prop && prop->isDictionary() && prop->get("N") && |
| 1864 prop->get("N")->isInteger() && prop->get("N")->intValue(
) == 3) { |
1818 colorOperator->setColorSpace(&strings_DeviceRGB); | 1865 colorOperator->setColorSpace(&strings_DeviceRGB); |
1819 return kPartial_SkPdfResult; | 1866 return kPartial_SkPdfResult; |
1820 } | 1867 } |
1821 return kNYI_SkPdfResult; | 1868 return kNYI_SkPdfResult; |
1822 } | 1869 } |
1823 } | 1870 } |
1824 } | 1871 } |
1825 | 1872 |
1826 return kPartial_SkPdfResult; | 1873 return kPartial_SkPdfResult; |
1827 } | 1874 } |
1828 | 1875 |
1829 static SkPdfResult PdfOp_CS(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 1876 static SkPdfResult PdfOp_CS(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1830 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); | 1877 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); |
1831 } | 1878 } |
1832 | 1879 |
1833 static SkPdfResult PdfOp_cs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 1880 static SkPdfResult PdfOp_cs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1834 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); | 1881 return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); |
1835 } | 1882 } |
1836 | 1883 |
1837 static SkPdfResult PdfOp_SC_sc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdf
ColorOperator* colorOperator) { | 1884 static SkPdfResult PdfOp_SC_sc(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1885 SkPdfColorOperator* colorOperator) { |
1838 double c[4]; | 1886 double c[4]; |
1839 // int64_t v[4]; | 1887 // int64_t v[4]; |
1840 | 1888 |
1841 int n = GetColorSpaceComponents(colorOperator->fColorSpace); | 1889 int n = GetColorSpaceComponents(colorOperator->fColorSpace); |
1842 | 1890 |
1843 bool doubles = true; | 1891 bool doubles = true; |
1844 if (colorOperator->fColorSpace.equals("Indexed")) { | 1892 if (colorOperator->fColorSpace.equals("Indexed")) { |
1845 doubles = false; | 1893 doubles = false; |
1846 } | 1894 } |
1847 | 1895 |
1848 #ifdef PDF_TRACE | 1896 #ifdef PDF_TRACE |
1849 printf("color space = %s, N = %i\n", colorOperator->fColorSpace.fBuffer, n); | 1897 printf("color space = %s, N = %i\n", colorOperator->fColorSpace.fBuffer, n); |
1850 #endif | 1898 #endif |
1851 | 1899 |
1852 EXPECT_OPERANDS("SC/sc", pdfContext, n); | 1900 EXPECT_OPERANDS("SC/sc", pdfContext, n); |
1853 | 1901 |
1854 for (int i = n - 1; i >= 0 ; i--) { | 1902 for (int i = n - 1; i >= 0 ; i--) { |
1855 if (doubles) { | 1903 if (doubles) { |
1856 POP_NUMBER_INTO(pdfContext, c[i]); | 1904 POP_NUMBER_INTO(pdfContext, c[i]); |
1857 // } else { | 1905 // } else { |
1858 // v[i] = pdfContext->fObjectStack.top()->intValue(); pdfConte
xt->fObjectStack.pop(); | 1906 // v[i] = pdfContext->fObjectStack.top()->intValue(); pdfConte
xt->fObjectStack.pop(); |
1859 } | 1907 } |
1860 } | 1908 } |
1861 CHECK_PARAMETERS(); | 1909 CHECK_PARAMETERS(); |
1862 | 1910 |
1863 // TODO(edisonn): Now, set that color. Only DeviceRGB supported. | 1911 // TODO(edisonn): Now, set that color. Only DeviceRGB supported. |
1864 // TODO(edisonn): do possible field values to enum at parsing time! | 1912 // TODO(edisonn): do possible field values to enum at parsing time! |
1865 // TODO(edisonn): support also abreviations /DeviceRGB == /RGB | 1913 // TODO(edisonn): support also abbreviations /DeviceRGB == /RGB |
1866 if (colorOperator->fColorSpace.equals("DeviceRGB") || colorOperator->fColorS
pace.equals("RGB")) { | 1914 if (colorOperator->fColorSpace.equals("DeviceRGB") || |
1867 colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*c[0]), (U8CPU)(255*
c[1]), (U8CPU)(255*c[2]))); | 1915 colorOperator->fColorSpace.equals("RGB")) { |
| 1916 colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*c[0]), |
| 1917 (U8CPU)(255*c[1]), |
| 1918 (U8CPU)(255*c[2]))); |
1868 } | 1919 } |
1869 return kPartial_SkPdfResult; | 1920 return kPartial_SkPdfResult; |
1870 } | 1921 } |
1871 | 1922 |
1872 static SkPdfResult PdfOp_SC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 1923 static SkPdfResult PdfOp_SC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1873 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); | 1924 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); |
1874 } | 1925 } |
1875 | 1926 |
1876 static SkPdfResult PdfOp_sc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 1927 static SkPdfResult PdfOp_sc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1877 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); | 1928 return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); |
1878 } | 1929 } |
1879 | 1930 |
1880 static SkPdfResult PdfOp_SCN_scn(SkPdfContext* pdfContext, SkCanvas* canvas, SkP
dfColorOperator* colorOperator) { | 1931 static SkPdfResult PdfOp_SCN_scn(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1932 SkPdfColorOperator* colorOperator) { |
1881 if (pdfContext->fObjectStack.count() > 0 && pdfContext->fObjectStack.top()->
isName()) { | 1933 if (pdfContext->fObjectStack.count() > 0 && pdfContext->fObjectStack.top()->
isName()) { |
1882 SkPdfNativeObject* name = pdfContext->fObjectStack.top(); pdfContext-
>fObjectStack.pop(); | 1934 SkPdfNativeObject* name = pdfContext->fObjectStack.top(); pdfContext-
>fObjectStack.pop(); |
1883 | 1935 |
1884 //Next, get the ExtGState Dictionary from the Resource Dictionary: | 1936 SkPdfDictionary* patternResources |
1885 SkPdfDictionary* patternResources = pdfContext->fGraphicsState.fResource
s->Pattern(pdfContext->fPdfDoc); | 1937 = pdfContext->fGraphicsState.fResources->Pattern(pdfContext->fPd
fDoc); |
1886 | 1938 |
1887 if (patternResources == NULL) { | 1939 if (patternResources == NULL) { |
1888 #ifdef PDF_TRACE | 1940 #ifdef PDF_TRACE |
1889 printf("ExtGState is NULL!\n"); | 1941 printf("ExtGState is NULL!\n"); |
1890 #endif | 1942 #endif |
1891 return kIgnoreError_SkPdfResult; | 1943 return kIgnoreError_SkPdfResult; |
1892 } | 1944 } |
1893 | 1945 |
1894 colorOperator->setPatternColorSpace(pdfContext->fPdfDoc->resolveReferenc
e(patternResources->get(name))); | 1946 colorOperator->setPatternColorSpace( |
| 1947 pdfContext->fPdfDoc->resolveReference(patternResources->get(name
))); |
1895 } | 1948 } |
1896 | 1949 |
1897 // TODO(edisonn): SCN supports more color spaces than SCN. Read and implemen
t spec. | 1950 // TODO(edisonn): SCN supports more color spaces than SCN. Read and implemen
t spec. |
1898 PdfOp_SC_sc(pdfContext, canvas, colorOperator); | 1951 PdfOp_SC_sc(pdfContext, canvas, colorOperator); |
1899 | 1952 |
1900 return kPartial_SkPdfResult; | 1953 return kPartial_SkPdfResult; |
1901 } | 1954 } |
1902 | 1955 |
1903 static SkPdfResult PdfOp_SCN(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { | 1956 static SkPdfResult PdfOp_SCN(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { |
1904 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroki
ng); | 1957 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroki
ng); |
1905 } | 1958 } |
1906 | 1959 |
1907 static SkPdfResult PdfOp_scn(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { | 1960 static SkPdfResult PdfOp_scn(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { |
1908 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStr
oking); | 1961 return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStr
oking); |
1909 } | 1962 } |
1910 | 1963 |
1911 static SkPdfResult PdfOp_G_g(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfCo
lorOperator* colorOperator) { | 1964 static SkPdfResult PdfOp_G_g(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1965 SkPdfColorOperator* colorOperator) { |
1912 EXPECT_OPERANDS("G/g", pdfContext, 1); | 1966 EXPECT_OPERANDS("G/g", pdfContext, 1); |
1913 POP_NUMBER(pdfContext, gray); | 1967 POP_NUMBER(pdfContext, gray); |
1914 CHECK_PARAMETERS(); | 1968 CHECK_PARAMETERS(); |
1915 | 1969 |
1916 colorOperator->fColorSpace = strings_DeviceRGB; // TODO(edisonn): HACK - it
should be device gray, but not suported right now | 1970 // TODO(edisonn): limit gray in [0, 1] |
1917 colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*gray), (U8CPU)(255*gray
), (U8CPU)(255*gray))); | 1971 |
| 1972 // TODO(edisonn): HACK - it should be device gray, but not suported right no
w |
| 1973 colorOperator->fColorSpace = strings_DeviceRGB; |
| 1974 colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255 * gray), |
| 1975 (U8CPU)(255 * gray), |
| 1976 (U8CPU)(255 * gray))); |
1918 | 1977 |
1919 return kPartial_SkPdfResult; | 1978 return kPartial_SkPdfResult; |
1920 } | 1979 } |
1921 | 1980 |
1922 static SkPdfResult PdfOp_G(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 1981 static SkPdfResult PdfOp_G(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1923 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); | 1982 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); |
1924 } | 1983 } |
1925 | 1984 |
1926 static SkPdfResult PdfOp_g(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 1985 static SkPdfResult PdfOp_g(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1927 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
g); | 1986 return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
g); |
1928 } | 1987 } |
1929 | 1988 |
1930 static SkPdfResult PdfOp_RG_rg(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdf
ColorOperator* colorOperator) { | 1989 static SkPdfResult PdfOp_RG_rg(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 1990 SkPdfColorOperator* colorOperator) { |
1931 EXPECT_OPERANDS("RG/rg", pdfContext, 3); | 1991 EXPECT_OPERANDS("RG/rg", pdfContext, 3); |
1932 POP_NUMBER(pdfContext, b); | 1992 POP_NUMBER(pdfContext, b); |
1933 POP_NUMBER(pdfContext, g); | 1993 POP_NUMBER(pdfContext, g); |
1934 POP_NUMBER(pdfContext, r); | 1994 POP_NUMBER(pdfContext, r); |
1935 CHECK_PARAMETERS(); | 1995 CHECK_PARAMETERS(); |
1936 | 1996 |
1937 colorOperator->fColorSpace = strings_DeviceRGB; | 1997 colorOperator->fColorSpace = strings_DeviceRGB; |
1938 colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*r), (U8CPU)(255*g), (U8
CPU)(255*b))); | 1998 colorOperator->setRGBColor(SkColorSetRGB((U8CPU)(255*r), (U8CPU)(255*g), (U8
CPU)(255*b))); |
1939 return kOK_SkPdfResult; | 1999 return kOK_SkPdfResult; |
1940 } | 2000 } |
1941 | 2001 |
1942 static SkPdfResult PdfOp_RG(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2002 static SkPdfResult PdfOp_RG(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1943 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); | 2003 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking
); |
1944 } | 2004 } |
1945 | 2005 |
1946 static SkPdfResult PdfOp_rg(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2006 static SkPdfResult PdfOp_rg(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1947 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); | 2007 return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrok
ing); |
1948 } | 2008 } |
1949 | 2009 |
1950 static SkPdfResult PdfOp_K_k(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfCo
lorOperator* colorOperator) { | 2010 static SkPdfResult PdfOp_K_k(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 2011 SkPdfColorOperator* colorOperator) { |
1951 // TODO(edisonn): spec has some rules about overprint, implement them. | 2012 // TODO(edisonn): spec has some rules about overprint, implement them. |
1952 EXPECT_OPERANDS("K/k", pdfContext, 4); | 2013 EXPECT_OPERANDS("K/k", pdfContext, 4); |
1953 POP_NUMBER(pdfContext, k); | 2014 POP_NUMBER(pdfContext, k); |
1954 POP_NUMBER(pdfContext, y); | 2015 POP_NUMBER(pdfContext, y); |
1955 POP_NUMBER(pdfContext, m); | 2016 POP_NUMBER(pdfContext, m); |
1956 POP_NUMBER(pdfContext, c); | 2017 POP_NUMBER(pdfContext, c); |
1957 CHECK_PARAMETERS(); | 2018 CHECK_PARAMETERS(); |
1958 | 2019 |
1959 // TODO(edisonn): silly way to remove compiler warning | 2020 // TODO(edisonn): really silly quick way to remove compiler warning |
1960 if (k + y + m + c == 0) { | 2021 if (k + y + m + c == 0) { |
1961 return kNYI_SkPdfResult; | 2022 return kNYI_SkPdfResult; |
1962 } | 2023 } |
1963 | 2024 |
1964 //colorOperator->fColorSpace = strings_DeviceCMYK; | 2025 //colorOperator->fColorSpace = strings_DeviceCMYK; |
1965 // TODO(edisonn): Set color. | 2026 // TODO(edisonn): Set color. |
1966 return kNYI_SkPdfResult; | 2027 return kNYI_SkPdfResult; |
1967 } | 2028 } |
1968 | 2029 |
1969 static SkPdfResult PdfOp_K(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 2030 static SkPdfResult PdfOp_K(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1970 return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); | 2031 return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking); |
1971 } | 2032 } |
1972 | 2033 |
1973 static SkPdfResult PdfOp_k(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 2034 static SkPdfResult PdfOp_k(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1974 return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
g); | 2035 return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStrokin
g); |
1975 } | 2036 } |
1976 | 2037 |
1977 static SkPdfResult PdfOp_W(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 2038 static SkPdfResult PdfOp_W(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
1978 pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath; | 2039 pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath; |
1979 pdfContext->fGraphicsState.fHasClipPathToApply = true; | 2040 pdfContext->fGraphicsState.fHasClipPathToApply = true; |
1980 | 2041 |
1981 return kOK_SkPdfResult; | 2042 return kOK_SkPdfResult; |
1982 } | 2043 } |
1983 | 2044 |
1984 static SkPdfResult PdfOp_W_star(SkPdfContext* pdfContext, SkCanvas* canvas, PdfT
okenLooper** looper) { | 2045 static SkPdfResult PdfOp_W_star(SkPdfContext* pdfContext, SkCanvas* canvas, |
| 2046 PdfTokenLooper** looper) { |
1985 pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath; | 2047 pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath; |
1986 | 2048 |
1987 pdfContext->fGraphicsState.fClipPath.setFillType(SkPath::kEvenOdd_FillType); | 2049 pdfContext->fGraphicsState.fClipPath.setFillType(SkPath::kEvenOdd_FillType); |
1988 pdfContext->fGraphicsState.fHasClipPathToApply = true; | 2050 pdfContext->fGraphicsState.fHasClipPathToApply = true; |
1989 | 2051 |
1990 return kOK_SkPdfResult; | 2052 return kOK_SkPdfResult; |
1991 } | 2053 } |
1992 | 2054 |
1993 static SkPdfResult PdfOp_BX(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2055 static SkPdfResult PdfOp_BX(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1994 *looper = new PdfCompatibilitySectionLooper(); | 2056 *looper = new PdfCompatibilitySectionLooper(); |
1995 return kOK_SkPdfResult; | 2057 return kOK_SkPdfResult; |
1996 } | 2058 } |
1997 | 2059 |
1998 static SkPdfResult PdfOp_EX(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2060 static SkPdfResult PdfOp_EX(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
1999 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, "EX ope
rator should not be called, it is habdled in a looper, unless the file is corrup
ted, we should assert", NULL, pdfContext); | 2061 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, |
| 2062 "EX operator should not be called, it is handled in a looper, " |
| 2063 "unless the file is corrupted, we should assert", |
| 2064 NULL, pdfContext); |
2000 | 2065 |
2001 return kIgnoreError_SkPdfResult; | 2066 return kIgnoreError_SkPdfResult; |
2002 } | 2067 } |
2003 | 2068 |
2004 static SkPdfResult PdfOp_BI(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2069 static SkPdfResult PdfOp_BI(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2005 *looper = new PdfInlineImageLooper(); | 2070 *looper = new PdfInlineImageLooper(); |
2006 return kOK_SkPdfResult; | 2071 return kOK_SkPdfResult; |
2007 } | 2072 } |
2008 | 2073 |
2009 static SkPdfResult PdfOp_ID(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2074 static SkPdfResult PdfOp_ID(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2010 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, "ID ope
rator should not be called, it is habdled in a looper, unless the file is corrup
ted, we should assert", NULL, pdfContext); | 2075 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, |
| 2076 "ID operator should not be called, it is habdled in a looper, " |
| 2077 "unless the file is corrupted, we should assert", |
| 2078 NULL, pdfContext); |
2011 return kIgnoreError_SkPdfResult; | 2079 return kIgnoreError_SkPdfResult; |
2012 } | 2080 } |
2013 | 2081 |
2014 static SkPdfResult PdfOp_EI(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2082 static SkPdfResult PdfOp_EI(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2015 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, "EI ope
rator should not be called, it is habdled in a looper, unless the file is corrup
ted, we should assert", NULL, pdfContext); | 2083 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue, |
| 2084 "EI operator should not be called, it is habdled in a looper, " |
| 2085 "unless the file is corrupted, we should assert", |
| 2086 NULL, pdfContext); |
2016 return kIgnoreError_SkPdfResult; | 2087 return kIgnoreError_SkPdfResult; |
2017 } | 2088 } |
2018 | 2089 |
2019 // TODO(edisonn): security review here, make sure all parameters are valid, and
safe. | |
2020 static SkPdfResult skpdfGraphicsStateApply_ca(SkPdfContext* pdfContext, double c
a) { | 2090 static SkPdfResult skpdfGraphicsStateApply_ca(SkPdfContext* pdfContext, double c
a) { |
2021 pdfContext->fGraphicsState.fNonStroking.fOpacity = ca; | 2091 pdfContext->fGraphicsState.fNonStroking.fOpacity = ca; |
2022 return kOK_SkPdfResult; | 2092 return kOK_SkPdfResult; |
2023 } | 2093 } |
2024 | 2094 |
2025 static SkPdfResult skpdfGraphicsStateApply_CA(SkPdfContext* pdfContext, double C
A) { | 2095 static SkPdfResult skpdfGraphicsStateApply_CA(SkPdfContext* pdfContext, double C
A) { |
2026 pdfContext->fGraphicsState.fStroking.fOpacity = CA; | 2096 pdfContext->fGraphicsState.fStroking.fOpacity = CA; |
2027 return kOK_SkPdfResult; | 2097 return kOK_SkPdfResult; |
2028 } | 2098 } |
2029 | 2099 |
(...skipping 10 matching lines...) Expand all Loading... |
2040 static SkPdfResult skpdfGraphicsStateApplyLJ(SkPdfContext* pdfContext, int64_t l
ineJoin) { | 2110 static SkPdfResult skpdfGraphicsStateApplyLJ(SkPdfContext* pdfContext, int64_t l
ineJoin) { |
2041 pdfContext->fGraphicsState.fLineJoin = (int)lineJoin; | 2111 pdfContext->fGraphicsState.fLineJoin = (int)lineJoin; |
2042 return kOK_SkPdfResult; | 2112 return kOK_SkPdfResult; |
2043 } | 2113 } |
2044 | 2114 |
2045 static SkPdfResult skpdfGraphicsStateApplyML(SkPdfContext* pdfContext, double mi
terLimit) { | 2115 static SkPdfResult skpdfGraphicsStateApplyML(SkPdfContext* pdfContext, double mi
terLimit) { |
2046 pdfContext->fGraphicsState.fMiterLimit = miterLimit; | 2116 pdfContext->fGraphicsState.fMiterLimit = miterLimit; |
2047 return kOK_SkPdfResult; | 2117 return kOK_SkPdfResult; |
2048 } | 2118 } |
2049 | 2119 |
2050 // TODO(edisonn): implement all rules, as of now 3) and 5) and 6) do not seem su
ported by skia, but I am not sure | 2120 // TODO(edisonn): test all dashing rules, not sure if they work as in skia. |
2051 /* | 2121 /* |
2052 1) [ ] 0 No dash; solid, unbroken lines | 2122 1) [ ] 0 No dash; solid, unbroken lines |
2053 2) [3] 0 3 units on, 3 units off, … | 2123 2) [3] 0 3 units on, 3 units off, … |
2054 3) [2] 1 1 on, 2 off, 2 on, 2 off, … | 2124 3) [2] 1 1 on, 2 off, 2 on, 2 off, … |
2055 4) [2 1] 0 2 on, 1 off, 2 on, 1 off, … | 2125 4) [2 1] 0 2 on, 1 off, 2 on, 1 off, … |
2056 5) [3 5] 6 2 off, 3 on, 5 off, 3 on, 5 off, … | 2126 5) [3 5] 6 2 off, 3 on, 5 off, 3 on, 5 off, … |
2057 6) [2 3] 11 1 on, 3 off, 2 on, 3 off, 2 on, … | 2127 6) [2 3] 11 1 on, 3 off, 2 on, 3 off, 2 on, … |
2058 */ | 2128 */ |
2059 | 2129 |
2060 static SkPdfResult skpdfGraphicsStateApplyD(SkPdfContext* pdfContext, SkPdfArray
* intervals, SkPdfNativeObject* phase) { | 2130 static SkPdfResult skpdfGraphicsStateApplyD(SkPdfContext* pdfContext, SkPdfArray
* intervals, |
| 2131 SkPdfNativeObject* phase) { |
2061 if (intervals == NULL) { | 2132 if (intervals == NULL) { |
2062 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, interva
ls, SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext); | 2133 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, interva
ls, |
| 2134 SkPdfNativeObject::_kNumber_PdfObjectType, pdf
Context); |
2063 return kIgnoreError_SkPdfResult; | 2135 return kIgnoreError_SkPdfResult; |
2064 } | 2136 } |
2065 | 2137 |
2066 if (phase == NULL) { | 2138 if (phase == NULL) { |
2067 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, phase,
SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext); | 2139 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, phase, |
| 2140 SkPdfNativeObject::_kNumber_PdfObjectType, pdf
Context); |
2068 return kIgnoreError_SkPdfResult; | 2141 return kIgnoreError_SkPdfResult; |
2069 } | 2142 } |
2070 | 2143 |
2071 int cnt = intervals->size(); | 2144 int cnt = intervals->size(); |
2072 if (cnt >= 256) { | 2145 if (cnt >= 256) { |
2073 // TODO(edisonn): alloc memory | 2146 // TODO(edisonn): alloc memory |
2074 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "dash arra
y size unssuported, cnt > 256", intervals, pdfContext); | 2147 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, |
| 2148 "dash array size unssuported, cnt > 256", intervals, pdfCont
ext); |
2075 return kIgnoreError_SkPdfResult; | 2149 return kIgnoreError_SkPdfResult; |
2076 } | 2150 } |
2077 for (int i = 0; i < cnt; i++) { | 2151 for (int i = 0; i < cnt; i++) { |
2078 if (!intervals->objAtAIndex(i) || !intervals->objAtAIndex(i)->isNumber()
) { | 2152 if (!intervals->objAtAIndex(i) || !intervals->objAtAIndex(i)->isNumber()
) { |
2079 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, int
ervals->objAtAIndex(i), SkPdfNativeObject::_kNumber_PdfObjectType, NULL); | 2153 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, |
| 2154 intervals->objAtAIndex(i), |
| 2155 SkPdfNativeObject::_kNumber_PdfObjectType,
NULL); |
2080 return kIgnoreError_SkPdfResult; | 2156 return kIgnoreError_SkPdfResult; |
2081 } | 2157 } |
2082 } | 2158 } |
2083 | 2159 |
2084 double total = 0; | 2160 double total = 0; |
2085 for (int i = 0 ; i < cnt; i++) { | 2161 for (int i = 0 ; i < cnt; i++) { |
2086 pdfContext->fGraphicsState.fDashArray[i] = intervals->objAtAIndex(i)->sc
alarValue(); | 2162 pdfContext->fGraphicsState.fDashArray[i] = intervals->objAtAIndex(i)->sc
alarValue(); |
2087 total += pdfContext->fGraphicsState.fDashArray[i]; | 2163 total += pdfContext->fGraphicsState.fDashArray[i]; |
2088 } | 2164 } |
2089 if (cnt & 1) { | 2165 if (cnt & 1) { |
(...skipping 10 matching lines...) Expand all Loading... |
2100 if (pdfContext->fGraphicsState.fDashPhase == 0) { | 2176 if (pdfContext->fGraphicsState.fDashPhase == 0) { |
2101 // other rules, changes? | 2177 // other rules, changes? |
2102 pdfContext->fGraphicsState.fDashPhase = SkDoubleToScalar(total); | 2178 pdfContext->fGraphicsState.fDashPhase = SkDoubleToScalar(total); |
2103 } | 2179 } |
2104 | 2180 |
2105 return kOK_SkPdfResult; | 2181 return kOK_SkPdfResult; |
2106 } | 2182 } |
2107 | 2183 |
2108 static SkPdfResult skpdfGraphicsStateApplyD(SkPdfContext* pdfContext, SkPdfArray
* dash) { | 2184 static SkPdfResult skpdfGraphicsStateApplyD(SkPdfContext* pdfContext, SkPdfArray
* dash) { |
2109 if (!dash || dash->isArray()) { | 2185 if (!dash || dash->isArray()) { |
2110 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash, S
kPdfNativeObject::kArray_PdfObjectType, pdfContext); | 2186 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash, |
| 2187 SkPdfNativeObject::kArray_PdfObjectType, pdfCo
ntext); |
2111 return kIgnoreError_SkPdfResult; | 2188 return kIgnoreError_SkPdfResult; |
2112 } | 2189 } |
2113 | 2190 |
2114 if (dash->size() != 2) { | 2191 if (dash->size() != 2) { |
2115 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIss
ue, "hash array must have 2 elements", dash, pdfContext); | 2192 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIss
ue, |
| 2193 "hash array must have 2 elements", dash, pdfContext); |
2116 return kIgnoreError_SkPdfResult; | 2194 return kIgnoreError_SkPdfResult; |
2117 } | 2195 } |
2118 | 2196 |
2119 if (!dash->objAtAIndex(0) || !dash->objAtAIndex(0)->isArray()) { | 2197 if (!dash->objAtAIndex(0) || !dash->objAtAIndex(0)->isArray()) { |
2120 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash->o
bjAtAIndex(0), SkPdfNativeObject::kArray_PdfObjectType, pdfContext); | 2198 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash->o
bjAtAIndex(0), |
| 2199 SkPdfNativeObject::kArray_PdfObjectType, pdfCo
ntext); |
2121 return kIgnoreError_SkPdfResult; | 2200 return kIgnoreError_SkPdfResult; |
2122 } | 2201 } |
2123 | 2202 |
2124 if (!dash->objAtAIndex(1) || !dash->objAtAIndex(1)->isNumber()) { | 2203 if (!dash->objAtAIndex(1) || !dash->objAtAIndex(1)->isNumber()) { |
2125 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash->o
bjAtAIndex(1), SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext); | 2204 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, dash->o
bjAtAIndex(1), |
| 2205 SkPdfNativeObject::_kNumber_PdfObjectType, pdf
Context); |
2126 return kIgnoreError_SkPdfResult; | 2206 return kIgnoreError_SkPdfResult; |
2127 } | 2207 } |
2128 | 2208 |
2129 return skpdfGraphicsStateApplyD(pdfContext, (SkPdfArray*)dash->objAtAIndex(0
), dash->objAtAIndex(1)); | 2209 return skpdfGraphicsStateApplyD(pdfContext, (SkPdfArray*)dash->objAtAIndex(0
), |
| 2210 dash->objAtAIndex(1)); |
2130 } | 2211 } |
2131 | 2212 |
2132 static void skpdfGraphicsStateApplyFont(SkPdfContext* pdfContext, SkPdfArray* fo
ntAndSize) { | 2213 static void skpdfGraphicsStateApplyFont(SkPdfContext* pdfContext, SkPdfArray* fo
ntAndSize) { |
2133 if (!fontAndSize || !fontAndSize->isArray()) { | 2214 if (!fontAndSize || !fontAndSize->isArray()) { |
2134 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, fontAnd
Size, SkPdfNativeObject::kArray_PdfObjectType, pdfContext); | 2215 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, fontAnd
Size, |
| 2216 SkPdfNativeObject::kArray_PdfObjectType, pdfCo
ntext); |
2135 return; | 2217 return; |
2136 } | 2218 } |
2137 | 2219 |
2138 if (fontAndSize->size() != 2) { | 2220 if (fontAndSize->size() != 2) { |
2139 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIss
ue, "font array must have 2 elements", fontAndSize, pdfContext); | 2221 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIss
ue, |
| 2222 "font array must have 2 elements", fontAndSize, pdfContext); |
2140 return; | 2223 return; |
2141 } | 2224 } |
2142 | 2225 |
2143 if (!fontAndSize->objAtAIndex(0) || !fontAndSize->objAtAIndex(0)->isName())
{ | 2226 if (!fontAndSize->objAtAIndex(0) || !fontAndSize->objAtAIndex(0)->isName())
{ |
2144 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, fontAnd
Size->objAtAIndex(0), SkPdfNativeObject::kName_PdfObjectType, pdfContext); | 2227 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, |
| 2228 fontAndSize->objAtAIndex(0), |
| 2229 SkPdfNativeObject::kName_PdfObjectType, pdfCon
text); |
2145 return; | 2230 return; |
2146 } | 2231 } |
2147 | 2232 |
2148 | 2233 |
2149 if (!fontAndSize->objAtAIndex(1) || !fontAndSize->objAtAIndex(1)->isNumber()
) { | 2234 if (!fontAndSize->objAtAIndex(1) || !fontAndSize->objAtAIndex(1)->isNumber()
) { |
2150 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, fontAnd
Size->objAtAIndex(0), SkPdfNativeObject::_kNumber_PdfObjectType, pdfContext); | 2235 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, |
| 2236 fontAndSize->objAtAIndex(0), |
| 2237 SkPdfNativeObject::_kNumber_PdfObjectType, pdf
Context); |
2151 return; | 2238 return; |
2152 } | 2239 } |
2153 | 2240 |
2154 skpdfGraphicsStateApplyFontCore(pdfContext, fontAndSize->objAtAIndex(0), fon
tAndSize->objAtAIndex(1)->numberValue()); | 2241 skpdfGraphicsStateApplyFontCore(pdfContext, fontAndSize->objAtAIndex(0), |
| 2242 fontAndSize->objAtAIndex(1)->numberValue()); |
2155 } | 2243 } |
2156 | 2244 |
2157 | 2245 |
2158 //lineWidth w Set the line width in the graphics state (see “Line Width” on page
152). | 2246 //lineWidth w Set the line width in the graphics state (see “Line Width” on page
152). |
2159 static SkPdfResult PdfOp_w(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 2247 static SkPdfResult PdfOp_w(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
2160 EXPECT_OPERANDS("w", pdfContext, 1); | 2248 EXPECT_OPERANDS("w", pdfContext, 1); |
2161 POP_NUMBER(pdfContext, lw); | 2249 POP_NUMBER(pdfContext, lw); |
2162 CHECK_PARAMETERS(); | 2250 CHECK_PARAMETERS(); |
2163 | 2251 |
2164 return skpdfGraphicsStateApplyLW(pdfContext, lw); | 2252 return skpdfGraphicsStateApplyLW(pdfContext, lw); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2196 //page 155). | 2284 //page 155). |
2197 static SkPdfResult PdfOp_d(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 2285 static SkPdfResult PdfOp_d(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
2198 EXPECT_OPERANDS("d", pdfContext, 2); | 2286 EXPECT_OPERANDS("d", pdfContext, 2); |
2199 POP_OBJ(pdfContext, phase); | 2287 POP_OBJ(pdfContext, phase); |
2200 POP_ARRAY(pdfContext, array); | 2288 POP_ARRAY(pdfContext, array); |
2201 CHECK_PARAMETERS(); | 2289 CHECK_PARAMETERS(); |
2202 | 2290 |
2203 return skpdfGraphicsStateApplyD(pdfContext, array, phase); | 2291 return skpdfGraphicsStateApplyD(pdfContext, array, phase); |
2204 } | 2292 } |
2205 | 2293 |
2206 //intent ri (PDF 1.1) Set the color rendering intent in the graphics state (see
“Rendering Intents” on page 197). | 2294 //intent ri (PDF 1.1) Set the color rendering intent in the graphics state (see
“Rendering Intents” |
| 2295 // on page 197). |
2207 static SkPdfResult PdfOp_ri(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2296 static SkPdfResult PdfOp_ri(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2208 pdfContext->fObjectStack.pop(); | 2297 pdfContext->fObjectStack.pop(); |
2209 | 2298 |
2210 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "render intent
NYI", NULL, pdfContext); | 2299 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "render intent
NYI", NULL, |
| 2300 pdfContext); |
2211 | 2301 |
2212 return kNYI_SkPdfResult; | 2302 return kNYI_SkPdfResult; |
2213 } | 2303 } |
2214 | 2304 |
2215 //flatness i Set the flatness tolerance in the graphics state (see Section 6.5.1,
“Flatness | 2305 //flatness i Set the flatness tolerance in the graphics state (see Section 6.5.1,
“Flatness |
2216 //Tolerance”). flatness is a number in the range 0 to 100; a value of 0 speci- | 2306 //Tolerance”). flatness is a number in the range 0 to 100; a value of 0 speci- |
2217 //fies the output device’s default flatness tolerance. | 2307 //fies the output device’s default flatness tolerance. |
2218 static SkPdfResult PdfOp_i(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { | 2308 static SkPdfResult PdfOp_i(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
ooper** looper) { |
2219 EXPECT_OPERANDS("i", pdfContext, 1); | 2309 EXPECT_OPERANDS("i", pdfContext, 1); |
2220 POP_NUMBER(pdfContext, flatness); | 2310 POP_NUMBER(pdfContext, flatness); |
2221 CHECK_PARAMETERS(); | 2311 CHECK_PARAMETERS(); |
2222 | 2312 |
2223 if (flatness < 0 || flatness > 100) { | 2313 if (flatness < 0 || flatness > 100) { |
2224 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, "fl
atness must be a real in [0, 100] range", flatness_obj, pdfContext); | 2314 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, |
| 2315 "flatness must be a real in [0, 100] range", flatness_obj, p
dfContext); |
2225 return kIgnoreError_SkPdfResult; | 2316 return kIgnoreError_SkPdfResult; |
2226 } | 2317 } |
2227 | 2318 |
2228 return kNYI_SkPdfResult; | 2319 return kNYI_SkPdfResult; |
2229 } | 2320 } |
2230 | 2321 |
2231 SkTDict<SkXfermode::Mode> gPdfBlendModes(20); | 2322 SkTDict<SkXfermode::Mode> gPdfBlendModes(20); |
2232 | 2323 |
2233 class InitBlendModes { | 2324 class InitBlendModes { |
2234 public: | 2325 public: |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2266 | 2357 |
2267 return (SkXfermode::Mode)(SkXfermode::kLastMode + 1); | 2358 return (SkXfermode::Mode)(SkXfermode::kLastMode + 1); |
2268 } | 2359 } |
2269 | 2360 |
2270 static void skpdfGraphicsStateApplyBM_name(SkPdfContext* pdfContext, const SkStr
ing& blendMode) { | 2361 static void skpdfGraphicsStateApplyBM_name(SkPdfContext* pdfContext, const SkStr
ing& blendMode) { |
2271 SkXfermode::Mode mode = xferModeFromBlendMode(blendMode.c_str(), blendMode.s
ize()); | 2362 SkXfermode::Mode mode = xferModeFromBlendMode(blendMode.c_str(), blendMode.s
ize()); |
2272 if (mode <= SkXfermode::kLastMode) { | 2363 if (mode <= SkXfermode::kLastMode) { |
2273 pdfContext->fGraphicsState.fBlendModesLength = 1; | 2364 pdfContext->fGraphicsState.fBlendModesLength = 1; |
2274 pdfContext->fGraphicsState.fBlendModes[0] = mode; | 2365 pdfContext->fGraphicsState.fBlendModes[0] = mode; |
2275 } else { | 2366 } else { |
2276 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnknownBlendMode_SkPdfIssu
e, blendMode.c_str(), NULL, pdfContext); | 2367 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnknownBlendMode_SkPdfIssu
e, |
| 2368 blendMode.c_str(), NULL, pdfContext); |
2277 } | 2369 } |
2278 } | 2370 } |
2279 | 2371 |
2280 static void skpdfGraphicsStateApplyBM_array(SkPdfContext* pdfContext, SkPdfArray
* blendModes) { | 2372 static void skpdfGraphicsStateApplyBM_array(SkPdfContext* pdfContext, SkPdfArray
* blendModes) { |
2281 if (!blendModes || !blendModes->isArray()) { | 2373 if (!blendModes || !blendModes->isArray()) { |
2282 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, blendMo
des, SkPdfNativeObject::kArray_PdfObjectType, pdfContext); | 2374 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, blendMo
des, |
| 2375 SkPdfNativeObject::kArray_PdfObjectType, pdfCo
ntext); |
2283 return; | 2376 return; |
2284 } | 2377 } |
2285 | 2378 |
2286 if (blendModes->size() == 0 || blendModes->size() > 256) { | 2379 if (blendModes->size() == 0 || blendModes->size() > 256) { |
2287 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIss
ue, "length of blendmodes, 0, is an erro, 256+, is NYI", blendModes, pdfContext)
; | 2380 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncostistentSizes_SkPdfIss
ue, |
| 2381 "length of blendmodes, 0, is an erro, 256+, is NYI", blendMo
des, pdfContext); |
2288 return; | 2382 return; |
2289 } | 2383 } |
2290 | 2384 |
2291 SkXfermode::Mode modes[256]; | 2385 SkXfermode::Mode modes[256]; |
2292 int cnt = blendModes->size(); | 2386 int cnt = blendModes->size(); |
2293 for (int i = 0; i < cnt; i++) { | 2387 for (int i = 0; i < cnt; i++) { |
2294 SkPdfNativeObject* name = blendModes->objAtAIndex(i); | 2388 SkPdfNativeObject* name = blendModes->objAtAIndex(i); |
2295 if (!name || !name->isName()) { | 2389 if (!name || !name->isName()) { |
2296 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, nam
e, SkPdfNativeObject::kName_PdfObjectType, pdfContext); | 2390 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, nam
e, |
| 2391 SkPdfNativeObject::kName_PdfObjectType, pd
fContext); |
2297 return; | 2392 return; |
2298 } | 2393 } |
2299 SkXfermode::Mode mode = xferModeFromBlendMode(name->c_str(), name->lenst
r()); | 2394 SkXfermode::Mode mode = xferModeFromBlendMode(name->c_str(), name->lenst
r()); |
2300 if (mode > SkXfermode::kLastMode) { | 2395 if (mode > SkXfermode::kLastMode) { |
2301 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnknownBlendMode_SkPdf
Issue, NULL, name, pdfContext); | 2396 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kUnknownBlendMode_SkPdf
Issue, NULL, name, |
| 2397 pdfContext); |
2302 return; | 2398 return; |
2303 } | 2399 } |
2304 } | 2400 } |
2305 | 2401 |
2306 pdfContext->fGraphicsState.fBlendModesLength = cnt; | 2402 pdfContext->fGraphicsState.fBlendModesLength = cnt; |
2307 for (int i = 0; i < cnt; i++) { | 2403 for (int i = 0; i < cnt; i++) { |
2308 pdfContext->fGraphicsState.fBlendModes[i] = modes[i]; | 2404 pdfContext->fGraphicsState.fBlendModes[i] = modes[i]; |
2309 } | 2405 } |
2310 } | 2406 } |
2311 | 2407 |
2312 static void skpdfGraphicsStateApplySMask_dict(SkPdfContext* pdfContext, SkPdfDic
tionary* sMask) { | 2408 static void skpdfGraphicsStateApplySMask_dict(SkPdfContext* pdfContext, SkPdfDic
tionary* sMask) { |
2313 if (!sMask || !sMask->isName()) { | 2409 if (!sMask || !sMask->isName()) { |
2314 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, sMask,
SkPdfNativeObject::kArray_PdfObjectType, pdfContext); | 2410 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, sMask, |
| 2411 SkPdfNativeObject::kArray_PdfObjectType, pdfCo
ntext); |
2315 return; | 2412 return; |
2316 } | 2413 } |
2317 | 2414 |
2318 if (pdfContext->fPdfDoc->mapper()->mapSoftMaskDictionary(sMask)) { | 2415 if (pdfContext->fPdfDoc->mapper()->mapSoftMaskDictionary(sMask)) { |
2319 pdfContext->fGraphicsState.fSoftMaskDictionary = (SkPdfSoftMaskDictionar
y*)sMask; | 2416 pdfContext->fGraphicsState.fSoftMaskDictionary = (SkPdfSoftMaskDictionar
y*)sMask; |
2320 } else if (pdfContext->fPdfDoc->mapper()->mapSoftMaskImageDictionary(sMask))
{ | 2417 } else if (pdfContext->fPdfDoc->mapper()->mapSoftMaskImageDictionary(sMask))
{ |
2321 SkPdfSoftMaskImageDictionary* smid = (SkPdfSoftMaskImageDictionary*)sMas
k; | 2418 SkPdfSoftMaskImageDictionary* smid = (SkPdfSoftMaskImageDictionary*)sMas
k; |
2322 pdfContext->fGraphicsState.fSMask = getImageFromObject(pdfContext, smid,
true); | 2419 pdfContext->fGraphicsState.fSMask = getImageFromObject(pdfContext, smid,
true); |
2323 } else { | 2420 } else { |
2324 // TODO(edisonn): make the dictionary types an enum? | 2421 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, |
2325 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "Dictionary m
ust be SoftMask, or SoftMaskImage", sMask, SkPdfNativeObject::kDictionary_PdfObj
ectType, pdfContext); | 2422 "Dictionary must be SoftMask, or SoftMaskImage
", |
| 2423 sMask, SkPdfNativeObject::kDictionary_PdfObjec
tType, pdfContext); |
2326 } | 2424 } |
2327 } | 2425 } |
2328 | 2426 |
2329 static void skpdfGraphicsStateApplySMask_name(SkPdfContext* pdfContext, const Sk
String& sMask) { | 2427 static void skpdfGraphicsStateApplySMask_name(SkPdfContext* pdfContext, const Sk
String& sMask) { |
2330 if (sMask.equals("None")) { | 2428 if (sMask.equals("None")) { |
2331 pdfContext->fGraphicsState.fSoftMaskDictionary = NULL; | 2429 pdfContext->fGraphicsState.fSoftMaskDictionary = NULL; |
2332 pdfContext->fGraphicsState.fSMask = NULL; | 2430 pdfContext->fGraphicsState.fSMask = NULL; |
2333 return; | 2431 return; |
2334 } | 2432 } |
2335 | 2433 |
2336 //Next, get the ExtGState Dictionary from the Resource Dictionary: | 2434 SkPdfDictionary* extGStateDictionary |
2337 SkPdfDictionary* extGStateDictionary = pdfContext->fGraphicsState.fResources
->ExtGState(pdfContext->fPdfDoc); | 2435 = pdfContext->fGraphicsState.fResources->ExtGState(pdfContext->fPdfD
oc); |
2338 | 2436 |
2339 if (extGStateDictionary == NULL) { | 2437 if (extGStateDictionary == NULL) { |
2340 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingExtGState_SkPdfIssu
e, NULL, pdfContext->fGraphicsState.fResources, pdfContext); | 2438 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingExtGState_SkPdfIssu
e, NULL, |
| 2439 pdfContext->fGraphicsState.fResources, pdfContext); |
2341 return; | 2440 return; |
2342 } | 2441 } |
2343 | 2442 |
2344 SkPdfNativeObject* obj = pdfContext->fPdfDoc->resolveReference(extGStateDict
ionary->get(sMask.c_str())); | 2443 SkPdfNativeObject* obj |
| 2444 = pdfContext->fPdfDoc->resolveReference(extGStateDictionary->get(sMa
sk.c_str())); |
2345 if (!obj || !obj->isDictionary()) { | 2445 if (!obj || !obj->isDictionary()) { |
2346 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, obj, Sk
PdfNativeObject::kDictionary_PdfObjectType, pdfContext); | 2446 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, obj, |
| 2447 SkPdfNativeObject::kDictionary_PdfObjectType,
pdfContext); |
2347 return; | 2448 return; |
2348 } | 2449 } |
2349 | 2450 |
2350 pdfContext->fGraphicsState.fSoftMaskDictionary = NULL; | 2451 pdfContext->fGraphicsState.fSoftMaskDictionary = NULL; |
2351 pdfContext->fGraphicsState.fSMask = NULL; | 2452 pdfContext->fGraphicsState.fSMask = NULL; |
2352 | 2453 |
2353 skpdfGraphicsStateApplySMask_dict(pdfContext, obj->asDictionary()); | 2454 skpdfGraphicsStateApplySMask_dict(pdfContext, obj->asDictionary()); |
2354 } | 2455 } |
2355 | 2456 |
2356 static void skpdfGraphicsStateApplyAIS(SkPdfContext* pdfContext, bool alphaSourc
e) { | 2457 static void skpdfGraphicsStateApplyAIS(SkPdfContext* pdfContext, bool alphaSourc
e) { |
2357 pdfContext->fGraphicsState.fAlphaSource = alphaSource; | 2458 pdfContext->fGraphicsState.fAlphaSource = alphaSource; |
2358 } | 2459 } |
2359 | 2460 |
2360 | 2461 |
2361 //dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictN
ame is | 2462 //dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictN
ame is |
2362 //the name of a graphics state parameter dictionary in the ExtGState subdictiona
ry of the current resource dictionary (see the next section). | 2463 //the name of a graphics state parameter dictionary in the ExtGState subdictiona
ry of the current |
| 2464 //resource dictionary (see the next section). |
2363 static SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2465 static SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2364 EXPECT_OPERANDS("gs", pdfContext, 1); | 2466 EXPECT_OPERANDS("gs", pdfContext, 1); |
2365 POP_NAME(pdfContext, name); | 2467 POP_NAME(pdfContext, name); |
2366 CHECK_PARAMETERS(); | 2468 CHECK_PARAMETERS(); |
2367 | 2469 |
2368 #ifdef PDF_TRACE | 2470 SkPdfDictionary* extGStateDictionary |
2369 SkString str; | 2471 = pdfContext->fGraphicsState.fResources->ExtGState(pdfContext->fPdfD
oc); |
2370 #endif | |
2371 | |
2372 //Next, get the ExtGState Dictionary from the Resource Dictionary: | |
2373 SkPdfDictionary* extGStateDictionary = pdfContext->fGraphicsState.fResources
->ExtGState(pdfContext->fPdfDoc); | |
2374 | 2472 |
2375 if (extGStateDictionary == NULL) { | 2473 if (extGStateDictionary == NULL) { |
2376 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingExtGState_SkPdfIssu
e, NULL, pdfContext->fGraphicsState.fResources, pdfContext); | 2474 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingExtGState_SkPdfIssu
e, NULL, |
| 2475 pdfContext->fGraphicsState.fResources, pdfContext); |
2377 return kIgnoreError_SkPdfResult; | 2476 return kIgnoreError_SkPdfResult; |
2378 } | 2477 } |
2379 | 2478 |
2380 SkPdfNativeObject* value = pdfContext->fPdfDoc->resolveReference(extGStateDi
ctionary->get(name)); | 2479 SkPdfNativeObject* value |
| 2480 = pdfContext->fPdfDoc->resolveReference(extGStateDictionary->get(nam
e)); |
2381 | 2481 |
2382 if (kNone_SkPdfNativeObjectType == pdfContext->fPdfDoc->mapper()->mapGraphic
sStateDictionary(value)) { | 2482 if (kNone_SkPdfNativeObjectType == |
| 2483 pdfContext->fPdfDoc->mapper()->mapGraphicsStateDictionary(value)
) { |
2383 return kIgnoreError_SkPdfResult; | 2484 return kIgnoreError_SkPdfResult; |
2384 } | 2485 } |
2385 SkPdfGraphicsStateDictionary* gs = (SkPdfGraphicsStateDictionary*)value; | 2486 SkPdfGraphicsStateDictionary* gs = (SkPdfGraphicsStateDictionary*)value; |
2386 | 2487 |
2387 // TODO(edisonn): now load all those properties in graphic state. | |
2388 if (gs == NULL) { | 2488 if (gs == NULL) { |
2389 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, gs, SkP
dfNativeObject::kDictionary_PdfObjectType, pdfContext); | 2489 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, |
| 2490 gs, SkPdfNativeObject::kDictionary_PdfObjectTy
pe, pdfContext); |
2390 return kIgnoreError_SkPdfResult; | 2491 return kIgnoreError_SkPdfResult; |
2391 } | 2492 } |
2392 | 2493 |
2393 if (gs->has_LW()) { | 2494 if (gs->has_LW()) { |
2394 skpdfGraphicsStateApplyLW(pdfContext, gs->LW(pdfContext->fPdfDoc)); | 2495 skpdfGraphicsStateApplyLW(pdfContext, gs->LW(pdfContext->fPdfDoc)); |
2395 } | 2496 } |
2396 | 2497 |
2397 if (gs->has_LC()) { | 2498 if (gs->has_LC()) { |
2398 skpdfGraphicsStateApplyLC(pdfContext, gs->LC(pdfContext->fPdfDoc)); | 2499 skpdfGraphicsStateApplyLC(pdfContext, gs->LC(pdfContext->fPdfDoc)); |
2399 } | 2500 } |
(...skipping 13 matching lines...) Expand all Loading... |
2413 if (gs->has_Font()) { | 2514 if (gs->has_Font()) { |
2414 skpdfGraphicsStateApplyFont(pdfContext, gs->Font(pdfContext->fPdfDoc)); | 2515 skpdfGraphicsStateApplyFont(pdfContext, gs->Font(pdfContext->fPdfDoc)); |
2415 } | 2516 } |
2416 | 2517 |
2417 if (gs->has_BM()) { | 2518 if (gs->has_BM()) { |
2418 if (gs->isBMAName(pdfContext->fPdfDoc)) { | 2519 if (gs->isBMAName(pdfContext->fPdfDoc)) { |
2419 skpdfGraphicsStateApplyBM_name(pdfContext, gs->getBMAsName(pdfContex
t->fPdfDoc)); | 2520 skpdfGraphicsStateApplyBM_name(pdfContext, gs->getBMAsName(pdfContex
t->fPdfDoc)); |
2420 } else if (gs->isBMAArray(pdfContext->fPdfDoc)) { | 2521 } else if (gs->isBMAArray(pdfContext->fPdfDoc)) { |
2421 skpdfGraphicsStateApplyBM_array(pdfContext, gs->getBMAsArray(pdfCont
ext->fPdfDoc)); | 2522 skpdfGraphicsStateApplyBM_array(pdfContext, gs->getBMAsArray(pdfCont
ext->fPdfDoc)); |
2422 } else { | 2523 } else { |
2423 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "wrong ty
pe", gs->get("BM"), SkPdfNativeObject::kArray_PdfObjectType || SkPdfNativeObject
::kName_PdfObjectType, pdfContext); | 2524 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "wrong ty
pe", gs->get("BM"), |
| 2525 SkPdfNativeObject::kArray_PdfObjectType || |
| 2526 SkPdfNativeObject::kName_PdfObject
Type, pdfContext); |
2424 } | 2527 } |
2425 } | 2528 } |
2426 | 2529 |
2427 if (gs->has_SMask()) { | 2530 if (gs->has_SMask()) { |
2428 if (gs->isSMaskAName(pdfContext->fPdfDoc)) { | 2531 if (gs->isSMaskAName(pdfContext->fPdfDoc)) { |
2429 skpdfGraphicsStateApplySMask_name(pdfContext, gs->getSMaskAsName(pdf
Context->fPdfDoc)); | 2532 skpdfGraphicsStateApplySMask_name(pdfContext, gs->getSMaskAsName(pdf
Context->fPdfDoc)); |
2430 } else if (gs->isSMaskADictionary(pdfContext->fPdfDoc)) { | 2533 } else if (gs->isSMaskADictionary(pdfContext->fPdfDoc)) { |
2431 skpdfGraphicsStateApplySMask_dict(pdfContext, gs->getSMaskAsDictiona
ry(pdfContext->fPdfDoc)); | 2534 skpdfGraphicsStateApplySMask_dict(pdfContext, |
| 2535 gs->getSMaskAsDictionary(pdfContex
t->fPdfDoc)); |
2432 } else { | 2536 } else { |
2433 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, "wrong ty
pe", gs->get("BM"), SkPdfNativeObject::kDictionary_PdfObjectType || SkPdfNativeO
bject::kName_PdfObjectType, pdfContext); | 2537 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, |
| 2538 "wrong type", |
| 2539 gs->get("BM"), |
| 2540 SkPdfNativeObject::kDictionary_PdfObjectTy
pe || |
| 2541 SkPdfNativeObject::kName_PdfObject
Type, |
| 2542 pdfContext); |
2434 } | 2543 } |
2435 } | 2544 } |
2436 | 2545 |
2437 if (gs->has_ca()) { | 2546 if (gs->has_ca()) { |
2438 skpdfGraphicsStateApply_ca(pdfContext, gs->ca(pdfContext->fPdfDoc)); | 2547 skpdfGraphicsStateApply_ca(pdfContext, gs->ca(pdfContext->fPdfDoc)); |
2439 } | 2548 } |
2440 | 2549 |
2441 if (gs->has_CA()) { | 2550 if (gs->has_CA()) { |
2442 skpdfGraphicsStateApply_CA(pdfContext, gs->CA(pdfContext->fPdfDoc)); | 2551 skpdfGraphicsStateApply_CA(pdfContext, gs->CA(pdfContext->fPdfDoc)); |
2443 } | 2552 } |
2444 | 2553 |
2445 if (gs->has_AIS()) { | 2554 if (gs->has_AIS()) { |
2446 skpdfGraphicsStateApplyAIS(pdfContext, gs->AIS(pdfContext->fPdfDoc)); | 2555 skpdfGraphicsStateApplyAIS(pdfContext, gs->AIS(pdfContext->fPdfDoc)); |
2447 } | 2556 } |
2448 | 2557 |
| 2558 // TODO(edisonn): make sure we loaded all those properties in graphic state. |
| 2559 |
2449 return kOK_SkPdfResult; | 2560 return kOK_SkPdfResult; |
2450 } | 2561 } |
2451 | 2562 |
2452 //charSpace Tc Set the character spacing, Tc | 2563 //charSpace Tc Set the character spacing, Tc |
2453 //, to charSpace, which is a number expressed in unscaled text space units. Char
acter spacing is used by the Tj, TJ, and ' operators. | 2564 //, to charSpace, which is a number expressed in unscaled text space units. |
| 2565 // Character spacing is used by the Tj, TJ, and ' operators. |
2454 //Initial value: 0. | 2566 //Initial value: 0. |
2455 SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper) { | 2567 SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
* looper) { |
2456 EXPECT_OPERANDS("Tc", pdfContext, 1); | 2568 EXPECT_OPERANDS("Tc", pdfContext, 1); |
2457 POP_NUMBER(pdfContext, charSpace); | 2569 POP_NUMBER(pdfContext, charSpace); |
2458 CHECK_PARAMETERS(); | 2570 CHECK_PARAMETERS(); |
2459 | 2571 |
2460 pdfContext->fGraphicsState.fCharSpace = charSpace; | 2572 pdfContext->fGraphicsState.fCharSpace = charSpace; |
2461 | 2573 |
2462 return kOK_SkPdfResult; | 2574 return kOK_SkPdfResult; |
2463 } | 2575 } |
(...skipping 15 matching lines...) Expand all Loading... |
2479 | 2591 |
2480 //scale Tz Set the horizontal scaling, Th | 2592 //scale Tz Set the horizontal scaling, Th |
2481 //, to (scale ˜ 100). scale is a number specifying the | 2593 //, to (scale ˜ 100). scale is a number specifying the |
2482 //percentage of the normal width. Initial value: 100 (normal width). | 2594 //percentage of the normal width. Initial value: 100 (normal width). |
2483 static SkPdfResult PdfOp_Tz(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2595 static SkPdfResult PdfOp_Tz(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2484 EXPECT_OPERANDS("Tz", pdfContext, 1); | 2596 EXPECT_OPERANDS("Tz", pdfContext, 1); |
2485 POP_NUMBER(pdfContext, scale); | 2597 POP_NUMBER(pdfContext, scale); |
2486 CHECK_PARAMETERS(); | 2598 CHECK_PARAMETERS(); |
2487 | 2599 |
2488 if (scale < 0) { | 2600 if (scale < 0) { |
2489 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, "sc
ale must a positive real number", scale_obj, pdfContext); | 2601 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, |
| 2602 "scale must a positive real number", scale_obj, pdfContext); |
2490 return kError_SkPdfResult; | 2603 return kError_SkPdfResult; |
2491 } | 2604 } |
2492 | 2605 |
2493 return kNYI_SkPdfResult; | 2606 return kNYI_SkPdfResult; |
2494 } | 2607 } |
2495 | 2608 |
2496 //render Tr Set the text rendering mode, T | 2609 //render Tr Set the text rendering mode, T |
2497 //mode, to render, which is an integer. Initial value: 0. | 2610 //mode, to render, which is an integer. Initial value: 0. |
2498 static SkPdfResult PdfOp_Tr(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2611 static SkPdfResult PdfOp_Tr(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2499 EXPECT_OPERANDS("Tr", pdfContext, 1); | 2612 EXPECT_OPERANDS("Tr", pdfContext, 1); |
2500 POP_INTEGER(pdfContext, mode); | 2613 POP_INTEGER(pdfContext, mode); |
2501 CHECK_PARAMETERS(); | 2614 CHECK_PARAMETERS(); |
2502 | 2615 |
2503 if (mode < 0) { // TODO(edisonn): function/enums with supported modes | 2616 if (mode < 0) { // TODO(edisonn): function/enums with supported modes |
2504 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, "mo
de must a positive integer or 0", mode_obj, pdfContext); | 2617 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, |
| 2618 "mode must a positive integer or 0", mode_obj, pdfContext); |
2505 return kError_SkPdfResult; | 2619 return kError_SkPdfResult; |
2506 } | 2620 } |
2507 | 2621 |
2508 return kNYI_SkPdfResult; | 2622 return kNYI_SkPdfResult; |
2509 } | 2623 } |
2510 //rise Ts Set the text rise, Trise, to rise, which is a number expressed in unsc
aled text space | 2624 //rise Ts Set the text rise, Trise, to rise, which is a number expressed in unsc
aled text space |
2511 //units. Initial value: 0. | 2625 //units. Initial value: 0. |
2512 static SkPdfResult PdfOp_Ts(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2626 static SkPdfResult PdfOp_Ts(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2513 EXPECT_OPERANDS("Ts", pdfContext, 1); | 2627 EXPECT_OPERANDS("Ts", pdfContext, 1); |
2514 POP_NUMBER(pdfContext, rise); | 2628 POP_NUMBER(pdfContext, rise); |
2515 CHECK_PARAMETERS(); | 2629 CHECK_PARAMETERS(); |
2516 | 2630 |
2517 if (rise < 0) { | 2631 if (rise < 0) { |
2518 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, "ri
se must a positive real number", rise_obj, pdfContext); | 2632 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, |
| 2633 "rise must a positive real number", rise_obj, pdfContext); |
2519 return kNYI_SkPdfResult; | 2634 return kNYI_SkPdfResult; |
2520 } | 2635 } |
2521 | 2636 |
2522 return kNYI_SkPdfResult; | 2637 return kNYI_SkPdfResult; |
2523 } | 2638 } |
2524 | 2639 |
2525 //wx wy d0 | 2640 //wx wy d0 |
2526 static SkPdfResult PdfOp_d0(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2641 static SkPdfResult PdfOp_d0(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2527 EXPECT_OPERANDS("d0", pdfContext, 2); | 2642 EXPECT_OPERANDS("d0", pdfContext, 2); |
2528 POP_NUMBER(pdfContext, wy); | 2643 POP_NUMBER(pdfContext, wy); |
2529 POP_NUMBER(pdfContext, wx); | 2644 POP_NUMBER(pdfContext, wx); |
2530 CHECK_PARAMETERS(); | 2645 CHECK_PARAMETERS(); |
2531 | 2646 |
2532 if (wx < 0) { | 2647 if (wx < 0) { |
2533 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, "wx
must a positive real number", wx_obj, pdfContext); | 2648 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, |
| 2649 "wx must a positive real number", wx_obj, pdfContext); |
2534 return kError_SkPdfResult; | 2650 return kError_SkPdfResult; |
2535 } | 2651 } |
2536 | 2652 |
2537 if (wy < 0) { | 2653 if (wy < 0) { |
2538 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, "wy
must a positive real number", wy_obj, pdfContext); | 2654 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kOutOfRange_SkPdfIssue, |
| 2655 "wy must a positive real number", wy_obj, pdfContext); |
2539 return kError_SkPdfResult; | 2656 return kError_SkPdfResult; |
2540 } | 2657 } |
2541 | 2658 |
2542 return kNYI_SkPdfResult; | 2659 return kNYI_SkPdfResult; |
2543 } | 2660 } |
2544 | 2661 |
2545 //wx wy llx lly urx ury d1 | 2662 //wx wy llx lly urx ury d1 |
2546 static SkPdfResult PdfOp_d1(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2663 static SkPdfResult PdfOp_d1(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2547 EXPECT_OPERANDS("d1", pdfContext, 6); | 2664 EXPECT_OPERANDS("d1", pdfContext, 6); |
2548 POP_NUMBER(pdfContext, ury); | 2665 POP_NUMBER(pdfContext, ury); |
2549 POP_NUMBER(pdfContext, urx); | 2666 POP_NUMBER(pdfContext, urx); |
2550 POP_NUMBER(pdfContext, lly); | 2667 POP_NUMBER(pdfContext, lly); |
2551 POP_NUMBER(pdfContext, llx); | 2668 POP_NUMBER(pdfContext, llx); |
2552 POP_NUMBER(pdfContext, wy); | 2669 POP_NUMBER(pdfContext, wy); |
2553 POP_NUMBER(pdfContext, wx); | 2670 POP_NUMBER(pdfContext, wx); |
2554 CHECK_PARAMETERS(); | 2671 CHECK_PARAMETERS(); |
2555 | 2672 |
2556 // TODO(edisonn): silly way to remove warning | 2673 // TODO(edisonn): really silly quick way to remove warning |
2557 if (wx + wy + llx + lly + urx + ury) { | 2674 if (wx + wy + llx + lly + urx + ury) { |
2558 return kNYI_SkPdfResult; | 2675 return kNYI_SkPdfResult; |
2559 } | 2676 } |
2560 | 2677 |
2561 return kNYI_SkPdfResult; | 2678 return kNYI_SkPdfResult; |
2562 } | 2679 } |
2563 | 2680 |
2564 //name sh | 2681 //name sh |
2565 static SkPdfResult PdfOp_sh(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2682 static SkPdfResult PdfOp_sh(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2566 EXPECT_OPERANDS("sh", pdfContext, 1); | 2683 EXPECT_OPERANDS("sh", pdfContext, 1); |
2567 POP_NAME(pdfContext, name); | 2684 POP_NAME(pdfContext, name); |
2568 CHECK_PARAMETERS(); | 2685 CHECK_PARAMETERS(); |
2569 | 2686 |
2570 if (name == NULL) { | 2687 if (name == NULL) { |
2571 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, name, S
kPdfNativeObject::kName_PdfObjectType, pdfContext); | 2688 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, name, |
| 2689 SkPdfNativeObject::kName_PdfObjectType, pdfCon
text); |
2572 return kError_SkPdfResult; | 2690 return kError_SkPdfResult; |
2573 } | 2691 } |
2574 | 2692 |
2575 return kNYI_SkPdfResult; | 2693 return kNYI_SkPdfResult; |
2576 } | 2694 } |
2577 | 2695 |
2578 //name Do | 2696 //name Do |
2579 static SkPdfResult PdfOp_Do(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2697 static SkPdfResult PdfOp_Do(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2580 EXPECT_OPERANDS("Do", pdfContext, 1); | 2698 EXPECT_OPERANDS("Do", pdfContext, 1); |
2581 POP_NAME(pdfContext, name); | 2699 POP_NAME(pdfContext, name); |
2582 CHECK_PARAMETERS(); | 2700 CHECK_PARAMETERS(); |
2583 | 2701 |
2584 SkPdfDictionary* xObject = pdfContext->fGraphicsState.fResources->XObject(p
dfContext->fPdfDoc); | 2702 SkPdfDictionary* xObject = pdfContext->fGraphicsState.fResources->XObject(p
dfContext->fPdfDoc); |
2585 | 2703 |
2586 if (xObject == NULL) { | 2704 if (xObject == NULL) { |
2587 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingXObject_SkPdfIssue,
NULL, pdfContext->fGraphicsState.fResources, pdfContext); | 2705 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingXObject_SkPdfIssue,
NULL, |
| 2706 pdfContext->fGraphicsState.fResources, pdfContext); |
2588 return kIgnoreError_SkPdfResult; | 2707 return kIgnoreError_SkPdfResult; |
2589 } | 2708 } |
2590 | 2709 |
2591 SkPdfNativeObject* value = xObject->get(name); | 2710 SkPdfNativeObject* value = xObject->get(name); |
2592 value = pdfContext->fPdfDoc->resolveReference(value); | 2711 value = pdfContext->fPdfDoc->resolveReference(value); |
2593 | 2712 |
2594 return doXObject(pdfContext, canvas, value); | 2713 return doXObject(pdfContext, canvas, value); |
2595 } | 2714 } |
2596 | 2715 |
2597 //tag MP Designate a marked-content point. tag is a name object indicating the r
ole or | 2716 //tag MP Designate a marked-content point. tag is a name object indicating the r
ole or |
2598 //significance of the point. | 2717 //significance of the point. |
2599 static SkPdfResult PdfOp_MP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2718 static SkPdfResult PdfOp_MP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2600 EXPECT_OPERANDS("MP", pdfContext, 1); | 2719 EXPECT_OPERANDS("MP", pdfContext, 1); |
2601 POP_OBJ(pdfContext, tag); | 2720 POP_OBJ(pdfContext, tag); |
2602 CHECK_PARAMETERS(); | 2721 CHECK_PARAMETERS(); |
2603 | 2722 |
2604 if (tag == NULL) { | 2723 if (tag == NULL) { |
2605 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, Sk
PdfNativeObject::_kObject_PdfObjectType, pdfContext); | 2724 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, |
| 2725 SkPdfNativeObject::_kObject_PdfObjectType, pdf
Context); |
2606 return kNYI_SkPdfResult; | 2726 return kNYI_SkPdfResult; |
2607 } | 2727 } |
2608 | 2728 |
2609 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "MP NYI", NULL
, NULL); | 2729 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "MP NYI", NULL
, NULL); |
2610 return kNYI_SkPdfResult; | 2730 return kNYI_SkPdfResult; |
2611 } | 2731 } |
2612 | 2732 |
2613 //tag properties DP Designate a marked-content point with an associated property
list. tag is a | 2733 //tag properties DP Designate a marked-content point with an associated property
list. tag is a |
2614 //name object indicating the role or significance of the point; properties is | 2734 //name object indicating the role or significance of the point; properties is |
2615 //either an inline dictionary containing the property list or a name object | 2735 //either an inline dictionary containing the property list or a name object |
2616 //associated with it in the Properties subdictionary of the current resource | 2736 //associated with it in the Properties subdictionary of the current resource |
2617 //dictionary (see Section 9.5.1, “Property Lists”). | 2737 //dictionary (see Section 9.5.1, “Property Lists”). |
2618 static SkPdfResult PdfOp_DP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { | 2738 static SkPdfResult PdfOp_DP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
Looper** looper) { |
2619 EXPECT_OPERANDS("DP", pdfContext, 2); | 2739 EXPECT_OPERANDS("DP", pdfContext, 2); |
2620 POP_OBJ(pdfContext, properties); | 2740 POP_OBJ(pdfContext, properties); |
2621 POP_OBJ(pdfContext, tag); | 2741 POP_OBJ(pdfContext, tag); |
2622 CHECK_PARAMETERS(); | 2742 CHECK_PARAMETERS(); |
2623 | 2743 |
2624 if (tag == NULL) { | 2744 if (tag == NULL) { |
2625 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, Sk
PdfNativeObject::_kObject_PdfObjectType, pdfContext); | 2745 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, |
| 2746 SkPdfNativeObject::_kObject_PdfObjectType, pdf
Context); |
2626 return kNYI_SkPdfResult; | 2747 return kNYI_SkPdfResult; |
2627 } | 2748 } |
2628 | 2749 |
2629 if (properties == NULL) { | 2750 if (properties == NULL) { |
2630 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, propert
ies, SkPdfNativeObject::_kObject_PdfObjectType, pdfContext); | 2751 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, propert
ies, |
| 2752 SkPdfNativeObject::_kObject_PdfObjectType, pdf
Context); |
2631 return kNYI_SkPdfResult; | 2753 return kNYI_SkPdfResult; |
2632 } | 2754 } |
2633 | 2755 |
2634 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "DP NYI", NULL
, NULL); | 2756 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "DP NYI", NULL
, NULL); |
2635 return kNYI_SkPdfResult; | 2757 return kNYI_SkPdfResult; |
2636 } | 2758 } |
2637 | 2759 |
2638 //tag BMC Begin a marked-content sequence terminated by a balancing EMC operator
. | 2760 //tag BMC Begin a marked-content sequence terminated by a balancing EMC operator
. |
2639 //tag is a name object indicating the role or significance of the sequence. | 2761 //tag is a name object indicating the role or significance of the sequence. |
2640 static SkPdfResult PdfOp_BMC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { | 2762 static SkPdfResult PdfOp_BMC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { |
2641 EXPECT_OPERANDS("BMC", pdfContext, 1); | 2763 EXPECT_OPERANDS("BMC", pdfContext, 1); |
2642 POP_OBJ(pdfContext, tag); | 2764 POP_OBJ(pdfContext, tag); |
2643 CHECK_PARAMETERS(); | 2765 CHECK_PARAMETERS(); |
2644 | 2766 |
2645 if (tag == NULL) { | 2767 if (tag == NULL) { |
2646 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, Sk
PdfNativeObject::_kObject_PdfObjectType, pdfContext); | 2768 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, |
| 2769 SkPdfNativeObject::_kObject_PdfObjectType, pdf
Context); |
2647 return kNYI_SkPdfResult; | 2770 return kNYI_SkPdfResult; |
2648 } | 2771 } |
2649 | 2772 |
2650 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "BMC NYI", NUL
L, NULL); | 2773 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "BMC NYI", NUL
L, NULL); |
2651 return kNYI_SkPdfResult; | 2774 return kNYI_SkPdfResult; |
2652 } | 2775 } |
2653 | 2776 |
2654 //tag properties BDC Begin a marked-content sequence with an associated property
list, terminated | 2777 //tag properties BDC Begin a marked-content sequence with an associated property
list, terminated |
2655 //by a balancing EMCoperator. tag is a name object indicating the role or signif
icance of the sequence; propertiesis either an inline dictionary containing the | 2778 //by a balancing EMCoperator. tag is a name object indicating the role or signif
icance of the |
2656 //property list or a name object associated with it in the Properties subdiction
ary of the current resource dictionary (see Section 9.5.1, “Property Lists”). | 2779 // sequence; propertiesis either an inline dictionary containing the |
| 2780 //property list or a name object associated with it in the Properties subdiction
ary of the current |
| 2781 //resource dictionary (see Section 9.5.1, “Property Lists”). |
2657 static SkPdfResult PdfOp_BDC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { | 2782 static SkPdfResult PdfOp_BDC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { |
2658 EXPECT_OPERANDS("BDC", pdfContext, 2); | 2783 EXPECT_OPERANDS("BDC", pdfContext, 2); |
2659 POP_OBJ(pdfContext, properties); | 2784 POP_OBJ(pdfContext, properties); |
2660 POP_OBJ(pdfContext, tag); | 2785 POP_OBJ(pdfContext, tag); |
2661 CHECK_PARAMETERS(); | 2786 CHECK_PARAMETERS(); |
2662 | 2787 |
2663 if (tag == NULL) { | 2788 if (tag == NULL) { |
2664 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, Sk
PdfNativeObject::_kObject_PdfObjectType, pdfContext); | 2789 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, tag, |
| 2790 SkPdfNativeObject::_kObject_PdfObjectType, pdf
Context); |
2665 return kNYI_SkPdfResult; | 2791 return kNYI_SkPdfResult; |
2666 } | 2792 } |
2667 | 2793 |
2668 if (properties == NULL) { | 2794 if (properties == NULL) { |
2669 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, propert
ies, SkPdfNativeObject::_kObject_PdfObjectType, pdfContext); | 2795 SkPdfReportUnexpectedType(kIgnoreError_SkPdfIssueSeverity, NULL, propert
ies, |
| 2796 SkPdfNativeObject::_kObject_PdfObjectType, pdf
Context); |
2670 return kNYI_SkPdfResult; | 2797 return kNYI_SkPdfResult; |
2671 } | 2798 } |
2672 | 2799 |
2673 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "BDC NYI", NUL
L, NULL); | 2800 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "BDC NYI", NUL
L, NULL); |
2674 return kNYI_SkPdfResult; | 2801 return kNYI_SkPdfResult; |
2675 } | 2802 } |
2676 | 2803 |
2677 //— EMC End a marked-content sequence begun by a BMC or BDC operator. | 2804 //— EMC End a marked-content sequence begun by a BMC or BDC operator. |
2678 static SkPdfResult PdfOp_EMC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { | 2805 static SkPdfResult PdfOp_EMC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
nLooper** looper) { |
2679 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "EMC NYI", NUL
L, NULL); | 2806 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "EMC NYI", NUL
L, NULL); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2794 int value = 0; | 2921 int value = 0; |
2795 while ((key = iter.next(&value)) != NULL) { | 2922 while ((key = iter.next(&value)) != NULL) { |
2796 printf("%s: %s -> count %i\n", gRenderStatsNames[i], key, value); | 2923 printf("%s: %s -> count %i\n", gRenderStatsNames[i], key, value); |
2797 } | 2924 } |
2798 } | 2925 } |
2799 } | 2926 } |
2800 | 2927 |
2801 SkPdfResult PdfMainLooper::consumeToken(PdfToken& token) { | 2928 SkPdfResult PdfMainLooper::consumeToken(PdfToken& token) { |
2802 if (token.fType == kKeyword_TokenType && token.fKeywordLength < 256) | 2929 if (token.fType == kKeyword_TokenType && token.fKeywordLength < 256) |
2803 { | 2930 { |
2804 // TODO(edisonn): log trace flag (verbose, error, info, warning, ...) | |
2805 PdfOperatorRenderer pdfOperatorRenderer = NULL; | 2931 PdfOperatorRenderer pdfOperatorRenderer = NULL; |
2806 if (gPdfOps.find(token.fKeyword, token.fKeywordLength, &pdfOperatorRende
rer) && pdfOperatorRenderer) { | 2932 if (gPdfOps.find(token.fKeyword, token.fKeywordLength, &pdfOperatorRende
rer) && |
2807 // caller, main work is done by pdfOperatorRenderer(...) | 2933 pdfOperatorRenderer) { |
2808 PdfTokenLooper* childLooper = NULL; | 2934 PdfTokenLooper* childLooper = NULL; |
| 2935 // Main work is done by pdfOperatorRenderer(...) |
2809 SkPdfResult result = pdfOperatorRenderer(fPdfContext, fCanvas, &chil
dLooper); | 2936 SkPdfResult result = pdfOperatorRenderer(fPdfContext, fCanvas, &chil
dLooper); |
2810 | 2937 |
2811 int cnt = 0; | 2938 int cnt = 0; |
2812 gRenderStats[result].find(token.fKeyword, token.fKeywordLength, &cnt
); | 2939 gRenderStats[result].find(token.fKeyword, token.fKeywordLength, &cnt
); |
2813 gRenderStats[result].set(token.fKeyword, token.fKeywordLength, cnt +
1); | 2940 gRenderStats[result].set(token.fKeyword, token.fKeywordLength, cnt +
1); |
2814 | 2941 |
2815 if (childLooper) { | 2942 if (childLooper) { |
2816 childLooper->setUp(this); | 2943 childLooper->setUp(this); |
2817 childLooper->loop(); | 2944 childLooper->loop(); |
2818 delete childLooper; | 2945 delete childLooper; |
2819 } | 2946 } |
2820 } else { | 2947 } else { |
2821 int cnt = 0; | 2948 int cnt = 0; |
2822 gRenderStats[kUnsupported_SkPdfResult].find(token.fKeyword, token.fK
eywordLength, &cnt); | 2949 gRenderStats[kUnsupported_SkPdfResult].find(token.fKeyword, |
2823 gRenderStats[kUnsupported_SkPdfResult].set(token.fKeyword, token.fKe
ywordLength, cnt + 1); | 2950 token.fKeywordLength, |
| 2951 &cnt); |
| 2952 gRenderStats[kUnsupported_SkPdfResult].set(token.fKeyword, |
| 2953 token.fKeywordLength, |
| 2954 cnt + 1); |
2824 } | 2955 } |
2825 } | 2956 } |
2826 else if (token.fType == kObject_TokenType) | 2957 else if (token.fType == kObject_TokenType) |
2827 { | 2958 { |
2828 fPdfContext->fObjectStack.push( token.fObject ); | 2959 fPdfContext->fObjectStack.push( token.fObject ); |
2829 } | 2960 } |
2830 else { | 2961 else { |
2831 // TODO(edisonn): store the keyword as a object, so we can track the loc
ation in file, and report it | 2962 // TODO(edisonn): store the keyword as a object, so we can track the loc
ation in file, |
2832 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, token.fKey
word, NULL, fPdfContext); | 2963 // and report where the error was triggered |
| 2964 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, token.fKey
word, NULL, |
| 2965 fPdfContext); |
2833 return kIgnoreError_SkPdfResult; | 2966 return kIgnoreError_SkPdfResult; |
2834 } | 2967 } |
2835 return kOK_SkPdfResult; | 2968 return kOK_SkPdfResult; |
2836 } | 2969 } |
2837 | 2970 |
2838 void PdfMainLooper::loop() { | 2971 void PdfMainLooper::loop() { |
2839 PdfToken token; | 2972 PdfToken token; |
2840 while (readToken(fTokenizer, &token)) { | 2973 while (readToken(fTokenizer, &token)) { |
2841 consumeToken(token); | 2974 consumeToken(token); |
2842 } | 2975 } |
(...skipping 10 matching lines...) Expand all Loading... |
2853 | 2986 |
2854 SkPdfResult PdfInlineImageLooper::done() { | 2987 SkPdfResult PdfInlineImageLooper::done() { |
2855 return kNYI_SkPdfResult; | 2988 return kNYI_SkPdfResult; |
2856 } | 2989 } |
2857 | 2990 |
2858 SkPdfResult PdfCompatibilitySectionLooper::consumeToken(PdfToken& token) { | 2991 SkPdfResult PdfCompatibilitySectionLooper::consumeToken(PdfToken& token) { |
2859 return fParent->consumeToken(token); | 2992 return fParent->consumeToken(token); |
2860 } | 2993 } |
2861 | 2994 |
2862 void PdfCompatibilitySectionLooper::loop() { | 2995 void PdfCompatibilitySectionLooper::loop() { |
2863 // TODO(edisonn): save stacks position, or create a new stack? | 2996 PdfOp_q(fPdfContext, fCanvas, NULL); |
2864 // TODO(edisonn): what happens if we pop out more variables then when we sta
rted? | 2997 |
2865 // restore them? fail? We could create a new operands stack for every new BX
/EX section, | |
2866 // pop-ing too much will not affect outside the section. | |
2867 PdfToken token; | 2998 PdfToken token; |
2868 while (readToken(fTokenizer, &token)) { | 2999 while (readToken(fTokenizer, &token)) { |
2869 if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "BX") ==
0) { | 3000 if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "BX") ==
0) { |
2870 PdfTokenLooper* looper = new PdfCompatibilitySectionLooper(); | 3001 PdfTokenLooper* looper = new PdfCompatibilitySectionLooper(); |
2871 looper->setUp(this); | 3002 looper->setUp(this); |
2872 looper->loop(); | 3003 looper->loop(); |
2873 delete looper; | 3004 delete looper; |
2874 } else { | 3005 } else { |
2875 if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "EX"
) == 0) break; | 3006 if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "EX"
) == 0) break; |
2876 fParent->consumeToken(token); | 3007 fParent->consumeToken(token); |
2877 } | 3008 } |
2878 } | 3009 } |
2879 // TODO(edisonn): restore stack. | 3010 |
| 3011 PdfOp_Q(fPdfContext, fCanvas, NULL); |
2880 } | 3012 } |
2881 | 3013 |
2882 // TODO(edisonn): fix PoDoFo load ~/crashing/Shading.pdf | 3014 // TODO(edisonn): for debugging - remove or put it in a #ifdef |
2883 // TODO(edisonn): Add API for Forms viewing and editing | |
2884 // e.g. SkBitmap getPage(int page); | |
2885 // int formsCount(); | |
2886 // SkForm getForm(int formID); // SkForm(SkRect, .. other data) | |
2887 // TODO (edisonn): Add intend when loading pdf, for example: for viewing, parsin
g all content, ... | |
2888 // if we load the first page, and we zoom to fit to screen horizontally, then lo
ad only those | |
2889 // resources needed, so the preview is fast. | |
2890 // TODO (edisonn): hide parser/tokenizer behind and interface and a query langua
ge, and resolve | |
2891 // references automatically. | |
2892 | |
2893 SkPdfContext* gPdfContext = NULL; | 3015 SkPdfContext* gPdfContext = NULL; |
2894 | 3016 |
2895 bool SkPdfRenderer::renderPage(int page, SkCanvas* canvas, const SkRect& dst) co
nst { | 3017 bool SkPdfRenderer::renderPage(int page, SkCanvas* canvas, const SkRect& dst) co
nst { |
2896 if (!fPdfDoc) { | 3018 if (!fPdfDoc) { |
2897 return false; | 3019 return false; |
2898 } | 3020 } |
2899 | 3021 |
2900 if (page < 0 || page >= pages()) { | 3022 if (page < 0 || page >= pages()) { |
2901 return false; | 3023 return false; |
2902 } | 3024 } |
2903 | 3025 |
2904 SkPdfContext pdfContext(fPdfDoc); | 3026 SkPdfContext pdfContext(fPdfDoc); |
2905 | 3027 |
2906 pdfContext.fOriginalMatrix = SkMatrix::I(); | 3028 pdfContext.fOriginalMatrix = SkMatrix::I(); |
2907 pdfContext.fGraphicsState.fResources = fPdfDoc->pageResources(page); | 3029 pdfContext.fGraphicsState.fResources = fPdfDoc->pageResources(page); |
2908 | 3030 |
2909 gPdfContext = &pdfContext; | 3031 gPdfContext = &pdfContext; |
2910 | 3032 |
2911 // TODO(edisonn): get matrix stuff right. | |
2912 SkScalar z = SkIntToScalar(0); | 3033 SkScalar z = SkIntToScalar(0); |
2913 SkScalar w = dst.width(); | 3034 SkScalar w = dst.width(); |
2914 SkScalar h = dst.height(); | 3035 SkScalar h = dst.height(); |
2915 | 3036 |
2916 if (SkScalarTruncToInt(w) <= 0 || SkScalarTruncToInt(h) <= 0) { | 3037 if (SkScalarTruncToInt(w) <= 0 || SkScalarTruncToInt(h) <= 0) { |
2917 return true; | 3038 return true; |
2918 } | 3039 } |
2919 | 3040 |
2920 SkScalar wp = fPdfDoc->MediaBox(page).width(); | 3041 SkScalar wp = fPdfDoc->MediaBox(page).width(); |
2921 SkScalar hp = fPdfDoc->MediaBox(page).height(); | 3042 SkScalar hp = fPdfDoc->MediaBox(page).height(); |
2922 | 3043 |
2923 SkPoint pdfSpace[4] = {SkPoint::Make(z, z), SkPoint::Make(wp, z), SkPoint::M
ake(wp, hp), SkPoint::Make(z, hp)}; | 3044 SkPoint pdfSpace[4] = {SkPoint::Make(z, z), |
2924 // SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w,
h), SkPoint::Make(w, z), SkPoint::Make(z, z)}; | 3045 SkPoint::Make(wp, z), |
| 3046 SkPoint::Make(wp, hp), |
| 3047 SkPoint::Make(z, hp)}; |
2925 | 3048 |
2926 // TODO(edisonn): add flag for this app to create sourunding buffer zone | 3049 #ifdef PDF_DEBUG_3X |
2927 // TODO(edisonn): add flagg for no clipping. | |
2928 // Use larger image to make sure we do not draw anything outside of page | 3050 // Use larger image to make sure we do not draw anything outside of page |
2929 // could be used in tests. | 3051 // could be used in tests. |
2930 | 3052 SkPoint skiaSpace[4] = {SkPoint::Make(w+z, h+h), |
2931 #ifdef PDF_DEBUG_3X | 3053 SkPoint::Make(w+w, h+h), |
2932 SkPoint skiaSpace[4] = {SkPoint::Make(w+z, h+h), SkPoint::Make(w+w, h+h), Sk
Point::Make(w+w, h+z), SkPoint::Make(w+z, h+z)}; | 3054 SkPoint::Make(w+w, h+z), |
| 3055 SkPoint::Make(w+z, h+z)}; |
2933 #else | 3056 #else |
2934 SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w, h), SkPoint::M
ake(w, z), SkPoint::Make(z, z)}; | 3057 SkPoint skiaSpace[4] = {SkPoint::Make(z, h), |
| 3058 SkPoint::Make(w, h), |
| 3059 SkPoint::Make(w, z), |
| 3060 SkPoint::Make(z, z)}; |
2935 #endif | 3061 #endif |
2936 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(w, h)}; | |
2937 //SkPoint skiaSpace[2] = {SkPoint::Make(w, z), SkPoint::Make(z, h)}; | |
2938 | |
2939 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(z, h)}; | |
2940 //SkPoint skiaSpace[2] = {SkPoint::Make(z, h), SkPoint::Make(z, z)}; | |
2941 | |
2942 //SkPoint pdfSpace[3] = {SkPoint::Make(z, z), SkPoint::Make(z, h), SkPoint::
Make(w, h)}; | |
2943 //SkPoint skiaSpace[3] = {SkPoint::Make(z, h), SkPoint::Make(z, z), SkPoint:
:Make(w, 0)}; | |
2944 | 3062 |
2945 SkAssertResult(pdfContext.fOriginalMatrix.setPolyToPoly(pdfSpace, skiaSpace,
4)); | 3063 SkAssertResult(pdfContext.fOriginalMatrix.setPolyToPoly(pdfSpace, skiaSpace,
4)); |
2946 SkTraceMatrix(pdfContext.fOriginalMatrix, "Original matrix"); | 3064 SkTraceMatrix(pdfContext.fOriginalMatrix, "Original matrix"); |
2947 | 3065 |
2948 pdfContext.fGraphicsState.fCTM = pdfContext.fOriginalMatrix; | 3066 pdfContext.fGraphicsState.fCTM = pdfContext.fOriginalMatrix; |
2949 pdfContext.fGraphicsState.fContentStreamMatrix = pdfContext.fOriginalMatrix; | 3067 pdfContext.fGraphicsState.fContentStreamMatrix = pdfContext.fOriginalMatrix; |
2950 pdfContext.fGraphicsState.fMatrixTm = pdfContext.fGraphicsState.fCTM; | 3068 pdfContext.fGraphicsState.fMatrixTm = pdfContext.fGraphicsState.fCTM; |
2951 pdfContext.fGraphicsState.fMatrixTlm = pdfContext.fGraphicsState.fCTM; | 3069 pdfContext.fGraphicsState.fMatrixTlm = pdfContext.fGraphicsState.fCTM; |
2952 | 3070 |
2953 #ifndef PDF_DEBUG_NO_PAGE_CLIPING | 3071 #ifndef PDF_DEBUG_NO_PAGE_CLIPING |
2954 canvas->clipRect(dst, SkRegion::kIntersect_Op, true); | 3072 canvas->clipRect(dst, SkRegion::kIntersect_Op, true); |
2955 #endif | 3073 #endif |
2956 | 3074 |
2957 canvas->setMatrix(pdfContext.fOriginalMatrix); | 3075 canvas->setMatrix(pdfContext.fOriginalMatrix); |
2958 | 3076 |
2959 doPage(&pdfContext, canvas, fPdfDoc->page(page)); | 3077 doPage(&pdfContext, canvas, fPdfDoc->page(page)); |
2960 | 3078 |
2961 // TODO(edisonn:) erase with white before draw? | 3079 // TODO(edisonn:) erase with white before draw? Right now the caller i
s responsible. |
2962 // SkPaint paint; | 3080 // SkPaint paint; |
2963 // paint.setColor(SK_ColorWHITE); | 3081 // paint.setColor(SK_ColorWHITE); |
2964 // canvas->drawRect(rect, paint); | 3082 // canvas->drawRect(rect, paint); |
2965 | 3083 |
2966 | 3084 |
2967 canvas->flush(); | 3085 canvas->flush(); |
2968 return true; | 3086 return true; |
2969 } | 3087 } |
2970 | 3088 |
2971 bool SkPdfRenderer::load(const SkString inputFileName) { | 3089 bool SkPdfRenderer::load(const SkString inputFileName) { |
2972 unload(); | 3090 unload(); |
2973 | 3091 |
2974 // TODO(edisonn): create static function that could return NULL if there are
errors | |
2975 fPdfDoc = new SkPdfNativeDoc(inputFileName.c_str()); | 3092 fPdfDoc = new SkPdfNativeDoc(inputFileName.c_str()); |
2976 if (fPdfDoc->pages() == 0) { | 3093 if (fPdfDoc->pages() == 0) { |
2977 delete fPdfDoc; | 3094 delete fPdfDoc; |
2978 fPdfDoc = NULL; | 3095 fPdfDoc = NULL; |
2979 } | 3096 } |
2980 | 3097 |
2981 return fPdfDoc != NULL; | 3098 return fPdfDoc != NULL; |
2982 } | 3099 } |
2983 | 3100 |
2984 bool SkPdfRenderer::load(SkStream* stream) { | 3101 bool SkPdfRenderer::load(SkStream* stream) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3032 | 3149 |
3033 rect = SkRect::MakeWH(width, height); | 3150 rect = SkRect::MakeWH(width, height); |
3034 | 3151 |
3035 setup_bitmap(output, (int)SkScalarToDouble(width), (int)SkScalarToDouble(hei
ght)); | 3152 setup_bitmap(output, (int)SkScalarToDouble(width), (int)SkScalarToDouble(hei
ght)); |
3036 | 3153 |
3037 SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (*output))); | 3154 SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (*output))); |
3038 SkCanvas canvas(device); | 3155 SkCanvas canvas(device); |
3039 | 3156 |
3040 return renderer.renderPage(page, &canvas, rect); | 3157 return renderer.renderPage(page, &canvas, rect); |
3041 } | 3158 } |
OLD | NEW |