blob: f64090aa72cb6e80de2494e54ef29328ba7c9c05 [file] [log] [blame]
edisonn@google.com3aac1f92013-07-02 22:42:53 +00001
2#include "SkPodofoUtils.h"
3#include "SkMatrix.h"
4#include "SkPdfHeaders_autogen.h"
5#include "SkPdfMapper_autogen.h"
6
7#include "podofo.h"
8
9const PoDoFo::PdfObject* resolveReferenceObject(const SkPodofoParsedPDF* pdfDoc,
10 const PoDoFo::PdfObject* obj,
11 bool resolveOneElementArrays) {
12 while (obj && (obj->IsReference() || (resolveOneElementArrays &&
13 obj->IsArray() &&
14 obj->GetArray().GetSize() == 1))) {
15 if (obj->IsReference()) {
16 // We need to force the non const, the only update we will do is for recurssion checks.
17 PoDoFo::PdfReference& ref = (PoDoFo::PdfReference&)obj->GetReference();
18 obj = pdfDoc->podofo()->GetObjects().GetObject(ref);
19 } else {
20 obj = &obj->GetArray()[0];
21 }
22 }
23
24 return obj;
25}
26
27// TODO(edisonn): deal with synonyms (/BPC == /BitsPerComponent), here or in GetKey?
28// Always pass long form in key, and have a map of long -> short key
29bool LongFromDictionary(const SkPodofoParsedPDF* pdfDoc,
30 const PoDoFo::PdfDictionary& dict,
31 const char* key,
32 long* data) {
33 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
34 dict.GetKey(PoDoFo::PdfName(key)));
35
36 if (value == NULL || !value->IsNumber()) {
37 return false;
38 }
39 if (data == NULL) {
40 return true;
41 }
42
43 *data = value->GetNumber();
44 return true;
45}
46
47bool LongFromDictionary(const SkPodofoParsedPDF* pdfDoc,
48 const PoDoFo::PdfDictionary& dict,
49 const char* key,
50 const char* abr,
51 long* data) {
52 if (LongFromDictionary(pdfDoc, dict, key, data)) return true;
53 if (abr == NULL || *abr == '\0') return false;
54 return LongFromDictionary(pdfDoc, dict, abr, data);
55}
56
57bool DoubleFromDictionary(const SkPodofoParsedPDF* pdfDoc,
58 const PoDoFo::PdfDictionary& dict,
59 const char* key,
60 double* data) {
61 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
62 dict.GetKey(PoDoFo::PdfName(key)));
63
64 if (value == NULL || (!value->IsReal() && !value->IsNumber())) {
65 return false;
66 }
67 if (data == NULL) {
68 return true;
69 }
70
71 *data = value->GetReal();
72 return true;
73}
74
75bool DoubleFromDictionary(const SkPodofoParsedPDF* pdfDoc,
76 const PoDoFo::PdfDictionary& dict,
77 const char* key,
78 const char* abr,
79 double* data) {
80 if (DoubleFromDictionary(pdfDoc, dict, key, data)) return true;
81 if (abr == NULL || *abr == '\0') return false;
82 return DoubleFromDictionary(pdfDoc, dict, abr, data);
83}
84
85
86bool BoolFromDictionary(const SkPodofoParsedPDF* pdfDoc,
87 const PoDoFo::PdfDictionary& dict,
88 const char* key,
89 bool* data) {
90 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
91 dict.GetKey(PoDoFo::PdfName(key)));
92
93 if (value == NULL || !value->IsBool()) {
94 return false;
95 }
96 if (data == NULL) {
97 return true;
98 }
99
100 *data = value->GetBool();
101 return true;
102}
103
104bool BoolFromDictionary(const SkPodofoParsedPDF* pdfDoc,
105 const PoDoFo::PdfDictionary& dict,
106 const char* key,
107 const char* abr,
108 bool* data) {
109 if (BoolFromDictionary(pdfDoc, dict, key, data)) return true;
110 if (abr == NULL || *abr == '\0') return false;
111 return BoolFromDictionary(pdfDoc, dict, abr, data);
112}
113
114bool NameFromDictionary(const SkPodofoParsedPDF* pdfDoc,
115 const PoDoFo::PdfDictionary& dict,
116 const char* key,
117 std::string* data) {
118 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
119 dict.GetKey(PoDoFo::PdfName(key)),
120 true);
121 if (value == NULL || !value->IsName()) {
122 return false;
123 }
124 if (data == NULL) {
125 return true;
126 }
127
128 *data = value->GetName().GetName();
129 return true;
130}
131
132bool NameFromDictionary(const SkPodofoParsedPDF* pdfDoc,
133 const PoDoFo::PdfDictionary& dict,
134 const char* key,
135 const char* abr,
136 std::string* data) {
137 if (NameFromDictionary(pdfDoc, dict, key, data)) return true;
138 if (abr == NULL || *abr == '\0') return false;
139 return NameFromDictionary(pdfDoc, dict, abr, data);
140}
141
142bool StringFromDictionary(const SkPodofoParsedPDF* pdfDoc,
143 const PoDoFo::PdfDictionary& dict,
144 const char* key,
145 std::string* data) {
146 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
147 dict.GetKey(PoDoFo::PdfName(key)),
148 true);
149 if (value == NULL || (!value->IsString() && !value->IsHexString())) {
150 return false;
151 }
152 if (data == NULL) {
153 return true;
154 }
155
156 *data = value->GetString().GetString();
157 return true;
158}
159
160bool StringFromDictionary(const SkPodofoParsedPDF* pdfDoc,
161 const PoDoFo::PdfDictionary& dict,
162 const char* key,
163 const char* abr,
164 std::string* data) {
165 if (StringFromDictionary(pdfDoc, dict, key, data)) return true;
166 if (abr == NULL || *abr == '\0') return false;
167 return StringFromDictionary(pdfDoc, dict, abr, data);
168}
169
170
171bool SkMatrixFromDictionary(const SkPodofoParsedPDF* pdfDoc,
172 const PoDoFo::PdfDictionary& dict,
173 const char* key,
174 SkMatrix** matrix) {
175 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
176 dict.GetKey(PoDoFo::PdfName(key)));
177
178 if (value == NULL || !value->IsArray()) {
179 return false;
180 }
181
182 if (value->GetArray().GetSize() != 6) {
183 return false;
184 }
185
186 double array[6];
187 for (int i = 0; i < 6; i++) {
188 const PoDoFo::PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray()[i]);
189 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) {
190 return false;
191 }
192 array[i] = elem->GetReal();
193 }
194
195 *matrix = new SkMatrix();
196 **matrix = SkMatrixFromPdfMatrix(array);
197 return true;
198}
199
200bool SkMatrixFromDictionary(const SkPodofoParsedPDF* pdfDoc,
201 const PoDoFo::PdfDictionary& dict,
202 const char* key,
203 const char* abr,
204 SkMatrix** data) {
205 if (SkMatrixFromDictionary(pdfDoc, dict, key, data)) return true;
206 if (abr == NULL || *abr == '\0') return false;
207 return SkMatrixFromDictionary(pdfDoc, dict, abr, data);
208
209}
210
211bool SkRectFromDictionary(const SkPodofoParsedPDF* pdfDoc,
212 const PoDoFo::PdfDictionary& dict,
213 const char* key,
214 SkRect** rect) {
215 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
216 dict.GetKey(PoDoFo::PdfName(key)));
217
218 if (value == NULL || !value->IsArray()) {
219 return false;
220 }
221
222 if (value->GetArray().GetSize() != 4) {
223 return false;
224 }
225
226 double array[4];
227 for (int i = 0; i < 4; i++) {
228 const PoDoFo::PdfObject* elem = resolveReferenceObject(pdfDoc, &value->GetArray()[i]);
229 if (elem == NULL || (!elem->IsReal() && !elem->IsNumber())) {
230 return false;
231 }
232 array[i] = elem->GetReal();
233 }
234
235 *rect = new SkRect();
236 **rect = SkRect::MakeLTRB(SkDoubleToScalar(array[0]),
237 SkDoubleToScalar(array[1]),
238 SkDoubleToScalar(array[2]),
239 SkDoubleToScalar(array[3]));
240 return true;
241}
242
243bool SkRectFromDictionary(const SkPodofoParsedPDF* pdfDoc,
244 const PoDoFo::PdfDictionary& dict,
245 const char* key,
246 const char* abr,
247 SkRect** data) {
248 if (SkRectFromDictionary(pdfDoc, dict, key, data)) return true;
249 if (abr == NULL || *abr == '\0') return false;
250 return SkRectFromDictionary(pdfDoc, dict, abr, data);
251
252}
253
254
255SkPdfObject* get(const SkPdfObject* obj, const char* key, const char* abr = "") {
256 PoDoFo::PdfObject* podofoObj = NULL;
257 if (obj == NULL) return NULL;
258 const SkPdfDictionary* dict = obj->asDictionary();
259 if (dict == NULL) return NULL;
260 if (!dict->podofo()->IsDictionary()) return NULL;
261 ObjectFromDictionary(dict->doc(), dict->podofo()->GetDictionary(), key, abr, &podofoObj);
262 SkPdfObject* ret = NULL;
263 obj->doc()->mapper()->mapObject(podofoObj, &ret);
264 return ret;
265}
266
267bool ArrayFromDictionary(const SkPodofoParsedPDF* pdfDoc,
268 const PoDoFo::PdfDictionary& dict,
269 const char* key,
270 const char* abr,
271 SkPdfArray* data) {return false;}
272
273bool FileSpecFromDictionary(const SkPodofoParsedPDF* pdfDoc,
274 const PoDoFo::PdfDictionary& dict,
275 const char* key,
276 const char* abr,
277 SkPdfFileSpec* data) {return false;}
278
279bool StreamFromDictionary(const SkPodofoParsedPDF* pdfDoc,
280 const PoDoFo::PdfDictionary& dict,
281 const char* key,
282 const char* abr,
283 SkPdfStream** data);
284
285bool TreeFromDictionary(const SkPodofoParsedPDF* pdfDoc,
286 const PoDoFo::PdfDictionary& dict,
287 const char* key,
288 const char* abr,
289 SkPdfTree** data) {return false;}
290
291bool DateFromDictionary(const SkPodofoParsedPDF* pdfDoc,
292 const PoDoFo::PdfDictionary& dict,
293 const char* key,
294 const char* abr,
295 SkPdfDate* data) {return false;}
296
297bool FunctionFromDictionary(const SkPodofoParsedPDF* pdfDoc,
298 const PoDoFo::PdfDictionary& dict,
299 const char* key,
300 const char* abr,
301 SkPdfFunction* data) {return false;}
302
303
304
305
306bool ArrayFromDictionary(const SkPodofoParsedPDF* pdfDoc,
307 const PoDoFo::PdfDictionary& dict,
308 const char* key,
309 SkPdfArray** data) {
310 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
311 dict.GetKey(PoDoFo::PdfName(key)),
312 true);
313 if (value == NULL || !value->IsArray()) {
314 return false;
315 }
316 if (data == NULL) {
317 return true;
318 }
319
320 return pdfDoc->mapper()->mapArray(value, data);
321}
322
323
324bool ArrayFromDictionary(const SkPodofoParsedPDF* pdfDoc,
325 const PoDoFo::PdfDictionary& dict,
326 const char* key,
327 const char* abr,
328 SkPdfArray** data) {
329 if (ArrayFromDictionary(pdfDoc, dict, key, data)) return true;
330 if (abr == NULL || *abr == '\0') return false;
331 return ArrayFromDictionary(pdfDoc, dict, abr, data);
332}
333
334/*
335bool DictionaryFromDictionary(const SkPodofoParsedPDF* pdfDoc,
336 const PoDoFo::PdfDictionary& dict,
337 const char* key,
338 SkPoDoFo::PdfDictionary** data) {
339 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
340 dict.GetKey(PoDoFo::PdfName(key)),
341 true);
342 if (value == NULL || !value->IsDictionary()) {
343 return false;
344 }
345 if (data == NULL) {
346 return true;
347 }
348
349 return pdfDoc->mapper()->mapDictionary(value, data);
350}
351
352bool DictionaryFromDictionary(const SkPodofoParsedPDF* pdfDoc,
353 const PoDoFo::PdfDictionary& dict,
354 const char* key,
355 const char* abr,
356 SkPoDoFo::PdfDictionary** data) {
357 if (DictionaryFromDictionary(pdfDoc, dict, key, data)) return true;
358 if (abr == NULL || *abr == '\0') return false;
359 return DictionaryFromDictionary(pdfDoc, dict, abr, data);
360}
361*/
362
363bool ObjectFromDictionary(const SkPodofoParsedPDF* pdfDoc,
364 const PoDoFo::PdfDictionary& dict,
365 const char* key,
366 PoDoFo::PdfObject** data) {
367 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
368 dict.GetKey(PoDoFo::PdfName(key)),
369 true);
370 if (value == NULL) {
371 return false;
372 }
373 if (data == NULL) {
374 return true;
375 }
376 *data = (PoDoFo::PdfObject*)value;
377 return true;
378}
379
380bool ObjectFromDictionary(const SkPodofoParsedPDF* pdfDoc,
381 const PoDoFo::PdfDictionary& dict,
382 const char* key,
383 const char* abr,
384 PoDoFo::PdfObject** data) {
385 if (ObjectFromDictionary(pdfDoc, dict, key, data)) return true;
386 if (abr == NULL || *abr == '\0') return false;
387 return ObjectFromDictionary(pdfDoc, dict, abr, data);
388}
389
390bool StreamFromDictionary(const SkPodofoParsedPDF* pdfDoc,
391 const PoDoFo::PdfDictionary& dict,
392 const char* key,
393 SkPdfStream** data) {
394 const PoDoFo::PdfObject* value = resolveReferenceObject(pdfDoc,
395 dict.GetKey(PoDoFo::PdfName(key)),
396 true);
397 if (value == NULL) {
398 return false;
399 }
400 if (data == NULL) {
401 return true;
402 }
403 return pdfDoc->mapper()->mapStream(value, data);
404}
405
406bool StreamFromDictionary(const SkPodofoParsedPDF* pdfDoc,
407 const PoDoFo::PdfDictionary& dict,
408 const char* key,
409 const char* abr,
410 SkPdfStream** data) {
411 if (StreamFromDictionary(pdfDoc, dict, key, data)) return true;
412 if (abr == NULL || *abr == '\0') return false;
413 return StreamFromDictionary(pdfDoc, dict, abr, data);
414}