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

Side by Side Diff: experimental/PdfViewer/pdfparser/native/SkPdfObject.h

Issue 18323019: work on the native parser, in progress, uploaded to have a backup (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #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"
15
16 class SkPdfDictionary;
17 class SkPdfStream;
18 class SkPdfAllocator;
19
20 // TODO(edisonn): macro it and move it to utils
21 SkMatrix SkMatrixFromPdfMatrix(double array[6]);
22
23
24 #define kFilteredStreamBit 0
25 #define kUnfilteredStreamBit 1
26
27
28 class SkPdfObject {
29 public:
30 enum ObjectType {
31 kInvalid_PdfObjectType,
32
33 kBoolean_PdfObjectType,
34 kInteger_PdfObjectType,
35 kReal_PdfObjectType,
36 kString_PdfObjectType,
37 kHexString_PdfObjectType,
38 kName_PdfObjectType,
39 kKeyword_PdfObjectType,
40 //kStream_PdfObjectType, // attached to a Dictionary
41 kArray_PdfObjectType,
42 kDictionary_PdfObjectType,
43 kNull_PdfObjectType,
44
45 // TODO(edisonn): after the pdf has been loaded completely, resolve all references
46 // try the same thing with delayed loaded ...
47 kReference_PdfObjectType,
48
49 kUndefined_PdfObjectType, // per 1.4 spec, if the same key appear twic e in the dictionary, the value is undefined
50 };
51
52 private:
53 struct NotOwnedString {
54 unsigned char* fBuffer;
55 size_t fBytes;
56 };
57
58 struct Reference {
59 unsigned int fId;
60 unsigned int fGen;
61 };
62
63 // TODO(edisonn): add stream start, stream end, where stream is weither the file
64 // or decoded/filtered pdf stream
65
66 // TODO(edisonn): add warning/report per object
67 // TODO(edisonn): add flag fUsed, to be used once the parsing is complete,
68 // so we could show what parts have been proccessed, ignored, or generated e rrors
69
70 ObjectType fObjectType;
71
72 union {
73 bool fBooleanValue;
74 int64_t fIntegerValue;
75 // TODO(edisonn): double, float? typedefed
76 double fRealValue;
77 NotOwnedString fStr;
78
79 // TODO(edisonn): make sure the foorprint of fArray and fMap is small, o therwise, use pointers, or classes with up to 8 bytes in footprint
80 SkTDArray<SkPdfObject*>* fArray;
81 Reference fRef;
82 };
83 SkTDict<SkPdfObject*>* fMap;
84 void* fData;
85
86
87 public:
88
89 SkPdfObject() : fObjectType(kInvalid_PdfObjectType), fData(NULL) {}
90
91 inline void* data() {
92 return fData;
93 }
94
95 inline void setData(void* data) {
96 fData = data;
97 }
98
99 ~SkPdfObject() {
100 reset();
101 }
102
103 void reset() {
104 switch (fObjectType) {
105 case kArray_PdfObjectType:
106 delete fArray;
107 break;
108
109 case kDictionary_PdfObjectType:
110 delete fMap;
111 break;
112
113 default:
114 break;
115 }
116 fObjectType = kInvalid_PdfObjectType;
117 }
118
119 ObjectType type() { return fObjectType; }
120
121 const char* c_str() const {
122 switch (fObjectType) {
123 case kString_PdfObjectType:
124 case kHexString_PdfObjectType:
125 case kKeyword_PdfObjectType:
126 return (const char*)fStr.fBuffer;
127
128 default:
129 // TODO(edisonn): report/warning
130 return NULL;
131 }
132 }
133
134 size_t len() const {
135 switch (fObjectType) {
136 case kString_PdfObjectType:
137 case kHexString_PdfObjectType:
138 case kKeyword_PdfObjectType:
139 return fStr.fBytes;
140
141 default:
142 // TODO(edisonn): report/warning
143 return 0;
144 }
145 }
146
147
148 // TODO(edisonn): NYI
149 SkPdfDate& dateValue() const {
150 static SkPdfDate nyi;
151 return nyi;
152 }
153
154 // TODO(edisonn): NYI
155 SkPdfFunction& functionValue() const {
156 static SkPdfFunction nyi;
157 return nyi;
158 }
159
160 // TODO(edisonn): NYI
161 SkPdfFileSpec& fileSpecValue() const {
162 static SkPdfFileSpec nyi;
163 return nyi;
164 }
165
166 // TODO(edisonn): NYI
167 SkPdfTree& treeValue() const {
168 static SkPdfTree nyi;
169 return nyi;
170 }
171
172
173 static void makeBoolean(bool value, SkPdfObject* obj) {
174 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
175
176 obj->fObjectType = kBoolean_PdfObjectType;
177 obj->fBooleanValue = value;
178 }
179
180 static SkPdfObject makeBoolean(bool value) {
181 SkPdfObject obj;
182 obj.fObjectType = kBoolean_PdfObjectType;
183 obj.fBooleanValue = value;
184 return obj;
185 }
186
187 static void makeInteger(int64_t value, SkPdfObject* obj) {
188 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
189
190 obj->fObjectType = kInteger_PdfObjectType;
191 obj->fIntegerValue = value;
192 }
193
194 static void makeReal(double value, SkPdfObject* obj) {
195 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
196
197 obj->fObjectType = kReal_PdfObjectType;
198 obj->fRealValue = value;
199 }
200
201 static void makeNull(SkPdfObject* obj) {
202 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
203
204 obj->fObjectType = kNull_PdfObjectType;
205 }
206
207 static SkPdfObject makeNull() {
208 SkPdfObject obj;
209 obj.fObjectType = kNull_PdfObjectType;
210 return obj;
211 }
212
213 static SkPdfObject kNull;
214
215 static void makeNumeric(unsigned char* start, unsigned char* end, SkPdfObjec t* obj) {
216 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
217
218 // TODO(edisonn): NYI properly
219 // if has dot (impl), or exceeds max int, is real, otherwise is int
220 bool isInt = true;
221 for (unsigned char* current = start; current < end; current++) {
222 if (*current == '.') {
223 isInt = false;
224 break;
225 }
226 // TODO(edisonn): report parse issue with numbers like "24asdasd123"
227 }
228 if (isInt) {
229 makeInteger(atol((const char*)start), obj);
230 } else {
231 makeReal(atof((const char*)start), obj);
232 }
233 }
234
235 static void makeReference(unsigned int id, unsigned int gen, SkPdfObject* ob j) {
236 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
237
238 obj->fObjectType = kReference_PdfObjectType;
239 obj->fRef.fId = id;
240 obj->fRef.fGen = gen;
241 }
242
243
244 static void makeString(unsigned char* start, SkPdfObject* obj) {
245 makeStringCore(start, strlen((const char*)start), obj, kString_PdfObject Type);
246 }
247
248 static void makeString(unsigned char* start, unsigned char* end, SkPdfObject * obj) {
249 makeStringCore(start, end - start, obj, kString_PdfObjectType);
250 }
251
252 static void makeString(unsigned char* start, size_t bytes, SkPdfObject* obj) {
253 makeStringCore(start, bytes, obj, kString_PdfObjectType);
254 }
255
256
257 static void makeHexString(unsigned char* start, SkPdfObject* obj) {
258 makeStringCore(start, strlen((const char*)start), obj, kHexString_PdfObj ectType);
259 }
260
261 static void makeHexString(unsigned char* start, unsigned char* end, SkPdfObj ect* obj) {
262 makeStringCore(start, end - start, obj, kHexString_PdfObjectType);
263 }
264
265 static void makeHexString(unsigned char* start, size_t bytes, SkPdfObject* o bj) {
266 makeStringCore(start, bytes, obj, kHexString_PdfObjectType);
267 }
268
269
270 static void makeName(unsigned char* start, SkPdfObject* obj) {
271 makeStringCore(start, strlen((const char*)start), obj, kName_PdfObjectTy pe);
272 }
273
274 static void makeName(unsigned char* start, unsigned char* end, SkPdfObject* obj) {
275 makeStringCore(start, end - start, obj, kName_PdfObjectType);
276 }
277
278 static void makeName(unsigned char* start, size_t bytes, SkPdfObject* obj) {
279 makeStringCore(start, bytes, obj, kName_PdfObjectType);
280 }
281
282
283 static void makeKeyword(unsigned char* start, SkPdfObject* obj) {
284 makeStringCore(start, strlen((const char*)start), obj, kKeyword_PdfObjec tType);
285 }
286
287 static void makeKeyword(unsigned char* start, unsigned char* end, SkPdfObjec t* obj) {
288 makeStringCore(start, end - start, obj, kKeyword_PdfObjectType);
289 }
290
291 static void makeKeyword(unsigned char* start, size_t bytes, SkPdfObject* obj ) {
292 makeStringCore(start, bytes, obj, kKeyword_PdfObjectType);
293 }
294
295
296
297 // TODO(edisonn): make the functions to return SkPdfArray, move these functi ons in SkPdfArray
298 static void makeEmptyArray(SkPdfObject* obj) {
299 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
300
301 obj->fObjectType = kArray_PdfObjectType;
302 obj->fArray = new SkTDArray<SkPdfObject*>();
303 // return (SkPdfArray*)obj;
304 }
305
306 bool appendInArray(SkPdfObject* obj) {
307 SkASSERT(fObjectType == kArray_PdfObjectType);
308 if (fObjectType != kArray_PdfObjectType) {
309 // TODO(edisonn): report err
310 return false;
311 }
312
313 fArray->push(obj);
314 return true;
315 }
316
317 size_t size() const {
318 SkASSERT(fObjectType == kArray_PdfObjectType);
319
320 return fArray->count();
321 }
322
323 SkPdfObject* objAtAIndex(int i) {
324 SkASSERT(fObjectType == kArray_PdfObjectType);
325
326 return (*fArray)[i];
327 }
328
329 SkPdfObject* removeLastInArray() {
330 SkASSERT(fObjectType == kArray_PdfObjectType);
331
332 SkPdfObject* ret = NULL;
333 fArray->pop(&ret);
334
335 return ret;
336 }
337
338
339 const SkPdfObject* objAtAIndex(int i) const {
340 SkASSERT(fObjectType == kArray_PdfObjectType);
341
342 return (*fArray)[i];
343 }
344
345 SkPdfObject* operator[](int i) {
346 SkASSERT(fObjectType == kArray_PdfObjectType);
347
348 return (*fArray)[i];
349 }
350
351 const SkPdfObject* operator[](int i) const {
352 SkASSERT(fObjectType == kArray_PdfObjectType);
353
354 return (*fArray)[i];
355 }
356
357
358 // TODO(edisonn): make the functions to return SkPdfDictionary, move these f unctions in SkPdfDictionary
359 static void makeEmptyDictionary(SkPdfObject* obj) {
360 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
361
362 obj->fObjectType = kDictionary_PdfObjectType;
363 obj->fMap = new SkTDict<SkPdfObject*>(1);
364 obj->fStr.fBuffer = NULL;
365 obj->fStr.fBytes = 0;
366 }
367
368 // TODO(edisonn): get all the possible names from spec, and compute a hash f unction
369 // that would create no overlaps in the same dictionary
370 // or build a tree of chars that when followed goes to a unique id/index/has h
371 // TODO(edisonn): generate constants like kDictFoo, kNameDict_name
372 // which will be used in code
373 // add function SkPdfFastNameKey key(const char* key);
374 // TODO(edisonn): setting the same key twike, will make the value undefined!
375 bool set(SkPdfObject* key, SkPdfObject* value) {
376 SkASSERT(fObjectType == kDictionary_PdfObjectType);
377 SkASSERT(key->fObjectType == kName_PdfObjectType);
378
379 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionar y_PdfObjectType) {
380 // TODO(edisonn): report err
381 return false;
382 }
383
384 // we rewrite all delimiters and white spaces with '\0', so we expect th e end of name to be '\0'
385 SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
386
387 return set((char*)key->fStr.fBuffer, value);
388 }
389
390 bool set(const char* key, SkPdfObject* value) {
391 SkASSERT(fObjectType == kDictionary_PdfObjectType);
392
393 if (fObjectType != kDictionary_PdfObjectType) {
394 // TODO(edisonn): report err
395 return false;
396 }
397
398 return fMap->set(key, value);
399 }
400
401 SkPdfObject* get(SkPdfObject* key) {
402 SkASSERT(fObjectType == kDictionary_PdfObjectType);
403 SkASSERT(key->fObjectType == kName_PdfObjectType);
404
405 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionar y_PdfObjectType) {
406 // TODO(edisonn): report err
407 return false;
408 }
409
410 SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
411
412 return get((char*)key->fStr.fBuffer);
413 }
414
415 SkPdfObject* get(const char* key) {
416 SkASSERT(fObjectType == kDictionary_PdfObjectType);
417 SkASSERT(key);
418 if (fObjectType != kDictionary_PdfObjectType) {
419 // TODO(edisonn): report err
420 return NULL;
421 }
422 SkPdfObject* ret = NULL;
423 fMap->find(key, &ret);
424 return ret;
425 }
426
427 const SkPdfObject* get(SkPdfObject* key) const {
428 SkASSERT(fObjectType == kDictionary_PdfObjectType);
429 SkASSERT(key->fObjectType == kName_PdfObjectType);
430
431 if (key->fObjectType != kName_PdfObjectType || fObjectType != kDictionar y_PdfObjectType) {
432 // TODO(edisonn): report err
433 return false;
434 }
435
436 SkASSERT(key->fStr.fBuffer[key->fStr.fBytes] == '\0');
437
438 return get((char*)key->fStr.fBuffer);
439 }
440
441
442 const SkPdfObject* get(const char* key) const {
443 SkASSERT(fObjectType == kDictionary_PdfObjectType);
444 SkASSERT(key);
445 if (fObjectType != kDictionary_PdfObjectType) {
446 // TODO(edisonn): report err
447 return NULL;
448 }
449 SkPdfObject* ret = NULL;
450 fMap->find(key, &ret);
451 return ret;
452 }
453
454 const SkPdfObject* get(const char* key, const char* abr) const {
455 const SkPdfObject* ret = get(key);
456 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL
457 // make this distiontion in generator, and remove "" from condition
458 if (ret != NULL || abr == NULL || *abr == '\0') {
459 return ret;
460 }
461 return get(abr);
462 }
463
464 SkPdfObject* get(const char* key, const char* abr) {
465 SkPdfObject* ret = get(key);
466 // TODO(edisonn): / is a valid name, and it might be an abreviation, so "" should not be like NULL
467 // make this distiontion in generator, and remove "" from condition
468 if (ret != NULL || abr == NULL || *abr == '\0') {
469 return ret;
470 }
471 return get(abr);
472 }
473
474 SkPdfDictionary* asDictionary() {
475 SkASSERT(isDictionary());
476 if (!isDictionary()) {
477 return NULL;
478 }
479 return (SkPdfDictionary*) this;
480 }
481
482 const SkPdfDictionary* asDictionary() const {
483 SkASSERT(isDictionary());
484 if (!isDictionary()) {
485 return NULL;
486 }
487 return (SkPdfDictionary*) this;
488 }
489
490
491 bool isReference() const {
492 return fObjectType == kReference_PdfObjectType;
493 }
494
495 bool isBoolean() const {
496 return fObjectType == kBoolean_PdfObjectType;
497 }
498
499 bool isInteger() const {
500 return fObjectType == kInteger_PdfObjectType;
501 }
502 private:
503 bool isReal() const {
504 return fObjectType == kReal_PdfObjectType;
505 }
506 public:
507 bool isNumber() const {
508 return fObjectType == kInteger_PdfObjectType || fObjectType == kReal_Pdf ObjectType;
509 }
510
511 bool isKeywordReference() const {
512 return fObjectType == kKeyword_PdfObjectType && fStr.fBytes == 1 && fStr .fBuffer[0] == 'R';
513 }
514
515 bool isKeyword() const {
516 return fObjectType == kKeyword_PdfObjectType;
517 }
518
519 bool isName() const {
520 return fObjectType == kName_PdfObjectType;
521 }
522
523 bool isArray() const {
524 return fObjectType == kArray_PdfObjectType;
525 }
526
527 bool isDate() const {
528 return fObjectType == kString_PdfObjectType || fObjectType == kHexString _PdfObjectType;
529 }
530
531 bool isDictionary() const {
532 return fObjectType == kDictionary_PdfObjectType;
533 }
534
535 bool isFunction() const {
536 return false; // NYI
537 }
538
539 bool isRectangle() const {
540 return fObjectType == kArray_PdfObjectType && fArray->count() == 4; // N YI + and elems are numbers
541 }
542
543 // TODO(edisonn): has stream .. or is stream ... TBD
544 bool hasStream() const {
545 return isDictionary() && fStr.fBuffer != NULL;
546 }
547
548 // TODO(edisonn): has stream .. or is stream ... TBD
549 const SkPdfStream* getStream() const {
550 return hasStream() ? (const SkPdfStream*)this : NULL;
551 }
552
553 SkPdfStream* getStream() {
554 return hasStream() ? (SkPdfStream*)this : NULL;
555 }
556
557 bool isAnyString() const {
558 return fObjectType == kString_PdfObjectType || fObjectType == kHexString _PdfObjectType;
559 }
560
561 bool isMatrix() const {
562 return fObjectType == kArray_PdfObjectType && fArray->count() == 6; // N YI + and elems are numbers
563 }
564
565 inline int64_t intValue() const {
566 SkASSERT(fObjectType == kInteger_PdfObjectType);
567
568 if (fObjectType != kInteger_PdfObjectType) {
569 // TODO(edisonn): log err
570 return 0;
571 }
572 return fIntegerValue;
573 }
574 private:
575 inline double realValue() const {
576 SkASSERT(fObjectType == kReal_PdfObjectType);
577
578 if (fObjectType != kReal_PdfObjectType) {
579 // TODO(edisonn): log err
580 return 0;
581 }
582 return fRealValue;
583 }
584 public:
585 inline double numberValue() const {
586 SkASSERT(isNumber());
587
588 if (!isNumber()) {
589 // TODO(edisonn): log err
590 return 0;
591 }
592 return fObjectType == kReal_PdfObjectType ? fRealValue : fIntegerValue;
593 }
594
595 int referenceId() const {
596 SkASSERT(fObjectType == kReference_PdfObjectType);
597 return fRef.fId;
598 }
599
600 int referenceGeneration() const {
601 SkASSERT(fObjectType == kReference_PdfObjectType);
602 return fRef.fGen;
603 }
604
605 inline const char* nameValue() const {
606 SkASSERT(fObjectType == kName_PdfObjectType);
607
608 if (fObjectType != kName_PdfObjectType) {
609 // TODO(edisonn): log err
610 return "";
611 }
612 return (const char*)fStr.fBuffer;
613 }
614
615 inline const char* stringValue() const {
616 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexStri ng_PdfObjectType);
617
618 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_Pd fObjectType) {
619 // TODO(edisonn): log err
620 return "";
621 }
622 return (const char*)fStr.fBuffer;
623 }
624
625 // TODO(edisonn): nameValue2 and stringValue2 are used to make code generati on easy,
626 // but it is not a performat way to do it, since it will create an extra cop y
627 // remove these functions and make code generated faster
628 inline std::string nameValue2() const {
629 SkASSERT(fObjectType == kName_PdfObjectType);
630
631 if (fObjectType != kName_PdfObjectType) {
632 // TODO(edisonn): log err
633 return "";
634 }
635 return (const char*)fStr.fBuffer;
636 }
637
638 inline std::string stringValue2() const {
639 SkASSERT(fObjectType == kString_PdfObjectType || fObjectType == kHexStri ng_PdfObjectType);
640
641 if (fObjectType != kString_PdfObjectType && fObjectType != kHexString_Pd fObjectType) {
642 // TODO(edisonn): log err
643 return "";
644 }
645 return (const char*)fStr.fBuffer;
646 }
647
648 inline bool boolValue() const {
649 SkASSERT(fObjectType == kBoolean_PdfObjectType);
650
651 if (fObjectType == kBoolean_PdfObjectType) {
652 // TODO(edisonn): log err
653 return false;
654 }
655 return fBooleanValue;
656 }
657
658 SkRect rectangleValue() const {
659 SkASSERT(isRectangle());
660 if (!isRectangle()) {
661 return SkRect::MakeEmpty();
662 }
663
664 double array[4];
665 for (int i = 0; i < 4; i++) {
666 // TODO(edisonn): version where we could resolve references?
667 const SkPdfObject* elem = objAtAIndex(i);
668 if (elem == NULL || !elem->isNumber()) {
669 // TODO(edisonn): report error
670 return SkRect::MakeEmpty();
671 }
672 array[i] = elem->numberValue();
673 }
674
675 return SkRect::MakeLTRB(SkDoubleToScalar(array[0]),
676 SkDoubleToScalar(array[1]),
677 SkDoubleToScalar(array[2]),
678 SkDoubleToScalar(array[3]));
679 }
680
681 SkMatrix matrixValue() const {
682 SkASSERT(isMatrix());
683 if (!isMatrix()) {
684 return SkMatrix::I();
685 }
686
687 double array[6];
688 for (int i = 0; i < 6; i++) {
689 // TODO(edisonn): version where we could resolve references?
690 const SkPdfObject* elem = objAtAIndex(i);
691 if (elem == NULL || !elem->isNumber()) {
692 // TODO(edisonn): report error
693 return SkMatrix::I();
694 }
695 array[i] = elem->numberValue();
696 }
697
698 return SkMatrixFromPdfMatrix(array);
699 }
700
701 bool filterStream(SkPdfAllocator* allocator);
702
703
704 bool GetFilteredStreamRef(unsigned char** buffer, size_t* len, SkPdfAllocato r* allocator) {
705 // TODO(edisonn): add params that couls let the last filter in place if it is jpeg or png to fast load images
706 if (!hasStream()) {
707 return false;
708 }
709
710 filterStream(allocator);
711
712 if (buffer) {
713 *buffer = fStr.fBuffer;
714 }
715
716 if (len) {
717 *len = fStr.fBytes >> 1; // last bit
718 }
719
720 return true;
721 }
722
723 bool isStreamFiltered() const {
724 return hasStream() && ((fStr.fBytes & 1) == kFilteredStreamBit);
725 }
726
727 bool GetUnfilteredStreamRef(unsigned char** buffer, size_t* len) const {
728 if (isStreamFiltered()) {
729 return false;
730 }
731
732 if (!hasStream()) {
733 return false;
734 }
735
736 if (buffer) {
737 *buffer = fStr.fBuffer;
738 }
739
740 if (len) {
741 *len = fStr.fBytes >> 1; // remove slast bit
742 }
743
744 return true;
745 }
746
747 bool addStream(unsigned char* buffer, size_t len) {
748 SkASSERT(!hasStream());
749 SkASSERT(isDictionary());
750
751 if (!isDictionary() || hasStream()) {
752 return false;
753 }
754
755 fStr.fBuffer = buffer;
756 fStr.fBytes = (len << 2) + kUnfilteredStreamBit;
757
758 return true;
759 }
760
761 SkString toString() {
762 SkString str;
763 switch (fObjectType) {
764 case kInvalid_PdfObjectType:
765 str.append("Invalid");
766 break;
767
768 case kBoolean_PdfObjectType:
769 str.appendf("Boolean: %s", fBooleanValue ? "true" : "false");
770 break;
771
772 case kInteger_PdfObjectType:
773 str.appendf("Integer: %i", (int)fIntegerValue);
774 break;
775
776 case kReal_PdfObjectType:
777 str.appendf("Real: %f", fRealValue);
778 break;
779
780 case kString_PdfObjectType:
781 str.appendf("String, len() = %u: ", (unsigned int)fStr.fBytes);
782 str.append((const char*)fStr.fBuffer, fStr.fBytes);
783 break;
784
785 case kHexString_PdfObjectType:
786 str.appendf("HexString, len() = %u: ", (unsigned int)fStr.fBytes );
787 str.append((const char*)fStr.fBuffer, fStr.fBytes);
788 break;
789
790 case kName_PdfObjectType:
791 str.appendf("Name, len() = %u: ", (unsigned int)fStr.fBytes);
792 str.append((const char*)fStr.fBuffer, fStr.fBytes);
793 break;
794
795 case kKeyword_PdfObjectType:
796 str.appendf("Keyword, len() = %u: ", (unsigned int)fStr.fBytes);
797 str.append((const char*)fStr.fBuffer, fStr.fBytes);
798 break;
799
800 case kArray_PdfObjectType:
801 str.append("Array, size() = %i [", size());
802 for (unsigned int i = 0; i < size(); i++) {
803 str.append(objAtAIndex(i)->toString());
804 }
805 str.append("]");
806 break;
807
808 case kDictionary_PdfObjectType:
809 // TODO(edisonn): NYI
810 str.append("Dictionary: NYI");
811 if (hasStream()) {
812 str.append(" HAS_STREAM");
813 }
814 break;
815
816 case kNull_PdfObjectType:
817 str = "NULL";
818 break;
819
820 case kReference_PdfObjectType:
821 str.appendf("Reference: %i %i", fRef.fId, fRef.fGen);
822 break;
823
824 case kUndefined_PdfObjectType:
825 str = "Undefined";
826 break;
827
828 default:
829 str = "Internal Error Object Type";
830 break;
831 }
832
833 return str;
834 }
835
836 private:
837 static void makeStringCore(unsigned char* start, SkPdfObject* obj, ObjectTyp e type) {
838 makeStringCore(start, strlen((const char*)start), obj, type);
839 }
840
841 static void makeStringCore(unsigned char* start, unsigned char* end, SkPdfOb ject* obj, ObjectType type) {
842 makeStringCore(start, end - start, obj, type);
843 }
844
845 static void makeStringCore(unsigned char* start, size_t bytes, SkPdfObject* obj, ObjectType type) {
846 SkASSERT(obj->fObjectType == kInvalid_PdfObjectType);
847
848 obj->fObjectType = type;
849 obj->fStr.fBuffer = start;
850 obj->fStr.fBytes = bytes;
851 }
852
853 bool applyFilter(const char* name, SkPdfAllocator* allocator);
854 bool applyFlateDecodeFilter(SkPdfAllocator* allocator);
855 bool applyDCTDecodeFilter(SkPdfAllocator* allocator);
856 };
857
858 class SkPdfStream : public SkPdfObject {};
859 class SkPdfArray : public SkPdfObject {};
860 class SkPdfString : public SkPdfObject {};
861 class SkPdfHexString : public SkPdfObject {};
862 class SkPdfInteger : public SkPdfObject {};
863 class SkPdfReal : public SkPdfObject {};
864 class SkPdfNumber : public SkPdfObject {};
865
866 #endif // EXPERIMENTAL_PDFVIEWER_PDFPARSER_NATIVE_SKPDFOBJECT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698