blob: 187f2b83fce05c5a2a9379d9bc60c061901519d7 [file] [log] [blame]
edisonn@google.com571c70b2013-07-10 17:09:50 +00001#ifndef EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFOBJECT_H_
2#define EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFOBJECT_H_
3
4#include <stdint.h>
5#include <string.h>
edisonn@google.com063d7072013-08-16 15:05:08 +00006#include "SkString.h"
edisonn@google.com571c70b2013-07-10 17:09:50 +00007#include "SkTDArray.h"
8#include "SkTDict.h"
9#include "SkRect.h"
10#include "SkMatrix.h"
11#include "SkString.h"
12
13#include "SkPdfNYI.h"
14#include "SkPdfConfig.h"
edisonn@google.com3aa35552013-08-14 18:26:20 +000015#include "SkPdfUtils.h"
16
17#include "SkPdfNativeTokenizer.h"
edisonn@google.com571c70b2013-07-10 17:09:50 +000018
19class SkPdfDictionary;
20class SkPdfStream;
21class SkPdfAllocator;
22
23// TODO(edisonn): macro it and move it to utils
24SkMatrix SkMatrixFromPdfMatrix(double array[6]);
25
26
27#define kFilteredStreamBit 0
28#define kUnfilteredStreamBit 1
edisonn@google.com2ccc3af2013-07-23 17:43:18 +000029#define kOwnedStreamBit 2
edisonn@google.com571c70b2013-07-10 17:09:50 +000030
edisonn@google.com3aa35552013-08-14 18:26:20 +000031class SkPdfNativeObject {
edisonn@google.com571c70b2013-07-10 17:09:50 +000032 public:
33 enum ObjectType {
34 kInvalid_PdfObjectType,
35
36 kBoolean_PdfObjectType,
37 kInteger_PdfObjectType,
38 kReal_PdfObjectType,
39 kString_PdfObjectType,
40 kHexString_PdfObjectType,
41 kName_PdfObjectType,
42 kKeyword_PdfObjectType,
43 //kStream_PdfObjectType, // attached to a Dictionary
44 kArray_PdfObjectType,
45 kDictionary_PdfObjectType,
46 kNull_PdfObjectType,
47
48 // TODO(edisonn): after the pdf has been loaded completely, resolve all references
49 // try the same thing with delayed loaded ...
50 kReference_PdfObjectType,
51
52 kUndefined_PdfObjectType, // per 1.4 spec, if the same key appear twice in the dictionary, the value is undefined
53 };
54
edisonn@google.comb0145ce2013-08-05 16:23:23 +000055 enum DataType {
56 kEmpty_Data,
57 kFont_Data,
58 kBitmap_Data,
59 };
60
edisonn@google.com571c70b2013-07-10 17:09:50 +000061private:
edisonn@google.com063d7072013-08-16 15:05:08 +000062 // TODO(edisonn): assert reset operations while in rendering!
63 uint32_t fInRendering : 1;
64 uint32_t fUnused : 31;
65
66
edisonn@google.com571c70b2013-07-10 17:09:50 +000067 struct Reference {
68 unsigned int fId;
69 unsigned int fGen;
70 };
71
72 // TODO(edisonn): add stream start, stream end, where stream is weither the file
73 // or decoded/filtered pdf stream
74
75 // TODO(edisonn): add warning/report per object
76 // TODO(edisonn): add flag fUsed, to be used once the parsing is complete,
77 // so we could show what parts have been proccessed, ignored, or generated errors
78
79 ObjectType fObjectType;
80
81 union {
82 bool fBooleanValue;
83 int64_t fIntegerValue;
84 // TODO(edisonn): double, float? typedefed
85 double fRealValue;
86 NotOwnedString fStr;
87
88 // 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 +000089 SkTDArray<SkPdfNativeObject*>* fArray;
edisonn@google.com571c70b2013-07-10 17:09:50 +000090 Reference fRef;
91 };
edisonn@google.com3aa35552013-08-14 18:26:20 +000092 SkTDict<SkPdfNativeObject*>* fMap;
edisonn@google.comb0145ce2013-08-05 16:23:23 +000093
94 // TODO(edisonn): rename data with cache
edisonn@google.com571c70b2013-07-10 17:09:50 +000095 void* fData;
edisonn@google.comb0145ce2013-08-05 16:23:23 +000096 DataType fDataType;
edisonn@google.com571c70b2013-07-10 17:09:50 +000097
98
99public:
100
edisonn@google.com063d7072013-08-16 15:05:08 +0000101 SkPdfNativeObject() : fInRendering(0), fObjectType(kInvalid_PdfObjectType), fMap(NULL), fData(NULL), fDataType(kEmpty_Data) {}
edisonn@google.com571c70b2013-07-10 17:09:50 +0000102
edisonn@google.com063d7072013-08-16 15:05:08 +0000103 bool inRendering() const { return fInRendering != 0; }
104 void startRendering() {fInRendering = 1;}
105 void doneRendering() {fInRendering = 0;}
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000106
107 inline bool hasData(DataType type) {
108 return type == fDataType;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000109 }
110
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000111 inline void* data(DataType type) {
112 return type == fDataType ? fData : NULL;
113 }
114
115 inline void setData(void* data, DataType type) {
116 releaseData();
117 fDataType = type;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000118 fData = data;
119 }
120
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000121 void releaseData();
122
edisonn@google.com3aa35552013-08-14 18:26:20 +0000123// ~SkPdfNativeObject() {
edisonn@google.com222382b2013-07-10 22:33:10 +0000124// //reset(); must be called manually!
125// }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000126
127 void reset() {
128 switch (fObjectType) {
129 case kArray_PdfObjectType:
130 delete fArray;
131 break;
132
133 case kDictionary_PdfObjectType:
134 delete fMap;
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000135 if (isStreamOwned()) {
136 delete[] fStr.fBuffer;
137 fStr.fBuffer = NULL;
138 fStr.fBytes = 0;
139 }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000140 break;
141
142 default:
143 break;
144 }
145 fObjectType = kInvalid_PdfObjectType;
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000146 releaseData();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000147 }
148
149 ObjectType type() { return fObjectType; }
150
151 const char* c_str() const {
152 switch (fObjectType) {
153 case kString_PdfObjectType:
154 case kHexString_PdfObjectType:
155 case kKeyword_PdfObjectType:
edisonn@google.com276fed92013-08-01 21:20:47 +0000156 case kName_PdfObjectType:
edisonn@google.com571c70b2013-07-10 17:09:50 +0000157 return (const char*)fStr.fBuffer;
158
159 default:
160 // TODO(edisonn): report/warning
161 return NULL;
162 }
163 }
164
edisonn@google.come878e722013-07-29 19:10:58 +0000165 size_t lenstr() const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000166 switch (fObjectType) {
167 case kString_PdfObjectType:
168 case kHexString_PdfObjectType:
169 case kKeyword_PdfObjectType:
edisonn@google.com276fed92013-08-01 21:20:47 +0000170 case kName_PdfObjectType:
edisonn@google.com571c70b2013-07-10 17:09:50 +0000171 return fStr.fBytes;
172
173 default:
174 // TODO(edisonn): report/warning
175 return 0;
176 }
177 }
178
179
180 // TODO(edisonn): NYI
181 SkPdfDate& dateValue() const {
182 static SkPdfDate nyi;
183 return nyi;
184 }
185
186 // TODO(edisonn): NYI
187 SkPdfFunction& functionValue() const {
188 static SkPdfFunction nyi;
189 return nyi;
190 }
191
192 // TODO(edisonn): NYI
193 SkPdfFileSpec& fileSpecValue() const {
194 static SkPdfFileSpec nyi;
195 return nyi;
196 }
197
198 // TODO(edisonn): NYI
199 SkPdfTree& treeValue() const {
200 static SkPdfTree nyi;
201 return nyi;
202 }
203
edisonn@google.com3aa35552013-08-14 18:26:20 +0000204 static void makeBoolean(bool value, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000205 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
206
207 obj->fObjectType = kBoolean_PdfObjectType;
208 obj->fBooleanValue = value;
209 }
210
edisonn@google.com3aa35552013-08-14 18:26:20 +0000211 static SkPdfNativeObject makeBoolean(bool value) {
212 SkPdfNativeObject obj;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000213 obj.fObjectType = kBoolean_PdfObjectType;
214 obj.fBooleanValue = value;
215 return obj;
216 }
217
edisonn@google.com3aa35552013-08-14 18:26:20 +0000218 static void makeInteger(int64_t value, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000219 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
220
221 obj->fObjectType = kInteger_PdfObjectType;
222 obj->fIntegerValue = value;
223 }
224
edisonn@google.com3aa35552013-08-14 18:26:20 +0000225 static void makeReal(double value, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000226 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
227
228 obj->fObjectType = kReal_PdfObjectType;
229 obj->fRealValue = value;
230 }
231
edisonn@google.com3aa35552013-08-14 18:26:20 +0000232 static void makeNull(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000233 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
234
235 obj->fObjectType = kNull_PdfObjectType;
236 }
237
edisonn@google.com3aa35552013-08-14 18:26:20 +0000238 static SkPdfNativeObject makeNull() {
239 SkPdfNativeObject obj;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000240 obj.fObjectType = kNull_PdfObjectType;
241 return obj;
242 }
243
edisonn@google.com3aa35552013-08-14 18:26:20 +0000244 static SkPdfNativeObject kNull;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000245
edisonn@google.com3aa35552013-08-14 18:26:20 +0000246 static void makeNumeric(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000247 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
248
249 // TODO(edisonn): NYI properly
250 // if has dot (impl), or exceeds max int, is real, otherwise is int
251 bool isInt = true;
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000252 for (const unsigned char* current = start; current < end; current++) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000253 if (*current == '.') {
254 isInt = false;
255 break;
256 }
257 // TODO(edisonn): report parse issue with numbers like "24asdasd123"
258 }
259 if (isInt) {
260 makeInteger(atol((const char*)start), obj);
261 } else {
262 makeReal(atof((const char*)start), obj);
263 }
264 }
265
edisonn@google.com3aa35552013-08-14 18:26:20 +0000266 static void makeReference(unsigned int id, unsigned int gen, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000267 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
268
269 obj->fObjectType = kReference_PdfObjectType;
270 obj->fRef.fId = id;
271 obj->fRef.fGen = gen;
272 }
273
274
edisonn@google.com3aa35552013-08-14 18:26:20 +0000275 static void makeString(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000276 makeStringCore(start, strlen((const char*)start), obj, kString_PdfObjectType);
277 }
278
edisonn@google.com3aa35552013-08-14 18:26:20 +0000279 static void makeString(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000280 makeStringCore(start, end - start, obj, kString_PdfObjectType);
281 }
282
edisonn@google.com3aa35552013-08-14 18:26:20 +0000283 static void makeString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000284 makeStringCore(start, bytes, obj, kString_PdfObjectType);
285 }
286
287
edisonn@google.com3aa35552013-08-14 18:26:20 +0000288 static void makeHexString(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000289 makeStringCore(start, strlen((const char*)start), obj, kHexString_PdfObjectType);
290 }
291
edisonn@google.com3aa35552013-08-14 18:26:20 +0000292 static void makeHexString(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000293 makeStringCore(start, end - start, obj, kHexString_PdfObjectType);
294 }
295
edisonn@google.com3aa35552013-08-14 18:26:20 +0000296 static void makeHexString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000297 makeStringCore(start, bytes, obj, kHexString_PdfObjectType);
298 }
299
300
edisonn@google.com3aa35552013-08-14 18:26:20 +0000301 static void makeName(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000302 makeStringCore(start, strlen((const char*)start), obj, kName_PdfObjectType);
303 }
304
edisonn@google.com3aa35552013-08-14 18:26:20 +0000305 static void makeName(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000306 makeStringCore(start, end - start, obj, kName_PdfObjectType);
307 }
308
edisonn@google.com3aa35552013-08-14 18:26:20 +0000309 static void makeName(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000310 makeStringCore(start, bytes, obj, kName_PdfObjectType);
311 }
312
313
edisonn@google.com3aa35552013-08-14 18:26:20 +0000314 static void makeKeyword(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000315 makeStringCore(start, strlen((const char*)start), obj, kKeyword_PdfObjectType);
316 }
317
edisonn@google.com3aa35552013-08-14 18:26:20 +0000318 static void makeKeyword(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000319 makeStringCore(start, end - start, obj, kKeyword_PdfObjectType);
320 }
321
edisonn@google.com3aa35552013-08-14 18:26:20 +0000322 static void makeKeyword(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000323 makeStringCore(start, bytes, obj, kKeyword_PdfObjectType);
324 }
325
326
327
328 // TODO(edisonn): make the functions to return SkPdfArray, move these functions in SkPdfArray
edisonn@google.com3aa35552013-08-14 18:26:20 +0000329 static void makeEmptyArray(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000330 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
331
332 obj->fObjectType = kArray_PdfObjectType;
edisonn@google.com3aa35552013-08-14 18:26:20 +0000333 obj->fArray = new SkTDArray<SkPdfNativeObject*>();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000334 // return (SkPdfArray*)obj;
335 }
336
edisonn@google.com3aa35552013-08-14 18:26:20 +0000337 bool appendInArray(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000338 SkASSERT(fObjectType == kArray_PdfObjectType);
339 if (fObjectType != kArray_PdfObjectType) {
340 // TODO(edisonn): report err
341 return false;
342 }
343
344 fArray->push(obj);
345 return true;
346 }
347
348 size_t size() const {
349 SkASSERT(fObjectType == kArray_PdfObjectType);
350
351 return fArray->count();
352 }
353
edisonn@google.com3aa35552013-08-14 18:26:20 +0000354 SkPdfNativeObject* objAtAIndex(int i) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000355 SkASSERT(fObjectType == kArray_PdfObjectType);
356
357 return (*fArray)[i];
358 }
359
edisonn@google.com3aa35552013-08-14 18:26:20 +0000360 SkPdfNativeObject* removeLastInArray() {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000361 SkASSERT(fObjectType == kArray_PdfObjectType);
362
edisonn@google.com3aa35552013-08-14 18:26:20 +0000363 SkPdfNativeObject* ret = NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000364 fArray->pop(&ret);
365
366 return ret;
367 }
368
369
edisonn@google.com3aa35552013-08-14 18:26:20 +0000370 const SkPdfNativeObject* objAtAIndex(int i) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000371 SkASSERT(fObjectType == kArray_PdfObjectType);
372
373 return (*fArray)[i];
374 }
375
edisonn@google.com3aa35552013-08-14 18:26:20 +0000376 SkPdfNativeObject* operator[](int i) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000377 SkASSERT(fObjectType == kArray_PdfObjectType);
378
379 return (*fArray)[i];
380 }
381
edisonn@google.com3aa35552013-08-14 18:26:20 +0000382 const SkPdfNativeObject* operator[](int i) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000383 SkASSERT(fObjectType == kArray_PdfObjectType);
384
385 return (*fArray)[i];
386 }
387
388
389 // TODO(edisonn): make the functions to return SkPdfDictionary, move these functions in SkPdfDictionary
edisonn@google.com3aa35552013-08-14 18:26:20 +0000390 static void makeEmptyDictionary(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000391 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
392
393 obj->fObjectType = kDictionary_PdfObjectType;
edisonn@google.com3aa35552013-08-14 18:26:20 +0000394 obj->fMap = new SkTDict<SkPdfNativeObject*>(1);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000395 obj->fStr.fBuffer = NULL;
396 obj->fStr.fBytes = 0;
397 }
398
399 // TODO(edisonn): get all the possible names from spec, and compute a hash function
400 // that would create no overlaps in the same dictionary
401 // or build a tree of chars that when followed goes to a unique id/index/hash
402 // TODO(edisonn): generate constants like kDictFoo, kNameDict_name
403 // which will be used in code
404 // add function SkPdfFastNameKey key(const char* key);
405 // TODO(edisonn): setting the same key twike, will make the value undefined!
edisonn@google.com3aa35552013-08-14 18:26:20 +0000406 bool set(const SkPdfNativeObject* key, SkPdfNativeObject* value) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000407 SkASSERT(fObjectType == kDictionary_PdfObjectType);
408 SkASSERT(key->fObjectType == kName_PdfObjectType);
409
410 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
411 // TODO(edisonn): report err
412 return false;
413 }
414
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000415 //// we rewrite all delimiters and white spaces with '\0', so we expect the end of name to be '\0'
416 //SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
edisonn@google.com571c70b2013-07-10 17:09:50 +0000417
edisonn@google.comd761e322013-07-22 17:29:43 +0000418 return set(key->fStr.fBuffer, key->fStr.fBytes, value);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000419 }
420
edisonn@google.com3aa35552013-08-14 18:26:20 +0000421 bool set(const char* key, SkPdfNativeObject* value) {
edisonn@google.comd761e322013-07-22 17:29:43 +0000422 return set((const unsigned char*)key, strlen(key), value);
423 }
424
edisonn@google.com3aa35552013-08-14 18:26:20 +0000425 bool set(const unsigned char* key, size_t len, SkPdfNativeObject* value) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000426 SkASSERT(fObjectType == kDictionary_PdfObjectType);
427
428 if (fObjectType != kDictionary_PdfObjectType) {
429 // TODO(edisonn): report err
430 return false;
431 }
432
edisonn@google.comd761e322013-07-22 17:29:43 +0000433 return fMap->set((const char*)key, len, value);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000434 }
435
edisonn@google.com3aa35552013-08-14 18:26:20 +0000436 SkPdfNativeObject* get(const SkPdfNativeObject* key) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000437 SkASSERT(fObjectType == kDictionary_PdfObjectType);
438 SkASSERT(key->fObjectType == kName_PdfObjectType);
439
440 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
441 // TODO(edisonn): report err
edisonn@google.com3fc48262013-07-22 15:29:55 +0000442 return NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000443 }
444
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000445 //SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
edisonn@google.com571c70b2013-07-10 17:09:50 +0000446
edisonn@google.comd761e322013-07-22 17:29:43 +0000447 return get(key->fStr.fBuffer, key->fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000448 }
449
edisonn@google.com3aa35552013-08-14 18:26:20 +0000450 SkPdfNativeObject* get(const char* key) {
edisonn@google.comd761e322013-07-22 17:29:43 +0000451 return get((const unsigned char*)key, strlen(key));
452 }
453
edisonn@google.com3aa35552013-08-14 18:26:20 +0000454 SkPdfNativeObject* get(const unsigned char* key, size_t len) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000455 SkASSERT(fObjectType == kDictionary_PdfObjectType);
456 SkASSERT(key);
457 if (fObjectType != kDictionary_PdfObjectType) {
458 // TODO(edisonn): report err
459 return NULL;
460 }
edisonn@google.com3aa35552013-08-14 18:26:20 +0000461 SkPdfNativeObject* ret = NULL;
edisonn@google.comd761e322013-07-22 17:29:43 +0000462 fMap->find((const char*)key, len, &ret);
edisonn@google.com9a43c182013-08-01 20:06:42 +0000463
464#ifdef PDF_TRACE
465 SkString _key;
466 _key.append((const char*)key, len);
467 printf("\nget(/%s) = %s\n", _key.c_str(), ret ? ret->toString(0, len + 9).c_str() : "_NOT_FOUND");
468#endif
469
edisonn@google.com571c70b2013-07-10 17:09:50 +0000470 return ret;
471 }
472
edisonn@google.com3aa35552013-08-14 18:26:20 +0000473 const SkPdfNativeObject* get(const SkPdfNativeObject* key) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000474 SkASSERT(fObjectType == kDictionary_PdfObjectType);
475 SkASSERT(key->fObjectType == kName_PdfObjectType);
476
477 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
478 // TODO(edisonn): report err
edisonn@google.com3fc48262013-07-22 15:29:55 +0000479 return NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000480 }
481
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000482 //SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
edisonn@google.com571c70b2013-07-10 17:09:50 +0000483
edisonn@google.comd761e322013-07-22 17:29:43 +0000484 return get(key->fStr.fBuffer, key->fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000485 }
486
edisonn@google.com3aa35552013-08-14 18:26:20 +0000487 const SkPdfNativeObject* get(const char* key) const {
edisonn@google.comd761e322013-07-22 17:29:43 +0000488 return get((const unsigned char*)key, strlen(key));
489 }
490
edisonn@google.com3aa35552013-08-14 18:26:20 +0000491 const SkPdfNativeObject* get(const unsigned char* key, size_t len) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000492 SkASSERT(fObjectType == kDictionary_PdfObjectType);
493 SkASSERT(key);
494 if (fObjectType != kDictionary_PdfObjectType) {
495 // TODO(edisonn): report err
496 return NULL;
497 }
edisonn@google.com3aa35552013-08-14 18:26:20 +0000498 SkPdfNativeObject* ret = NULL;
edisonn@google.comd761e322013-07-22 17:29:43 +0000499 fMap->find((const char*)key, len, &ret);
edisonn@google.com9a43c182013-08-01 20:06:42 +0000500
501#ifdef PDF_TRACE
502 SkString _key;
503 _key.append((const char*)key, len);
504 printf("\nget(/%s) = %s\n", _key.c_str(), ret ? ret->toString(0, len + 9).c_str() : "_NOT_FOUND");
505#endif
506
edisonn@google.com571c70b2013-07-10 17:09:50 +0000507 return ret;
508 }
509
edisonn@google.com3aa35552013-08-14 18:26:20 +0000510 const SkPdfNativeObject* get(const char* key, const char* abr) const {
511 const SkPdfNativeObject* ret = get(key);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000512 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL
513 // make this distiontion in generator, and remove "" from condition
514 if (ret != NULL || abr == NULL || *abr == '\0') {
515 return ret;
516 }
517 return get(abr);
518 }
519
edisonn@google.com3aa35552013-08-14 18:26:20 +0000520 SkPdfNativeObject* get(const char* key, const char* abr) {
521 SkPdfNativeObject* ret = get(key);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000522 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL
523 // make this distiontion in generator, and remove "" from condition
524 if (ret != NULL || abr == NULL || *abr == '\0') {
525 return ret;
526 }
527 return get(abr);
528 }
529
530 SkPdfDictionary* asDictionary() {
531 SkASSERT(isDictionary());
532 if (!isDictionary()) {
533 return NULL;
534 }
535 return (SkPdfDictionary*) this;
536 }
537
538 const SkPdfDictionary* asDictionary() const {
539 SkASSERT(isDictionary());
540 if (!isDictionary()) {
541 return NULL;
542 }
543 return (SkPdfDictionary*) this;
544 }
545
546
547 bool isReference() const {
548 return fObjectType == kReference_PdfObjectType;
549 }
550
551 bool isBoolean() const {
552 return fObjectType == kBoolean_PdfObjectType;
553 }
554
555 bool isInteger() const {
556 return fObjectType == kInteger_PdfObjectType;
557 }
558private:
559 bool isReal() const {
560 return fObjectType == kReal_PdfObjectType;
561 }
562public:
563 bool isNumber() const {
564 return fObjectType == kInteger_PdfObjectType || fObjectType == kReal_PdfObjectType;
565 }
566
567 bool isKeywordReference() const {
568 return fObjectType == kKeyword_PdfObjectType && fStr.fBytes == 1 && fStr.fBuffer[0] == 'R';
569 }
570
571 bool isKeyword() const {
572 return fObjectType == kKeyword_PdfObjectType;
573 }
574
edisonn@google.com4ef4bed2013-07-29 22:14:45 +0000575 bool isKeyword(const char* keyword) const {
576 if (!isKeyword()) {
577 return false;
578 }
579
580 if (strlen(keyword) != fStr.fBytes) {
581 return false;
582 }
583
584 if (strncmp(keyword, (const char*)fStr.fBuffer, fStr.fBytes) != 0) {
585 return false;
586 }
587
588 return true;
589 }
590
edisonn@google.com571c70b2013-07-10 17:09:50 +0000591 bool isName() const {
592 return fObjectType == kName_PdfObjectType;
593 }
594
edisonn@google.com78b38b12013-07-15 18:20:58 +0000595 bool isName(const char* name) const {
596 return fObjectType == kName_PdfObjectType && fStr.fBytes == strlen(name) && strncmp((const char*)fStr.fBuffer, name, fStr.fBytes) == 0;
597 }
598
edisonn@google.com571c70b2013-07-10 17:09:50 +0000599 bool isArray() const {
600 return fObjectType == kArray_PdfObjectType;
601 }
602
603 bool isDate() const {
604 return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType;
605 }
606
607 bool isDictionary() const {
608 return fObjectType == kDictionary_PdfObjectType;
609 }
610
611 bool isFunction() const {
612 return false; // NYI
613 }
614
615 bool isRectangle() const {
616 return fObjectType == kArray_PdfObjectType && fArray->count() == 4; // NYI + and elems are numbers
617 }
618
619 // TODO(edisonn): has stream .. or is stream ... TBD
620 bool hasStream() const {
621 return isDictionary() && fStr.fBuffer != NULL;
622 }
623
624 // TODO(edisonn): has stream .. or is stream ... TBD
625 const SkPdfStream* getStream() const {
626 return hasStream() ? (const SkPdfStream*)this : NULL;
627 }
628
629 SkPdfStream* getStream() {
630 return hasStream() ? (SkPdfStream*)this : NULL;
631 }
632
633 bool isAnyString() const {
634 return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType;
635 }
636
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000637 bool isHexString() const {
638 return fObjectType == kHexString_PdfObjectType;
639 }
640
edisonn@google.com571c70b2013-07-10 17:09:50 +0000641 bool isMatrix() const {
642 return fObjectType == kArray_PdfObjectType && fArray->count() == 6; // NYI + and elems are numbers
643 }
644
645 inline int64_t intValue() const {
646 SkASSERT(fObjectType == kInteger_PdfObjectType);
647
648 if (fObjectType != kInteger_PdfObjectType) {
649 // TODO(edisonn): log err
650 return 0;
651 }
652 return fIntegerValue;
653 }
654private:
655 inline double realValue() const {
656 SkASSERT(fObjectType == kReal_PdfObjectType);
657
658 if (fObjectType != kReal_PdfObjectType) {
659 // TODO(edisonn): log err
660 return 0;
661 }
662 return fRealValue;
663 }
664public:
665 inline double numberValue() const {
666 SkASSERT(isNumber());
667
668 if (!isNumber()) {
669 // TODO(edisonn): log err
670 return 0;
671 }
672 return fObjectType == kReal_PdfObjectType ? fRealValue : fIntegerValue;
673 }
674
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000675 inline SkScalar scalarValue() const {
676 SkASSERT(isNumber());
677
678 if (!isNumber()) {
679 // TODO(edisonn): log err
680 return SkIntToScalar(0);
681 }
682 return fObjectType == kReal_PdfObjectType ? SkDoubleToScalar(fRealValue) :
683 SkIntToScalar(fIntegerValue);
684 }
685
edisonn@google.com571c70b2013-07-10 17:09:50 +0000686 int referenceId() const {
687 SkASSERT(fObjectType == kReference_PdfObjectType);
688 return fRef.fId;
689 }
690
691 int referenceGeneration() const {
692 SkASSERT(fObjectType == kReference_PdfObjectType);
693 return fRef.fGen;
694 }
695
696 inline const char* nameValue() const {
697 SkASSERT(fObjectType == kName_PdfObjectType);
698
699 if (fObjectType != kName_PdfObjectType) {
700 // TODO(edisonn): log err
701 return "";
702 }
703 return (const char*)fStr.fBuffer;
704 }
705
706 inline const char* stringValue() const {
707 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType);
708
709 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) {
710 // TODO(edisonn): log err
711 return "";
712 }
713 return (const char*)fStr.fBuffer;
714 }
715
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000716 inline NotOwnedString strRef() {
717 switch (fObjectType) {
718 case kString_PdfObjectType:
719 case kHexString_PdfObjectType:
720 case kKeyword_PdfObjectType:
edisonn@google.com276fed92013-08-01 21:20:47 +0000721 case kName_PdfObjectType:
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000722 return fStr;
723
724 default:
725 // TODO(edisonn): report/warning
726 return NotOwnedString();
727 }
728 }
729
edisonn@google.com571c70b2013-07-10 17:09:50 +0000730 // TODO(edisonn): nameValue2 and stringValue2 are used to make code generation easy,
731 // but it is not a performat way to do it, since it will create an extra copy
732 // remove these functions and make code generated faster
edisonn@google.com063d7072013-08-16 15:05:08 +0000733 inline SkString nameValue2() const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000734 SkASSERT(fObjectType == kName_PdfObjectType);
735
736 if (fObjectType != kName_PdfObjectType) {
737 // TODO(edisonn): log err
edisonn@google.com063d7072013-08-16 15:05:08 +0000738 return SkString();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000739 }
edisonn@google.com063d7072013-08-16 15:05:08 +0000740 return SkString((const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000741 }
742
edisonn@google.com063d7072013-08-16 15:05:08 +0000743 inline SkString stringValue2() const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000744 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType);
745
746 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) {
747 // TODO(edisonn): log err
edisonn@google.com063d7072013-08-16 15:05:08 +0000748 return SkString();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000749 }
edisonn@google.com063d7072013-08-16 15:05:08 +0000750 return SkString((const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000751 }
752
753 inline bool boolValue() const {
754 SkASSERT(fObjectType == kBoolean_PdfObjectType);
755
edisonn@google.comf111a4b2013-07-31 18:22:36 +0000756 if (fObjectType != kBoolean_PdfObjectType) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000757 // TODO(edisonn): log err
758 return false;
759 }
760 return fBooleanValue;
761 }
762
763 SkRect rectangleValue() const {
764 SkASSERT(isRectangle());
765 if (!isRectangle()) {
766 return SkRect::MakeEmpty();
767 }
768
769 double array[4];
770 for (int i = 0; i < 4; i++) {
771 // TODO(edisonn): version where we could resolve references?
edisonn@google.com3aa35552013-08-14 18:26:20 +0000772 const SkPdfNativeObject* elem = objAtAIndex(i);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000773 if (elem == NULL || !elem->isNumber()) {
774 // TODO(edisonn): report error
775 return SkRect::MakeEmpty();
776 }
777 array[i] = elem->numberValue();
778 }
779
780 return SkRect::MakeLTRB(SkDoubleToScalar(array[0]),
781 SkDoubleToScalar(array[1]),
782 SkDoubleToScalar(array[2]),
783 SkDoubleToScalar(array[3]));
784 }
785
786 SkMatrix matrixValue() const {
787 SkASSERT(isMatrix());
788 if (!isMatrix()) {
789 return SkMatrix::I();
790 }
791
792 double array[6];
793 for (int i = 0; i < 6; i++) {
794 // TODO(edisonn): version where we could resolve references?
edisonn@google.com3aa35552013-08-14 18:26:20 +0000795 const SkPdfNativeObject* elem = objAtAIndex(i);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000796 if (elem == NULL || !elem->isNumber()) {
797 // TODO(edisonn): report error
798 return SkMatrix::I();
799 }
800 array[i] = elem->numberValue();
801 }
802
803 return SkMatrixFromPdfMatrix(array);
804 }
805
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000806 bool filterStream();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000807
808
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000809 bool GetFilteredStreamRef(unsigned char const** buffer, size_t* len) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000810 // TODO(edisonn): add params that couls let the last filter in place if it is jpeg or png to fast load images
811 if (!hasStream()) {
812 return false;
813 }
814
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000815 filterStream();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000816
817 if (buffer) {
818 *buffer = fStr.fBuffer;
819 }
820
821 if (len) {
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000822 *len = fStr.fBytes >> 2; // last 2 bits
edisonn@google.com571c70b2013-07-10 17:09:50 +0000823 }
824
825 return true;
826 }
827
828 bool isStreamFiltered() const {
829 return hasStream() && ((fStr.fBytes & 1) == kFilteredStreamBit);
830 }
831
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000832 bool isStreamOwned() const {
833 return hasStream() && ((fStr.fBytes & 2) == kOwnedStreamBit);
834 }
835
836 bool GetUnfilteredStreamRef(unsigned char const** buffer, size_t* len) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000837 if (isStreamFiltered()) {
838 return false;
839 }
840
841 if (!hasStream()) {
842 return false;
843 }
844
845 if (buffer) {
846 *buffer = fStr.fBuffer;
847 }
848
849 if (len) {
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000850 *len = fStr.fBytes >> 2; // remove last 2 bits
edisonn@google.com571c70b2013-07-10 17:09:50 +0000851 }
852
853 return true;
854 }
855
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000856 bool addStream(const unsigned char* buffer, size_t len) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000857 SkASSERT(!hasStream());
858 SkASSERT(isDictionary());
859
860 if (!isDictionary() || hasStream()) {
861 return false;
862 }
863
864 fStr.fBuffer = buffer;
865 fStr.fBytes = (len << 2) + kUnfilteredStreamBit;
866
867 return true;
868 }
869
edisonn@google.com276fed92013-08-01 21:20:47 +0000870 static void appendSpaces(SkString* str, int level) {
edisonn@google.com9a43c182013-08-01 20:06:42 +0000871 for (int i = 0 ; i < level; i++) {
872 str->append(" ");
873 }
874 }
875
edisonn@google.com3aa35552013-08-14 18:26:20 +0000876 static void append(SkString* str, const char* data, size_t len, const char* prefix = "\\x") {
877 for (unsigned int i = 0 ; i < len; i++) {
878 if (data[i] == kNUL_PdfWhiteSpace) {
879 str->append(prefix);
880 str->append("00");
881 } else if (data[i] == kHT_PdfWhiteSpace) {
882 str->append(prefix);
883 str->append("09");
884 } else if (data[i] == kLF_PdfWhiteSpace) {
885 str->append(prefix);
886 str->append("0A");
887 } else if (data[i] == kFF_PdfWhiteSpace) {
888 str->append(prefix);
889 str->append("0C");
890 } else if (data[i] == kCR_PdfWhiteSpace) {
891 str->append(prefix);
892 str->append("0D");
893 } else {
894 str->append(data + i, 1);
895 }
896 }
897 }
898
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000899 SkString toString(int firstRowLevel = 0, int level = 0) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000900 SkString str;
edisonn@google.com9a43c182013-08-01 20:06:42 +0000901 appendSpaces(&str, firstRowLevel);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000902 switch (fObjectType) {
903 case kInvalid_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000904 str.append("__Invalid");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000905 break;
906
907 case kBoolean_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000908 str.appendf("%s", fBooleanValue ? "true" : "false");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000909 break;
910
911 case kInteger_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000912 str.appendf("%i", (int)fIntegerValue);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000913 break;
914
915 case kReal_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000916 str.appendf("%f", fRealValue);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000917 break;
918
919 case kString_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000920 str.append("\"");
edisonn@google.com3aa35552013-08-14 18:26:20 +0000921 append(&str, (const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com9a43c182013-08-01 20:06:42 +0000922 str.append("\"");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000923 break;
924
925 case kHexString_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000926 str.append("<");
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000927 for (unsigned int i = 0 ; i < fStr.fBytes; i++) {
928 str.appendf("%02x", (unsigned int)fStr.fBuffer[i]);
929 }
edisonn@google.com9a43c182013-08-01 20:06:42 +0000930 str.append(">");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000931 break;
932
933 case kName_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000934 str.append("/");
edisonn@google.com3aa35552013-08-14 18:26:20 +0000935 append(&str, (const char*)fStr.fBuffer, fStr.fBytes, "#");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000936 break;
937
938 case kKeyword_PdfObjectType:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000939 append(&str, (const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000940 break;
941
942 case kArray_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000943 str.append("[\n");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000944 for (unsigned int i = 0; i < size(); i++) {
edisonn@google.com9a43c182013-08-01 20:06:42 +0000945 str.append(objAtAIndex(i)->toString(level + 1, level + 1));
946 if (i < size() - 1) {
947 str.append(",");
948 }
949 str.append("\n");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000950 }
edisonn@google.com9a43c182013-08-01 20:06:42 +0000951 appendSpaces(&str, level);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000952 str.append("]");
953 break;
954
edisonn@google.com9a43c182013-08-01 20:06:42 +0000955 case kDictionary_PdfObjectType: {
edisonn@google.com3aa35552013-08-14 18:26:20 +0000956 SkTDict<SkPdfNativeObject*>::Iter iter(*fMap);
957 SkPdfNativeObject* obj = NULL;
edisonn@google.com9a43c182013-08-01 20:06:42 +0000958 const char* key = NULL;
959 str.append("<<\n");
960 while ((key = iter.next(&obj)) != NULL) {
961 appendSpaces(&str, level + 2);
962 str.appendf("/%s %s\n", key, obj->toString(0, level + strlen(key) + 4).c_str());
963 }
964 appendSpaces(&str, level);
965 str.append(">>");
966 if (hasStream()) {
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000967 const unsigned char* stream = NULL;
968 size_t length = 0;
969 if (GetFilteredStreamRef(&stream, &length)) {
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000970 str.append("stream\n");
edisonn@google.com3aa35552013-08-14 18:26:20 +0000971 append(&str, (const char*)stream, length > 256 ? 256 : length);
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000972 str.append("\nendstream");
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000973 } else {
974 str.append("stream STREAM_ERROR endstream");
975 }
edisonn@google.com9a43c182013-08-01 20:06:42 +0000976 }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000977 }
978 break;
979
980 case kNull_PdfObjectType:
981 str = "NULL";
982 break;
983
984 case kReference_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000985 str.appendf("%i %i R", fRef.fId, fRef.fGen);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000986 break;
987
988 case kUndefined_PdfObjectType:
989 str = "Undefined";
990 break;
991
992 default:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000993 str = "Error";
edisonn@google.com571c70b2013-07-10 17:09:50 +0000994 break;
995 }
996
997 return str;
998 }
999
1000private:
edisonn@google.com3aa35552013-08-14 18:26:20 +00001001 static void makeStringCore(const unsigned char* start, SkPdfNativeObject* obj, ObjectType type) {
edisonn@google.com571c70b2013-07-10 17:09:50 +00001002 makeStringCore(start, strlen((const char*)start), obj, type);
1003 }
1004
edisonn@google.com3aa35552013-08-14 18:26:20 +00001005 static void makeStringCore(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj, ObjectType type) {
edisonn@google.com571c70b2013-07-10 17:09:50 +00001006 makeStringCore(start, end - start, obj, type);
1007 }
1008
edisonn@google.com3aa35552013-08-14 18:26:20 +00001009 static void makeStringCore(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj, ObjectType type) {
edisonn@google.com571c70b2013-07-10 17:09:50 +00001010 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
1011
1012 obj->fObjectType = type;
1013 obj->fStr.fBuffer = start;
1014 obj->fStr.fBytes = bytes;
1015 }
1016
edisonn@google.com2ccc3af2013-07-23 17:43:18 +00001017 bool applyFilter(const char* name);
1018 bool applyFlateDecodeFilter();
1019 bool applyDCTDecodeFilter();
edisonn@google.com571c70b2013-07-10 17:09:50 +00001020};
1021
edisonn@google.com3aa35552013-08-14 18:26:20 +00001022class SkPdfStream : public SkPdfNativeObject {};
1023class SkPdfArray : public SkPdfNativeObject {};
1024class SkPdfString : public SkPdfNativeObject {};
1025class SkPdfHexString : public SkPdfNativeObject {};
1026class SkPdfInteger : public SkPdfNativeObject {};
1027class SkPdfReal : public SkPdfNativeObject {};
1028class SkPdfNumber : public SkPdfNativeObject {};
edisonn@google.com571c70b2013-07-10 17:09:50 +00001029
edisonn@google.com3aa35552013-08-14 18:26:20 +00001030class SkPdfName : public SkPdfNativeObject {
1031 SkPdfName() : SkPdfNativeObject() {
1032 SkPdfNativeObject::makeName((const unsigned char*)"", this);
edisonn@google.com78b38b12013-07-15 18:20:58 +00001033 }
1034public:
edisonn@google.com3aa35552013-08-14 18:26:20 +00001035 SkPdfName(char* name) : SkPdfNativeObject() {
edisonn@google.com2ccc3af2013-07-23 17:43:18 +00001036 this->makeName((const unsigned char*)name, this);
edisonn@google.com78b38b12013-07-15 18:20:58 +00001037 }
1038};
1039
edisonn@google.com571c70b2013-07-10 17:09:50 +00001040#endif // EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFOBJECT_H_