Index: experimental/PdfViewer/src/SkPdfContext.cpp |
diff --git a/experimental/PdfViewer/src/SkPdfContext.cpp b/experimental/PdfViewer/src/SkPdfContext.cpp |
index 2ce01e75fabee85aaf47bc1d214c6fcac7c46452..6904e344b98d8fb228f95ecbd1c806a6b21a09ec 100644 |
--- a/experimental/PdfViewer/src/SkPdfContext.cpp |
+++ b/experimental/PdfViewer/src/SkPdfContext.cpp |
@@ -6,13 +6,130 @@ |
*/ |
#include "SkPdfContext.h" |
-#include "SkPdfNativeTokenizer.h" |
+#include "SkPdfNativeDoc.h" |
+#include "SkPdfReporter.h" |
+#include "SkPdfTokenLooper.h" |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+class PdfMainLooper : public SkPdfTokenLooper { |
+public: |
+ PdfMainLooper(SkPdfTokenLooper* parent, |
+ SkPdfNativeTokenizer* tokenizer, |
+ SkPdfContext* pdfContext, |
+ SkCanvas* canvas) |
+ : SkPdfTokenLooper(parent, tokenizer, pdfContext, canvas) {} |
+ |
+ virtual SkPdfResult consumeToken(PdfToken& token); |
+ virtual void loop(); |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
SkPdfContext::SkPdfContext(SkPdfNativeDoc* doc) |
: fPdfDoc(doc) |
- , fTmpPageAllocator(new SkPdfAllocator()) { |
+{ |
+ SkASSERT(fPdfDoc != NULL); |
+} |
+ |
+void SkPdfContext::parseStream(SkPdfNativeObject* stream, SkCanvas* canvas) { |
+ SkPdfNativeTokenizer* tokenizer = fPdfDoc->tokenizerOfStream(stream, &fTmpPageAllocator); |
+ if (NULL == tokenizer) { |
+ // Nothing to parse. |
+ return; |
+ } |
+ PdfMainLooper looper(NULL, tokenizer, this, canvas); |
+ looper.loop(); |
+ // FIXME (scroggo): Will restructure to put tokenizer on the stack. |
+ delete tokenizer; |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+// FIXME (scroggo): This probably belongs in a debugging file. |
+// For reportRenderStats declaration. |
+#include "SkPdfRenderer.h" |
+ |
+// Temp code to measure what operands fail. |
+template <typename T> class SkTDictWithDefaultConstructor : public SkTDict<T> { |
+public: |
+ SkTDictWithDefaultConstructor() : SkTDict<T>(10) {} |
+}; |
+ |
+SkTDictWithDefaultConstructor<int> gRenderStats[kCount_SkPdfResult]; |
+ |
+const char* gRenderStatsNames[kCount_SkPdfResult] = { |
+ "Success", |
+ "Partially implemented", |
+ "Not yet implemented", |
+ "Ignore Error", |
+ "Error", |
+ "Unsupported/Unknown" |
+}; |
+ |
+// Declared in SkPdfRenderer.h. Should be moved to a central debugging location. |
+void reportPdfRenderStats() { |
+ for (int i = 0 ; i < kCount_SkPdfResult; i++) { |
+ SkTDict<int>::Iter iter(gRenderStats[i]); |
+ const char* key; |
+ int value = 0; |
+ while ((key = iter.next(&value)) != NULL) { |
+ printf("%s: %s -> count %i\n", gRenderStatsNames[i], key, value); |
+ } |
+ } |
+} |
+ |
+#include "SkPdfOps.h" |
+ |
+SkPdfResult PdfMainLooper::consumeToken(PdfToken& token) { |
+ if (token.fType == kKeyword_TokenType && token.fKeywordLength < 256) |
+ { |
+ PdfOperatorRenderer pdfOperatorRenderer = NULL; |
+ if (gPdfOps.find(token.fKeyword, token.fKeywordLength, &pdfOperatorRenderer) && |
+ pdfOperatorRenderer) { |
+ SkPdfTokenLooper* childLooper = NULL; |
+ // Main work is done by pdfOperatorRenderer(...) |
+ SkPdfResult result = pdfOperatorRenderer(fPdfContext, fCanvas, &childLooper); |
+ |
+ int cnt = 0; |
+ gRenderStats[result].find(token.fKeyword, token.fKeywordLength, &cnt); |
+ gRenderStats[result].set(token.fKeyword, token.fKeywordLength, cnt + 1); |
+ if (childLooper) { |
+ // FIXME (scroggo): Auto delete this. |
+ childLooper->setUp(this); |
+ childLooper->loop(); |
+ delete childLooper; |
+ } |
+ } else { |
+ int cnt = 0; |
+ gRenderStats[kUnsupported_SkPdfResult].find(token.fKeyword, |
+ token.fKeywordLength, |
+ &cnt); |
+ gRenderStats[kUnsupported_SkPdfResult].set(token.fKeyword, |
+ token.fKeywordLength, |
+ cnt + 1); |
+ } |
+ } |
+ else if (token.fType == kObject_TokenType) |
+ { |
+ fPdfContext->fObjectStack.push( token.fObject ); |
+ } |
+ else { |
+ // TODO(edisonn): store the keyword as a object, so we can track the location in file, |
+ // and report where the error was triggered |
+ SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, token.fKeyword, NULL, |
+ fPdfContext); |
+ return kIgnoreError_SkPdfResult; |
+ } |
+ return kOK_SkPdfResult; |
} |
-SkPdfContext::~SkPdfContext() { |
- delete fTmpPageAllocator; |
+void PdfMainLooper::loop() { |
+ PdfToken token; |
+ // readToken defined in SkPdfTokenLooper.h |
+ // FIXME (scroggo): Remove readToken (which just calls fTokenizer->readToken, plus draws |
+ // some debugging info with PDF_DIFF_TRACE_IN_PNG) |
+ while (readToken(fTokenizer, &token)) { |
+ this->consumeToken(token); |
+ } |
} |