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

Side by Side Diff: experimental/PdfViewer/SkPdfParser.h

Issue 18042005: isolate podofo to prepare for native parser, autogenerate PDF API during build (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/SkPdfFont.cpp ('k') | experimental/PdfViewer/SkPdfParser.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 "podofo.h"
9 #include "SkPdfHeaders_autogen.h" 8 #include "SkPdfHeaders_autogen.h"
10 #include "SkPdfPodofoMapper_autogen.h" 9 #include "SkPdfMapper_autogen.h"
11 10
12 #ifndef SkPdfParser_DEFINED 11 #ifndef SkPdfParser_DEFINED
13 #define SkPdfParser_DEFINED 12 #define SkPdfParser_DEFINED
14 13
15 14 #include "SkPdfBasics.h"
16 enum SkPdfTokenType { 15 #include "SkPdfPodofoTokenizer.h"
17 kKeyword_TokenType,
18 kObject_TokenType,
19 kImageData_TokenType, // TODO(edisonn): inline images seem to work without it
20 };
21
22 struct PdfToken {
23 const char* fKeyword;
24 SkPdfObject* fObject;
25 SkPdfTokenType fType;
26
27 PdfToken() : fKeyword(NULL), fObject(NULL) {}
28 };
29
30 class SkPdfTokenizer {
31 PdfMemDocument* fDoc;
32 PdfContentsTokenizer* fTokenizer;
33
34 char* fUncompressedStream;
35 pdf_long fUncompressedStreamLength;
36
37 bool fEmpty;
38 bool fHasPutBack;
39 PdfToken fPutBack;
40
41 public:
42 SkPdfTokenizer(PdfMemDocument* doc = NULL, PdfContentsTokenizer* tokenizer = NULL) : fDoc(doc), fTokenizer(tokenizer), fUncompressedStream(NULL), fUncompres sedStreamLength(0), fEmpty(false), fHasPutBack(false) {}
43 SkPdfTokenizer(const SkPdfObject* objWithStream) : fDoc(NULL), fTokenizer(NU LL), fEmpty(false), fHasPutBack(false) {
44 fUncompressedStream = NULL;
45 fUncompressedStreamLength = 0;
46
47 fDoc = NULL;
48
49
50 try {
51 objWithStream->podofo()->GetStream()->GetFilteredCopy(&fUncompressed Stream, &fUncompressedStreamLength);
52 if (fUncompressedStream != NULL && fUncompressedStreamLength != 0) {
53 fTokenizer = new PdfContentsTokenizer(fUncompressedStream, fUnco mpressedStreamLength);
54 } else {
55 fEmpty = true;
56 }
57 } catch (PdfError& e) {
58 fEmpty = true;
59 }
60
61 }
62
63 SkPdfTokenizer(const char* buffer, int len) : fDoc(NULL), fTokenizer(NULL), fUncompressedStream(NULL), fUncompressedStreamLength(0), fEmpty(false), fHasPutB ack(false) {
64 try {
65 fTokenizer = new PdfContentsTokenizer(buffer, len);
66 } catch (PdfError& e) {
67 fEmpty = true;
68 }
69 }
70
71 ~SkPdfTokenizer() {
72 free(fUncompressedStream);
73 }
74
75 void PutBack(PdfToken token) {
76 SkASSERT(!fHasPutBack);
77 fHasPutBack = true;
78 fPutBack = token;
79 }
80
81 bool readToken(PdfToken* token) {
82 if (fHasPutBack) {
83 *token = fPutBack;
84 fHasPutBack = false;
85 return true;
86 }
87
88 if (fEmpty) {
89 return false;
90 }
91
92 PdfVariant var;
93 EPdfContentsType type;
94
95 token->fKeyword = NULL;
96 token->fObject = NULL;
97
98 bool ret = fTokenizer->ReadNext(type, token->fKeyword, var);
99
100 if (!ret) return ret;
101
102 switch (type) {
103 case ePdfContentsType_Keyword:
104 token->fType = kKeyword_TokenType;
105 break;
106
107 case ePdfContentsType_Variant: {
108 token->fType = kObject_TokenType;
109 PdfObject* obj = new PdfObject(var);
110 mapObject(*fDoc, *obj, &token->fObject);
111 }
112 break;
113
114 case ePdfContentsType_ImageData:
115 token->fType = kImageData_TokenType;
116 // TODO(edisonn): inline images seem to work without it
117 break;
118 }
119 #ifdef PDF_TRACE
120 std::string str;
121 if (token->fObject) {
122 token->fObject->podofo()->ToString(str);
123 }
124 printf("%s %s\n", token->fType == kKeyword_TokenType ? "Keyword" : token ->fType == kObject_TokenType ? "Object" : "ImageData", token->fKeyword ? token-> fKeyword : str.c_str());
125 #endif
126 return ret;
127 }
128 };
129 16
130 extern "C" PdfContext* gPdfContext; 17 extern "C" PdfContext* gPdfContext;
131 extern "C" SkBitmap* gDumpBitmap; 18 extern "C" SkBitmap* gDumpBitmap;
132 extern "C" SkCanvas* gDumpCanvas; 19 extern "C" SkCanvas* gDumpCanvas;
133 20
134 // TODO(edisonn): move in trace util.
135 #ifdef PDF_TRACE
136 static void SkTraceMatrix(const SkMatrix& matrix, const char* sz = "") {
137 printf("SkMatrix %s ", sz);
138 for (int i = 0 ; i < 9 ; i++) {
139 printf("%f ", SkScalarToDouble(matrix.get(i)));
140 }
141 printf("\n");
142 }
143
144 static void SkTraceRect(const SkRect& rect, const char* sz = "") {
145 printf("SkRect %s ", sz);
146 printf("x = %f ", SkScalarToDouble(rect.x()));
147 printf("y = %f ", SkScalarToDouble(rect.y()));
148 printf("w = %f ", SkScalarToDouble(rect.width()));
149 printf("h = %f ", SkScalarToDouble(rect.height()));
150 printf("\n");
151 }
152
153 #else
154 #define SkTraceMatrix(a,b)
155 #define SkTraceRect(a,b)
156 #endif
157
158 // TODO(edisonn): Document PdfTokenLooper and subclasses. 21 // TODO(edisonn): Document PdfTokenLooper and subclasses.
159 class PdfTokenLooper { 22 class PdfTokenLooper {
160 protected: 23 protected:
161 PdfTokenLooper* fParent; 24 PdfTokenLooper* fParent;
162 SkPdfTokenizer* fTokenizer; 25 SkPdfPodofoTokenizer* fTokenizer;
163 PdfContext* fPdfContext; 26 PdfContext* fPdfContext;
164 SkCanvas* fCanvas; 27 SkCanvas* fCanvas;
165 28
166 public: 29 public:
167 PdfTokenLooper(PdfTokenLooper* parent, 30 PdfTokenLooper(PdfTokenLooper* parent,
168 SkPdfTokenizer* tokenizer, 31 SkPdfPodofoTokenizer* tokenizer,
169 PdfContext* pdfContext, 32 PdfContext* pdfContext,
170 SkCanvas* canvas) 33 SkCanvas* canvas)
171 : fParent(parent), fTokenizer(tokenizer), fPdfContext(pdfContext), fCanv as(canvas) {} 34 : fParent(parent), fTokenizer(tokenizer), fPdfContext(pdfContext), fCanv as(canvas) {}
172 35
173 virtual PdfResult consumeToken(PdfToken& token) = 0; 36 virtual PdfResult consumeToken(PdfToken& token) = 0;
174 virtual void loop() = 0; 37 virtual void loop() = 0;
175 38
176 void setUp(PdfTokenLooper* parent) { 39 void setUp(PdfTokenLooper* parent) {
177 fParent = parent; 40 fParent = parent;
178 fTokenizer = parent->fTokenizer; 41 fTokenizer = parent->fTokenizer;
179 fPdfContext = parent->fPdfContext; 42 fPdfContext = parent->fPdfContext;
180 fCanvas = parent->fCanvas; 43 fCanvas = parent->fCanvas;
181 } 44 }
182 }; 45 };
183 46
184 class PdfMainLooper : public PdfTokenLooper { 47 class PdfMainLooper : public PdfTokenLooper {
185 public: 48 public:
186 PdfMainLooper(PdfTokenLooper* parent, 49 PdfMainLooper(PdfTokenLooper* parent,
187 SkPdfTokenizer* tokenizer, 50 SkPdfPodofoTokenizer* tokenizer,
188 PdfContext* pdfContext, 51 PdfContext* pdfContext,
189 SkCanvas* canvas) 52 SkCanvas* canvas)
190 : PdfTokenLooper(parent, tokenizer, pdfContext, canvas) {} 53 : PdfTokenLooper(parent, tokenizer, pdfContext, canvas) {}
191 54
192 virtual PdfResult consumeToken(PdfToken& token); 55 virtual PdfResult consumeToken(PdfToken& token);
193 virtual void loop(); 56 virtual void loop();
194 }; 57 };
195 58
196 class PdfInlineImageLooper : public PdfTokenLooper { 59 class PdfInlineImageLooper : public PdfTokenLooper {
197 public: 60 public:
198 PdfInlineImageLooper() 61 PdfInlineImageLooper()
199 : PdfTokenLooper(NULL, NULL, NULL, NULL) {} 62 : PdfTokenLooper(NULL, NULL, NULL, NULL) {}
200 63
201 virtual PdfResult consumeToken(PdfToken& token); 64 virtual PdfResult consumeToken(PdfToken& token);
202 virtual void loop(); 65 virtual void loop();
203 PdfResult done(); 66 PdfResult done();
204 }; 67 };
205 68
206 class PdfCompatibilitySectionLooper : public PdfTokenLooper { 69 class PdfCompatibilitySectionLooper : public PdfTokenLooper {
207 public: 70 public:
208 PdfCompatibilitySectionLooper() 71 PdfCompatibilitySectionLooper()
209 : PdfTokenLooper(NULL, NULL, NULL, NULL) {} 72 : PdfTokenLooper(NULL, NULL, NULL, NULL) {}
210 73
211 virtual PdfResult consumeToken(PdfToken& token); 74 virtual PdfResult consumeToken(PdfToken& token);
212 virtual void loop(); 75 virtual void loop();
213 }; 76 };
214 77
215 class SkPdfDoc {
216 PdfMemDocument fDoc;
217 public:
218
219 PdfMemDocument& podofo() {return fDoc;}
220
221 SkPdfDoc(const char* path) : fDoc(path) {}
222
223 int pages() {
224 return fDoc.GetPageCount();
225 }
226
227 double width(int n) {
228 PdfRect rect = fDoc.GetPage(n)->GetMediaBox();
229 return rect.GetWidth() + rect.GetLeft();
230 }
231
232 double height(int n) {
233 PdfRect rect = fDoc.GetPage(n)->GetMediaBox();
234 return rect.GetHeight() + rect.GetBottom();
235 }
236
237 // Can return NULL
238 SkPdfPageObjectDictionary* page(int n) {
239 SkPdfPageObjectDictionary* page = NULL;
240 mapPageObjectDictionary(fDoc, *fDoc.GetPage(n)->GetObject(), &page);
241 return page;
242 }
243
244 SkRect MediaBox(int n) {
245 PdfRect rect = fDoc.GetPage(n)->GetMediaBox();
246 SkRect skrect = SkRect::MakeLTRB(SkDoubleToScalar(rect.GetLeft()),
247 SkDoubleToScalar(rect.GetBottom()),
248 SkDoubleToScalar(rect.GetLeft() + rect. GetWidth()),
249 SkDoubleToScalar(rect.GetBottom() + rec t.GetHeight()));
250 return skrect;
251 }
252
253 void drawPage(int n, SkCanvas* canvas) {
254 SkPdfPageObjectDictionary* pg = page(n);
255 SkPdfTokenizer* tokenizer = tokenizerOfPage(n);
256
257 PdfContext pdfContext(this);
258 pdfContext.fOriginalMatrix = SkMatrix::I();
259 pdfContext.fGraphicsState.fResources = NULL;
260 mapResourceDictionary(*pg->Resources(), &pdfContext.fGraphicsState.fReso urces);
261
262 gPdfContext = &pdfContext;
263 gDumpCanvas = canvas;
264
265 // TODO(edisonn): get matrix stuff right.
266 // TODO(edisonn): add DPI/scale/zoom.
267 SkScalar z = SkIntToScalar(0);
268 SkRect rect = MediaBox(n);
269 SkScalar w = rect.width();
270 SkScalar h = rect.height();
271
272 SkPoint pdfSpace[4] = {SkPoint::Make(z, z), SkPoint::Make(w, z), SkPoint ::Make(w, h), SkPoint::Make(z, h)};
273 // SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w, h), SkPoint::Make(w, z), SkPoint::Make(z, z)};
274
275 // TODO(edisonn): add flag for this app to create sourunding buffer zone
276 // TODO(edisonn): add flagg for no clipping.
277 // Use larger image to make sure we do not draw anything outside of page
278 // could be used in tests.
279
280 #ifdef PDF_DEBUG_3X
281 SkPoint skiaSpace[4] = {SkPoint::Make(w+z, h+h), SkPoint::Make(w+w, h+h) , SkPoint::Make(w+w, h+z), SkPoint::Make(w+z, h+z)};
282 #else
283 SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w, h), SkPoin t::Make(w, z), SkPoint::Make(z, z)};
284 #endif
285 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(w, h)};
286 //SkPoint skiaSpace[2] = {SkPoint::Make(w, z), SkPoint::Make(z, h)};
287
288 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(z, h)};
289 //SkPoint skiaSpace[2] = {SkPoint::Make(z, h), SkPoint::Make(z, z)};
290
291 //SkPoint pdfSpace[3] = {SkPoint::Make(z, z), SkPoint::Make(z, h), SkPoi nt::Make(w, h)};
292 //SkPoint skiaSpace[3] = {SkPoint::Make(z, h), SkPoint::Make(z, z), SkPo int::Make(w, 0)};
293
294 SkAssertResult(pdfContext.fOriginalMatrix.setPolyToPoly(pdfSpace, skiaSp ace, 4));
295 SkTraceMatrix(pdfContext.fOriginalMatrix, "Original matrix");
296
297
298 pdfContext.fGraphicsState.fMatrix = pdfContext.fOriginalMatrix;
299 pdfContext.fGraphicsState.fMatrixTm = pdfContext.fGraphicsState.fMatrix;
300 pdfContext.fGraphicsState.fMatrixTlm = pdfContext.fGraphicsState.fMatrix ;
301
302 canvas->setMatrix(pdfContext.fOriginalMatrix);
303
304 #ifndef PDF_DEBUG_NO_PAGE_CLIPING
305 canvas->clipRect(SkRect::MakeXYWH(z, z, w, h), SkRegion::kIntersect_Op, true);
306 #endif
307
308 // erase with red before?
309 // SkPaint paint;
310 // paint.setColor(SK_ColorRED);
311 // canvas->drawRect(rect, paint);
312
313 PdfMainLooper looper(NULL, tokenizer, &pdfContext, canvas);
314 looper.loop();
315
316 delete tokenizer;
317
318
319 canvas->flush();
320 }
321
322 SkPdfTokenizer* tokenizerOfPage(int n) {
323 PdfContentsTokenizer* t = new PdfContentsTokenizer(fDoc.GetPage(n));
324 return new SkPdfTokenizer(&fDoc, t);
325 }
326 };
327
328 // TODO(edisonn): move in another file 78 // TODO(edisonn): move in another file
329 class SkPdfViewer : public SkRefCnt { 79 class SkPdfViewer : public SkRefCnt {
330 public: 80 public:
331 81
332 bool load(const SkString inputFileName, SkPicture* out); 82 bool load(const SkString inputFileName, SkPicture* out);
333 bool write(void*) const { return false; } 83 bool write(void*) const { return false; }
334 }; 84 };
335 85
336 void reportPdfRenderStats(); 86 void reportPdfRenderStats();
337 87
338 #endif // SkPdfParser_DEFINED 88 #endif // SkPdfParser_DEFINED
OLDNEW
« no previous file with comments | « experimental/PdfViewer/SkPdfFont.cpp ('k') | experimental/PdfViewer/SkPdfParser.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698