blob: edc65e9d88fdd52cd30990f55bacb8e4cc6695af [file] [log] [blame]
edisonn@google.com3aac1f92013-07-02 22:42:53 +00001#include "SkPodofoParsedPDF.h"
2
3#include "SkPdfPodofoTokenizer.h"
4#include "SkPdfHeaders_autogen.h"
5#include "SkPdfMapper_autogen.h"
6#include "SkPdfBasics.h"
7#include "SkPdfParser.h"
8
9#include "podofo.h"
10
11SkPodofoParsedPDF::SkPodofoParsedPDF(const char* path) : fDoc(new PoDoFo::PdfMemDocument(path))
12 , fMapper(new SkPdfMapper(this)) {}
13
14SkPodofoParsedPDF::~SkPodofoParsedPDF() {
15 delete fDoc;
16 delete fMapper;
17}
18
19int SkPodofoParsedPDF::pages() const {
20 return fDoc->GetPageCount();
21}
22
23double SkPodofoParsedPDF::width(int page) const {
24 PoDoFo::PdfRect rect = fDoc->GetPage(page)->GetMediaBox();
25 return rect.GetWidth() + rect.GetLeft();
26}
27
28double SkPodofoParsedPDF::height(int page) const {
29 PoDoFo::PdfRect rect = fDoc->GetPage(page)->GetMediaBox();
30 return rect.GetHeight() + rect.GetBottom();
31}
32
33const SkPdfResourceDictionary* SkPodofoParsedPDF::pageResources(int page) const {
34 SkPdfPageObjectDictionary* pg = NULL;
35 SkPdfObject* obj = make(fDoc->GetPage(page)->GetObject());
36 fMapper->mapPageObjectDictionary(obj, &pg);
37 return pg ? pg->Resources() : NULL;
38}
39
40SkRect SkPodofoParsedPDF::MediaBox(int page) const {
41 PoDoFo::PdfRect rect = fDoc->GetPage(page)->GetMediaBox();
42 SkRect skrect = SkRect::MakeLTRB(SkDoubleToScalar(rect.GetLeft()),
43 SkDoubleToScalar(rect.GetBottom()),
44 SkDoubleToScalar(rect.GetLeft() + rect.GetWidth()),
45 SkDoubleToScalar(rect.GetBottom() + rect.GetHeight()));
46 return skrect;
47}
48
49
50SkPdfPodofoTokenizer* SkPodofoParsedPDF::tokenizerOfPage(int page) const {
51 PoDoFo::PdfContentsTokenizer* t = new PoDoFo::PdfContentsTokenizer(fDoc->GetPage(page));
52 return new SkPdfPodofoTokenizer(this, t);
53}
54
55SkPdfPodofoTokenizer* SkPodofoParsedPDF::tokenizerOfStream(const SkPdfStream* stream) const {
56 if (stream == NULL) {
57 return NULL;
58 }
59
60 char* buffer = NULL;
61 long len = 0;
62 stream->GetFilteredCopy(&buffer, &len);
63 return tokenizerOfBuffer(buffer, len);
64}
65
66SkPdfPodofoTokenizer* SkPodofoParsedPDF::tokenizerOfBuffer(char* buffer, size_t len) const {
67 PoDoFo::PdfContentsTokenizer* t = new PoDoFo::PdfContentsTokenizer(buffer, len);
68 return new SkPdfPodofoTokenizer(this, t);
69}
70
71size_t SkPodofoParsedPDF::objects() const {
72 return fDoc->GetObjects().GetSize();
73}
74
75const SkPdfObject* SkPodofoParsedPDF::object(int i) const {
76 PoDoFo::PdfVecObjects& objects = (PoDoFo::PdfVecObjects&)fDoc->GetObjects();
77 return make(objects[i]);
78}
79
80SkPdfObject* SkPodofoParsedPDF::make(PoDoFo::PdfObject* obj) const {
81 return new SkPdfObject(this, obj);
82}
83
84const SkPdfObject* SkPodofoParsedPDF::make(const PoDoFo::PdfObject* obj) const {
85 return new SkPdfObject(this, obj);
86}
87
88const SkPdfMapper* SkPodofoParsedPDF::mapper() const {
89 return fMapper;
90}
91
92SkPdfNumber* SkPodofoParsedPDF::createNumber(double number) const {
93 return new SkPdfNumber(this, new PoDoFo::PdfObject(PoDoFo::PdfVariant(number)));
94}
95
96SkPdfInteger* SkPodofoParsedPDF::createInteger(int value) const {
97 return new SkPdfInteger(this, new PoDoFo::PdfObject(PoDoFo::PdfVariant((PoDoFo::pdf_int64)value)));
98}
99
100SkPdfString* SkPodofoParsedPDF::createString(char* sz, size_t len) const {
101 // TODO(edisonn): NYI
102 return NULL;
103}
104
105PdfContext* gPdfContext = NULL;
106
107void SkPodofoParsedPDF::drawPage(int page, SkCanvas* canvas) const {
108 SkPdfPodofoTokenizer* tokenizer = tokenizerOfPage(page);
109
110 PdfContext pdfContext(this);
111 pdfContext.fOriginalMatrix = SkMatrix::I();
112 pdfContext.fGraphicsState.fResources = pageResources(page);
113
114 gPdfContext = &pdfContext;
115
116 // TODO(edisonn): get matrix stuff right.
117 // TODO(edisonn): add DPI/scale/zoom.
118 SkScalar z = SkIntToScalar(0);
119 SkRect rect = MediaBox(page);
120 SkScalar w = rect.width();
121 SkScalar h = rect.height();
122
123 SkPoint pdfSpace[4] = {SkPoint::Make(z, z), SkPoint::Make(w, z), SkPoint::Make(w, h), SkPoint::Make(z, h)};
124// SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w, h), SkPoint::Make(w, z), SkPoint::Make(z, z)};
125
126 // TODO(edisonn): add flag for this app to create sourunding buffer zone
127 // TODO(edisonn): add flagg for no clipping.
128 // Use larger image to make sure we do not draw anything outside of page
129 // could be used in tests.
130
131#ifdef PDF_DEBUG_3X
132 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)};
133#else
134 SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w, h), SkPoint::Make(w, z), SkPoint::Make(z, z)};
135#endif
136 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(w, h)};
137 //SkPoint skiaSpace[2] = {SkPoint::Make(w, z), SkPoint::Make(z, h)};
138
139 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(z, h)};
140 //SkPoint skiaSpace[2] = {SkPoint::Make(z, h), SkPoint::Make(z, z)};
141
142 //SkPoint pdfSpace[3] = {SkPoint::Make(z, z), SkPoint::Make(z, h), SkPoint::Make(w, h)};
143 //SkPoint skiaSpace[3] = {SkPoint::Make(z, h), SkPoint::Make(z, z), SkPoint::Make(w, 0)};
144
145 SkAssertResult(pdfContext.fOriginalMatrix.setPolyToPoly(pdfSpace, skiaSpace, 4));
146 SkTraceMatrix(pdfContext.fOriginalMatrix, "Original matrix");
147
148
149 pdfContext.fGraphicsState.fMatrix = pdfContext.fOriginalMatrix;
150 pdfContext.fGraphicsState.fMatrixTm = pdfContext.fGraphicsState.fMatrix;
151 pdfContext.fGraphicsState.fMatrixTlm = pdfContext.fGraphicsState.fMatrix;
152
153 canvas->setMatrix(pdfContext.fOriginalMatrix);
154
155#ifndef PDF_DEBUG_NO_PAGE_CLIPING
156 canvas->clipRect(SkRect::MakeXYWH(z, z, w, h), SkRegion::kIntersect_Op, true);
157#endif
158
159// erase with red before?
160// SkPaint paint;
161// paint.setColor(SK_ColorRED);
162// canvas->drawRect(rect, paint);
163
164 PdfMainLooper looper(NULL, tokenizer, &pdfContext, canvas);
165 looper.loop();
166
167 delete tokenizer;
168
169 canvas->flush();
170}
171
172// TODO(edisonn): move in trace util.
173#include "SkMatrix.h"
174#include "SkRect.h"
175
176#ifdef PDF_TRACE
177void SkTraceMatrix(const SkMatrix& matrix, const char* sz) {
178 printf("SkMatrix %s ", sz);
179 for (int i = 0 ; i < 9 ; i++) {
180 printf("%f ", SkScalarToDouble(matrix.get(i)));
181 }
182 printf("\n");
183}
184
185void SkTraceRect(const SkRect& rect, const char* sz) {
186 printf("SkRect %s ", sz);
187 printf("x = %f ", SkScalarToDouble(rect.x()));
188 printf("y = %f ", SkScalarToDouble(rect.y()));
189 printf("w = %f ", SkScalarToDouble(rect.width()));
190 printf("h = %f ", SkScalarToDouble(rect.height()));
191 printf("\n");
192}
193#endif