blob: 1fa627290fcdab320cc28c9ab907946712164663 [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>
6#include <string>
7#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.com571c70b2013-07-10 17:09:50 +000062 struct Reference {
63 unsigned int fId;
64 unsigned int fGen;
65 };
66
67 // TODO(edisonn): add stream start, stream end, where stream is weither the file
68 // or decoded/filtered pdf stream
69
70 // TODO(edisonn): add warning/report per object
71 // TODO(edisonn): add flag fUsed, to be used once the parsing is complete,
72 // so we could show what parts have been proccessed, ignored, or generated errors
73
74 ObjectType fObjectType;
75
76 union {
77 bool fBooleanValue;
78 int64_t fIntegerValue;
79 // TODO(edisonn): double, float? typedefed
80 double fRealValue;
81 NotOwnedString fStr;
82
83 // 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 +000084 SkTDArray<SkPdfNativeObject*>* fArray;
edisonn@google.com571c70b2013-07-10 17:09:50 +000085 Reference fRef;
86 };
edisonn@google.com3aa35552013-08-14 18:26:20 +000087 SkTDict<SkPdfNativeObject*>* fMap;
edisonn@google.comb0145ce2013-08-05 16:23:23 +000088
89 // TODO(edisonn): rename data with cache
edisonn@google.com571c70b2013-07-10 17:09:50 +000090 void* fData;
edisonn@google.comb0145ce2013-08-05 16:23:23 +000091 DataType fDataType;
edisonn@google.com571c70b2013-07-10 17:09:50 +000092
93
94public:
95
edisonn@google.com3aa35552013-08-14 18:26:20 +000096 SkPdfNativeObject() : fObjectType(kInvalid_PdfObjectType), fMap(NULL), fData(NULL), fDataType(kEmpty_Data) {}
edisonn@google.com571c70b2013-07-10 17:09:50 +000097
edisonn@google.comb0145ce2013-08-05 16:23:23 +000098
99 inline bool hasData(DataType type) {
100 return type == fDataType;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000101 }
102
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000103 inline void* data(DataType type) {
104 return type == fDataType ? fData : NULL;
105 }
106
107 inline void setData(void* data, DataType type) {
108 releaseData();
109 fDataType = type;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000110 fData = data;
111 }
112
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000113 void releaseData();
114
edisonn@google.com3aa35552013-08-14 18:26:20 +0000115// ~SkPdfNativeObject() {
edisonn@google.com222382b2013-07-10 22:33:10 +0000116// //reset(); must be called manually!
117// }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000118
119 void reset() {
120 switch (fObjectType) {
121 case kArray_PdfObjectType:
122 delete fArray;
123 break;
124
125 case kDictionary_PdfObjectType:
126 delete fMap;
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000127 if (isStreamOwned()) {
128 delete[] fStr.fBuffer;
129 fStr.fBuffer = NULL;
130 fStr.fBytes = 0;
131 }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000132 break;
133
134 default:
135 break;
136 }
137 fObjectType = kInvalid_PdfObjectType;
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000138 releaseData();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000139 }
140
141 ObjectType type() { return fObjectType; }
142
143 const char* c_str() const {
144 switch (fObjectType) {
145 case kString_PdfObjectType:
146 case kHexString_PdfObjectType:
147 case kKeyword_PdfObjectType:
edisonn@google.com276fed92013-08-01 21:20:47 +0000148 case kName_PdfObjectType:
edisonn@google.com571c70b2013-07-10 17:09:50 +0000149 return (const char*)fStr.fBuffer;
150
151 default:
152 // TODO(edisonn): report/warning
153 return NULL;
154 }
155 }
156
edisonn@google.come878e722013-07-29 19:10:58 +0000157 size_t lenstr() const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000158 switch (fObjectType) {
159 case kString_PdfObjectType:
160 case kHexString_PdfObjectType:
161 case kKeyword_PdfObjectType:
edisonn@google.com276fed92013-08-01 21:20:47 +0000162 case kName_PdfObjectType:
edisonn@google.com571c70b2013-07-10 17:09:50 +0000163 return fStr.fBytes;
164
165 default:
166 // TODO(edisonn): report/warning
167 return 0;
168 }
169 }
170
171
172 // TODO(edisonn): NYI
173 SkPdfDate& dateValue() const {
174 static SkPdfDate nyi;
175 return nyi;
176 }
177
178 // TODO(edisonn): NYI
179 SkPdfFunction& functionValue() const {
180 static SkPdfFunction nyi;
181 return nyi;
182 }
183
184 // TODO(edisonn): NYI
185 SkPdfFileSpec& fileSpecValue() const {
186 static SkPdfFileSpec nyi;
187 return nyi;
188 }
189
190 // TODO(edisonn): NYI
191 SkPdfTree& treeValue() const {
192 static SkPdfTree nyi;
193 return nyi;
194 }
195
edisonn@google.com3aa35552013-08-14 18:26:20 +0000196 static void makeBoolean(bool value, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000197 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
198
199 obj->fObjectType = kBoolean_PdfObjectType;
200 obj->fBooleanValue = value;
201 }
202
edisonn@google.com3aa35552013-08-14 18:26:20 +0000203 static SkPdfNativeObject makeBoolean(bool value) {
204 SkPdfNativeObject obj;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000205 obj.fObjectType = kBoolean_PdfObjectType;
206 obj.fBooleanValue = value;
207 return obj;
208 }
209
edisonn@google.com3aa35552013-08-14 18:26:20 +0000210 static void makeInteger(int64_t value, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000211 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
212
213 obj->fObjectType = kInteger_PdfObjectType;
214 obj->fIntegerValue = value;
215 }
216
edisonn@google.com3aa35552013-08-14 18:26:20 +0000217 static void makeReal(double value, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000218 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
219
220 obj->fObjectType = kReal_PdfObjectType;
221 obj->fRealValue = value;
222 }
223
edisonn@google.com3aa35552013-08-14 18:26:20 +0000224 static void makeNull(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000225 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
226
227 obj->fObjectType = kNull_PdfObjectType;
228 }
229
edisonn@google.com3aa35552013-08-14 18:26:20 +0000230 static SkPdfNativeObject makeNull() {
231 SkPdfNativeObject obj;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000232 obj.fObjectType = kNull_PdfObjectType;
233 return obj;
234 }
235
edisonn@google.com3aa35552013-08-14 18:26:20 +0000236 static SkPdfNativeObject kNull;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000237
edisonn@google.com3aa35552013-08-14 18:26:20 +0000238 static void makeNumeric(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000239 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
240
241 // TODO(edisonn): NYI properly
242 // if has dot (impl), or exceeds max int, is real, otherwise is int
243 bool isInt = true;
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000244 for (const unsigned char* current = start; current < end; current++) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000245 if (*current == '.') {
246 isInt = false;
247 break;
248 }
249 // TODO(edisonn): report parse issue with numbers like "24asdasd123"
250 }
251 if (isInt) {
252 makeInteger(atol((const char*)start), obj);
253 } else {
254 makeReal(atof((const char*)start), obj);
255 }
256 }
257
edisonn@google.com3aa35552013-08-14 18:26:20 +0000258 static void makeReference(unsigned int id, unsigned int gen, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000259 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
260
261 obj->fObjectType = kReference_PdfObjectType;
262 obj->fRef.fId = id;
263 obj->fRef.fGen = gen;
264 }
265
266
edisonn@google.com3aa35552013-08-14 18:26:20 +0000267 static void makeString(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000268 makeStringCore(start, strlen((const char*)start), obj, kString_PdfObjectType);
269 }
270
edisonn@google.com3aa35552013-08-14 18:26:20 +0000271 static void makeString(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000272 makeStringCore(start, end - start, obj, kString_PdfObjectType);
273 }
274
edisonn@google.com3aa35552013-08-14 18:26:20 +0000275 static void makeString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000276 makeStringCore(start, bytes, obj, kString_PdfObjectType);
277 }
278
279
edisonn@google.com3aa35552013-08-14 18:26:20 +0000280 static void makeHexString(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000281 makeStringCore(start, strlen((const char*)start), obj, kHexString_PdfObjectType);
282 }
283
edisonn@google.com3aa35552013-08-14 18:26:20 +0000284 static void makeHexString(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000285 makeStringCore(start, end - start, obj, kHexString_PdfObjectType);
286 }
287
edisonn@google.com3aa35552013-08-14 18:26:20 +0000288 static void makeHexString(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000289 makeStringCore(start, bytes, obj, kHexString_PdfObjectType);
290 }
291
292
edisonn@google.com3aa35552013-08-14 18:26:20 +0000293 static void makeName(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000294 makeStringCore(start, strlen((const char*)start), obj, kName_PdfObjectType);
295 }
296
edisonn@google.com3aa35552013-08-14 18:26:20 +0000297 static void makeName(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000298 makeStringCore(start, end - start, obj, kName_PdfObjectType);
299 }
300
edisonn@google.com3aa35552013-08-14 18:26:20 +0000301 static void makeName(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000302 makeStringCore(start, bytes, obj, kName_PdfObjectType);
303 }
304
305
edisonn@google.com3aa35552013-08-14 18:26:20 +0000306 static void makeKeyword(const unsigned char* start, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000307 makeStringCore(start, strlen((const char*)start), obj, kKeyword_PdfObjectType);
308 }
309
edisonn@google.com3aa35552013-08-14 18:26:20 +0000310 static void makeKeyword(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000311 makeStringCore(start, end - start, obj, kKeyword_PdfObjectType);
312 }
313
edisonn@google.com3aa35552013-08-14 18:26:20 +0000314 static void makeKeyword(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000315 makeStringCore(start, bytes, obj, kKeyword_PdfObjectType);
316 }
317
318
319
320 // TODO(edisonn): make the functions to return SkPdfArray, move these functions in SkPdfArray
edisonn@google.com3aa35552013-08-14 18:26:20 +0000321 static void makeEmptyArray(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000322 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
323
324 obj->fObjectType = kArray_PdfObjectType;
edisonn@google.com3aa35552013-08-14 18:26:20 +0000325 obj->fArray = new SkTDArray<SkPdfNativeObject*>();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000326 // return (SkPdfArray*)obj;
327 }
328
edisonn@google.com3aa35552013-08-14 18:26:20 +0000329 bool appendInArray(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000330 SkASSERT(fObjectType == kArray_PdfObjectType);
331 if (fObjectType != kArray_PdfObjectType) {
332 // TODO(edisonn): report err
333 return false;
334 }
335
336 fArray->push(obj);
337 return true;
338 }
339
340 size_t size() const {
341 SkASSERT(fObjectType == kArray_PdfObjectType);
342
343 return fArray->count();
344 }
345
edisonn@google.com3aa35552013-08-14 18:26:20 +0000346 SkPdfNativeObject* objAtAIndex(int i) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000347 SkASSERT(fObjectType == kArray_PdfObjectType);
348
349 return (*fArray)[i];
350 }
351
edisonn@google.com3aa35552013-08-14 18:26:20 +0000352 SkPdfNativeObject* removeLastInArray() {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000353 SkASSERT(fObjectType == kArray_PdfObjectType);
354
edisonn@google.com3aa35552013-08-14 18:26:20 +0000355 SkPdfNativeObject* ret = NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000356 fArray->pop(&ret);
357
358 return ret;
359 }
360
361
edisonn@google.com3aa35552013-08-14 18:26:20 +0000362 const SkPdfNativeObject* objAtAIndex(int i) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000363 SkASSERT(fObjectType == kArray_PdfObjectType);
364
365 return (*fArray)[i];
366 }
367
edisonn@google.com3aa35552013-08-14 18:26:20 +0000368 SkPdfNativeObject* operator[](int i) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000369 SkASSERT(fObjectType == kArray_PdfObjectType);
370
371 return (*fArray)[i];
372 }
373
edisonn@google.com3aa35552013-08-14 18:26:20 +0000374 const SkPdfNativeObject* operator[](int i) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000375 SkASSERT(fObjectType == kArray_PdfObjectType);
376
377 return (*fArray)[i];
378 }
379
380
381 // TODO(edisonn): make the functions to return SkPdfDictionary, move these functions in SkPdfDictionary
edisonn@google.com3aa35552013-08-14 18:26:20 +0000382 static void makeEmptyDictionary(SkPdfNativeObject* obj) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000383 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
384
385 obj->fObjectType = kDictionary_PdfObjectType;
edisonn@google.com3aa35552013-08-14 18:26:20 +0000386 obj->fMap = new SkTDict<SkPdfNativeObject*>(1);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000387 obj->fStr.fBuffer = NULL;
388 obj->fStr.fBytes = 0;
389 }
390
391 // TODO(edisonn): get all the possible names from spec, and compute a hash function
392 // that would create no overlaps in the same dictionary
393 // or build a tree of chars that when followed goes to a unique id/index/hash
394 // TODO(edisonn): generate constants like kDictFoo, kNameDict_name
395 // which will be used in code
396 // add function SkPdfFastNameKey key(const char* key);
397 // TODO(edisonn): setting the same key twike, will make the value undefined!
edisonn@google.com3aa35552013-08-14 18:26:20 +0000398 bool set(const SkPdfNativeObject* key, SkPdfNativeObject* value) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000399 SkASSERT(fObjectType == kDictionary_PdfObjectType);
400 SkASSERT(key->fObjectType == kName_PdfObjectType);
401
402 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
403 // TODO(edisonn): report err
404 return false;
405 }
406
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000407 //// we rewrite all delimiters and white spaces with '\0', so we expect the end of name to be '\0'
408 //SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
edisonn@google.com571c70b2013-07-10 17:09:50 +0000409
edisonn@google.comd761e322013-07-22 17:29:43 +0000410 return set(key->fStr.fBuffer, key->fStr.fBytes, value);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000411 }
412
edisonn@google.com3aa35552013-08-14 18:26:20 +0000413 bool set(const char* key, SkPdfNativeObject* value) {
edisonn@google.comd761e322013-07-22 17:29:43 +0000414 return set((const unsigned char*)key, strlen(key), value);
415 }
416
edisonn@google.com3aa35552013-08-14 18:26:20 +0000417 bool set(const unsigned char* key, size_t len, SkPdfNativeObject* value) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000418 SkASSERT(fObjectType == kDictionary_PdfObjectType);
419
420 if (fObjectType != kDictionary_PdfObjectType) {
421 // TODO(edisonn): report err
422 return false;
423 }
424
edisonn@google.comd761e322013-07-22 17:29:43 +0000425 return fMap->set((const char*)key, len, value);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000426 }
427
edisonn@google.com3aa35552013-08-14 18:26:20 +0000428 SkPdfNativeObject* get(const SkPdfNativeObject* key) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000429 SkASSERT(fObjectType == kDictionary_PdfObjectType);
430 SkASSERT(key->fObjectType == kName_PdfObjectType);
431
432 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
433 // TODO(edisonn): report err
edisonn@google.com3fc48262013-07-22 15:29:55 +0000434 return NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000435 }
436
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000437 //SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
edisonn@google.com571c70b2013-07-10 17:09:50 +0000438
edisonn@google.comd761e322013-07-22 17:29:43 +0000439 return get(key->fStr.fBuffer, key->fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000440 }
441
edisonn@google.com3aa35552013-08-14 18:26:20 +0000442 SkPdfNativeObject* get(const char* key) {
edisonn@google.comd761e322013-07-22 17:29:43 +0000443 return get((const unsigned char*)key, strlen(key));
444 }
445
edisonn@google.com3aa35552013-08-14 18:26:20 +0000446 SkPdfNativeObject* get(const unsigned char* key, size_t len) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000447 SkASSERT(fObjectType == kDictionary_PdfObjectType);
448 SkASSERT(key);
449 if (fObjectType != kDictionary_PdfObjectType) {
450 // TODO(edisonn): report err
451 return NULL;
452 }
edisonn@google.com3aa35552013-08-14 18:26:20 +0000453 SkPdfNativeObject* ret = NULL;
edisonn@google.comd761e322013-07-22 17:29:43 +0000454 fMap->find((const char*)key, len, &ret);
edisonn@google.com9a43c182013-08-01 20:06:42 +0000455
456#ifdef PDF_TRACE
457 SkString _key;
458 _key.append((const char*)key, len);
459 printf("\nget(/%s) = %s\n", _key.c_str(), ret ? ret->toString(0, len + 9).c_str() : "_NOT_FOUND");
460#endif
461
edisonn@google.com571c70b2013-07-10 17:09:50 +0000462 return ret;
463 }
464
edisonn@google.com3aa35552013-08-14 18:26:20 +0000465 const SkPdfNativeObject* get(const SkPdfNativeObject* key) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000466 SkASSERT(fObjectType == kDictionary_PdfObjectType);
467 SkASSERT(key->fObjectType == kName_PdfObjectType);
468
469 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionary_PdfObjectType) {
470 // TODO(edisonn): report err
edisonn@google.com3fc48262013-07-22 15:29:55 +0000471 return NULL;
edisonn@google.com571c70b2013-07-10 17:09:50 +0000472 }
473
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000474 //SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
edisonn@google.com571c70b2013-07-10 17:09:50 +0000475
edisonn@google.comd761e322013-07-22 17:29:43 +0000476 return get(key->fStr.fBuffer, key->fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000477 }
478
edisonn@google.com3aa35552013-08-14 18:26:20 +0000479 const SkPdfNativeObject* get(const char* key) const {
edisonn@google.comd761e322013-07-22 17:29:43 +0000480 return get((const unsigned char*)key, strlen(key));
481 }
482
edisonn@google.com3aa35552013-08-14 18:26:20 +0000483 const SkPdfNativeObject* get(const unsigned char* key, size_t len) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000484 SkASSERT(fObjectType == kDictionary_PdfObjectType);
485 SkASSERT(key);
486 if (fObjectType != kDictionary_PdfObjectType) {
487 // TODO(edisonn): report err
488 return NULL;
489 }
edisonn@google.com3aa35552013-08-14 18:26:20 +0000490 SkPdfNativeObject* ret = NULL;
edisonn@google.comd761e322013-07-22 17:29:43 +0000491 fMap->find((const char*)key, len, &ret);
edisonn@google.com9a43c182013-08-01 20:06:42 +0000492
493#ifdef PDF_TRACE
494 SkString _key;
495 _key.append((const char*)key, len);
496 printf("\nget(/%s) = %s\n", _key.c_str(), ret ? ret->toString(0, len + 9).c_str() : "_NOT_FOUND");
497#endif
498
edisonn@google.com571c70b2013-07-10 17:09:50 +0000499 return ret;
500 }
501
edisonn@google.com3aa35552013-08-14 18:26:20 +0000502 const SkPdfNativeObject* get(const char* key, const char* abr) const {
503 const SkPdfNativeObject* ret = get(key);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000504 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL
505 // make this distiontion in generator, and remove "" from condition
506 if (ret != NULL || abr == NULL || *abr == '\0') {
507 return ret;
508 }
509 return get(abr);
510 }
511
edisonn@google.com3aa35552013-08-14 18:26:20 +0000512 SkPdfNativeObject* get(const char* key, const char* abr) {
513 SkPdfNativeObject* ret = get(key);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000514 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL
515 // make this distiontion in generator, and remove "" from condition
516 if (ret != NULL || abr == NULL || *abr == '\0') {
517 return ret;
518 }
519 return get(abr);
520 }
521
522 SkPdfDictionary* asDictionary() {
523 SkASSERT(isDictionary());
524 if (!isDictionary()) {
525 return NULL;
526 }
527 return (SkPdfDictionary*) this;
528 }
529
530 const SkPdfDictionary* asDictionary() const {
531 SkASSERT(isDictionary());
532 if (!isDictionary()) {
533 return NULL;
534 }
535 return (SkPdfDictionary*) this;
536 }
537
538
539 bool isReference() const {
540 return fObjectType == kReference_PdfObjectType;
541 }
542
543 bool isBoolean() const {
544 return fObjectType == kBoolean_PdfObjectType;
545 }
546
547 bool isInteger() const {
548 return fObjectType == kInteger_PdfObjectType;
549 }
550private:
551 bool isReal() const {
552 return fObjectType == kReal_PdfObjectType;
553 }
554public:
555 bool isNumber() const {
556 return fObjectType == kInteger_PdfObjectType || fObjectType == kReal_PdfObjectType;
557 }
558
559 bool isKeywordReference() const {
560 return fObjectType == kKeyword_PdfObjectType && fStr.fBytes == 1 && fStr.fBuffer[0] == 'R';
561 }
562
563 bool isKeyword() const {
564 return fObjectType == kKeyword_PdfObjectType;
565 }
566
edisonn@google.com4ef4bed2013-07-29 22:14:45 +0000567 bool isKeyword(const char* keyword) const {
568 if (!isKeyword()) {
569 return false;
570 }
571
572 if (strlen(keyword) != fStr.fBytes) {
573 return false;
574 }
575
576 if (strncmp(keyword, (const char*)fStr.fBuffer, fStr.fBytes) != 0) {
577 return false;
578 }
579
580 return true;
581 }
582
edisonn@google.com571c70b2013-07-10 17:09:50 +0000583 bool isName() const {
584 return fObjectType == kName_PdfObjectType;
585 }
586
edisonn@google.com78b38b12013-07-15 18:20:58 +0000587 bool isName(const char* name) const {
588 return fObjectType == kName_PdfObjectType && fStr.fBytes == strlen(name) && strncmp((const char*)fStr.fBuffer, name, fStr.fBytes) == 0;
589 }
590
edisonn@google.com571c70b2013-07-10 17:09:50 +0000591 bool isArray() const {
592 return fObjectType == kArray_PdfObjectType;
593 }
594
595 bool isDate() const {
596 return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType;
597 }
598
599 bool isDictionary() const {
600 return fObjectType == kDictionary_PdfObjectType;
601 }
602
603 bool isFunction() const {
604 return false; // NYI
605 }
606
607 bool isRectangle() const {
608 return fObjectType == kArray_PdfObjectType && fArray->count() == 4; // NYI + and elems are numbers
609 }
610
611 // TODO(edisonn): has stream .. or is stream ... TBD
612 bool hasStream() const {
613 return isDictionary() && fStr.fBuffer != NULL;
614 }
615
616 // TODO(edisonn): has stream .. or is stream ... TBD
617 const SkPdfStream* getStream() const {
618 return hasStream() ? (const SkPdfStream*)this : NULL;
619 }
620
621 SkPdfStream* getStream() {
622 return hasStream() ? (SkPdfStream*)this : NULL;
623 }
624
625 bool isAnyString() const {
626 return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType;
627 }
628
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000629 bool isHexString() const {
630 return fObjectType == kHexString_PdfObjectType;
631 }
632
edisonn@google.com571c70b2013-07-10 17:09:50 +0000633 bool isMatrix() const {
634 return fObjectType == kArray_PdfObjectType && fArray->count() == 6; // NYI + and elems are numbers
635 }
636
637 inline int64_t intValue() const {
638 SkASSERT(fObjectType == kInteger_PdfObjectType);
639
640 if (fObjectType != kInteger_PdfObjectType) {
641 // TODO(edisonn): log err
642 return 0;
643 }
644 return fIntegerValue;
645 }
646private:
647 inline double realValue() const {
648 SkASSERT(fObjectType == kReal_PdfObjectType);
649
650 if (fObjectType != kReal_PdfObjectType) {
651 // TODO(edisonn): log err
652 return 0;
653 }
654 return fRealValue;
655 }
656public:
657 inline double numberValue() const {
658 SkASSERT(isNumber());
659
660 if (!isNumber()) {
661 // TODO(edisonn): log err
662 return 0;
663 }
664 return fObjectType == kReal_PdfObjectType ? fRealValue : fIntegerValue;
665 }
666
edisonn@google.coma0cefa12013-07-28 18:34:14 +0000667 inline SkScalar scalarValue() const {
668 SkASSERT(isNumber());
669
670 if (!isNumber()) {
671 // TODO(edisonn): log err
672 return SkIntToScalar(0);
673 }
674 return fObjectType == kReal_PdfObjectType ? SkDoubleToScalar(fRealValue) :
675 SkIntToScalar(fIntegerValue);
676 }
677
edisonn@google.com571c70b2013-07-10 17:09:50 +0000678 int referenceId() const {
679 SkASSERT(fObjectType == kReference_PdfObjectType);
680 return fRef.fId;
681 }
682
683 int referenceGeneration() const {
684 SkASSERT(fObjectType == kReference_PdfObjectType);
685 return fRef.fGen;
686 }
687
688 inline const char* nameValue() const {
689 SkASSERT(fObjectType == kName_PdfObjectType);
690
691 if (fObjectType != kName_PdfObjectType) {
692 // TODO(edisonn): log err
693 return "";
694 }
695 return (const char*)fStr.fBuffer;
696 }
697
698 inline const char* stringValue() const {
699 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType);
700
701 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) {
702 // TODO(edisonn): log err
703 return "";
704 }
705 return (const char*)fStr.fBuffer;
706 }
707
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000708 inline NotOwnedString strRef() {
709 switch (fObjectType) {
710 case kString_PdfObjectType:
711 case kHexString_PdfObjectType:
712 case kKeyword_PdfObjectType:
edisonn@google.com276fed92013-08-01 21:20:47 +0000713 case kName_PdfObjectType:
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000714 return fStr;
715
716 default:
717 // TODO(edisonn): report/warning
718 return NotOwnedString();
719 }
720 }
721
edisonn@google.com571c70b2013-07-10 17:09:50 +0000722 // TODO(edisonn): nameValue2 and stringValue2 are used to make code generation easy,
723 // but it is not a performat way to do it, since it will create an extra copy
724 // remove these functions and make code generated faster
725 inline std::string nameValue2() const {
726 SkASSERT(fObjectType == kName_PdfObjectType);
727
728 if (fObjectType != kName_PdfObjectType) {
729 // TODO(edisonn): log err
730 return "";
731 }
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000732 return std::string((const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000733 }
734
735 inline std::string stringValue2() const {
736 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType);
737
738 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_PdfObjectType) {
739 // TODO(edisonn): log err
740 return "";
741 }
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000742 return std::string((const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000743 }
744
745 inline bool boolValue() const {
746 SkASSERT(fObjectType == kBoolean_PdfObjectType);
747
edisonn@google.comf111a4b2013-07-31 18:22:36 +0000748 if (fObjectType != kBoolean_PdfObjectType) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000749 // TODO(edisonn): log err
750 return false;
751 }
752 return fBooleanValue;
753 }
754
755 SkRect rectangleValue() const {
756 SkASSERT(isRectangle());
757 if (!isRectangle()) {
758 return SkRect::MakeEmpty();
759 }
760
761 double array[4];
762 for (int i = 0; i < 4; i++) {
763 // TODO(edisonn): version where we could resolve references?
edisonn@google.com3aa35552013-08-14 18:26:20 +0000764 const SkPdfNativeObject* elem = objAtAIndex(i);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000765 if (elem == NULL || !elem->isNumber()) {
766 // TODO(edisonn): report error
767 return SkRect::MakeEmpty();
768 }
769 array[i] = elem->numberValue();
770 }
771
772 return SkRect::MakeLTRB(SkDoubleToScalar(array[0]),
773 SkDoubleToScalar(array[1]),
774 SkDoubleToScalar(array[2]),
775 SkDoubleToScalar(array[3]));
776 }
777
778 SkMatrix matrixValue() const {
779 SkASSERT(isMatrix());
780 if (!isMatrix()) {
781 return SkMatrix::I();
782 }
783
784 double array[6];
785 for (int i = 0; i < 6; i++) {
786 // TODO(edisonn): version where we could resolve references?
edisonn@google.com3aa35552013-08-14 18:26:20 +0000787 const SkPdfNativeObject* elem = objAtAIndex(i);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000788 if (elem == NULL || !elem->isNumber()) {
789 // TODO(edisonn): report error
790 return SkMatrix::I();
791 }
792 array[i] = elem->numberValue();
793 }
794
795 return SkMatrixFromPdfMatrix(array);
796 }
797
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000798 bool filterStream();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000799
800
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000801 bool GetFilteredStreamRef(unsigned char const** buffer, size_t* len) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000802 // TODO(edisonn): add params that couls let the last filter in place if it is jpeg or png to fast load images
803 if (!hasStream()) {
804 return false;
805 }
806
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000807 filterStream();
edisonn@google.com571c70b2013-07-10 17:09:50 +0000808
809 if (buffer) {
810 *buffer = fStr.fBuffer;
811 }
812
813 if (len) {
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000814 *len = fStr.fBytes >> 2; // last 2 bits
edisonn@google.com571c70b2013-07-10 17:09:50 +0000815 }
816
817 return true;
818 }
819
820 bool isStreamFiltered() const {
821 return hasStream() && ((fStr.fBytes & 1) == kFilteredStreamBit);
822 }
823
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000824 bool isStreamOwned() const {
825 return hasStream() && ((fStr.fBytes & 2) == kOwnedStreamBit);
826 }
827
828 bool GetUnfilteredStreamRef(unsigned char const** buffer, size_t* len) const {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000829 if (isStreamFiltered()) {
830 return false;
831 }
832
833 if (!hasStream()) {
834 return false;
835 }
836
837 if (buffer) {
838 *buffer = fStr.fBuffer;
839 }
840
841 if (len) {
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000842 *len = fStr.fBytes >> 2; // remove last 2 bits
edisonn@google.com571c70b2013-07-10 17:09:50 +0000843 }
844
845 return true;
846 }
847
edisonn@google.com2ccc3af2013-07-23 17:43:18 +0000848 bool addStream(const unsigned char* buffer, size_t len) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000849 SkASSERT(!hasStream());
850 SkASSERT(isDictionary());
851
852 if (!isDictionary() || hasStream()) {
853 return false;
854 }
855
856 fStr.fBuffer = buffer;
857 fStr.fBytes = (len << 2) + kUnfilteredStreamBit;
858
859 return true;
860 }
861
edisonn@google.com276fed92013-08-01 21:20:47 +0000862 static void appendSpaces(SkString* str, int level) {
edisonn@google.com9a43c182013-08-01 20:06:42 +0000863 for (int i = 0 ; i < level; i++) {
864 str->append(" ");
865 }
866 }
867
edisonn@google.com3aa35552013-08-14 18:26:20 +0000868 static void append(SkString* str, const char* data, size_t len, const char* prefix = "\\x") {
869 for (unsigned int i = 0 ; i < len; i++) {
870 if (data[i] == kNUL_PdfWhiteSpace) {
871 str->append(prefix);
872 str->append("00");
873 } else if (data[i] == kHT_PdfWhiteSpace) {
874 str->append(prefix);
875 str->append("09");
876 } else if (data[i] == kLF_PdfWhiteSpace) {
877 str->append(prefix);
878 str->append("0A");
879 } else if (data[i] == kFF_PdfWhiteSpace) {
880 str->append(prefix);
881 str->append("0C");
882 } else if (data[i] == kCR_PdfWhiteSpace) {
883 str->append(prefix);
884 str->append("0D");
885 } else {
886 str->append(data + i, 1);
887 }
888 }
889 }
890
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000891 SkString toString(int firstRowLevel = 0, int level = 0) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000892 SkString str;
edisonn@google.com9a43c182013-08-01 20:06:42 +0000893 appendSpaces(&str, firstRowLevel);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000894 switch (fObjectType) {
895 case kInvalid_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000896 str.append("__Invalid");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000897 break;
898
899 case kBoolean_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000900 str.appendf("%s", fBooleanValue ? "true" : "false");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000901 break;
902
903 case kInteger_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000904 str.appendf("%i", (int)fIntegerValue);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000905 break;
906
907 case kReal_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000908 str.appendf("%f", fRealValue);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000909 break;
910
911 case kString_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000912 str.append("\"");
edisonn@google.com3aa35552013-08-14 18:26:20 +0000913 append(&str, (const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com9a43c182013-08-01 20:06:42 +0000914 str.append("\"");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000915 break;
916
917 case kHexString_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000918 str.append("<");
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000919 for (unsigned int i = 0 ; i < fStr.fBytes; i++) {
920 str.appendf("%02x", (unsigned int)fStr.fBuffer[i]);
921 }
edisonn@google.com9a43c182013-08-01 20:06:42 +0000922 str.append(">");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000923 break;
924
925 case kName_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000926 str.append("/");
edisonn@google.com3aa35552013-08-14 18:26:20 +0000927 append(&str, (const char*)fStr.fBuffer, fStr.fBytes, "#");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000928 break;
929
930 case kKeyword_PdfObjectType:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000931 append(&str, (const char*)fStr.fBuffer, fStr.fBytes);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000932 break;
933
934 case kArray_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000935 str.append("[\n");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000936 for (unsigned int i = 0; i < size(); i++) {
edisonn@google.com9a43c182013-08-01 20:06:42 +0000937 str.append(objAtAIndex(i)->toString(level + 1, level + 1));
938 if (i < size() - 1) {
939 str.append(",");
940 }
941 str.append("\n");
edisonn@google.com571c70b2013-07-10 17:09:50 +0000942 }
edisonn@google.com9a43c182013-08-01 20:06:42 +0000943 appendSpaces(&str, level);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000944 str.append("]");
945 break;
946
edisonn@google.com9a43c182013-08-01 20:06:42 +0000947 case kDictionary_PdfObjectType: {
edisonn@google.com3aa35552013-08-14 18:26:20 +0000948 SkTDict<SkPdfNativeObject*>::Iter iter(*fMap);
949 SkPdfNativeObject* obj = NULL;
edisonn@google.com9a43c182013-08-01 20:06:42 +0000950 const char* key = NULL;
951 str.append("<<\n");
952 while ((key = iter.next(&obj)) != NULL) {
953 appendSpaces(&str, level + 2);
954 str.appendf("/%s %s\n", key, obj->toString(0, level + strlen(key) + 4).c_str());
955 }
956 appendSpaces(&str, level);
957 str.append(">>");
958 if (hasStream()) {
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000959 const unsigned char* stream = NULL;
960 size_t length = 0;
961 if (GetFilteredStreamRef(&stream, &length)) {
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000962 str.append("stream\n");
edisonn@google.com3aa35552013-08-14 18:26:20 +0000963 append(&str, (const char*)stream, length > 256 ? 256 : length);
edisonn@google.comb0145ce2013-08-05 16:23:23 +0000964 str.append("\nendstream");
edisonn@google.come2e01ff2013-08-02 20:24:48 +0000965 } else {
966 str.append("stream STREAM_ERROR endstream");
967 }
edisonn@google.com9a43c182013-08-01 20:06:42 +0000968 }
edisonn@google.com571c70b2013-07-10 17:09:50 +0000969 }
970 break;
971
972 case kNull_PdfObjectType:
973 str = "NULL";
974 break;
975
976 case kReference_PdfObjectType:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000977 str.appendf("%i %i R", fRef.fId, fRef.fGen);
edisonn@google.com571c70b2013-07-10 17:09:50 +0000978 break;
979
980 case kUndefined_PdfObjectType:
981 str = "Undefined";
982 break;
983
984 default:
edisonn@google.com9a43c182013-08-01 20:06:42 +0000985 str = "Error";
edisonn@google.com571c70b2013-07-10 17:09:50 +0000986 break;
987 }
988
989 return str;
990 }
991
992private:
edisonn@google.com3aa35552013-08-14 18:26:20 +0000993 static void makeStringCore(const unsigned char* start, SkPdfNativeObject* obj, ObjectType type) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000994 makeStringCore(start, strlen((const char*)start), obj, type);
995 }
996
edisonn@google.com3aa35552013-08-14 18:26:20 +0000997 static void makeStringCore(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* obj, ObjectType type) {
edisonn@google.com571c70b2013-07-10 17:09:50 +0000998 makeStringCore(start, end - start, obj, type);
999 }
1000
edisonn@google.com3aa35552013-08-14 18:26:20 +00001001 static void makeStringCore(const unsigned char* start, size_t bytes, SkPdfNativeObject* obj, ObjectType type) {
edisonn@google.com571c70b2013-07-10 17:09:50 +00001002 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
1003
1004 obj->fObjectType = type;
1005 obj->fStr.fBuffer = start;
1006 obj->fStr.fBytes = bytes;
1007 }
1008
edisonn@google.com2ccc3af2013-07-23 17:43:18 +00001009 bool applyFilter(const char* name);
1010 bool applyFlateDecodeFilter();
1011 bool applyDCTDecodeFilter();
edisonn@google.com571c70b2013-07-10 17:09:50 +00001012};
1013
edisonn@google.com3aa35552013-08-14 18:26:20 +00001014class SkPdfStream : public SkPdfNativeObject {};
1015class SkPdfArray : public SkPdfNativeObject {};
1016class SkPdfString : public SkPdfNativeObject {};
1017class SkPdfHexString : public SkPdfNativeObject {};
1018class SkPdfInteger : public SkPdfNativeObject {};
1019class SkPdfReal : public SkPdfNativeObject {};
1020class SkPdfNumber : public SkPdfNativeObject {};
edisonn@google.com571c70b2013-07-10 17:09:50 +00001021
edisonn@google.com3aa35552013-08-14 18:26:20 +00001022class SkPdfName : public SkPdfNativeObject {
1023 SkPdfName() : SkPdfNativeObject() {
1024 SkPdfNativeObject::makeName((const unsigned char*)"", this);
edisonn@google.com78b38b12013-07-15 18:20:58 +00001025 }
1026public:
edisonn@google.com3aa35552013-08-14 18:26:20 +00001027 SkPdfName(char* name) : SkPdfNativeObject() {
edisonn@google.com2ccc3af2013-07-23 17:43:18 +00001028 this->makeName((const unsigned char*)name, this);
edisonn@google.com78b38b12013-07-15 18:20:58 +00001029 }
1030};
1031
edisonn@google.com571c70b2013-07-10 17:09:50 +00001032#endif // EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFOBJECT_H_