Add an option to have a PdfViewer in SampleApp. Add a parameter --pdfDir to pass the dir with pdfs. Add flag --sort to sort samples acording to title, so foo.skp follows foo.pdf and we can quickly compare diffs.
The option needs to be enabled manually by developer to be compiled locally, since the pdf viewer is work in progress.

R=reed@google.com

Review URL: https://codereview.chromium.org/17904006

git-svn-id: http://skia.googlecode.com/svn/trunk@10004 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp
index f379f99..5d7a7b0 100644
--- a/samplecode/SampleApp.cpp
+++ b/samplecode/SampleApp.cpp
@@ -15,6 +15,7 @@
 #include "SkPaint.h"
 #include "SkPicture.h"
 #include "SkStream.h"
+#include "SkTSort.h"
 #include "SkTime.h"
 #include "SkWindow.h"
 
@@ -54,6 +55,19 @@
     }
 };
 
+#ifdef SAMPLE_PDF_FILE_VIEWER
+extern SampleView* CreateSamplePdfFileViewer(const char filename[]);
+
+class PdfFileViewerFactory : public SkViewFactory {
+    SkString fFilename;
+public:
+    PdfFileViewerFactory(const SkString& filename) : fFilename(filename) {}
+    virtual SkView* operator() () const SK_OVERRIDE {
+        return CreateSamplePdfFileViewer(fFilename.c_str());
+    }
+};
+#endif  // SAMPLE_PDF_FILE_VIEWER
+
 #define PIPE_FILEx
 #ifdef  PIPE_FILE
 #define FILE_PATH "/path/to/drawing.data"
@@ -690,12 +704,29 @@
 }
 
 static void usage(const char * argv0) {
-    SkDebugf("%s [--slide sampleName] [-i resourcePath] [--msaa sampleCount] [--pictureDir dirPath] [--picture path]\n", argv0);
+    SkDebugf("%s [--slide sampleName] [-i resourcePath] [--msaa sampleCount] [--pictureDir dirPath] [--picture path] [--sort]\n", argv0);
+#ifdef SAMPLE_PDF_FILE_VIEWER
+    SkDebugf("                [--pdfDir pdfPath]\n");
+    SkDebugf("    pdfPath: path to directory pdf files are read from\n");
+#endif  // SAMPLE_PDF_FILE_VIEWER
     SkDebugf("    sampleName: sample at which to start.\n");
     SkDebugf("    resourcePath: directory that stores image resources.\n");
     SkDebugf("    msaa: request multisampling with the given sample count.\n");
     SkDebugf("    dirPath: path to directory skia pictures are read from\n");
     SkDebugf("    path: path to skia picture\n");
+    SkDebugf("    --sort: sort samples by title, this would help to compare pdf rendering (P:foo.pdf) with skp rendering (P:foo.pdf)\n");
+}
+
+static SkString getSampleTitle(const SkViewFactory* sampleFactory) {
+    SkView* view = (*sampleFactory)();
+    SkString title;
+    SampleCode::RequestTitle(view, &title);
+    view->unref();
+    return title;
+}
+
+bool compareSampleTitle(const SkViewFactory* first, const SkViewFactory* second) {
+    return strcmp(getSampleTitle(first).c_str(), getSampleTitle(second).c_str()) < 0;
 }
 
 SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* devManager)
@@ -706,6 +737,9 @@
 
     this->registerPictFileSamples(argv, argc);
     this->registerPictFileSample(argv, argc);
+#ifdef SAMPLE_PDF_FILE_VIEWER
+    this->registerPdfFileViewerSamples(argv, argc);
+#endif  // SAMPLE_PDF_FILE_VIEWER
     SkGMRegistyToSampleRegistry();
     {
         const SkViewRegister* reg = SkViewRegister::Head();
@@ -715,6 +749,20 @@
         }
     }
 
+    bool sort = false;
+    for (int i = 0; i < argc; ++i) {
+        if (!strcmp(argv[i], "--sort")) {
+            sort = true;
+            break;
+        }
+    }
+
+    if (sort) {
+        // Sort samples, so foo.skp and foo.pdf are consecutive and we can quickly spot where
+        // skp -> pdf -> png fails.
+        SkTQSort(fSamples.begin(), fSamples.end() ? fSamples.end() - 1 : NULL, compareSampleTitle);
+    }
+
     const char* resourcePath = NULL;
     fMSAASampleCount = 0;
 
@@ -970,6 +1018,32 @@
     }
 }
 
