aboutsummaryrefslogtreecommitdiffhomepage
path: root/experimental
diff options
context:
space:
mode:
authorGravatar scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-12-02 20:18:09 +0000
committerGravatar scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-12-02 20:18:09 +0000
commit248647cebb3724fd2ce1d41745afb786516af4f8 (patch)
treeade53aade566adfa77c86ba7787e32efb1811403 /experimental
parent24339aa2113cf0a018109318e9900902ee5b0023 (diff)
Restructuring of PdfViewer code.
The only change in behavior is that SkPdfAllocator on SkPdfContext is no longer allocated on the heap. In general, I have just moved code. SkPdfContext: Inherit from SkNoncopyable. Make SkPdfContext directly own fTmpPageAllocator. fTmpPageAllocator is created when SkPdfContext is, and destroyed at the same time as well, so there is no reason for the extra allocation. Add the function parseStream. This eliminates code duplication, and allows making fTmpPageAllocator private. Move PdfMainLooper into the implementation file, since it is now only used by parseStream. Move SkTDictWithDefaultConstructor and render stats info here, in support of PdfMainLooper. SkPdfTokenLooper: Rename PdfTokenLooper to SkPdfTokenLooper. Move readToken here, unchanged. Remove tokenizer(), which is unused. SkPdfNativeDoc: Remove tokenizerOfPage and tokenizerOfBuffer, which are unused. SkPdfOps: Move gPdfOps and PdfOperatorRenderer into a header file (hidden for now), so they can be accessed by both SkPdfRenderer.cpp and SkPdfContext.cpp. SkPdfRenderer: Harvest things into other files: PdfMainLooper (and the code that calls it) -> SkPdfContext. readToken -> SkPdfTokenLooper. R=mtklein@google.com Review URL: https://codereview.chromium.org/79933003 git-svn-id: http://skia.googlecode.com/svn/trunk@12435 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'experimental')
-rw-r--r--experimental/PdfViewer/inc/SkPdfContext.h30
-rw-r--r--experimental/PdfViewer/inc/SkPdfTokenLooper.h24
-rw-r--r--experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.cpp15
-rw-r--r--experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h10
-rw-r--r--experimental/PdfViewer/src/SkPdfContext.cpp125
-rw-r--r--experimental/PdfViewer/src/SkPdfOps.h18
-rw-r--r--experimental/PdfViewer/src/SkPdfRenderer.cpp418
-rw-r--r--experimental/PdfViewer/src/SkPdfTokenLooper.cpp156
8 files changed, 424 insertions, 372 deletions
diff --git a/experimental/PdfViewer/inc/SkPdfContext.h b/experimental/PdfViewer/inc/SkPdfContext.h
index 7bb9c840b1..a547fd6c30 100644
--- a/experimental/PdfViewer/inc/SkPdfContext.h
+++ b/experimental/PdfViewer/inc/SkPdfContext.h
@@ -9,26 +9,40 @@
#define SkPdfContext_DEFINED
#include "SkMatrix.h"
-#include "SkTDStackNester.h"
#include "SkPdfGraphicsState.h"
+#include "SkPdfNativeTokenizer.h"
+#include "SkTDStackNester.h"
+#include "SkTypes.h"
-class SkPdfAllocator;
+class SkCanvas;
class SkPdfNativeDoc;
class SkPdfNativeObject;
-/** \class SkPdfContext
- * The context of the drawing. The document we draw from, the current stack of objects, ...
+/**
+ * The context of the drawing. The document we draw from, the current stack of
+ * objects, ...
*/
-class SkPdfContext {
+class SkPdfContext : public SkNoncopyable {
public:
+ // FIXME (scroggo): Add functions for accessing these.
SkTDStackNester<SkPdfNativeObject*> fObjectStack;
SkTDStackNester<SkPdfGraphicsState> fStateStack;
SkPdfGraphicsState fGraphicsState;
SkPdfNativeDoc* fPdfDoc;
- SkPdfAllocator* fTmpPageAllocator;
SkMatrix fOriginalMatrix;
- SkPdfContext(SkPdfNativeDoc* doc);
- ~SkPdfContext();
+ // Does not take ownership of the doc.
+ explicit SkPdfContext(SkPdfNativeDoc* doc);
+
+ /**
+ * Parse the stream and draw its commands to the canvas.
+ * FIXME (scroggo): May not be the best place for this, but leaving here
+ * for now, since it uses SkPdfContext's members.
+ */
+ void parseStream(SkPdfNativeObject* stream, SkCanvas* canvas);
+
+private:
+ // FIXME (scroggo): Is this the right place for the allocator?
+ SkPdfAllocator fTmpPageAllocator;
};
#endif // SkPdfContext_DEFINED
diff --git a/experimental/PdfViewer/inc/SkPdfTokenLooper.h b/experimental/PdfViewer/inc/SkPdfTokenLooper.h
index abbc53f7cc..8911474226 100644
--- a/experimental/PdfViewer/inc/SkPdfTokenLooper.h
+++ b/experimental/PdfViewer/inc/SkPdfTokenLooper.h
@@ -8,36 +8,44 @@
#ifndef SkPdfTokenLooper_DEFINED
#define SkPdfTokenLooper_DEFINED
+#include "SkPdfNativeTokenizer.h"
+// For SkPdfResult
+#include "SkPdfUtils.h"
+
class SkCanvas;
-class SkPdfNativeTokenizer;
class SkPdfContext;
-class PdfTokenLooper {
+class SkPdfTokenLooper {
protected:
- PdfTokenLooper* fParent;
+ SkPdfTokenLooper* fParent;
SkPdfNativeTokenizer* fTokenizer;
SkPdfContext* fPdfContext;
SkCanvas* fCanvas;
public:
- PdfTokenLooper(PdfTokenLooper* parent,
+ SkPdfTokenLooper(SkPdfTokenLooper* parent,
SkPdfNativeTokenizer* tokenizer,
SkPdfContext* pdfContext,
SkCanvas* canvas)
: fParent(parent), fTokenizer(tokenizer), fPdfContext(pdfContext), fCanvas(canvas) {}
- virtual ~PdfTokenLooper() {}
+ virtual ~SkPdfTokenLooper() {}
virtual SkPdfResult consumeToken(PdfToken& token) = 0;
virtual void loop() = 0;
- void setUp(PdfTokenLooper* parent) {
+ void setUp(SkPdfTokenLooper* parent) {
fParent = parent;
fTokenizer = parent->fTokenizer;
fPdfContext = parent->fPdfContext;
fCanvas = parent->fCanvas;
}
-
- SkPdfNativeTokenizer* tokenizer() { return fTokenizer; }
};
+
+// Calls SkPdfNativeTokenizer::readToken, and also does debugging help.
+// TODO(edisonn): Pass SkPdfContext and SkCanvas only with the define for instrumentation.
+// FIXME (scroggo): This calls tokenizer->readToken(). The rest of its functionality should
+// be moved to a debugging file.
+bool readToken(SkPdfNativeTokenizer*, PdfToken*);
+
#endif // SkPdfTokenLooper_DEFINED
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.cpp b/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.cpp
index d3fea715df..1c376b8508 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.cpp
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.cpp
@@ -479,16 +479,6 @@ SkRect SkPdfNativeDoc::MediaBox(int page) {
return SkRect::MakeEmpty();
}
-SkPdfNativeTokenizer* SkPdfNativeDoc::tokenizerOfPage(int page, SkPdfAllocator* allocator) {
- if (fPages[page]->isContentsAStream(this)) {
- return tokenizerOfStream(fPages[page]->getContentsAsStream(this), allocator);
- } else {
- // TODO(edisonn): NYI, we need to concatenate all streams in the array or
- // make the tokenizer smart so we don't allocate new memory.
- return NULL;
- }
-}
-
SkPdfNativeTokenizer* SkPdfNativeDoc::tokenizerOfStream(SkPdfNativeObject* stream,
SkPdfAllocator* allocator) {
if (stream == NULL) {
@@ -498,11 +488,6 @@ SkPdfNativeTokenizer* SkPdfNativeDoc::tokenizerOfStream(SkPdfNativeObject* strea
return new SkPdfNativeTokenizer(stream, allocator, this);
}
-SkPdfNativeTokenizer* SkPdfNativeDoc::tokenizerOfBuffer(const unsigned char* buffer, size_t len,
- SkPdfAllocator* allocator) {
- return new SkPdfNativeTokenizer(buffer, len, allocator, this);
-}
-
size_t SkPdfNativeDoc::objects() const {
return fObjects.count();
}
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h b/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h
index 73265cad89..ea04616364 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h
@@ -82,20 +82,10 @@ public:
// returns the page's mediabox i points - the page physical boundaries.
SkRect MediaBox(int page);
- // Returns a tokenizer of a page. The passed allocator will be used to allocate objects that
- // are parsed. It should be destroyed after the tokenizer.
- SkPdfNativeTokenizer* tokenizerOfPage(int n, SkPdfAllocator* allocator);
-
// Returns a tokenizer of a pdf stream. The passed allocator will be used to allocate objects
// that are parsed. It should be destroyed after the tokenizer.
SkPdfNativeTokenizer* tokenizerOfStream(SkPdfNativeObject* stream, SkPdfAllocator* allocator);
- // Returns a tokenizer of a memory buffer. The passed allocator will be used to allocate objects
- // that are parsed. It should be destroyed after the tokenizer.
- SkPdfNativeTokenizer* tokenizerOfBuffer(const unsigned char* buffer, size_t len,
- SkPdfAllocator* allocator);
-
-
//returns objects that are references and can be queried.
size_t objects() const;
diff --git a/experimental/PdfViewer/src/SkPdfContext.cpp b/experimental/PdfViewer/src/SkPdfContext.cpp
index 2ce01e75fa..6904e344b9 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);
+ }
}
diff --git a/experimental/PdfViewer/src/SkPdfOps.h b/experimental/PdfViewer/src/SkPdfOps.h
new file mode 100644
index 0000000000..1712e20812
--- /dev/null
+++ b/experimental/PdfViewer/src/SkPdfOps.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPdfOps_DEFINED
+#define SkPdfOps_DEFINED
+
+// Signature for all the operations available in pdf.
+typedef SkPdfResult (*PdfOperatorRenderer)(SkPdfContext*, SkCanvas*, SkPdfTokenLooper**);
+
+// FIXME (scroggo): Make a cleaner interface for this, and avoid statics and globals.
+// Map of string to function pointer for all known draw operations.
+extern SkTDict<PdfOperatorRenderer> gPdfOps;
+
+#endif // SkPdfOps_DEFINED
diff --git a/experimental/PdfViewer/src/SkPdfRenderer.cpp b/experimental/PdfViewer/src/SkPdfRenderer.cpp
index 3adb61c146..16e285aef8 100644
--- a/experimental/PdfViewer/src/SkPdfRenderer.cpp
+++ b/experimental/PdfViewer/src/SkPdfRenderer.cpp
@@ -32,8 +32,6 @@
// TODO(edisonn): #ifdef these ones, as they are used only for debugging.
extern "C" SkPdfContext* gPdfContext;
-extern "C" SkBitmap* gDumpBitmap;
-extern "C" SkCanvas* gDumpCanvas;
__SK_FORCE_IMAGE_DECODER_LINKING;
@@ -207,33 +205,21 @@ public:
// TODO(edisonn): this will not work in chrome! Find another solution!
StringsInit gStringsInit;
-// TODO(edisonn): Document PdfTokenLooper and subclasses.
-class PdfMainLooper : public PdfTokenLooper {
-public:
- PdfMainLooper(PdfTokenLooper* parent,
- SkPdfNativeTokenizer* tokenizer,
- SkPdfContext* pdfContext,
- SkCanvas* canvas)
- : PdfTokenLooper(parent, tokenizer, pdfContext, canvas) {}
-
- virtual SkPdfResult consumeToken(PdfToken& token);
- virtual void loop();
-};
-
-class PdfInlineImageLooper : public PdfTokenLooper {
+// TODO(edisonn): Document SkPdfTokenLooper and subclasses.
+class PdfInlineImageLooper : public SkPdfTokenLooper {
public:
PdfInlineImageLooper()
- : PdfTokenLooper(NULL, NULL, NULL, NULL) {}
+ : SkPdfTokenLooper(NULL, NULL, NULL, NULL) {}
virtual SkPdfResult consumeToken(PdfToken& token);
virtual void loop();
SkPdfResult done();
};
-class PdfCompatibilitySectionLooper : public PdfTokenLooper {
+class PdfCompatibilitySectionLooper : public SkPdfTokenLooper {
public:
PdfCompatibilitySectionLooper()
- : PdfTokenLooper(NULL, NULL, NULL, NULL) {}
+ : SkPdfTokenLooper(NULL, NULL, NULL, NULL) {}
virtual SkPdfResult consumeToken(PdfToken& token);
virtual void loop();
@@ -310,146 +296,6 @@ SkMatrix SkMatrixFromPdfArray(SkPdfArray* pdfArray) {
// TODO(edisonn): debug code, used to analyze rendering when we find bugs.
extern "C" SkPdfNativeDoc* gDoc;
-SkBitmap* gDumpBitmap = NULL;
-SkCanvas* gDumpCanvas = NULL;
-char gLastKeyword[100] = "";
-int gLastOpKeyword = -1;
-int gReadOp = 0;
-
-#ifdef PDF_TRACE_DIFF_IN_PNG
-char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh,EI,Do,EX,";
-static bool hasVisualEffect(const char* pdfOp) {
- return true;
- if (*pdfOp == '\0') return false;
-
- char markedPdfOp[100] = ",";
- strcat(markedPdfOp, pdfOp);
- strcat(markedPdfOp, ",");
-
- return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL);
-}
-#endif // PDF_TRACE_DIFF_IN_PNG
-
-// TODO(edisonn): Pass SkPdfContext and SkCanvasd only with the define for instrumentation.
-static bool readToken(SkPdfNativeTokenizer* fTokenizer, PdfToken* token) {
- bool ret = fTokenizer->readToken(token);
-
- gReadOp++;
- gLastOpKeyword++;
-#ifdef PDF_TRACE_DIFF_IN_PNG
- // TODO(edisonn): this code is used to make a step by step history of all the draw operations
- // so we could find the step where something is wrong.
- if (gLastKeyword[0] && hasVisualEffect(gLastKeyword)) {
- gDumpCanvas->flush();
-
- SkBitmap bitmap;
- setup_bitmap(&bitmap, gDumpBitmap->width(), gDumpBitmap->height());
-
- memcpy(bitmap.getPixels(), gDumpBitmap->getPixels(), gDumpBitmap->getSize());
-
- SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
- SkCanvas canvas(device);
-
- // draw context stuff here
- SkPaint blueBorder;
- blueBorder.setColor(SK_ColorBLUE);
- blueBorder.setStyle(SkPaint::kStroke_Style);
- blueBorder.setTextSize(SkDoubleToScalar(20));
-
- SkString str;
-
- const SkClipStack* clipStack = gDumpCanvas->getClipStack();
- if (clipStack) {
- SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
- const SkClipStack::Element* elem;
- double y = 0;
- int total = 0;
- while ((elem = iter.next()) != NULL) {
- total++;
- y += 30;
-
- switch (elem->getType()) {
- case SkClipStack::Element::kRect_Type:
- canvas.drawRect(elem->getRect(), blueBorder);
- canvas.drawText("Rect Clip", strlen("Rect Clip"),
- SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
- break;
- case SkClipStack::Element::kPath_Type:
- canvas.drawPath(elem->getPath(), blueBorder);
- canvas.drawText("Path Clip", strlen("Path Clip"),
- SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
- break;
- case SkClipStack::Element::kEmpty_Type:
- canvas.drawText("Empty Clip!!!", strlen("Empty Clip!!!"),
- SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
- break;
- default:
- canvas.drawText("Unkown Clip!!!", strlen("Unkown Clip!!!"),
- SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
- break;
- }
- }
-
- y += 30;
- str.printf("Number of clips in stack: %i", total);
- canvas.drawText(str.c_str(), str.size(),
- SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
- }
-
- const SkRegion& clipRegion = gDumpCanvas->getTotalClip();
- SkPath clipPath;
- if (clipRegion.getBoundaryPath(&clipPath)) {
- SkPaint redBorder;
- redBorder.setColor(SK_ColorRED);
- redBorder.setStyle(SkPaint::kStroke_Style);
- canvas.drawPath(clipPath, redBorder);
- }
-
- canvas.flush();
-
- SkString out;
-
- // TODO(edisonn): overlay on top of image inf about the clip , grafic state, the stack
-
- out.appendf("/tmp/log_step_by_step/step-%i-%s.png",
- gLastOpKeyword, gLastKeyword);
- SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);
- }
-
- if (ret && token->fType == kKeyword_TokenType &&
- token->fKeyword && token->fKeywordLength > 0 && token->fKeywordLength < 100) {
- strncpy(gLastKeyword, token->fKeyword, token->fKeywordLength);
- gLastKeyword[token->fKeywordLength] = '\0';
- } else {
- gLastKeyword[0] = '\0';
- }
-#endif
-
- return ret;
-}
-
-// Signature for all the operations available in pdf.
-typedef SkPdfResult (*PdfOperatorRenderer)(SkPdfContext*, SkCanvas*, PdfTokenLooper**);
-
-// Map of string to function pointer for all known draw operations.
-SkTDict<PdfOperatorRenderer> gPdfOps(100);
-
-// 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"
-};
static SkPdfResult DrawText(SkPdfContext* pdfContext,
const SkPdfNativeObject* _str,
@@ -501,10 +347,10 @@ static SkPdfResult DrawText(SkPdfContext* pdfContext,
}
// TODO(edisonn): create header files with declarations!
-SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper);
-SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper);
-SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper);
-SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper);
+SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper);
+SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper);
+SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper);
+SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper);
// TODO(edisonn): perf!!!
static SkColorTable* getGrayColortable() {
@@ -866,13 +712,7 @@ static SkPdfResult doXObject_Form(SkPdfContext* pdfContext, SkCanvas* canvas,
SkPdfStream* stream = (SkPdfStream*)skobj;
- SkPdfNativeTokenizer* tokenizer =
- pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageAllocator);
- if (tokenizer != NULL) {
- PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas);
- looper.loop();
- delete tokenizer;
- }
+ pdfContext->parseStream(stream, canvas);
if (skobj->has_Group()) {
canvas->restore();
@@ -921,13 +761,7 @@ static SkPdfResult doXObject_Pattern(SkPdfContext* pdfContext, SkCanvas* canvas,
SkPdfStream* stream = (SkPdfStream*)skobj;
- SkPdfNativeTokenizer* tokenizer =
- pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageAllocator);
- if (tokenizer != NULL) {
- PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas);
- looper.loop();
- delete tokenizer;
- }
+ pdfContext->parseStream(stream, canvas);
PdfOp_Q(pdfContext, canvas, NULL);
return kPartial_SkPdfResult;
@@ -971,13 +805,7 @@ SkPdfResult doType3Char(SkPdfContext* pdfContext, SkCanvas* canvas, const SkPdfN
SkPdfStream* stream = (SkPdfStream*)skobj;
- SkPdfNativeTokenizer* tokenizer =
- pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageAllocator);
- if (tokenizer != NULL) {
- PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas);
- looper.loop();
- delete tokenizer;
- }
+ pdfContext->parseStream(stream, canvas);
PdfOp_Q(pdfContext, canvas, NULL);
@@ -1080,28 +908,21 @@ static SkPdfResult doPage(SkPdfContext* pdfContext, SkCanvas* canvas,
canvas->save();
}
-
- SkPdfNativeTokenizer* tokenizer =
- pdfContext->fPdfDoc->tokenizerOfStream(stream, pdfContext->fTmpPageAllocator);
- if (tokenizer != NULL) {
- PdfMainLooper looper(NULL, tokenizer, pdfContext, canvas);
- looper.loop();
- delete tokenizer;
- }
+ pdfContext->parseStream(stream, canvas);
canvas->restore();
PdfOp_Q(pdfContext, canvas, NULL);
return kPartial_SkPdfResult;
}
-SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+SkPdfResult PdfOp_q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
pdfContext->fStateStack.push(pdfContext->fGraphicsState);
canvas->save();
pdfContext->fObjectStack.nest();
return kOK_SkPdfResult;
}
-SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
if (pdfContext->fStateStack.count() > 0) {
pdfContext->fGraphicsState = pdfContext->fStateStack.top();
pdfContext->fStateStack.pop();
@@ -1123,7 +944,7 @@ SkPdfResult PdfOp_Q(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper**
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_cm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_cm(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("cm", pdfContext, 6);
POP_NUMBER(pdfContext, f);
POP_NUMBER(pdfContext, e);
@@ -1164,7 +985,7 @@ static SkPdfResult PdfOp_cm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//leading TL Set the text leading, Tl
//, to leading, which is a number expressed in unscaled text
//space units. Text leading is used only by the T*, ', and " operators. Initial value: 0.
-static SkPdfResult PdfOp_TL(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_TL(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("TL", pdfContext, 1);
POP_NUMBER(pdfContext, ty);
CHECK_PARAMETERS();
@@ -1174,7 +995,7 @@ static SkPdfResult PdfOp_TL(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_Td(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_Td(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Td", pdfContext, 2);
POP_NUMBER(pdfContext, ty);
POP_NUMBER(pdfContext, tx);
@@ -1189,7 +1010,7 @@ static SkPdfResult PdfOp_Td(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
return kPartial_SkPdfResult;
}
-static SkPdfResult PdfOp_TD(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_TD(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("TD", pdfContext, 2)
POP_NUMBER(pdfContext, ty);
POP_NUMBER(pdfContext, tx);
@@ -1212,7 +1033,7 @@ static SkPdfResult PdfOp_TD(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
return ret;
}
-static SkPdfResult PdfOp_Tm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_Tm(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Tm", pdfContext, 6);
POP_NUMBER(pdfContext, f);
POP_NUMBER(pdfContext, e);
@@ -1248,7 +1069,7 @@ static SkPdfResult PdfOp_Tm(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//0 Tl Td
//where Tl is the current leading parameter in the text state
static SkPdfResult PdfOp_T_star(SkPdfContext* pdfContext, SkCanvas* canvas,
- PdfTokenLooper** looper) {
+ SkPdfTokenLooper** looper) {
SkPdfReal* zero = pdfContext->fPdfDoc->createReal(0.0);
SkPdfReal* tl = pdfContext->fPdfDoc->createReal(pdfContext->fGraphicsState.fTextLeading);
@@ -1260,7 +1081,7 @@ static SkPdfResult PdfOp_T_star(SkPdfContext* pdfContext, SkCanvas* canvas,
return ret;
}
-static SkPdfResult PdfOp_m(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_m(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
if (pdfContext->fGraphicsState.fPathClosed) {
pdfContext->fGraphicsState.fPath.reset();
pdfContext->fGraphicsState.fPathClosed = false;
@@ -1280,7 +1101,7 @@ static SkPdfResult PdfOp_m(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_l(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_l(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
if (pdfContext->fGraphicsState.fPathClosed) {
pdfContext->fGraphicsState.fPath.reset();
pdfContext->fGraphicsState.fPathClosed = false;
@@ -1300,7 +1121,7 @@ static SkPdfResult PdfOp_l(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_c(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_c(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
if (pdfContext->fGraphicsState.fPathClosed) {
pdfContext->fGraphicsState.fPath.reset();
pdfContext->fGraphicsState.fPathClosed = false;
@@ -1325,7 +1146,7 @@ static SkPdfResult PdfOp_c(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_v(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_v(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
if (pdfContext->fGraphicsState.fPathClosed) {
pdfContext->fGraphicsState.fPath.reset();
pdfContext->fGraphicsState.fPathClosed = false;
@@ -1351,7 +1172,7 @@ static SkPdfResult PdfOp_v(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_y(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_y(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
if (pdfContext->fGraphicsState.fPathClosed) {
pdfContext->fGraphicsState.fPath.reset();
pdfContext->fGraphicsState.fPathClosed = false;
@@ -1377,7 +1198,7 @@ static SkPdfResult PdfOp_y(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_re(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_re(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
if (pdfContext->fGraphicsState.fPathClosed) {
pdfContext->fGraphicsState.fPath.reset();
pdfContext->fGraphicsState.fPathClosed = false;
@@ -1401,7 +1222,7 @@ static SkPdfResult PdfOp_re(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_h(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_h(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
pdfContext->fGraphicsState.fPath.close();
return kOK_SkPdfResult;
}
@@ -1551,46 +1372,46 @@ static SkPdfResult PdfOp_fillAndStroke(SkPdfContext* pdfContext, SkCanvas* canva
}
-static SkPdfResult PdfOp_S(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_S(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_fillAndStroke(pdfContext, canvas, false, true, false, false);
}
-static SkPdfResult PdfOp_s(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_s(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_fillAndStroke(pdfContext, canvas, false, true, true, false);
}
-static SkPdfResult PdfOp_F(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_F(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false);
}
-static SkPdfResult PdfOp_f(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_f(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, false);
}
static SkPdfResult PdfOp_f_star(SkPdfContext* pdfContext, SkCanvas* canvas,
- PdfTokenLooper** looper) {
+ SkPdfTokenLooper** looper) {
return PdfOp_fillAndStroke(pdfContext, canvas, true, false, false, true);
}
-static SkPdfResult PdfOp_B(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_B(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, false);
}
static SkPdfResult PdfOp_B_star(SkPdfContext* pdfContext, SkCanvas* canvas,
- PdfTokenLooper** looper) {
+ SkPdfTokenLooper** looper) {
return PdfOp_fillAndStroke(pdfContext, canvas, true, true, false, true);
}
-static SkPdfResult PdfOp_b(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_b(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, false);
}
static SkPdfResult PdfOp_b_star(SkPdfContext* pdfContext, SkCanvas* canvas,
- PdfTokenLooper** looper) {
+ SkPdfTokenLooper** looper) {
return PdfOp_fillAndStroke(pdfContext, canvas, true, true, true, true);
}
-static SkPdfResult PdfOp_n(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_n(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
canvas->setMatrix(pdfContext->fGraphicsState.fCTM);
if (pdfContext->fGraphicsState.fHasClipPathToApply) {
#ifndef PDF_DEBUG_NO_CLIPING
@@ -1605,7 +1426,7 @@ static SkPdfResult PdfOp_n(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_BT(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_BT(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
pdfContext->fGraphicsState.fTextBlock = true;
SkMatrix matrix = pdfContext->fGraphicsState.fCTM;
matrix.preScale(SkDoubleToScalar(1), SkDoubleToScalar(-1));
@@ -1615,7 +1436,7 @@ static SkPdfResult PdfOp_BT(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
return kPartial_SkPdfResult;
}
-static SkPdfResult PdfOp_ET(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_ET(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
if (!pdfContext->fGraphicsState.fTextBlock) {
SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue, "ET without BT", NULL,
pdfContext);
@@ -1668,7 +1489,7 @@ static SkPdfResult skpdfGraphicsStateApplyFontCore(SkPdfContext* pdfContext,
//font resource in the Fontsubdictionary of the current resource dictionary; size is
//a number representing a scale factor. There is no initial value for either font or
//size; they must be specified explicitly using Tf before any text is shown.
-static SkPdfResult PdfOp_Tf(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_Tf(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Tf", pdfContext, 2);
POP_NUMBER(pdfContext, fontSize);
POP_NAME(pdfContext, fontName);
@@ -1677,7 +1498,7 @@ static SkPdfResult PdfOp_Tf(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
return skpdfGraphicsStateApplyFontCore(pdfContext, fontName, fontSize);
}
-static SkPdfResult PdfOp_Tj(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_Tj(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Tj", pdfContext, 1);
POP_STRING(pdfContext, str);
CHECK_PARAMETERS();
@@ -1695,7 +1516,7 @@ static SkPdfResult PdfOp_Tj(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
static SkPdfResult PdfOp_quote(SkPdfContext* pdfContext, SkCanvas* canvas,
- PdfTokenLooper** looper) {
+ SkPdfTokenLooper** looper) {
if (!pdfContext->fGraphicsState.fTextBlock) {
// TODO(edisonn): try to recover and draw it any way?
SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue,
@@ -1709,7 +1530,7 @@ static SkPdfResult PdfOp_quote(SkPdfContext* pdfContext, SkCanvas* canvas,
}
static SkPdfResult PdfOp_doublequote(SkPdfContext* pdfContext, SkCanvas* canvas,
- PdfTokenLooper** looper) {
+ SkPdfTokenLooper** looper) {
if (!pdfContext->fGraphicsState.fTextBlock) {
// TODO(edisonn): try to recover and draw it any way?
SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kMissingBT_SkPdfIssue,
@@ -1735,7 +1556,7 @@ static SkPdfResult PdfOp_doublequote(SkPdfContext* pdfContext, SkCanvas* canvas,
return kPartial_SkPdfResult;
}
-static SkPdfResult PdfOp_TJ(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_TJ(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Tf", pdfContext, 1);
POP_ARRAY(pdfContext, array);
CHECK_PARAMETERS();
@@ -1849,11 +1670,11 @@ static SkPdfResult PdfOp_CS_cs(SkPdfContext* pdfContext, SkCanvas* canvas,
return kPartial_SkPdfResult;
}
-static SkPdfResult PdfOp_CS(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_CS(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}
-static SkPdfResult PdfOp_cs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_cs(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_CS_cs(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}
@@ -1896,11 +1717,11 @@ static SkPdfResult PdfOp_SC_sc(SkPdfContext* pdfContext, SkCanvas* canvas,
return kPartial_SkPdfResult;
}
-static SkPdfResult PdfOp_SC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_SC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}
-static SkPdfResult PdfOp_sc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_sc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_SC_sc(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}
@@ -1929,11 +1750,11 @@ static SkPdfResult PdfOp_SCN_scn(SkPdfContext* pdfContext, SkCanvas* canvas,
return kPartial_SkPdfResult;
}
-static SkPdfResult PdfOp_SCN(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_SCN(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}
-static SkPdfResult PdfOp_scn(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_scn(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_SCN_scn(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}
@@ -1954,11 +1775,11 @@ static SkPdfResult PdfOp_G_g(SkPdfContext* pdfContext, SkCanvas* canvas,
return kPartial_SkPdfResult;
}
-static SkPdfResult PdfOp_G(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_G(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}
-static SkPdfResult PdfOp_g(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_g(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_G_g(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}
@@ -1975,11 +1796,11 @@ static SkPdfResult PdfOp_RG_rg(SkPdfContext* pdfContext, SkCanvas* canvas,
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_RG(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_RG(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}
-static SkPdfResult PdfOp_rg(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_rg(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_RG_rg(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}
@@ -2003,15 +1824,15 @@ static SkPdfResult PdfOp_K_k(SkPdfContext* pdfContext, SkCanvas* canvas,
return kNYI_SkPdfResult;
}
-static SkPdfResult PdfOp_K(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_K(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fStroking);
}
-static SkPdfResult PdfOp_k(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_k(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
return PdfOp_K_k(pdfContext, canvas, &pdfContext->fGraphicsState.fNonStroking);
}
-static SkPdfResult PdfOp_W(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_W(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath;
pdfContext->fGraphicsState.fHasClipPathToApply = true;
@@ -2019,7 +1840,7 @@ static SkPdfResult PdfOp_W(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
}
static SkPdfResult PdfOp_W_star(SkPdfContext* pdfContext, SkCanvas* canvas,
- PdfTokenLooper** looper) {
+ SkPdfTokenLooper** looper) {
pdfContext->fGraphicsState.fClipPath = pdfContext->fGraphicsState.fPath;
pdfContext->fGraphicsState.fClipPath.setFillType(SkPath::kEvenOdd_FillType);
@@ -2028,12 +1849,12 @@ static SkPdfResult PdfOp_W_star(SkPdfContext* pdfContext, SkCanvas* canvas,
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_BX(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_BX(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
*looper = new PdfCompatibilitySectionLooper();
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_EX(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_EX(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue,
"EX operator should not be called, it is handled in a looper, "
"unless the file is corrupted, we should assert",
@@ -2042,12 +1863,12 @@ static SkPdfResult PdfOp_EX(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
return kIgnoreError_SkPdfResult;
}
-static SkPdfResult PdfOp_BI(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_BI(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
*looper = new PdfInlineImageLooper();
return kOK_SkPdfResult;
}
-static SkPdfResult PdfOp_ID(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_ID(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue,
"ID operator should not be called, it is habdled in a looper, "
"unless the file is corrupted, we should assert",
@@ -2055,7 +1876,7 @@ static SkPdfResult PdfOp_ID(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
return kIgnoreError_SkPdfResult;
}
-static SkPdfResult PdfOp_EI(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_EI(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNullObject_SkPdfIssue,
"EI operator should not be called, it is habdled in a looper, "
"unless the file is corrupted, we should assert",
@@ -2220,7 +2041,7 @@ static void skpdfGraphicsStateApplyFont(SkPdfContext* pdfContext, SkPdfArray* fo
//lineWidth w Set the line width in the graphics state (see “Line Width” on page 152).
-static SkPdfResult PdfOp_w(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_w(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("w", pdfContext, 1);
POP_NUMBER(pdfContext, lw);
CHECK_PARAMETERS();
@@ -2229,7 +2050,7 @@ static SkPdfResult PdfOp_w(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
}
//lineCap J Set the line cap style in the graphics state (see “Line Cap Style” on page 153).
-static SkPdfResult PdfOp_J(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_J(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
// TODO(edisonn): round/ceil to int?
EXPECT_OPERANDS("J", pdfContext, 1);
POP_NUMBER(pdfContext, lc);
@@ -2239,7 +2060,7 @@ static SkPdfResult PdfOp_J(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
}
//lineJoin j Set the line join style in the graphics state (see “Line Join Style” on page 153).
-static SkPdfResult PdfOp_j(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_j(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
// TODO(edisonn): round/ceil to int?
EXPECT_OPERANDS("j", pdfContext, 1);
POP_NUMBER(pdfContext, lj);
@@ -2249,7 +2070,7 @@ static SkPdfResult PdfOp_j(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
}
//miterLimit M Set the miter limit in the graphics state (see “Miter Limit” on page 153).
-static SkPdfResult PdfOp_M(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_M(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("M", pdfContext, 1);
POP_NUMBER(pdfContext, ml);
CHECK_PARAMETERS();
@@ -2258,7 +2079,7 @@ static SkPdfResult PdfOp_M(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
//dashArray dashPhase d Set the line dash pattern in the graphics state (see “Line Dash Pattern” on
//page 155).
-static SkPdfResult PdfOp_d(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_d(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("d", pdfContext, 2);
POP_OBJ(pdfContext, phase);
POP_ARRAY(pdfContext, array);
@@ -2269,7 +2090,7 @@ static SkPdfResult PdfOp_d(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenL
//intent ri (PDF 1.1) Set the color rendering intent in the graphics state (see “Rendering Intents”
// on page 197).
-static SkPdfResult PdfOp_ri(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_ri(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
pdfContext->fObjectStack.pop();
SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "render intent NYI", NULL,
@@ -2281,7 +2102,7 @@ static SkPdfResult PdfOp_ri(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//flatness i Set the flatness tolerance in the graphics state (see Section 6.5.1, “Flatness
//Tolerance”). flatness is a number in the range 0 to 100; a value of 0 speci-
//fies the output device’s default flatness tolerance.
-static SkPdfResult PdfOp_i(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_i(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("i", pdfContext, 1);
POP_NUMBER(pdfContext, flatness);
CHECK_PARAMETERS();
@@ -2438,7 +2259,7 @@ static void skpdfGraphicsStateApplyAIS(SkPdfContext* pdfContext, bool alphaSourc
//dictName gs (PDF 1.2) Set the specified parameters in the graphics state. dictName is
//the name of a graphics state parameter dictionary in the ExtGState subdictionary of the current
//resource dictionary (see the next section).
-static SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("gs", pdfContext, 1);
POP_NAME(pdfContext, name);
CHECK_PARAMETERS();
@@ -2540,7 +2361,7 @@ static SkPdfResult PdfOp_gs(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//, to charSpace, which is a number expressed in unscaled text space units.
// Character spacing is used by the Tj, TJ, and ' operators.
//Initial value: 0.
-SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Tc", pdfContext, 1);
POP_NUMBER(pdfContext, charSpace);
CHECK_PARAMETERS();
@@ -2555,7 +2376,7 @@ SkPdfResult PdfOp_Tc(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
//, to wordSpace, which is a number expressed in unscaled
//text space units. Word spacing is used by the Tj, TJ, and ' operators. Initial
//value: 0.
-SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Tw", pdfContext, 1);
POP_NUMBER(pdfContext, wordSpace);
CHECK_PARAMETERS();
@@ -2568,7 +2389,7 @@ SkPdfResult PdfOp_Tw(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper*
//scale Tz Set the horizontal scaling, Th
//, to (scale ˜ 100). scale is a number specifying the
//percentage of the normal width. Initial value: 100 (normal width).
-static SkPdfResult PdfOp_Tz(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_Tz(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Tz", pdfContext, 1);
POP_NUMBER(pdfContext, scale);
CHECK_PARAMETERS();
@@ -2584,7 +2405,7 @@ static SkPdfResult PdfOp_Tz(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//render Tr Set the text rendering mode, T
//mode, to render, which is an integer. Initial value: 0.
-static SkPdfResult PdfOp_Tr(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_Tr(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Tr", pdfContext, 1);
POP_INTEGER(pdfContext, mode);
CHECK_PARAMETERS();
@@ -2599,7 +2420,7 @@ static SkPdfResult PdfOp_Tr(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
//rise Ts Set the text rise, Trise, to rise, which is a number expressed in unscaled text space
//units. Initial value: 0.
-static SkPdfResult PdfOp_Ts(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_Ts(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Ts", pdfContext, 1);
POP_NUMBER(pdfContext, rise);
CHECK_PARAMETERS();
@@ -2614,7 +2435,7 @@ static SkPdfResult PdfOp_Ts(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
//wx wy d0
-static SkPdfResult PdfOp_d0(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_d0(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("d0", pdfContext, 2);
POP_NUMBER(pdfContext, wy);
POP_NUMBER(pdfContext, wx);
@@ -2636,7 +2457,7 @@ static SkPdfResult PdfOp_d0(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
//wx wy llx lly urx ury d1
-static SkPdfResult PdfOp_d1(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_d1(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("d1", pdfContext, 6);
POP_NUMBER(pdfContext, ury);
POP_NUMBER(pdfContext, urx);
@@ -2655,7 +2476,7 @@ static SkPdfResult PdfOp_d1(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
//name sh
-static SkPdfResult PdfOp_sh(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_sh(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("sh", pdfContext, 1);
POP_NAME(pdfContext, name);
CHECK_PARAMETERS();
@@ -2670,7 +2491,7 @@ static SkPdfResult PdfOp_sh(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
}
//name Do
-static SkPdfResult PdfOp_Do(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_Do(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("Do", pdfContext, 1);
POP_NAME(pdfContext, name);
CHECK_PARAMETERS();
@@ -2691,7 +2512,7 @@ static SkPdfResult PdfOp_Do(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//tag MP Designate a marked-content point. tag is a name object indicating the role or
//significance of the point.
-static SkPdfResult PdfOp_MP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_MP(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("MP", pdfContext, 1);
POP_OBJ(pdfContext, tag);
CHECK_PARAMETERS();
@@ -2711,7 +2532,7 @@ static SkPdfResult PdfOp_MP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//either an inline dictionary containing the property list or a name object
//associated with it in the Properties subdictionary of the current resource
//dictionary (see Section 9.5.1, “Property Lists”).
-static SkPdfResult PdfOp_DP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_DP(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("DP", pdfContext, 2);
POP_OBJ(pdfContext, properties);
POP_OBJ(pdfContext, tag);
@@ -2735,7 +2556,7 @@ static SkPdfResult PdfOp_DP(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToken
//tag BMC Begin a marked-content sequence terminated by a balancing EMC operator.
//tag is a name object indicating the role or significance of the sequence.
-static SkPdfResult PdfOp_BMC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_BMC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("BMC", pdfContext, 1);
POP_OBJ(pdfContext, tag);
CHECK_PARAMETERS();
@@ -2755,7 +2576,7 @@ static SkPdfResult PdfOp_BMC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
// sequence; propertiesis either an inline dictionary containing the
//property list or a name object associated with it in the Properties subdictionary of the current
//resource dictionary (see Section 9.5.1, “Property Lists”).
-static SkPdfResult PdfOp_BDC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_BDC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
EXPECT_OPERANDS("BDC", pdfContext, 2);
POP_OBJ(pdfContext, properties);
POP_OBJ(pdfContext, tag);
@@ -2778,11 +2599,15 @@ static SkPdfResult PdfOp_BDC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfToke
}
//— EMC End a marked-content sequence begun by a BMC or BDC operator.
-static SkPdfResult PdfOp_EMC(SkPdfContext* pdfContext, SkCanvas* canvas, PdfTokenLooper** looper) {
+static SkPdfResult PdfOp_EMC(SkPdfContext* pdfContext, SkCanvas* canvas, SkPdfTokenLooper** looper) {
SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "EMC NYI", NULL, NULL);
return kNYI_SkPdfResult;
}
+#include "SkPdfOps.h"
+
+SkTDict<PdfOperatorRenderer> gPdfOps(100);
+
static void initPdfOperatorRenderes() {
static bool gInitialized = false;
if (gInitialized) {
@@ -2890,67 +2715,6 @@ public:
InitPdfOps gInitPdfOps;
-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);
- }
- }
-}
-
-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) {
- PdfTokenLooper* 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) {
- 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;
-}
-
-void PdfMainLooper::loop() {
- PdfToken token;
- while (readToken(fTokenizer, &token)) {
- consumeToken(token);
- }
-}
-
SkPdfResult PdfInlineImageLooper::consumeToken(PdfToken& token) {
SkASSERT(false);
return kIgnoreError_SkPdfResult;
@@ -2974,7 +2738,7 @@ void PdfCompatibilitySectionLooper::loop() {
PdfToken token;
while (readToken(fTokenizer, &token)) {
if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "BX") == 0) {
- PdfTokenLooper* looper = new PdfCompatibilitySectionLooper();
+ SkPdfTokenLooper* looper = new PdfCompatibilitySectionLooper();
looper->setUp(this);
looper->loop();
delete looper;
diff --git a/experimental/PdfViewer/src/SkPdfTokenLooper.cpp b/experimental/PdfViewer/src/SkPdfTokenLooper.cpp
new file mode 100644
index 0000000000..9193e332a4
--- /dev/null
+++ b/experimental/PdfViewer/src/SkPdfTokenLooper.cpp
@@ -0,0 +1,156 @@
+/*
+ * 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 "SkPdfTokenLooper.h"
+#include "SkPdfNativeTokenizer.h"
+#include "SkBitmap.h"
+
+#ifdef PDF_TRACE_DIFF_IN_PNG
+#include "SkBitmapDevice.h"
+#include "SkCanvas.h"
+#include "SkClipStack.h"
+#include "SkColor.h"
+#include "SkImageEncoder.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkRegion.h"
+#include "SkScalar.h"
+#include "SkString.h"
+#endif // PDF_TRACE_DIFF_IN_PNG
+
+// FIXME (scroggo): Put behind build flags.
+extern "C" SkBitmap* gDumpBitmap;
+extern "C" SkCanvas* gDumpCanvas;
+SkBitmap* gDumpBitmap = NULL;
+SkCanvas* gDumpCanvas = NULL;
+int gReadOp;
+int gLastOpKeyword;
+char gLastKeyword[100] = "";
+
+#ifdef PDF_TRACE_DIFF_IN_PNG
+// FIXME (scroggo): allOpWithVisualEffects can be local to hasVisualEffect.
+char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh,EI,Do,EX,";
+// FIXME (scroggo): has_visual_effect
+static bool hasVisualEffect(const char* pdfOp) {
+ return true;
+ if (*pdfOp == '\0') return false;
+
+ char markedPdfOp[100] = ",";
+ strcat(markedPdfOp, pdfOp);
+ strcat(markedPdfOp, ",");
+
+ return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL);
+}
+
+static void setup_bitmap(SkBitmap* bitmap, int width, int height) {
+ bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
+
+ bitmap->allocPixels();
+ bitmap->eraseColor(SK_ColorWHITE);
+}
+
+#endif // PDF_TRACE_DIFF_IN_PNG
+
+// FIXME (scroggo): fTokenizer -> tokenizer.
+bool readToken(SkPdfNativeTokenizer* fTokenizer, PdfToken* token) {
+ bool ret = fTokenizer->readToken(token);
+
+ gReadOp++;
+ gLastOpKeyword++;
+#ifdef PDF_TRACE_DIFF_IN_PNG
+ // TODO(edisonn): this code is used to make a step by step history of all the draw operations
+ // so we could find the step where something is wrong.
+ if (gLastKeyword[0] && hasVisualEffect(gLastKeyword)) {
+ gDumpCanvas->flush();
+
+ // FIXME (scroggo): Could use SkSurface/SkImage?
+ SkBitmap bitmap;
+ setup_bitmap(&bitmap, gDumpBitmap->width(), gDumpBitmap->height());
+
+ memcpy(bitmap.getPixels(), gDumpBitmap->getPixels(), gDumpBitmap->getSize());
+
+ SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
+ SkCanvas canvas(device);
+
+ // draw context stuff here
+ SkPaint blueBorder;
+ blueBorder.setColor(SK_ColorBLUE);
+ blueBorder.setStyle(SkPaint::kStroke_Style);
+ blueBorder.setTextSize(SkDoubleToScalar(20));
+
+ SkString str;
+
+ const SkClipStack* clipStack = gDumpCanvas->getClipStack();
+ if (clipStack) {
+ SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
+ const SkClipStack::Element* elem;
+ double y = 0;
+ int total = 0;
+ while ((elem = iter.next()) != NULL) {
+ total++;
+ y += 30;
+
+ switch (elem->getType()) {
+ case SkClipStack::Element::kRect_Type:
+ canvas.drawRect(elem->getRect(), blueBorder);
+ canvas.drawText("Rect Clip", strlen("Rect Clip"),
+ SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
+ break;
+ case SkClipStack::Element::kPath_Type:
+ canvas.drawPath(elem->getPath(), blueBorder);
+ canvas.drawText("Path Clip", strlen("Path Clip"),
+ SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
+ break;
+ case SkClipStack::Element::kEmpty_Type:
+ canvas.drawText("Empty Clip!!!", strlen("Empty Clip!!!"),
+ SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
+ break;
+ default:
+ canvas.drawText("Unkown Clip!!!", strlen("Unkown Clip!!!"),
+ SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
+ break;
+ }
+ }
+
+ y += 30;
+ str.printf("Number of clips in stack: %i", total);
+ canvas.drawText(str.c_str(), str.size(),
+ SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
+ }
+
+ const SkRegion& clipRegion = gDumpCanvas->getTotalClip();
+ SkPath clipPath;
+ if (clipRegion.getBoundaryPath(&clipPath)) {
+ SkPaint redBorder;
+ redBorder.setColor(SK_ColorRED);
+ redBorder.setStyle(SkPaint::kStroke_Style);
+ canvas.drawPath(clipPath, redBorder);
+ }
+
+ canvas.flush();
+
+ SkString out;
+
+ // TODO(edisonn): overlay on top of image inf about the clip , grafic state, the stack
+
+ out.appendf("/tmp/log_step_by_step/step-%i-%s.png",
+ gLastOpKeyword, gLastKeyword);
+ SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);
+ }
+
+ if (ret && token->fType == kKeyword_TokenType &&
+ token->fKeyword && token->fKeywordLength > 0 && token->fKeywordLength < 100) {
+ strncpy(gLastKeyword, token->fKeyword, token->fKeywordLength);
+ gLastKeyword[token->fKeywordLength] = '\0';
+ } else {
+ gLastKeyword[0] = '\0';
+ }
+#endif
+
+ return ret;
+}
+