blob: a06998cf4a214f5e5b2de63a5ec248a366db7d45 [file] [log] [blame]
edisonn@google.comcf2cfa12013-08-21 16:31:37 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkPdfNativeObject_DEFINED
9#define SkPdfNativeObject_DEFINED
edisonn@google.com571c70b2013-07-10 17:09:50 +000010
11#include <stdint.h>
12#include <string.h>
edisonn@google.com063d7072013-08-16 15:05:08 +000013#include "SkString.h"
edisonn@google.com571c70b2013-07-10 17:09:50 +000014#include "SkTDArray.h"
15#include "SkTDict.h"
16#include "SkRect.h"
17#include "SkMatrix.h"
18#include "SkString.h"
19
20#include "SkPdfNYI.h"
21#include "SkPdfConfig.h"
edisonn@google.com3aa35552013-08-14 18:26:20 +000022#include "SkPdfUtils.h"
23
24#include "SkPdfNativeTokenizer.h"
edisonn@google.com571c70b2013-07-10 17:09:50 +000025
26class SkPdfDictionary;
27class SkPdfStream;
28class SkPdfAllocator;
29
30// TODO(edisonn): macro it and move it to utils
31SkMatrix SkMatrixFromPdfMatrix(double array[6]);
32
33
34#define kFilteredStreamBit 0
35#define kUnfilteredStreamBit 1
edisonn@google.com2ccc3af2013-07-23 17:43:18 +000036#define kOwnedStreamBit 2
edisonn@google.com571c70b2013-07-10 17:09:50 +000037
edisonn@google.com3aa35552013-08-14 18:26:20 +000038class SkPdfNativeObject {
edisonn@google.com571c70b2013-07-10 17:09:50 +000039 public:
40 enum ObjectType {
41 kInvalid_PdfObjectType,
42
43 kBoolean_PdfObjectType,
44 kInteger_PdfObjectType,
45 kReal_PdfObjectType,
46 kString_PdfObjectType,
47 kHexString_PdfObjectType,
48 kName_PdfObjectType,
49 kKeyword_PdfObjectType,
50 //kStream_PdfObjectType, // attached to a Dictionary
51 kArray_PdfObjectType,
52 kDictionary_PdfObjectType,
53 kNull_PdfObjectType,
54
55 // TODO(edisonn): after the pdf has been loaded completely, resolve all references
56 // try the same thing with delayed loaded ...
57 kReference_PdfObjectType,
58
59 kUndefined_PdfObjectType, // per 1.4 spec, if the same key appear twice in the dictionary, the value is undefined
60 };
61
edisonn@google.comb0145ce2013-08-05 16:23:23 +000062 enum DataType {
63 kEmpty_Data,
64 kFont_Data,
65 kBitmap_Data,
66 };
67
edisonn@google.com571c70b2013-07-10 17:09:50 +000068private:
edisonn@google.com063d7072013-08-16 15:05:08 +000069 // TODO(edisonn): assert reset operations while in rendering!
70 uint32_t fInRendering : 1;
71 uint32_t fUnused : 31;
72
73
edisonn@google.com571c70b2013-07-10 17:09:50 +000074 struct Reference {
75 unsigned int fId;
76 unsigned int fGen;
77 };
78
79 // TODO(edisonn): add stream start, stream end, where stream is weither the file
80 // or decoded/filtered pdf stream
81
82 // TODO(edisonn): add warning/report per object
83 // TODO(edisonn): add flag fUsed, to be used once the parsing is complete,
84 // so we could show what parts have been proccessed, ignored, or generated errors
85
86 ObjectType fObjectType;
87
88 union {
89 bool fBooleanValue;
90 int64_t fIntegerValue;
91 // TODO(edisonn): double, float? typedefed
92 double fRealValue;
93 NotOwnedString fStr;
94
95 // TODO(edisonn): make sure the foorprint of fArray and fMap is small, otherwise, use pointers, or classes with up to 8 bytes in footprint
edisonn@google.com3aa35552013-08-14 18:26:20 +000096 SkTDArray<SkPdfNativeObject*>* fArray;
edisonn@google.com571c70b2013-07-10 17:09:50 +000097 Reference fRef;
98 };
edisonn@google.com3aa35552013-08-14 18:26:20 +000099 SkTDict<SkPdfNativeObject*>* fMap;
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000100
101 // TODO(edisonn): rename data with cache
edisonn@google.com571c70b2013-07-10 17:09:50 +0000102 void* fData;
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000103 DataType fDataType;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000104
105
106public:
107
edisonn@google.com063d7072013-08-16 15:05:08 +0000108 SkPdfNativeObject() : fInRendering(0), fObjectType(kInvalid_PdfObjectType), fMap(NULL), fData(NULL), fDataType(kEmpty_Data) {}
edisonn@google.com571c70b2013-07-10 17:09:50 +0000109
edisonn@google.com063d7072013-08-16 15:05:08 +0000110 bool inRendering() const { return fInRendering != 0; }
111 void startRendering() {fInRendering = 1;}
112 void doneRendering() {fInRendering = 0;}
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000113
114 inline bool hasData(DataType type) {
115 return type == fDataType;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000116 }
117
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000118 inline void* data(DataType type) {
119 return type == fDataType ? fData : NULL;
120 }
121
122 inline void setData(void* data, DataType type) {
123 releaseData();
124 fDataType = type;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000125 fData = data;
126 }
127
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000128 void releaseData();
129
edisonn@google.com3aa35552013-08-14 18:26:20 +0000130// ~SkPdfNativeObject() {
edisonn@google.com222382b2013-07-10 22:33:10 +0000131// //reset(); must be called manually!
132// }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000133
134 void reset() {
135 switch (fObjectType) {
136 case kArray_PdfObjectType:
137 delete fArray;
138 break;
139
140 case kDictionary_PdfObjectType:
141 delete fMap;
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000142 if (isStreamOwned()) {
143 delete[] fStr.fBuffer;
144 fStr.fBuffer = NULL;
145 fStr.fBytes = 0;
146 }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000147 break;
148
149 default:
150 break;
151 }
152 fObjectType = kInvalid_PdfObjectType;
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000153 releaseData();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000154 }
155
156 ObjectType type() { return fObjectType; }
157
158 const char* c_str() const {
159 switch (fObjectType) {
160 case kString_PdfObjectType:
161 case kHexString_PdfObjectType:
162 case kKeyword_PdfObjectType:
edisonn@google.com276fed92013-08-01 21:20:47 +0000163 case kName_PdfObjectType:
edisonn@google.com571c70b2013-07-10 17:09:50 +0000164 return (const char*)fStr.fBuffer;
165
166 default:
167 // TODO(edisonn): report/warning
168 return NULL;
169 }
170 }
171
edisonn@google.come878e722013-07-29 19:10:58 +0000172 size_t lenstr() const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000173 switch (fObjectType) {
174 case kString_PdfObjectType:
175 case kHexString_PdfObjectType:
176 case kKeyword_PdfObjectType:
edisonn@google.com276fed92013-08-01 21:20:47 +0000177 case kName_PdfObjectType:
edisonn@google.com571c70b2013-07-10 17:09:50 +0000178 return fStr.fBytes;
179
180 default:
181 // TODO(edisonn): report/warning
182 return 0;
183 }
184 }
185
186
187 // TODO(edisonn): NYI
188 SkPdfDate& dateValue() const {
189 static SkPdfDate nyi;
190 return nyi;
191 }
192
193 // TODO(edisonn): NYI
194 SkPdfFunction& functionValue() const {
195 static SkPdfFunction nyi;
196 return nyi;
197 }
198
199 // TODO(edisonn): NYI
200 SkPdfFileSpec& fileSpecValue() const {
201 static SkPdfFileSpec nyi;
202 return nyi;
203 }
204
205 // TODO(edisonn): NYI
206 SkPdfTree& treeValue() const {
207 static SkPdfTree nyi;
208 return nyi;
209 }
210
edisonn@google.com3aa35552013-08-14 18:26:20 +0000211 static void makeBoolean(bool value, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000212 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
213
214 obj->fObjectType = kBoolean_PdfObjectType;
215 obj->fBooleanValue = value;
216 }
217
edisonn@google.com3aa35552013-08-14 18:26:20 +0000218 static SkPdfNativeObject makeBoolean(bool value) {
219 SkPdfNativeObject obj;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000220 obj.fObjectType = kBoolean_PdfObjectType;
221 obj.fBooleanValue = value;
222 return obj;
223 }
224
edisonn@google.com3aa35552013-08-14 18:26:20 +0000225 static void makeInteger(int64_t value, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000226 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
227
228 obj->fObjectType = kInteger_PdfObjectType;
229 obj->fIntegerValue = value;
230 }
231
edisonn@google.com3aa35552013-08-14 18:26:20 +0000232 static void makeReal(double value, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000233 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
234
235 obj->fObjectType = kReal_PdfObjectType;
236 obj->fRealValue = value;
237 }
238
edisonn@google.com3aa35552013-08-14 18:26:20 +0000239 static void makeNull(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000240 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
241
242 obj->fObjectType = kNull_PdfObjectType;
243 }
244
edisonn@google.com3aa35552013-08-14 18:26:20 +0000245 static SkPdfNativeObject makeNull() {
246 SkPdfNativeObject obj;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000247 obj.fObjectType = kNull_PdfObjectType;
248 return obj;
249 }
250
edisonn@google.com3aa35552013-08-14 18:26:20 +0000251 static SkPdfNativeObject kNull;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000252
edisonn@google.com3aa35552013-08-14 18:26:20 +0000253 static void makeNumeric(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000254 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
255
256 // TODO(edisonn): NYI properly
257 // if has dot (impl), or exceeds max int, is real, otherwise is int
258 bool isInt = true;
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000259 for (const unsigned char* current = start; current < end; current++) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000260 if (*current == '.') {
261 isInt = false;
262 break;
263 }
264 // TODO(edisonn): report parse issue with numbers like "24asdasd123"
265 }
266 if (isInt) {
267 makeInteger(atol((const char*)start), obj);
268 } else {
269 makeReal(atof((const char*)start), obj);
270 }
271 }
272
edisonn@google.com3aa35552013-08-14 18:26:20 +0000273 static void makeReference(unsigned int id, unsigned int gen, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000274 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
275
276 obj->fObjectType = kReference_PdfObjectType;
277 obj->fRef.fId = id;
278 obj->fRef.fGen = gen;
279 }
280
281
edisonn@google.com3aa35552013-08-14 18:26:20 +0000282 static void makeString(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000283 makeStringCore(start, strlen((const char*)start), obj, kString_PdfObjectType);
284 }
285
edisonn@google.com3aa35552013-08-14 18:26:20 +0000286 static void makeString(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000287 makeStringCore(start, end - start, obj, kString_PdfObjectType);
288 }
289
edisonn@google.com3aa35552013-08-14 18:26:20 +0000290 static void makeString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000291 makeStringCore(start, bytes, obj, kString_PdfObjectType);
292 }
293
294
edisonn@google.com3aa35552013-08-14 18:26:20 +0000295 static void makeHexString(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000296 makeStringCore(start, strlen((const char*)start), obj, kHexString_PdfObjectType);
297 }
298
edisonn@google.com3aa35552013-08-14 18:26:20 +0000299 static void makeHexString(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000300 makeStringCore(start, end - start, obj, kHexString_PdfObjectType);
301 }
302
edisonn@google.com3aa35552013-08-14 18:26:20 +0000303 static void makeHexString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000304 makeStringCore(start, bytes, obj, kHexString_PdfObjectType);
305 }
306
307
edisonn@google.com3aa35552013-08-14 18:26:20 +0000308 static void makeName(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000309 makeStringCore(start, strlen((const char*)start), obj, kName_PdfObjectType);
310 }
311
edisonn@google.com3aa35552013-08-14 18:26:20 +0000312 static void makeName(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000313 makeStringCore(start, end - start, obj, kName_PdfObjectType);
314 }
315
edisonn@google.com3aa35552013-08-14 18:26:20 +0000316 static void makeName(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000317 makeStringCore(start, bytes, obj, kName_PdfObjectType);
318 }
319
320
edisonn@google.com3aa35552013-08-14 18:26:20 +0000321 static void makeKeyword(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000322 makeStringCore(start, strlen((const char*)start), obj, kKeyword_PdfObjectType);
323 }
324
edisonn@google.com3aa35552013-08-14 18:26:20 +0000325 static void makeKeyword(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000326 makeStringCore(start, end - start, obj, kKeyword_PdfObjectType);
327 }
328
edisonn@google.com3aa35552013-08-14 18:26:20 +0000329 static void makeKeyword(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000330 makeStringCore(start, bytes, obj, kKeyword_PdfObjectType);
331 }
332
333
334
335 // TODO(edisonn): make the functions to return SkPdfArray, move these functions in SkPdfArray
edisonn@google.com3aa35552013-08-14 18:26:20 +0000336 static void makeEmptyArray(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000337 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
338
339 obj->fObjectType = kArray_PdfObjectType;
edisonn@google.com3aa35552013-08-14 18:26:20 +0000340 obj->fArray = new SkTDArray<SkPdfNativeObject*>();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000341 // return (SkPdfArray*)obj;
342 }
343
edisonn@google.com3aa35552013-08-14 18:26:20 +0000344 bool appendInArray(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000345 SkASSERT(fObjectType == kArray_PdfObjectType);
346 if (fObjectType != kArray_PdfObjectType) {
347 // TODO(edisonn): report err
348 return false;
349 }
350
351 fArray->push(obj);
352 return true;
353 }
354
355 size_t size() const {
356 SkASSERT(fObjectType == kArray_PdfObjectType);
357
358 return fArray->count();
359 }
360
edisonn@google.com3aa35552013-08-14 18:26:20 +0000361 SkPdfNativeObject* objAtAIndex(int i) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000362 SkASSERT(fObjectType == kArray_PdfObjectType);
363
364 return (*fArray)[i];
365 }
366
edisonn@google.com3aa35552013-08-14 18:26:20 +0000367 SkPdfNativeObject* removeLastInArray() {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000368 SkASSERT(fObjectType == kArray_PdfObjectType);
369
edisonn@google.com3aa35552013-08-14 18:26:20 +0000370 SkPdfNativeObject* ret = NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000371 fArray->pop(&ret);
372
373 return ret;
374 }
375
376
edisonn@google.com3aa35552013-08-14 18:26:20 +0000377 const SkPdfNativeObject* objAtAIndex(int i) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000378 SkASSERT(fObjectType == kArray_PdfObjectType);
379
380 return (*fArray)[i];
381 }
382
edisonn@google.com3aa35552013-08-14 18:26:20 +0000383 SkPdfNativeObject* operator[](int i) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000384 SkASSERT(fObjectType == kArray_PdfObjectType);
385
386 return (*fArray)[i];
387 }
388
edisonn@google.com3aa35552013-08-14 18:26:20 +0000389 const SkPdfNativeObject* operator[](int i) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000390 SkASSERT(fObjectType == kArray_PdfObjectType);
391
392 return (*fArray)[i];
393 }
394
395
396 // TODO(edisonn): make the functions to return SkPdfDictionary, move these functions in SkPdfDictionary
edisonn@google.com3aa35552013-08-14 18:26:20 +0000397 static void makeEmptyDictionary(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000398 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
399
400 obj->fObjectType = kDictionary_PdfObjectType;
edisonn@google.com3aa35552013-08-14 18:26:20 +0000401 obj->fMap = new SkTDict<SkPdfNativeObject*>(1);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000402 obj->fStr.fBuffer = NULL;
403 obj->fStr.fBytes = 0;
404 }
405
406 // TODO(edisonn): get all the possible names from spec, and compute a hash function
407 // that would create no overlaps in the same dictionary
408 // or build a tree of chars that when followed goes to a unique id/index/hash
409 // TODO(edisonn): generate constants like kDictFoo, kNameDict_name
410 // which will be used in code
411 // add function SkPdfFastNameKey key(const char* key);
412 // TODO(edisonn): setting the same key twike, will make the value undefined!
edisonn@google.com3aa35552013-08-14 18:26:20 +0000413 bool set(const SkPdfNativeObject* key, SkPdfNativeObject* value) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000414 SkASSERT(fObjectType == kDictionary_PdfObjectType);
415 SkASSERT(key->fObjectType == kName_PdfObjectType);
416
417 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
418 // TODO(edisonn): report err
419 return false;
420 }
421
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000422 //// we rewrite all delimiters and white spaces with '\0', so we expect the end of name to be '\0'
423 //SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
edisonn@google.com571c70b2013-07-10 17:09:50 +0000424
edisonn@google.comd761e322013-07-22 17:29:43 +0000425 return set(key->fStr.fBuffer, key->fStr.fBytes, value);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000426 }
427
edisonn@google.com3aa35552013-08-14 18:26:20 +0000428 bool set(const char* key, SkPdfNativeObject* value) {
edisonn@google.comd761e322013-07-22 17:29:43 +0000429 return set((const unsigned char*)key, strlen(key), value);
430 }
431
edisonn@google.com3aa35552013-08-14 18:26:20 +0000432 bool set(const unsigned char* key, size_t len, SkPdfNativeObject* value) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000433 SkASSERT(fObjectType == kDictionary_PdfObjectType);
434
435 if (fObjectType != kDictionary_PdfObjectType) {
436 // TODO(edisonn): report err
437 return false;
438 }
439
edisonn@google.comd761e322013-07-22 17:29:43 +0000440 return fMap->set((const char*)key, len, value);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000441 }
442
edisonn@google.com3aa35552013-08-14 18:26:20 +0000443 SkPdfNativeObject* get(const SkPdfNativeObject* key) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000444 SkASSERT(fObjectType == kDictionary_PdfObjectType);
445 SkASSERT(key->fObjectType == kName_PdfObjectType);
446
447 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
448 // TODO(edisonn): report err
edisonn@google.com3fc48262013-07-22 15:29:55 +0000449 return NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000450 }
451
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000452 //SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
edisonn@google.com571c70b2013-07-10 17:09:50 +0000453
edisonn@google.comd761e322013-07-22 17:29:43 +0000454 return get(key->fStr.fBuffer, key->fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000455 }
456
edisonn@google.com3aa35552013-08-14 18:26:20 +0000457 SkPdfNativeObject* get(const char* key) {
edisonn@google.comd761e322013-07-22 17:29:43 +0000458 return get((const unsigned char*)key, strlen(key));
459 }
460
edisonn@google.com3aa35552013-08-14 18:26:20 +0000461 SkPdfNativeObject* get(const unsigned char* key, size_t len) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000462 SkASSERT(fObjectType == kDictionary_PdfObjectType);
463 SkASSERT(key);
464 if (fObjectType != kDictionary_PdfObjectType) {
465 // TODO(edisonn): report err
466 return NULL;
467 }
edisonn@google.com3aa35552013-08-14 18:26:20 +0000468 SkPdfNativeObject* ret = NULL;
edisonn@google.comd761e322013-07-22 17:29:43 +0000469 fMap->find((const char*)key, len, &ret);
edisonn@google.com9a43c182013-08-01 20:06:42 +0000470
471#ifdef PDF_TRACE
472 SkString _key;
473 _key.append((const char*)key, len);
474 printf("\nget(/%s) = %s\n", _key.c_str(), ret ? ret->toString(0, len + 9).c_str() : "_NOT_FOUND");
475#endif
476
edisonn@google.com571c70b2013-07-10 17:09:50 +0000477 return ret;
478 }
479
edisonn@google.com3aa35552013-08-14 18:26:20 +0000480 const SkPdfNativeObject* get(const SkPdfNativeObject* key) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000481 SkASSERT(fObjectType == kDictionary_PdfObjectType);
482 SkASSERT(key->fObjectType == kName_PdfObjectType);
483
484 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
485 // TODO(edisonn): report err
edisonn@google.com3fc48262013-07-22 15:29:55 +0000486 return NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000487 }
488
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000489 //SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
edisonn@google.com571c70b2013-07-10 17:09:50 +0000490
edisonn@google.comd761e322013-07-22 17:29:43 +0000491 return get(key->fStr.fBuffer, key->fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000492 }
493
edisonn@google.com3aa35552013-08-14 18:26:20 +0000494 const SkPdfNativeObject* get(const char* key) const {
edisonn@google.comd761e322013-07-22 17:29:43 +0000495 return get((const unsigned char*)key, strlen(key));
496 }
497
edisonn@google.com3aa35552013-08-14 18:26:20 +0000498 const SkPdfNativeObject* get(const unsigned char* key, size_t len) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000499 SkASSERT(fObjectType == kDictionary_PdfObjectType);
500 SkASSERT(key);
501 if (fObjectType != kDictionary_PdfObjectType) {
502 // TODO(edisonn): report err
503 return NULL;
504 }
edisonn@google.com3aa35552013-08-14 18:26:20 +0000505 SkPdfNativeObject* ret = NULL;
edisonn@google.comd761e322013-07-22 17:29:43 +0000506 fMap->find((const char*)key, len, &ret);
edisonn@google.com9a43c182013-08-01 20:06:42 +0000507
508#ifdef PDF_TRACE
509 SkString _key;
510 _key.append((const char*)key, len);
511 printf("\nget(/%s) = %s\n", _key.c_str(), ret ? ret->toString(0, len + 9).c_str() : "_NOT_FOUND");
512#endif
513
edisonn@google.com571c70b2013-07-10 17:09:50 +0000514 return ret;
515 }
516
edisonn@google.com3aa35552013-08-14 18:26:20 +0000517 const SkPdfNativeObject* get(const char* key, const char* abr) const {
518 const SkPdfNativeObject* ret = get(key);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000519 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL
520 // make this distiontion in generator, and remove "" from condition
521 if (ret != NULL || abr == NULL || *abr == '\0') {
522 return ret;
523 }
524 return get(abr);
525 }
526
edisonn@google.com3aa35552013-08-14 18:26:20 +0000527 SkPdfNativeObject* get(const char* key, const char* abr) {
528 SkPdfNativeObject* ret = get(key);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000529 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL
530 // make this distiontion in generator, and remove "" from condition
531 if (ret != NULL || abr == NULL || *abr == '\0') {
532 return ret;
533 }
534 return get(abr);
535 }
536
537 SkPdfDictionary* asDictionary() {
538 SkASSERT(isDictionary());
539 if (!isDictionary()) {
540 return NULL;
541 }
542 return (SkPdfDictionary*) this;
543 }
544
545 const SkPdfDictionary* asDictionary() const {
546 SkASSERT(isDictionary());
547 if (!isDictionary()) {
548 return NULL;
549 }
550 return (SkPdfDictionary*) this;
551 }
552
553
554 bool isReference() const {
555 return fObjectType == kReference_PdfObjectType;
556 }
557
558 bool isBoolean() const {
559 return fObjectType == kBoolean_PdfObjectType;
560 }
561
562 bool isInteger() const {
563 return fObjectType == kInteger_PdfObjectType;
564 }
565private:
566 bool isReal() const {
567 return fObjectType == kReal_PdfObjectType;
568 }
569public:
570 bool isNumber() const {
571 return fObjectType == kInteger_PdfObjectType || fObjectType == kReal_PdfObjectType;
572 }
573
574 bool isKeywordReference() const {
575 return fObjectType == kKeyword_PdfObjectType && fStr.fBytes == 1 && fStr.fBuffer[0] == 'R';
576 }
577
578 bool isKeyword() const {
579 return fObjectType == kKeyword_PdfObjectType;
580 }
581
edisonn@google.com4ef4bed2013-07-29 22:14:45 +0000582 bool isKeyword(const char* keyword) const {
583 if (!isKeyword()) {
584 return false;
585 }
586
587 if (strlen(keyword) != fStr.fBytes) {
588 return false;
589 }
590
591 if (strncmp(keyword, (const char*)fStr.fBuffer, fStr.fBytes) != 0) {
592 return false;
593 }
594
595 return true;
596 }
597
edisonn@google.com571c70b2013-07-10 17:09:50 +0000598 bool isName() const {
599 return fObjectType == kName_PdfObjectType;
600 }
601
edisonn@google.com78b38b12013-07-15 18:20:58 +0000602 bool isName(const char* name) const {
603 return fObjectType == kName_PdfObjectType && fStr.fBytes == strlen(name) && strncmp((const char*)fStr.fBuffer, name, fStr.fBytes) == 0;
604 }
605
edisonn@google.com571c70b2013-07-10 17:09:50 +0000606 bool isArray() const {
607 return fObjectType == kArray_PdfObjectType;
608 }
609
610 bool isDate() const {
611 return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType;
612 }
613
614 bool isDictionary() const {
615 return fObjectType == kDictionary_PdfObjectType;
616 }
617
618 bool isFunction() const {
619 return false; // NYI
620 }
621
622 bool isRectangle() const {
623 return fObjectType == kArray_PdfObjectType && fArray->count() == 4; // NYI + and elems are numbers
624 }
625
626 // TODO(edisonn): has stream .. or is stream ... TBD
627 bool hasStream() const {
628 return isDictionary() && fStr.fBuffer != NULL;
629 }
630
631 // TODO(edisonn): has stream .. or is stream ... TBD
632 const SkPdfStream* getStream() const {
633 return hasStream() ? (const SkPdfStream*)this : NULL;
634 }
635
636 SkPdfStream* getStream() {
637 return hasStream() ? (SkPdfStream*)this : NULL;
638 }
639
640 bool isAnyString() const {
641 return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType;
642 }
643
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000644 bool isHexString() const {
645 return fObjectType == kHexString_PdfObjectType;
646 }
647
edisonn@google.com571c70b2013-07-10 17:09:50 +0000648 bool isMatrix() const {
649 return fObjectType == kArray_PdfObjectType && fArray->count() == 6; // NYI + and elems are numbers
650 }
651
652 inline int64_t intValue() const {
653 SkASSERT(fObjectType == kInteger_PdfObjectType);
654
655 if (fObjectType != kInteger_PdfObjectType) {
656 // TODO(edisonn): log err
657 return 0;
658 }
659 return fIntegerValue;
660 }
661private:
662 inline double realValue() const {
663 SkASSERT(fObjectType == kReal_PdfObjectType);
664
665 if (fObjectType != kReal_PdfObjectType) {
666 // TODO(edisonn): log err
667 return 0;
668 }
669 return fRealValue;
670 }
671public:
672 inline double numberValue() const {
673 SkASSERT(isNumber());
674
675 if (!isNumber()) {
676 // TODO(edisonn): log err
677 return 0;
678 }
679 return fObjectType == kReal_PdfObjectType ? fRealValue : fIntegerValue;
680 }
681
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000682 inline SkScalar scalarValue() const {
683 SkASSERT(isNumber());
684
685 if (!isNumber()) {
686 // TODO(edisonn): log err
687 return SkIntToScalar(0);
688 }
689 return fObjectType == kReal_PdfObjectType ? SkDoubleToScalar(fRealValue) :
690 SkIntToScalar(fIntegerValue);
691 }
692
edisonn@google.com571c70b2013-07-10 17:09:50 +0000693 int referenceId() const {
694 SkASSERT(fObjectType == kReference_PdfObjectType);
695 return fRef.fId;
696 }
697
698 int referenceGeneration() const {
699 SkASSERT(fObjectType == kReference_PdfObjectType);
700 return fRef.fGen;
701 }
702
703 inline const char* nameValue() const {
704 SkASSERT(fObjectType == kName_PdfObjectType);
705
706 if (fObjectType != kName_PdfObjectType) {
707 // TODO(edisonn): log err
708 return "";
709 }
710 return (const char*)fStr.fBuffer;
711 }
712
713 inline const char* stringValue() const {
714 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType);
715
716 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) {
717 // TODO(edisonn): log err
718 return "";
719 }
720 return (const char*)fStr.fBuffer;
721 }
722
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000723 inline NotOwnedString strRef() {
724 switch (fObjectType) {
725 case kString_PdfObjectType:
726 case kHexString_PdfObjectType:
727 case kKeyword_PdfObjectType:
edisonn@google.com276fed92013-08-01 21:20:47 +0000728 case kName_PdfObjectType:
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000729 return fStr;
730
731 default:
732 // TODO(edisonn): report/warning
733 return NotOwnedString();
734 }
735 }
736
edisonn@google.com571c70b2013-07-10 17:09:50 +0000737 // TODO(edisonn): nameValue2 and stringValue2 are used to make code generation easy,
738 // but it is not a performat way to do it, since it will create an extra copy
739 // remove these functions and make code generated faster
edisonn@google.com063d7072013-08-16 15:05:08 +0000740 inline SkString nameValue2() const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000741 SkASSERT(fObjectType == kName_PdfObjectType);
742
743 if (fObjectType != kName_PdfObjectType) {
744 // TODO(edisonn): log err
edisonn@google.com063d7072013-08-16 15:05:08 +0000745 return SkString();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000746 }
edisonn@google.com063d7072013-08-16 15:05:08 +0000747 return SkString((const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000748 }
749
edisonn@google.com063d7072013-08-16 15:05:08 +0000750 inline SkString stringValue2() const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000751 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType);
752
753 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) {
754 // TODO(edisonn): log err
edisonn@google.com063d7072013-08-16 15:05:08 +0000755 return SkString();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000756 }
edisonn@google.com063d7072013-08-16 15:05:08 +0000757 return SkString((const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000758 }
759
760 inline bool boolValue() const {
761 SkASSERT(fObjectType == kBoolean_PdfObjectType);
762
edisonn@google.comf111a4b2013-07-31 18:22:36 +0000763 if (fObjectType != kBoolean_PdfObjectType) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000764 // TODO(edisonn): log err
765 return false;
766 }
767 return fBooleanValue;
768 }
769
770 SkRect rectangleValue() const {
771 SkASSERT(isRectangle());
772 if (!isRectangle()) {
773 return SkRect::MakeEmpty();
774 }
775
776 double array[4];
777 for (int i = 0; i < 4; i++) {
778 // TODO(edisonn): version where we could resolve references?
edisonn@google.com3aa35552013-08-14 18:26:20 +0000779 const SkPdfNativeObject* elem = objAtAIndex(i);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000780 if (elem == NULL || !elem->isNumber()) {
781 // TODO(edisonn): report error
782 return SkRect::MakeEmpty();
783 }
784 array[i] = elem->numberValue();
785 }
786
787 return SkRect::MakeLTRB(SkDoubleToScalar(array[0]),
788 SkDoubleToScalar(array[1]),
789 SkDoubleToScalar(array[2]),
790 SkDoubleToScalar(array[3]));
791 }
792
793 SkMatrix matrixValue() const {
794 SkASSERT(isMatrix());
795 if (!isMatrix()) {
796 return SkMatrix::I();
797 }
798
799 double array[6];
800 for (int i = 0; i < 6; i++) {
801 // TODO(edisonn): version where we could resolve references?
edisonn@google.com3aa35552013-08-14 18:26:20 +0000802 const SkPdfNativeObject* elem = objAtAIndex(i);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000803 if (elem == NULL || !elem->isNumber()) {
804 // TODO(edisonn): report error
805 return SkMatrix::I();
806 }
807 array[i] = elem->numberValue();
808 }
809
810 return SkMatrixFromPdfMatrix(array);
811 }
812
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000813 bool filterStream();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000814
815
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000816 bool GetFilteredStreamRef(unsigned char const** buffer, size_t* len) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000817 // TODO(edisonn): add params that couls let the last filter in place if it is jpeg or png to fast load images
818 if (!hasStream()) {
819 return false;
820 }
821
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000822 filterStream();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000823
824 if (buffer) {
825 *buffer = fStr.fBuffer;
826 }
827
828 if (len) {
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000829 *len = fStr.fBytes >> 2; // last 2 bits
edisonn@google.com571c70b2013-07-10 17:09:50 +0000830 }
831
832 return true;
833 }
834
835 bool isStreamFiltered() const {
836 return hasStream() && ((fStr.fBytes & 1) == kFilteredStreamBit);
837 }
838
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000839 bool isStreamOwned() const {
840 return hasStream() && ((fStr.fBytes & 2) == kOwnedStreamBit);
841 }
842
843 bool GetUnfilteredStreamRef(unsigned char const** buffer, size_t* len) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000844 if (isStreamFiltered()) {
845 return false;
846 }
847
848 if (!hasStream()) {
849 return false;
850 }
851
852 if (buffer) {
853 *buffer = fStr.fBuffer;
854 }
855
856 if (len) {
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000857 *len = fStr.fBytes >> 2; // remove last 2 bits
edisonn@google.com571c70b2013-07-10 17:09:50 +0000858 }
859
860 return true;
861 }
862
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000863 bool addStream(const unsigned char* buffer, size_t len) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000864 SkASSERT(!hasStream());
865 SkASSERT(isDictionary());
866
867 if (!isDictionary() || hasStream()) {
868 return false;
869 }
870
871 fStr.fBuffer = buffer;
872 fStr.fBytes = (len << 2) + kUnfilteredStreamBit;
873
874 return true;
875 }
876
edisonn@google.com276fed92013-08-01 21:20:47 +0000877 static void appendSpaces(SkString* str, int level) {
edisonn@google.com9a43c182013-08-01 20:06:42 +0000878 for (int i = 0 ; i < level; i++) {
879 str->append(" ");
880 }
881 }
882
edisonn@google.com3aa35552013-08-14 18:26:20 +0000883 static void append(SkString* str, const char* data, size_t len, const char* prefix = "\\x") {
884 for (unsigned int i = 0 ; i < len; i++) {
885 if (data[i] == kNUL_PdfWhiteSpace) {
886 str->append(prefix);
887 str->append("00");
888 } else if (data[i] == kHT_PdfWhiteSpace) {
889 str->append(prefix);
890 str->append("09");
891 } else if (data[i] == kLF_PdfWhiteSpace) {
892 str->append(prefix);
893 str->append("0A");
894 } else if (data[i] == kFF_PdfWhiteSpace) {
895 str->append(prefix);
896 str->append("0C");
897 } else if (data[i] == kCR_PdfWhiteSpace) {
898 str->append(prefix);
899 str->append("0D");
900 } else {
901 str->append(data + i, 1);
902 }
903 }
904 }
905
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000906 SkString toString(int firstRowLevel = 0, int level = 0) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000907 SkString str;
edisonn@google.com9a43c182013-08-01 20:06:42 +0000908 appendSpaces(&str, firstRowLevel);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000909 switch (fObjectType) {
910 case kInvalid_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000911 str.append("__Invalid");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000912 break;
913
914 case kBoolean_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000915 str.appendf("%s", fBooleanValue ? "true" : "false");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000916 break;
917
918 case kInteger_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000919 str.appendf("%i", (int)fIntegerValue);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000920 break;
921
922 case kReal_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000923 str.appendf("%f", fRealValue);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000924 break;
925
926 case kString_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000927 str.append("\"");
edisonn@google.com3aa35552013-08-14 18:26:20 +0000928 append(&str, (const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com9a43c182013-08-01 20:06:42 +0000929 str.append("\"");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000930 break;
931
932 case kHexString_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000933 str.append("<");
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000934 for (unsigned int i = 0 ; i < fStr.fBytes; i++) {
935 str.appendf("%02x", (unsigned int)fStr.fBuffer[i]);
936 }
edisonn@google.com9a43c182013-08-01 20:06:42 +0000937 str.append(">");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000938 break;
939
940 case kName_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000941 str.append("/");
edisonn@google.com3aa35552013-08-14 18:26:20 +0000942 append(&str, (const char*)fStr.fBuffer, fStr.fBytes, "#");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000943 break;
944
945 case kKeyword_PdfObjectType:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000946 append(&str, (const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000947 break;
948
949 case kArray_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000950 str.append("[\n");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000951 for (unsigned int i = 0; i < size(); i++) {
edisonn@google.com9a43c182013-08-01 20:06:42 +0000952 str.append(objAtAIndex(i)->toString(level + 1, level + 1));
953 if (i < size() - 1) {
954 str.append(",");
955 }
956 str.append("\n");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000957 }
edisonn@google.com9a43c182013-08-01 20:06:42 +0000958 appendSpaces(&str, level);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000959 str.append("]");
960 break;
961
edisonn@google.com9a43c182013-08-01 20:06:42 +0000962 case kDictionary_PdfObjectType: {
edisonn@google.com3aa35552013-08-14 18:26:20 +0000963 SkTDict<SkPdfNativeObject*>::Iter iter(*fMap);
964 SkPdfNativeObject* obj = NULL;
edisonn@google.com9a43c182013-08-01 20:06:42 +0000965 const char* key = NULL;
966 str.append("<<\n");
967 while ((key = iter.next(&obj)) != NULL) {
968 appendSpaces(&str, level + 2);
969 str.appendf("/%s %s\n", key, obj->toString(0, level + strlen(key) + 4).c_str());
970 }
971 appendSpaces(&str, level);
972 str.append(">>");
973 if (hasStream()) {
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000974 const unsigned char* stream = NULL;
975 size_t length = 0;
976 if (GetFilteredStreamRef(&stream, &length)) {
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000977 str.append("stream\n");
edisonn@google.com3aa35552013-08-14 18:26:20 +0000978 append(&str, (const char*)stream, length > 256 ? 256 : length);
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000979 str.append("\nendstream");
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000980 } else {
981 str.append("stream STREAM_ERROR endstream");
982 }
edisonn@google.com9a43c182013-08-01 20:06:42 +0000983 }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000984 }
985 break;
986
987 case kNull_PdfObjectType:
988 str = "NULL";
989 break;
990
991 case kReference_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000992 str.appendf("%i %i R", fRef.fId, fRef.fGen);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000993 break;
994
995 case kUndefined_PdfObjectType:
996 str = "Undefined";
997 break;
998
999 default:
edisonn@google.com9a43c182013-08-01 20:06:42 +00001000 str = "Error";
edisonn@google.com571c70b2013-07-10 17:09:50 +00001001 break;
1002 }
1003
1004 return str;
1005 }
1006
1007private:
edisonn@google.com3aa35552013-08-14 18:26:20 +00001008 static void makeStringCore(const unsigned char* start, SkPdfNativeObject* obj, ObjectType type) {
edisonn@google.com571c70b2013-07-10 17:09:50 +00001009 makeStringCore(start, strlen((const char*)start), obj, type);
1010 }
1011
edisonn@google.com3aa35552013-08-14 18:26:20 +00001012 static void makeStringCore(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj, ObjectType type) {
edisonn@google.com571c70b2013-07-10 17:09:50 +00001013 makeStringCore(start, end - start, obj, type);
1014 }
1015
edisonn@google.com3aa35552013-08-14 18:26:20 +00001016 static void makeStringCore(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj, ObjectType type) {
edisonn@google.com571c70b2013-07-10 17:09:50 +00001017 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
1018
1019 obj->fObjectType = type;
1020 obj->fStr.fBuffer = start;
1021 obj->fStr.fBytes = bytes;
1022 }
1023
edisonn@google.com2ccc3af2013-07-23 17:43:18 +00001024 bool applyFilter(const char* name);
1025 bool applyFlateDecodeFilter();
1026 bool applyDCTDecodeFilter();
edisonn@google.com571c70b2013-07-10 17:09:50 +00001027};
1028
edisonn@google.com3aa35552013-08-14 18:26:20 +00001029class SkPdfStream : public SkPdfNativeObject {};
1030class SkPdfArray : public SkPdfNativeObject {};
1031class SkPdfString : public SkPdfNativeObject {};
1032class SkPdfHexString : public SkPdfNativeObject {};
1033class SkPdfInteger : public SkPdfNativeObject {};
1034class SkPdfReal : public SkPdfNativeObject {};
1035class SkPdfNumber : public SkPdfNativeObject {};
edisonn@google.com571c70b2013-07-10 17:09:50 +00001036
edisonn@google.com3aa35552013-08-14 18:26:20 +00001037class SkPdfName : public SkPdfNativeObject {
1038 SkPdfName() : SkPdfNativeObject() {
1039 SkPdfNativeObject::makeName((const unsigned char*)"", this);
edisonn@google.com78b38b12013-07-15 18:20:58 +00001040 }
1041public:
edisonn@google.com3aa35552013-08-14 18:26:20 +00001042 SkPdfName(char* name) : SkPdfNativeObject() {
edisonn@google.com2ccc3af2013-07-23 17:43:18 +00001043 this->makeName((const unsigned char*)name, this);
edisonn@google.com78b38b12013-07-15 18:20:58 +00001044 }
1045};
1046
edisonn@google.comcf2cfa12013-08-21 16:31:37 +00001047#endif // SkPdfNativeObject