Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: experimental/PdfViewer/SkPdfRenderer.cpp

Issue 18435007: pdf viewer: refactor and fix a bug (SkPdfobject should not reset on destruct) (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « experimental/PdfViewer/SkPdfRenderer.h ('k') | experimental/PdfViewer/pdf_viewer_main.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCanvas.h" 8 #include "SkCanvas.h"
9 #include "SkDevice.h" 9 #include "SkDevice.h"
10 #include "SkForceLinking.h" 10 #include "SkForceLinking.h"
(...skipping 27 matching lines...) Expand all
38 /* 38 /*
39 #ifdef PDF_TRACE 39 #ifdef PDF_TRACE
40 std::string str; 40 std::string str;
41 pdfContext->fGraphicsState.fResources->native()->ToString(str); 41 pdfContext->fGraphicsState.fResources->native()->ToString(str);
42 printf("Print Tf Resources: %s\n", str.c_str()); 42 printf("Print Tf Resources: %s\n", str.c_str());
43 #endif 43 #endif
44 */ 44 */
45 45
46 #include "SkPdfHeaders_autogen.h" 46 #include "SkPdfHeaders_autogen.h"
47 #include "SkPdfMapper_autogen.h" 47 #include "SkPdfMapper_autogen.h"
48 #include "SkPdfParser.h" 48 #include "SkPdfRenderer.h"
49 49
50 #include "SkPdfBasics.h" 50 #include "SkPdfBasics.h"
51 #include "SkPdfUtils.h" 51 #include "SkPdfUtils.h"
52 52
53 #include "SkPdfFont.h" 53 #include "SkPdfFont.h"
54 54
55 /* 55 /*
56 * TODO(edisonn): 56 * TODO(edisonn):
57 * - all font types and all ppdf font features 57 * - all font types and all ppdf font features
58 * - word spacing 58 * - word spacing
59 * - load font for baidu.pdf 59 * - load font for baidu.pdf
60 * - load font for youtube.pdf 60 * - load font for youtube.pdf
61 * - parser for pdf from the definition already available in pdfspec_autoge n.py 61 * - parser for pdf from the definition already available in pdfspec_autoge n.py
62 * - all docs from ~/work 62 * - all docs from ~/work
63 * - encapsulate native in the pdf api so the skpdf does not know anything about native ... in progress 63 * - encapsulate native in the pdf api so the skpdf does not know anything about native ... in progress
64 * - load gs/ especially smask and already known prop (skp) ... in progress 64 * - load gs/ especially smask and already known prop (skp) ... in progress
65 * - wrapper on classes for customizations? e.g. 65 * - wrapper on classes for customizations? e.g.
66 * SkPdfPageObjectVanila - has only the basic loaders/getters 66 * SkPdfPageObjectVanila - has only the basic loaders/getters
67 * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add custom izations here 67 * SkPdfPageObject : public SkPdfPageObjectVanila, extends, and I can add custom izations here
68 * need to find a nice object model for all this with constructors and factories 68 * need to find a nice object model for all this with constructors and factories
69 * - deal with inheritable automatically ? 69 * - deal with inheritable automatically ?
70 * - deal with specific type in spec directly, add all dictionary types to known types 70 * - deal with specific type in spec directly, add all dictionary types to known types
71 */ 71 */
72 72
73 using namespace std; 73 using namespace std;
74 74
75
76
77 // TODO(edisonn): Document PdfTokenLooper and subclasses.
78 class PdfTokenLooper {
79 protected:
80 PdfTokenLooper* fParent;
81 SkPdfNativeTokenizer* fTokenizer;
82 PdfContext* fPdfContext;
83 SkCanvas* fCanvas;
84
85 public:
86 PdfTokenLooper(PdfTokenLooper* parent,
87 SkPdfNativeTokenizer* tokenizer,
88 PdfContext* pdfContext,
89 SkCanvas* canvas)
90 : fParent(parent), fTokenizer(tokenizer), fPdfContext(pdfContext), fCanv as(canvas) {}
91
92 virtual ~PdfTokenLooper() {}
93
94 virtual PdfResult consumeToken(PdfToken& token) = 0;
95 virtual void loop() = 0;
96
97 void setUp(PdfTokenLooper* parent) {
98 fParent = parent;
99 fTokenizer = parent->fTokenizer;
100 fPdfContext = parent->fPdfContext;
101 fCanvas = parent->fCanvas;
102 }
103 };
104
105 class PdfMainLooper : public PdfTokenLooper {
106 public:
107 PdfMainLooper(PdfTokenLooper* parent,
108 SkPdfNativeTokenizer* tokenizer,
109 PdfContext* pdfContext,
110 SkCanvas* canvas)
111 : PdfTokenLooper(parent, tokenizer, pdfContext, canvas) {}
112
113 virtual PdfResult consumeToken(PdfToken& token);
114 virtual void loop();
115 };
116
117 class PdfInlineImageLooper : public PdfTokenLooper {
118 public:
119 PdfInlineImageLooper()
120 : PdfTokenLooper(NULL, NULL, NULL, NULL) {}
121
122 virtual PdfResult consumeToken(PdfToken& token);
123 virtual void loop();
124 PdfResult done();
125 };
126
127 class PdfCompatibilitySectionLooper : public PdfTokenLooper {
128 public:
129 PdfCompatibilitySectionLooper()
130 : PdfTokenLooper(NULL, NULL, NULL, NULL) {}
131
132 virtual PdfResult consumeToken(PdfToken& token);
133 virtual void loop();
134 };
135
75 // Utilities 136 // Utilities
76 static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color = SK_ColorWHITE) { 137 static void setup_bitmap(SkBitmap* bitmap, int width, int height, SkColor color = SK_ColorWHITE) {
77 bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); 138 bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height);
78 139
79 bitmap->allocPixels(); 140 bitmap->allocPixels();
80 bitmap->eraseColor(color); 141 bitmap->eraseColor(color);
81 } 142 }
82 143
83 // TODO(edisonn): synonyms? DeviceRGB and RGB ... 144 // TODO(edisonn): synonyms? DeviceRGB and RGB ...
84 static int GetColorSpaceComponents(const std::string& colorSpace) { 145 static int GetColorSpaceComponents(const std::string& colorSpace) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 const SkPdfObject* elem = pdfArray->operator [](i); 181 const SkPdfObject* elem = pdfArray->operator [](i);
121 if (elem == NULL || !elem->isNumber()) { 182 if (elem == NULL || !elem->isNumber()) {
122 return SkMatrix::I(); // TODO(edisonn): report issue 183 return SkMatrix::I(); // TODO(edisonn): report issue
123 } 184 }
124 array[i] = elem->numberValue(); 185 array[i] = elem->numberValue();
125 } 186 }
126 187
127 return SkMatrixFromPdfMatrix(array); 188 return SkMatrixFromPdfMatrix(array);
128 } 189 }
129 190
191
192 extern "C" SkNativeParsedPDF* gDoc;
130 SkBitmap* gDumpBitmap = NULL; 193 SkBitmap* gDumpBitmap = NULL;
131 SkCanvas* gDumpCanvas = NULL; 194 SkCanvas* gDumpCanvas = NULL;
132 char gLastKeyword[100] = ""; 195 char gLastKeyword[100] = "";
133 int gLastOpKeyword = -1; 196 int gLastOpKeyword = -1;
134 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh ,EI,Do,EX,"; 197 char allOpWithVisualEffects[100] = ",S,s,f,F,f*,B,B*,b,b*,n,Tj,TJ,\',\",d0,d1,sh ,EI,Do,EX,";
135 int gReadOp = 0; 198 int gReadOp = 0;
136 199
137 200
138 #ifdef PDF_TRACE_DIFF_IN_PNG 201 #ifdef PDF_TRACE_DIFF_IN_PNG
139 static bool hasVisualEffect(const char* pdfOp) { 202 static bool hasVisualEffect(const char* pdfOp) {
140 return true; 203 return true;
141 if (*pdfOp == '\0') return false; 204 if (*pdfOp == '\0') return false;
142 205
143 char markedPdfOp[100] = ","; 206 char markedPdfOp[100] = ",";
144 strcat(markedPdfOp, pdfOp); 207 strcat(markedPdfOp, pdfOp);
145 strcat(markedPdfOp, ","); 208 strcat(markedPdfOp, ",");
146 209
147 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL); 210 return (strstr(allOpWithVisualEffects, markedPdfOp) != NULL);
148 } 211 }
149 #endif // PDF_TRACE_DIFF_IN_PNG 212 #endif // PDF_TRACE_DIFF_IN_PNG
150 213
214
215
151 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum entation. 216 // TODO(edisonn): Pass PdfContext and SkCanvasd only with the define for instrum entation.
152 static bool readToken(SkPdfNativeTokenizer* fTokenizer, PdfToken* token) { 217 static bool readToken(SkPdfNativeTokenizer* fTokenizer, PdfToken* token) {
153 bool ret = fTokenizer->readToken(token); 218 bool ret = fTokenizer->readToken(token);
154 219
155 gReadOp++; 220 gReadOp++;
156 221
157 #ifdef PDF_TRACE_DIFF_IN_PNG 222 #ifdef PDF_TRACE_DIFF_IN_PNG
158 // TODO(edisonn): compare with old bitmap, and save only new bits are availa ble, and save 223 // TODO(edisonn): compare with old bitmap, and save only new bits are availa ble, and save
159 // the numbar and name of last operation, so the file name will reflect op t hat changed. 224 // the numbar and name of last operation, so the file name will reflect op t hat changed.
160 if (hasVisualEffect(gLastKeyword)) { // TODO(edisonn): and has dirty bits. 225 if (hasVisualEffect(gLastKeyword)) { // TODO(edisonn): and has dirty bits.
(...skipping 1688 matching lines...) Expand 10 before | Expand all | Expand 10 after
1849 // TODO(edisonn): Add API for Forms viewing and editing 1914 // TODO(edisonn): Add API for Forms viewing and editing
1850 // e.g. SkBitmap getPage(int page); 1915 // e.g. SkBitmap getPage(int page);
1851 // int formsCount(); 1916 // int formsCount();
1852 // SkForm getForm(int formID); // SkForm(SkRect, .. other data) 1917 // SkForm getForm(int formID); // SkForm(SkRect, .. other data)
1853 // TODO (edisonn): Add intend when loading pdf, for example: for viewing, parsin g all content, ... 1918 // TODO (edisonn): Add intend when loading pdf, for example: for viewing, parsin g all content, ...
1854 // if we load the first page, and we zoom to fit to screen horizontally, then lo ad only those 1919 // if we load the first page, and we zoom to fit to screen horizontally, then lo ad only those
1855 // resources needed, so the preview is fast. 1920 // resources needed, so the preview is fast.
1856 // TODO (edisonn): hide parser/tokenizer behind and interface and a query langua ge, and resolve 1921 // TODO (edisonn): hide parser/tokenizer behind and interface and a query langua ge, and resolve
1857 // references automatically. 1922 // references automatically.
1858 1923
1859 bool SkPdfViewer::load(const SkString inputFileName, SkPicture* out) { 1924 PdfContext* gPdfContext = NULL;
1860 std::cout << "PDF Loaded: " << inputFileName.c_str() << std::endl;
1861 1925
1862 SkNativeParsedPDF* doc = new SkNativeParsedPDF(inputFileName.c_str()); 1926 bool SkPdfRenderer::renderPage(int page, SkCanvas* canvas) const {
1863 if (!doc->pages()) 1927 if (!fPdfDoc) {
1864 {
1865 std::cout << "ERROR: Empty PDF Document" << inputFileName.c_str() << std ::endl;
1866 return false; 1928 return false;
1867 } else { 1929 }
1868 1930
1869 for (int pn = 0; pn < doc->pages(); ++pn) { 1931 if (page < 0 || page >= pages()) {
1870 // TODO(edisonn): implement inheritance properties as per PDF spec 1932 return false;
1871 //SkRect rect = page->MediaBox(); 1933 }
1872 SkRect rect = doc->MediaBox(pn);
1873 1934
1874 #ifdef PDF_TRACE 1935 SkPdfNativeTokenizer* tokenizer = fPdfDoc->tokenizerOfPage(page);
1875 printf("Page Width: %f, Page Height: %f\n", SkScalarToDouble(rect.wi dth()), SkScalarToDouble(rect.height())); 1936
1937 PdfContext pdfContext(fPdfDoc);
1938 pdfContext.fOriginalMatrix = SkMatrix::I();
1939 pdfContext.fGraphicsState.fResources = fPdfDoc->pageResources(page);
1940
1941 gPdfContext = &pdfContext;
1942
1943 // TODO(edisonn): get matrix stuff right.
1944 // TODO(edisonn): add DPI/scale/zoom.
1945 SkScalar z = SkIntToScalar(0);
1946 SkRect rect = fPdfDoc->MediaBox(page);
1947 SkScalar w = rect.width();
1948 SkScalar h = rect.height();
1949
1950 SkPoint pdfSpace[4] = {SkPoint::Make(z, z), SkPoint::Make(w, z), SkPoint::Ma ke(w, h), SkPoint::Make(z, h)};
1951 // SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w, h), SkPoint::Make(w, z), SkPoint::Make(z, z)};
1952
1953 // TODO(edisonn): add flag for this app to create sourunding buffer zone
1954 // TODO(edisonn): add flagg for no clipping.
1955 // Use larger image to make sure we do not draw anything outside of page
1956 // could be used in tests.
1957
1958 #ifdef PDF_DEBUG_3X
1959 SkPoint skiaSpace[4] = {SkPoint::Make(w+z, h+h), SkPoint::Make(w+w, h+h), Sk Point::Make(w+w, h+z), SkPoint::Make(w+z, h+z)};
1960 #else
1961 SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w, h), SkPoint::M ake(w, z), SkPoint::Make(z, z)};
1962 #endif
1963 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(w, h)};
1964 //SkPoint skiaSpace[2] = {SkPoint::Make(w, z), SkPoint::Make(z, h)};
1965
1966 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(z, h)};
1967 //SkPoint skiaSpace[2] = {SkPoint::Make(z, h), SkPoint::Make(z, z)};
1968
1969 //SkPoint pdfSpace[3] = {SkPoint::Make(z, z), SkPoint::Make(z, h), SkPoint:: Make(w, h)};
1970 //SkPoint skiaSpace[3] = {SkPoint::Make(z, h), SkPoint::Make(z, z), SkPoint: :Make(w, 0)};
1971
1972 SkAssertResult(pdfContext.fOriginalMatrix.setPolyToPoly(pdfSpace, skiaSpace, 4));
1973 SkTraceMatrix(pdfContext.fOriginalMatrix, "Original matrix");
1974
1975
1976 pdfContext.fGraphicsState.fMatrix = pdfContext.fOriginalMatrix;
1977 pdfContext.fGraphicsState.fMatrixTm = pdfContext.fGraphicsState.fMatrix;
1978 pdfContext.fGraphicsState.fMatrixTlm = pdfContext.fGraphicsState.fMatrix;
1979
1980 canvas->setMatrix(pdfContext.fOriginalMatrix);
1981
1982 #ifndef PDF_DEBUG_NO_PAGE_CLIPING
1983 canvas->clipRect(SkRect::MakeXYWH(z, z, w, h), SkRegion::kIntersect_Op, true );
1876 #endif 1984 #endif
1877 1985
1878 // TODO(edisonn): page->GetCropBox(), page->GetTrimBox() ... how to use? 1986 // erase with red before?
1987 // SkPaint paint;
1988 // paint.setColor(SK_ColorRED);
1989 // canvas->drawRect(rect, paint);
1879 1990
1880 SkBitmap bitmap; 1991 PdfMainLooper looper(NULL, tokenizer, &pdfContext, canvas);
1881 #ifdef PDF_DEBUG_3X 1992 looper.loop();
1882 setup_bitmap(&bitmap, 3 * (int)SkScalarToDouble(rect.width()), 3 * ( int)SkScalarToDouble(rect.height()));
1883 #else
1884 setup_bitmap(&bitmap, (int)SkScalarToDouble(rect.width()), (int)SkSc alarToDouble(rect.height()));
1885 #endif
1886 SkAutoTUnref<SkDevice> device(SkNEW_ARGS(SkDevice, (bitmap)));
1887 SkCanvas canvas(device);
1888 1993
1889 gDumpBitmap = &bitmap; 1994 delete tokenizer;
1890 1995
1891 gDumpCanvas = &canvas; 1996 canvas->flush();
1892 doc->drawPage(pn, &canvas);
1893
1894 SkString out;
1895 if (doc->pages() > 1) {
1896 out.appendf("%s-%i.png", inputFileName.c_str(), pn);
1897 } else {
1898 out = inputFileName;
1899 // .pdf -> .png
1900 out[out.size() - 2] = 'n';
1901 out[out.size() - 1] = 'g';
1902 }
1903 SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG _Type, 100);
1904 }
1905 return true;
1906 }
1907
1908 return true; 1997 return true;
1909 } 1998 }
1999
2000 bool SkPdfRenderer::load(const SkString inputFileName) {
2001 unload();
2002
2003 // TODO(edisonn): create static function that could return NULL if there are errors
2004 fPdfDoc = new SkNativeParsedPDF(inputFileName.c_str());
2005
2006 return fPdfDoc != NULL;
2007 }
2008
2009 int SkPdfRenderer::pages() const {
2010 return fPdfDoc != NULL ? fPdfDoc->pages() : 0;
2011 }
2012
2013 void SkPdfRenderer::unload() {
2014 delete fPdfDoc;
2015 fPdfDoc = NULL;
2016 }
2017
2018 SkRect SkPdfRenderer::MediaBox(int page) const {
2019 SkASSERT(fPdfDoc);
2020 return fPdfDoc->MediaBox(page);
2021 }
OLDNEW
« no previous file with comments | « experimental/PdfViewer/SkPdfRenderer.h ('k') | experimental/PdfViewer/pdf_viewer_main.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698