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:22:31 +0000
committerGravatar scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-12-02 20:22:31 +0000
commit5092adc5461a7c5cb3e1fad01be2174c3f4a0c46 (patch)
tree9c53fcd18cac52b437d21dcb6dc2154bbfc26792 /experimental
parent248647cebb3724fd2ce1d41745afb786516af4f8 (diff)
Separate and update PDF_DIFF_TRACE_IN_PNG
Move its functionality out of readToken() and into its own class. Callers of the previous readToken() now call SkPdfNativeTokenizer::readToken(), which in turn calls a function for writing the diff to a file, if the caller requests it and PDF_TRACE_DIFF_IN_PNG is defined. Do not attempt to draw a diff for compatibility sections, which we do not draw. Use SkString to handle string manipulation. Hide globals only used by PDF_TRACE_DIFF_IN_PNG behind that flag. Remove hasVisualEffects, which always returns true. Rename gLastOpKeyword to gOpCounter for clarity. In SkPdfNativeTokenizer, set fEmpty to true when the entire stream has been read. Use SkBitmap::copyTo instead of manually copying an SkBitmap. Builds on https://codereview.chromium.org/79933003/ R=mtklein@google.com Review URL: https://codereview.chromium.org/80463005 git-svn-id: http://skia.googlecode.com/svn/trunk@12436 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'experimental')
-rw-r--r--experimental/PdfViewer/inc/SkPdfDiffEncoder.h25
-rw-r--r--experimental/PdfViewer/inc/SkPdfTokenLooper.h6
-rw-r--r--experimental/PdfViewer/pdf_viewer_main.cpp6
-rw-r--r--experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp21
-rw-r--r--experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h5
-rw-r--r--experimental/PdfViewer/src/SkPdfContext.cpp5
-rw-r--r--experimental/PdfViewer/src/SkPdfDiffEncoder.cpp131
-rw-r--r--experimental/PdfViewer/src/SkPdfRenderer.cpp2
-rw-r--r--experimental/PdfViewer/src/SkPdfTokenLooper.cpp156
9 files changed, 182 insertions, 175 deletions
diff --git a/experimental/PdfViewer/inc/SkPdfDiffEncoder.h b/experimental/PdfViewer/inc/SkPdfDiffEncoder.h
new file mode 100644
index 0000000000..9acd82f569
--- /dev/null
+++ b/experimental/PdfViewer/inc/SkPdfDiffEncoder.h
@@ -0,0 +1,25 @@
+/*
+ * 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 SkPdfDiffEncoder_DEFINED
+#define SkPdfDiffEncoder_DEFINED
+
+struct PdfToken;
+
+namespace SkPdfDiffEncoder {
+ /**
+ * If PDF_TRACE_DIFF_IN_PNG is defined, the PDF commands so far are written
+ * to a file with the difference created by using this token highlighted.
+ * The file is named "/tmp/log_step_by_step/step-%i-%s.png", where %i is
+ * the number of the command and %s is the name of the command. If
+ * PDF_TRACE_DIFF_IN_PNG is not defined this function does nothing.
+ * TODO(scroggo): Pass SkPdfContext and SkCanvas for info.
+ */
+ void WriteToFile(PdfToken*);
+};
+
+#endif // SkPdfDiffEncoder_DEFINED
diff --git a/experimental/PdfViewer/inc/SkPdfTokenLooper.h b/experimental/PdfViewer/inc/SkPdfTokenLooper.h
index 8911474226..8deca1708e 100644
--- a/experimental/PdfViewer/inc/SkPdfTokenLooper.h
+++ b/experimental/PdfViewer/inc/SkPdfTokenLooper.h
@@ -42,10 +42,4 @@ public:
}
};
-// 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/pdf_viewer_main.cpp b/experimental/PdfViewer/pdf_viewer_main.cpp
index 5ecd2dbd97..6395585c4d 100644
--- a/experimental/PdfViewer/pdf_viewer_main.cpp
+++ b/experimental/PdfViewer/pdf_viewer_main.cpp
@@ -13,6 +13,7 @@
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
+#include "SkPdfConfig.h"
#include "SkPdfRenderer.h"
#include "SkPicture.h"
#include "SkStream.h"
@@ -122,8 +123,10 @@ static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color)
* @param page -1 means there is only one page (0), and render in a file without page extension
*/
+#ifdef PDF_TRACE_DIFF_IN_PNG
extern "C" SkBitmap* gDumpBitmap;
extern "C" SkCanvas* gDumpCanvas;
+#endif
#if SK_SUPPORT_GPU
GrContextFactory gContextFactory;
@@ -192,9 +195,10 @@ static bool render_page(const SkString& outputDir,
}
SkCanvas canvas(device);
+#ifdef PDF_TRACE_DIFF_IN_PNG
gDumpBitmap = &bitmap;
-
gDumpCanvas = &canvas;
+#endif
renderer.renderPage(page < 0 ? 0 : page, &canvas, rect);
SkString outputPath;
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp
index 79935bc954..5dfe14e5fc 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp
@@ -6,6 +6,7 @@
*/
#include "SkPdfConfig.h"
+#include "SkPdfDiffEncoder.h"
#include "SkPdfNativeObject.h"
#include "SkPdfNativeTokenizer.h"
#include "SkPdfUtils.h"
@@ -940,6 +941,7 @@ bool SkPdfNativeTokenizer::readTokenCore(PdfToken* token) {
fUncompressedStream = skipPdfWhiteSpaces(fUncompressedStream, fUncompressedStreamEnd);
if (fUncompressedStream >= fUncompressedStreamEnd) {
+ fEmpty = true;
return false;
}
@@ -985,26 +987,33 @@ void SkPdfNativeTokenizer::PutBack(PdfToken token) {
#endif
}
-bool SkPdfNativeTokenizer::readToken(PdfToken* token) {
+bool SkPdfNativeTokenizer::readToken(PdfToken* token, bool writeDiff) {
if (fHasPutBack) {
*token = fPutBack;
fHasPutBack = false;
#ifdef PDF_TRACE_READ_TOKEN
- printf("READ_BACK %s %s\n", token->fType == kKeyword_TokenType ? "Keyword" : "Object",
- token->fKeyword ? SkString(token->fKeyword, token->fKeywordLength).c_str() :
- token->fObject->toString().c_str());
+ printf("READ_BACK %s %s\n", token->fType == kKeyword_TokenType ? "Keyword" : "Object",
+ token->fKeyword ? SkString(token->fKeyword, token->fKeywordLength).c_str() :
+ token->fObject->toString().c_str());
#endif
+ if (writeDiff) {
+ SkPdfDiffEncoder::WriteToFile(token);
+ }
return true;
}
if (fEmpty) {
#ifdef PDF_TRACE_READ_TOKEN
- printf("EMPTY TOKENIZER\n");
+ printf("EMPTY TOKENIZER\n");
#endif
return false;
}
- return readTokenCore(token);
+ const bool result = readTokenCore(token);
+ if (result && writeDiff) {
+ SkPdfDiffEncoder::WriteToFile(token);
+ }
+ return result;
}
#define DECLARE_PDF_NAME(longName) SkPdfName longName((char*)#longName)
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h
index 8ed354cfa1..79b070f12e 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.h
@@ -165,7 +165,10 @@ public:
virtual ~SkPdfNativeTokenizer();
// Reads one token. Returns false if there are no more tokens.
- bool readToken(PdfToken* token);
+ // If writeDiff is true, and a token was read, create a PNG highlighting
+ // the difference caused by this command in /tmp/log_step_by_step.
+ // If PDF_TRACE_DIFF_IN_PNG is not defined, writeDiff does nothing.
+ bool readToken(PdfToken* token, bool writeDiff = false);
// Put back a token to be read in the nextToken read. Only one token is allowed to be put
// back. Must not necesaarely be the last token read.
diff --git a/experimental/PdfViewer/src/SkPdfContext.cpp b/experimental/PdfViewer/src/SkPdfContext.cpp
index 6904e344b9..c2162556bb 100644
--- a/experimental/PdfViewer/src/SkPdfContext.cpp
+++ b/experimental/PdfViewer/src/SkPdfContext.cpp
@@ -126,10 +126,7 @@ SkPdfResult PdfMainLooper::consumeToken(PdfToken& token) {
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)) {
+ while (fTokenizer->readToken(&token, true)) {
this->consumeToken(token);
}
}
diff --git a/experimental/PdfViewer/src/SkPdfDiffEncoder.cpp b/experimental/PdfViewer/src/SkPdfDiffEncoder.cpp
new file mode 100644
index 0000000000..5d4c4322dc
--- /dev/null
+++ b/experimental/PdfViewer/src/SkPdfDiffEncoder.cpp
@@ -0,0 +1,131 @@
+/*
+ * 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 "SkPdfDiffEncoder.h"
+#include "SkPdfNativeTokenizer.h"
+
+#ifdef PDF_TRACE_DIFF_IN_PNG
+#include "SkBitmap.h"
+#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"
+
+extern "C" SkBitmap* gDumpBitmap;
+extern "C" SkCanvas* gDumpCanvas;
+SkBitmap* gDumpBitmap = NULL;
+SkCanvas* gDumpCanvas = NULL;
+static int gReadOp;
+static int gOpCounter;
+static SkString gLastKeyword;
+#endif // PDF_TRACE_DIFF_IN_PNG
+
+void SkPdfDiffEncoder::WriteToFile(PdfToken* token) {
+#ifdef PDF_TRACE_DIFF_IN_PNG
+ gReadOp++;
+ gOpCounter++;
+
+ // Only attempt to write if the dump bitmap and canvas are non NULL. They are set by
+ // pdf_viewer_main.cpp
+ if (NULL == gDumpBitmap || NULL == gDumpCanvas) {
+ return;
+ }
+
+ // 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.isEmpty()) {
+ gDumpCanvas->flush();
+
+ // Copy the existing drawing. Then we will draw the difference caused by this command,
+ // highlighted with a blue border.
+ SkBitmap bitmap;
+ if (gDumpBitmap->copyTo(&bitmap, SkBitmap::kARGB_8888_Config)) {
+
+ 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("Unknown Clip!!!", strlen("Unknown 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", gOpCounter, gLastKeyword.c_str());
+
+ SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);
+ }
+ }
+
+ if (token->fType == kKeyword_TokenType && token->fKeyword && token->fKeywordLength > 0) {
+ gLastKeyword.set(token->fKeyword, token->fKeywordLength);
+ } else {
+ gLastKeyword.reset();
+ }
+#endif
+}
+
diff --git a/experimental/PdfViewer/src/SkPdfRenderer.cpp b/experimental/PdfViewer/src/SkPdfRenderer.cpp
index 16e285aef8..69adbda415 100644
--- a/experimental/PdfViewer/src/SkPdfRenderer.cpp
+++ b/experimental/PdfViewer/src/SkPdfRenderer.cpp
@@ -2736,7 +2736,7 @@ void PdfCompatibilitySectionLooper::loop() {
PdfOp_q(fPdfContext, fCanvas, NULL);
PdfToken token;
- while (readToken(fTokenizer, &token)) {
+ while (fTokenizer->readToken(&token)) {
if (token.fType == kKeyword_TokenType && strcmp(token.fKeyword, "BX") == 0) {
SkPdfTokenLooper* looper = new PdfCompatibilitySectionLooper();
looper->setUp(this);
diff --git a/experimental/PdfViewer/src/SkPdfTokenLooper.cpp b/experimental/PdfViewer/src/SkPdfTokenLooper.cpp
deleted file mode 100644
index 9193e332a4..0000000000
--- a/experimental/PdfViewer/src/SkPdfTokenLooper.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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;
-}
-