Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: experimental/PdfViewer/SkPdfRenderer.cpp

Issue 26912005: mode code cleanup (100c / l, comments) (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « experimental/PdfViewer/SkPdfRenderer.h ('k') | experimental/PdfViewer/SkPdfReporter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « experimental/PdfViewer/SkPdfRenderer.h ('k') | experimental/PdfViewer/SkPdfReporter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698