OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2013 Google Inc. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 |
| 8 #include "podofo.h" |
| 9 #include "SkPdfHeaders_autogen.h" |
| 10 #include "SkPdfPodofoMapper_autogen.h" |
| 11 |
| 12 #ifndef SkPdfParser_DEFINED |
| 13 #define SkPdfParser_DEFINED |
| 14 |
| 15 |
| 16 enum SkPdfTokenType { |
| 17 kKeyword_TokenType, |
| 18 kObject_TokenType, |
| 19 kImageData_TokenType, // TODO(edisonn): inline images seem to work without
it |
| 20 }; |
| 21 |
| 22 struct PdfToken { |
| 23 const char* fKeyword; |
| 24 SkPdfObject* fObject; |
| 25 SkPdfTokenType fType; |
| 26 |
| 27 PdfToken() : fKeyword(NULL), fObject(NULL) {} |
| 28 }; |
| 29 |
| 30 class SkPdfTokenizer { |
| 31 PdfContentsTokenizer* fTokenizer; |
| 32 PdfMemDocument* fDoc; |
| 33 |
| 34 char* fUncompressedStream; |
| 35 pdf_long fUncompressedStreamLength; |
| 36 |
| 37 bool fEmpty; |
| 38 bool fHasPutBack; |
| 39 PdfToken fPutBack; |
| 40 |
| 41 public: |
| 42 SkPdfTokenizer(PdfMemDocument* doc = NULL, PdfContentsTokenizer* tokenizer =
NULL) : fDoc(doc), fTokenizer(tokenizer), fEmpty(false), fUncompressedStream(NU
LL), fUncompressedStreamLength(0), fHasPutBack(false) {} |
| 43 SkPdfTokenizer(const SkPdfObject* objWithStream) : fDoc(NULL), fTokenizer(NU
LL), fHasPutBack(false), fEmpty(false) { |
| 44 fUncompressedStream = NULL; |
| 45 fUncompressedStreamLength = 0; |
| 46 |
| 47 fDoc = NULL; |
| 48 |
| 49 |
| 50 try { |
| 51 objWithStream->podofo()->GetStream()->GetFilteredCopy(&fUncompressed
Stream, &fUncompressedStreamLength); |
| 52 if (fUncompressedStream != NULL && fUncompressedStreamLength != 0) { |
| 53 fTokenizer = new PdfContentsTokenizer(fUncompressedStream, fUnco
mpressedStreamLength); |
| 54 } else { |
| 55 fEmpty = true; |
| 56 } |
| 57 } catch (PdfError& e) { |
| 58 fEmpty = true; |
| 59 } |
| 60 |
| 61 } |
| 62 |
| 63 SkPdfTokenizer(const char* buffer, int len) : fDoc(NULL), fTokenizer(NULL),
fHasPutBack(false), fUncompressedStream(NULL), fUncompressedStreamLength(0), fEm
pty(false) { |
| 64 try { |
| 65 fTokenizer = new PdfContentsTokenizer(buffer, len); |
| 66 } catch (PdfError& e) { |
| 67 fEmpty = true; |
| 68 } |
| 69 } |
| 70 |
| 71 ~SkPdfTokenizer() { |
| 72 free(fUncompressedStream); |
| 73 } |
| 74 |
| 75 void PutBack(PdfToken token) { |
| 76 SkASSERT(!fHasPutBack); |
| 77 fHasPutBack = true; |
| 78 fPutBack = token; |
| 79 } |
| 80 |
| 81 bool readToken(PdfToken* token) { |
| 82 if (fHasPutBack) { |
| 83 *token = fPutBack; |
| 84 fHasPutBack = false; |
| 85 return true; |
| 86 } |
| 87 |
| 88 if (fEmpty) { |
| 89 return false; |
| 90 } |
| 91 |
| 92 PdfVariant var; |
| 93 EPdfContentsType type; |
| 94 |
| 95 token->fKeyword = NULL; |
| 96 token->fObject = NULL; |
| 97 |
| 98 bool ret = fTokenizer->ReadNext(type, token->fKeyword, var); |
| 99 |
| 100 if (!ret) return ret; |
| 101 |
| 102 switch (type) { |
| 103 case ePdfContentsType_Keyword: |
| 104 token->fType = kKeyword_TokenType; |
| 105 break; |
| 106 |
| 107 case ePdfContentsType_Variant: { |
| 108 token->fType = kObject_TokenType; |
| 109 PdfObject* obj = new PdfObject(var); |
| 110 PodofoMapper::map(*fDoc, *obj, &token->fObject); |
| 111 } |
| 112 break; |
| 113 |
| 114 case ePdfContentsType_ImageData: |
| 115 token->fType = kImageData_TokenType; |
| 116 // TODO(edisonn): inline images seem to work without it |
| 117 break; |
| 118 } |
| 119 #ifdef PDF_TRACE |
| 120 std::string str; |
| 121 if (token->fObject) { |
| 122 token->fObject->podofo()->ToString(str); |
| 123 } |
| 124 printf("%s %s\n", token->fType == kKeyword_TokenType ? "Keyword" : token
->fType == kObject_TokenType ? "Object" : "ImageData", token->fKeyword ? token->
fKeyword : str.c_str()); |
| 125 #endif |
| 126 return ret; |
| 127 } |
| 128 }; |
| 129 |
| 130 class SkPdfDoc { |
| 131 PdfMemDocument fDoc; |
| 132 public: |
| 133 |
| 134 PdfMemDocument& podofo() {return fDoc;} |
| 135 |
| 136 SkPdfDoc(const char* path) : fDoc(path) {} |
| 137 |
| 138 int pages() { |
| 139 return fDoc.GetPageCount(); |
| 140 } |
| 141 |
| 142 // Can return NULL |
| 143 SkPdfPageObjectDictionary* page(int n) { |
| 144 SkPdfPageObjectDictionary* page = NULL; |
| 145 PodofoMapper::map(fDoc, *fDoc.GetPage(n)->GetObject(), &page); |
| 146 return page; |
| 147 } |
| 148 |
| 149 SkRect MediaBox(int n) { |
| 150 PdfRect rect = fDoc.GetPage(n)->GetMediaBox(); |
| 151 SkRect skrect = SkRect::MakeLTRB(SkDoubleToScalar(rect.GetLeft()), |
| 152 SkDoubleToScalar(rect.GetBottom()), |
| 153 SkDoubleToScalar(rect.GetLeft() + rect.
GetWidth()), |
| 154 SkDoubleToScalar(rect.GetBottom() + rec
t.GetHeight())); |
| 155 return skrect; |
| 156 } |
| 157 |
| 158 SkPdfTokenizer* tokenizerOfPage(int n) { |
| 159 PdfContentsTokenizer* t = new PdfContentsTokenizer(fDoc.GetPage(n)); |
| 160 return new SkPdfTokenizer(&fDoc, t); |
| 161 } |
| 162 }; |
| 163 |
| 164 #endif // SkPdfParser_DEFINED |
OLD | NEW |