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