+#ifdef SAMPLE_PDF_FILE_VIEWER
+void SampleWindow::registerPdfFileViewerSamples(char** argv, int argc) {
+    const char* pdfDir = NULL;
+
+    for (int i = 0; i < argc; ++i) {
+        if (!strcmp(argv[i], "--pdfDir")) {
+            i += 1;
+            if (i < argc) {
+                pdfDir = argv[i];
+                break;
+            }
+        }
+    }
+    if (pdfDir) {
+        SkOSFile::Iter iter(pdfDir, "pdf");
+        SkString filename;
+        while (iter.next(&filename)) {
+            SkString path;
+            make_filepath(&path, pdfDir, filename);
+            *fSamples.append() = new PdfFileViewerFactory(path);
+        }
+    }
+}
+#endif  // SAMPLE_PDF_FILE_VIEWER
+
+
 int SampleWindow::findByTitle(const char title[]) {
     int i, count = fSamples.count();
     for (i = 0; i < count; i++) {
@@ -1540,11 +1614,7 @@
 }
 
 SkString SampleWindow::getSampleTitle(int i) {
-    SkView* view = (*fSamples[i])();
-    SkString title;
-    SampleCode::RequestTitle(view, &title);
-    view->unref();
-    return title;
+    return ::getSampleTitle(fSamples[i]);
 }
 
 int SampleWindow::sampleCount() {
diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h
index 714c39d..61e6c5d 100644
--- a/samplecode/SampleApp.h
+++ b/samplecode/SampleApp.h
@@ -158,6 +158,11 @@
     void registerPictFileSamples(char** argv, int argc);
     void registerPictFileSample(char** argv, int argc);
 
+#ifdef SAMPLE_PDF_FILE_VIEWER
+    void registerPdfFileViewerSamples(char** argv, int argc);
+#endif  // SAMPLE_PDF_FILE_VIEWER
+
+
 private:
     class DefaultDeviceManager;
 
diff --git a/samplecode/SamplePdfFileViewer.cpp b/samplecode/SamplePdfFileViewer.cpp
new file mode 100644
index 0000000..cd39901
--- /dev/null
+++ b/samplecode/SamplePdfFileViewer.cpp
@@ -0,0 +1,106 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifdef SAMPLE_PDF_FILE_VIEWER
+
+#include "SampleCode.h"
+#include "SkDumpCanvas.h"
+#include "SkView.h"
+#include "SkCanvas.h"
+#include "Sk64.h"
+#include "SkGradientShader.h"
+#include "SkGraphics.h"
+#include "SkImageDecoder.h"
+#include "SkOSFile.h"
+#include "SkPath.h"
+#include "SkPicture.h"
+#include "SkRandom.h"
+#include "SkRegion.h"
+#include "SkShader.h"
+#include "SkUtils.h"
+#include "SkColorPriv.h"
+#include "SkColorFilter.h"
+#include "SkTime.h"
+#include "SkTypeface.h"
+#include "SkXfermode.h"
+
+#include "SkPodofoParsedPDF.h"
+
+class PdfFileViewer : public SampleView {
+private:
+    SkString    fFilename;
+    SkPicture*  fPicture;  // TODO(edisonn): multiple pages, one page / picture, make it an array
+
+    static SkPicture* LoadPdf(const char path[]) {
+        SkPicture* pic = NULL;
+
+        SkPodofoParsedPDF doc(path);
+        if (doc.pages()) {
+            pic = SkNEW(SkPicture);
+            SkCanvas* canvas = pic->beginRecording((int)doc.width(0), (int)doc.height(0));
+            doc.drawPage(0, canvas);
+            pic->endRecording();
+        }
+        return pic;
+    }
+
+public:
+    PdfFileViewer(const char name[] = NULL) : fFilename(name) {
+        fPicture = NULL;
+    }
+
+    virtual ~PdfFileViewer() {
+        SkSafeUnref(fPicture);
+    }
+
+protected:
+    // overrides from SkEventSink
+    virtual bool onQuery(SkEvent* evt) {
+        if (SampleCode::TitleQ(*evt)) {
+            SkString name("P:");
+            const char* basename = strrchr(fFilename.c_str(), SkPATH_SEPARATOR);
+            name.append(basename ? basename+1: fFilename.c_str());
+            SampleCode::TitleR(evt, name.c_str());
+            return true;
+        }
+        return this->INHERITED::onQuery(evt);
+    }
+
+    virtual bool onEvent(const SkEvent& evt) {
+        // TODO(edisonn): add here event handlers to disable clipping, or to show helpful info
+        // like pdf object from click, ...
+        // TODO(edisonn): first, next, prev, last page navigation + slideshow
+        return this->INHERITED::onEvent(evt);
+    }
+
+    virtual void onDrawContent(SkCanvas* canvas) {
+        if (!fPicture) {
+            fPicture = LoadPdf(fFilename.c_str());
+        }
+        if (fPicture) {
+            canvas->drawPicture(*fPicture);
+        }
+    }
+
+private:
+    typedef SampleView INHERITED;
+};
+
+SampleView* CreateSamplePdfFileViewer(const char filename[]);
+SampleView* CreateSamplePdfFileViewer(const char filename[]) {
+    return new PdfFileViewer(filename);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+#if 0
+static SkView* MyFactory() { return new PdfFileViewer; }
+static SkViewRegister reg(MyFactory);
+#endif
+
+#endif  // SAMPLE_PDF_FILE_VIEWER