Index: experimental/PdfViewer/SkPdfParser.h |
=================================================================== |
--- experimental/PdfViewer/SkPdfParser.h (revision 0) |
+++ experimental/PdfViewer/SkPdfParser.h (revision 0) |
@@ -0,0 +1,164 @@ |
+/* |
+ * Copyright 2013 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "podofo.h" |
+#include "SkPdfHeaders_autogen.h" |
+#include "SkPdfPodofoMapper_autogen.h" |
+ |
+#ifndef SkPdfParser_DEFINED |
+#define SkPdfParser_DEFINED |
+ |
+ |
+enum SkPdfTokenType { |
+ kKeyword_TokenType, |
+ kObject_TokenType, |
+ kImageData_TokenType, // TODO(edisonn): inline images seem to work without it |
+}; |
+ |
+struct PdfToken { |
+ const char* fKeyword; |
+ SkPdfObject* fObject; |
+ SkPdfTokenType fType; |
+ |
+ PdfToken() : fKeyword(NULL), fObject(NULL) {} |
+}; |
+ |
+class SkPdfTokenizer { |
+ PdfContentsTokenizer* fTokenizer; |
+ PdfMemDocument* fDoc; |
+ |
+ char* fUncompressedStream; |
+ pdf_long fUncompressedStreamLength; |
+ |
+ bool fEmpty; |
+ bool fHasPutBack; |
+ PdfToken fPutBack; |
+ |
+public: |
+ SkPdfTokenizer(PdfMemDocument* doc = NULL, PdfContentsTokenizer* tokenizer = NULL) : fDoc(doc), fTokenizer(tokenizer), fEmpty(false), fUncompressedStream(NULL), fUncompressedStreamLength(0), fHasPutBack(false) {} |
+ SkPdfTokenizer(const SkPdfObject* objWithStream) : fDoc(NULL), fTokenizer(NULL), fHasPutBack(false), fEmpty(false) { |
+ fUncompressedStream = NULL; |
+ fUncompressedStreamLength = 0; |
+ |
+ fDoc = NULL; |
+ |
+ |
+ try { |
+ objWithStream->podofo()->GetStream()->GetFilteredCopy(&fUncompressedStream, &fUncompressedStreamLength); |
+ if (fUncompressedStream != NULL && fUncompressedStreamLength != 0) { |
+ fTokenizer = new PdfContentsTokenizer(fUncompressedStream, fUncompressedStreamLength); |
+ } else { |
+ fEmpty = true; |
+ } |
+ } catch (PdfError& e) { |
+ fEmpty = true; |
+ } |
+ |
+ } |
+ |
+ SkPdfTokenizer(const char* buffer, int len) : fDoc(NULL), fTokenizer(NULL), fHasPutBack(false), fUncompressedStream(NULL), fUncompressedStreamLength(0), fEmpty(false) { |
+ try { |
+ fTokenizer = new PdfContentsTokenizer(buffer, len); |
+ } catch (PdfError& e) { |
+ fEmpty = true; |
+ } |
+ } |
+ |
+ ~SkPdfTokenizer() { |
+ free(fUncompressedStream); |
+ } |
+ |
+ void PutBack(PdfToken token) { |
+ SkASSERT(!fHasPutBack); |
+ fHasPutBack = true; |
+ fPutBack = token; |
+ } |
+ |
+ bool readToken(PdfToken* token) { |
+ if (fHasPutBack) { |
+ *token = fPutBack; |
+ fHasPutBack = false; |
+ return true; |
+ } |
+ |
+ if (fEmpty) { |
+ return false; |
+ } |
+ |
+ PdfVariant var; |
+ EPdfContentsType type; |
+ |
+ token->fKeyword = NULL; |
+ token->fObject = NULL; |
+ |
+ bool ret = fTokenizer->ReadNext(type, token->fKeyword, var); |
+ |
+ if (!ret) return ret; |
+ |
+ switch (type) { |
+ case ePdfContentsType_Keyword: |
+ token->fType = kKeyword_TokenType; |
+ break; |
+ |
+ case ePdfContentsType_Variant: { |
+ token->fType = kObject_TokenType; |
+ PdfObject* obj = new PdfObject(var); |
+ PodofoMapper::map(*fDoc, *obj, &token->fObject); |
+ } |
+ break; |
+ |
+ case ePdfContentsType_ImageData: |
+ token->fType = kImageData_TokenType; |
+ // TODO(edisonn): inline images seem to work without it |
+ break; |
+ } |
+#ifdef PDF_TRACE |
+ std::string str; |
+ if (token->fObject) { |
+ token->fObject->podofo()->ToString(str); |
+ } |
+ printf("%s %s\n", token->fType == kKeyword_TokenType ? "Keyword" : token->fType == kObject_TokenType ? "Object" : "ImageData", token->fKeyword ? token->fKeyword : str.c_str()); |
+#endif |
+ return ret; |
+ } |
+}; |
+ |
+class SkPdfDoc { |
+ PdfMemDocument fDoc; |
+public: |
+ |
+ PdfMemDocument& podofo() {return fDoc;} |
+ |
+ SkPdfDoc(const char* path) : fDoc(path) {} |
+ |
+ int pages() { |
+ return fDoc.GetPageCount(); |
+ } |
+ |
+ // Can return NULL |
+ SkPdfPageObjectDictionary* page(int n) { |
+ SkPdfPageObjectDictionary* page = NULL; |
+ PodofoMapper::map(fDoc, *fDoc.GetPage(n)->GetObject(), &page); |
+ return page; |
+ } |
+ |
+ SkRect MediaBox(int n) { |
+ PdfRect rect = fDoc.GetPage(n)->GetMediaBox(); |
+ SkRect skrect = SkRect::MakeLTRB(SkDoubleToScalar(rect.GetLeft()), |
+ SkDoubleToScalar(rect.GetBottom()), |
+ SkDoubleToScalar(rect.GetLeft() + rect.GetWidth()), |
+ SkDoubleToScalar(rect.GetBottom() + rect.GetHeight())); |
+ return skrect; |
+ } |
+ |
+ SkPdfTokenizer* tokenizerOfPage(int n) { |
+ PdfContentsTokenizer* t = new PdfContentsTokenizer(fDoc.GetPage(n)); |
+ return new SkPdfTokenizer(&fDoc, t); |
+ } |
+}; |
+ |
+#endif // SkPdfParser_DEFINED |