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

Side by Side Diff: experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.cpp

Issue 23020003: pdfviewer: debug code for drawText (show magenta background for text, to show text even when we fai… (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 4 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
OLDNEW
1 #include "SkNativeParsedPDF.h" 1 #include "SkPdfNativeDoc.h"
2 #include "SkPdfNativeTokenizer.h" 2 #include "SkPdfNativeTokenizer.h"
3 #include "SkPdfBasics.h" 3 #include "SkPdfNativeObject.h"
4 #include "SkPdfObject.h"
5 4
6 #include <stdio.h> 5 #include <stdio.h>
7 #include <string.h> 6 #include <string.h>
8 #include <sys/types.h> 7 #include <sys/types.h>
9 #include <sys/stat.h> 8 #include <sys/stat.h>
10 9
11 #include "SkPdfFileTrailerDictionary_autogen.h" 10 #include "SkPdfFileTrailerDictionary_autogen.h"
12 #include "SkPdfCatalogDictionary_autogen.h" 11 #include "SkPdfCatalogDictionary_autogen.h"
13 #include "SkPdfPageObjectDictionary_autogen.h" 12 #include "SkPdfPageObjectDictionary_autogen.h"
14 #include "SkPdfPageTreeNodeDictionary_autogen.h" 13 #include "SkPdfPageTreeNodeDictionary_autogen.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 while (current < end && !isPdfEOL(*current)) { 51 while (current < end && !isPdfEOL(*current)) {
53 current++; 52 current++;
54 } 53 }
55 current++; 54 current++;
56 if (current < end && isPdfEOL(*current) && *current != *(current - 1)) { 55 if (current < end && isPdfEOL(*current) && *current != *(current - 1)) {
57 current++; 56 current++;
58 } 57 }
59 return current; 58 return current;
60 } 59 }
61 60
62 SkNativeParsedPDF* gDoc = NULL; 61 SkPdfNativeDoc* gDoc = NULL;
63 62
64 // TODO(edisonn): NYI 63 // TODO(edisonn): NYI
65 // TODO(edisonn): 3 constructuctors from URL, from stream, from file ... 64 // TODO(edisonn): 3 constructuctors from URL, from stream, from file ...
66 // TODO(edisonn): write one that accepts errors in the file and ignores/fixis th em 65 // TODO(edisonn): write one that accepts errors in the file and ignores/fixis th em
67 // TODO(edisonn): testing: 66 // TODO(edisonn): testing:
68 // 1) run on a lot of file 67 // 1) run on a lot of file
69 // 2) recoverable corupt file: remove endobj, endsteam, remove other keywords, u se other white spaces, insert comments randomly, ... 68 // 2) recoverable corupt file: remove endobj, endsteam, remove other keywords, u se other white spaces, insert comments randomly, ...
70 // 3) irrecoverable corrupt file 69 // 3) irrecoverable corrupt file
71 70
72 SkNativeParsedPDF::SkNativeParsedPDF(SkStream* stream) 71 SkPdfNativeDoc::SkPdfNativeDoc(SkStream* stream)
73 : fAllocator(new SkPdfAllocator()) 72 : fAllocator(new SkPdfAllocator())
74 , fFileContent(NULL) 73 , fFileContent(NULL)
75 , fContentLength(0) 74 , fContentLength(0)
76 , fRootCatalogRef(NULL) 75 , fRootCatalogRef(NULL)
77 , fRootCatalog(NULL) { 76 , fRootCatalog(NULL) {
78 size_t size = stream->getLength(); 77 size_t size = stream->getLength();
79 void* ptr = sk_malloc_throw(size); 78 void* ptr = sk_malloc_throw(size);
80 stream->read(ptr, size); 79 stream->read(ptr, size);
81 80
82 init(ptr, size); 81 init(ptr, size);
83 } 82 }
84 83
85 SkNativeParsedPDF::SkNativeParsedPDF(const char* path) 84 SkPdfNativeDoc::SkPdfNativeDoc(const char* path)
86 : fAllocator(new SkPdfAllocator()) 85 : fAllocator(new SkPdfAllocator())
87 , fFileContent(NULL) 86 , fFileContent(NULL)
88 , fContentLength(0) 87 , fContentLength(0)
89 , fRootCatalogRef(NULL) 88 , fRootCatalogRef(NULL)
90 , fRootCatalog(NULL) { 89 , fRootCatalog(NULL) {
91 gDoc = this; 90 gDoc = this;
92 FILE* file = fopen(path, "r"); 91 FILE* file = fopen(path, "r");
93 // TODO(edisonn): put this in a function that can return NULL 92 // TODO(edisonn): put this in a function that can return NULL
94 if (file) { 93 if (file) {
95 size_t size = getFileSize(path); 94 size_t size = getFileSize(path);
96 void* content = sk_malloc_throw(size); 95 void* content = sk_malloc_throw(size);
97 bool ok = (0 != fread(content, size, 1, file)); 96 bool ok = (0 != fread(content, size, 1, file));
98 fclose(file); 97 fclose(file);
99 if (!ok) { 98 if (!ok) {
100 sk_free(content); 99 sk_free(content);
101 // TODO(edisonn): report read error 100 // TODO(edisonn): report read error
102 // TODO(edisonn): not nice to return like this from constructor, cre ate a static 101 // TODO(edisonn): not nice to return like this from constructor, cre ate a static
103 // function that can report NULL for failures. 102 // function that can report NULL for failures.
104 return; // Doc will have 0 pages 103 return; // Doc will have 0 pages
105 } 104 }
106 105
107 init(content, size); 106 init(content, size);
108 } 107 }
109 } 108 }
110 109
111 void SkNativeParsedPDF::init(const void* bytes, size_t length) { 110 void SkPdfNativeDoc::init(const void* bytes, size_t length) {
112 fFileContent = (const unsigned char*)bytes; 111 fFileContent = (const unsigned char*)bytes;
113 fContentLength = length; 112 fContentLength = length;
114 const unsigned char* eofLine = lineHome(fFileContent, fFileContent + fConten tLength - 1); 113 const unsigned char* eofLine = lineHome(fFileContent, fFileContent + fConten tLength - 1);
115 const unsigned char* xrefByteOffsetLine = previousLineHome(fFileContent, eof Line); 114 const unsigned char* xrefByteOffsetLine = previousLineHome(fFileContent, eof Line);
116 const unsigned char* xrefstartKeywordLine = previousLineHome(fFileContent, x refByteOffsetLine); 115 const unsigned char* xrefstartKeywordLine = previousLineHome(fFileContent, x refByteOffsetLine);
117 116
118 if (strcmp((char*)xrefstartKeywordLine, "startxref") != 0) { 117 if (strcmp((char*)xrefstartKeywordLine, "startxref") != 0) {
119 // TODO(edisonn): report/issue 118 // TODO(edisonn): report/issue
120 } 119 }
121 120
(...skipping 29 matching lines...) Expand all
151 loadWithoutXRef(); 150 loadWithoutXRef();
152 } 151 }
153 152
154 // TODO(edisonn): corrupted pdf, read it from beginning and rebuild (xref, t railer, or just reall all objects) 153 // TODO(edisonn): corrupted pdf, read it from beginning and rebuild (xref, t railer, or just reall all objects)
155 // 0 pages 154 // 0 pages
156 155
157 // now actually read all objects if we want, or do it lazyly 156 // now actually read all objects if we want, or do it lazyly
158 // and resolve references?... or not ... 157 // and resolve references?... or not ...
159 } 158 }
160 159
161 void SkNativeParsedPDF::loadWithoutXRef() { 160 void SkPdfNativeDoc::loadWithoutXRef() {
162 const unsigned char* current = fFileContent; 161 const unsigned char* current = fFileContent;
163 const unsigned char* end = fFileContent + fContentLength; 162 const unsigned char* end = fFileContent + fContentLength;
164 163
165 // TODO(edisonn): read pdf version 164 // TODO(edisonn): read pdf version
166 current = ignoreLine(current, end); 165 current = ignoreLine(current, end);
167 166
168 current = skipPdfWhiteSpaces(0, current, end); 167 current = skipPdfWhiteSpaces(0, current, end);
169 while (current < end) { 168 while (current < end) {
170 SkPdfObject token; 169 SkPdfNativeObject token;
171 current = nextObject(0, current, end, &token, NULL, NULL); 170 current = nextObject(0, current, end, &token, NULL, NULL);
172 if (token.isInteger()) { 171 if (token.isInteger()) {
173 int id = (int)token.intValue(); 172 int id = (int)token.intValue();
174 173
175 token.reset(); 174 token.reset();
176 current = nextObject(0, current, end, &token, NULL, NULL); 175 current = nextObject(0, current, end, &token, NULL, NULL);
177 // int generation = (int)token.intValue(); // TODO(edisonn): ignore d for now 176 // int generation = (int)token.intValue(); // TODO(edisonn): ignore d for now
178 177
179 token.reset(); 178 token.reset();
180 current = nextObject(0, current, end, &token, NULL, NULL); 179 current = nextObject(0, current, end, &token, NULL, NULL);
181 // TODO(edisonn): must be obj, return error if not? ignore ? 180 // TODO(edisonn): must be obj, return error if not? ignore ?
182 if (!token.isKeyword("obj")) { 181 if (!token.isKeyword("obj")) {
183 continue; 182 continue;
184 } 183 }
185 184
186 while (fObjects.count() < id + 1) { 185 while (fObjects.count() < id + 1) {
187 reset(fObjects.append()); 186 reset(fObjects.append());
188 } 187 }
189 188
190 fObjects[id].fOffset = current - fFileContent; 189 fObjects[id].fOffset = current - fFileContent;
191 190
192 SkPdfObject* obj = fAllocator->allocObject(); 191 SkPdfNativeObject* obj = fAllocator->allocObject();
193 current = nextObject(0, current, end, obj, fAllocator, this); 192 current = nextObject(0, current, end, obj, fAllocator, this);
194 193
195 fObjects[id].fResolvedReference = obj; 194 fObjects[id].fResolvedReference = obj;
196 fObjects[id].fObj = obj; 195 fObjects[id].fObj = obj;
197 196
198 // set objects 197 // set objects
199 } else if (token.isKeyword("trailer")) { 198 } else if (token.isKeyword("trailer")) {
200 long dummy; 199 long dummy;
201 current = readTrailer(current, end, true, &dummy, true); 200 current = readTrailer(current, end, true, &dummy, true);
202 } else if (token.isKeyword("startxref")) { 201 } else if (token.isKeyword("startxref")) {
203 token.reset(); 202 token.reset();
204 current = nextObject(0, current, end, &token, NULL, NULL); // ignor e 203 current = nextObject(0, current, end, &token, NULL, NULL); // ignor e
205 } 204 }
206 205
207 current = skipPdfWhiteSpaces(0, current, end); 206 current = skipPdfWhiteSpaces(0, current, end);
208 } 207 }
209 208
210 // TODO(edisonn): hack, detect root catalog - we need to implement liniarize d support, and remove this hack. 209 // TODO(edisonn): hack, detect root catalog - we need to implement liniarize d support, and remove this hack.
211 if (!fRootCatalogRef) { 210 if (!fRootCatalogRef) {
212 for (unsigned int i = 0 ; i < objects(); i++) { 211 for (unsigned int i = 0 ; i < objects(); i++) {
213 SkPdfObject* obj = object(i); 212 SkPdfNativeObject* obj = object(i);
214 SkPdfObject* root = (obj && obj->isDictionary()) ? obj->get("Root") : NULL; 213 SkPdfNativeObject* root = (obj && obj->isDictionary()) ? obj->get("R oot") : NULL;
215 if (root && root->isReference()) { 214 if (root && root->isReference()) {
216 fRootCatalogRef = root; 215 fRootCatalogRef = root;
217 } 216 }
218 } 217 }
219 } 218 }
220 219
221 220
222 if (fRootCatalogRef) { 221 if (fRootCatalogRef) {
223 fRootCatalog = (SkPdfCatalogDictionary*)resolveReference(fRootCatalogRef ); 222 fRootCatalog = (SkPdfCatalogDictionary*)resolveReference(fRootCatalogRef );
224 if (fRootCatalog->isDictionary() && fRootCatalog->valid()) { 223 if (fRootCatalog->isDictionary() && fRootCatalog->valid()) {
225 SkPdfPageTreeNodeDictionary* tree = fRootCatalog->Pages(this); 224 SkPdfPageTreeNodeDictionary* tree = fRootCatalog->Pages(this);
226 if (tree && tree->isDictionary() && tree->valid()) { 225 if (tree && tree->isDictionary() && tree->valid()) {
227 fillPages(tree); 226 fillPages(tree);
228 } 227 }
229 } 228 }
230 } 229 }
231 230
232 231
233 } 232 }
234 233
235 // TODO(edisonn): NYI 234 // TODO(edisonn): NYI
236 SkNativeParsedPDF::~SkNativeParsedPDF() { 235 SkPdfNativeDoc::~SkPdfNativeDoc() {
237 sk_free((void*)fFileContent); 236 sk_free((void*)fFileContent);
238 delete fAllocator; 237 delete fAllocator;
239 } 238 }
240 239
241 const unsigned char* SkNativeParsedPDF::readCrossReferenceSection(const unsigned char* xrefStart, const unsigned char* trailerEnd) { 240 const unsigned char* SkPdfNativeDoc::readCrossReferenceSection(const unsigned ch ar* xrefStart, const unsigned char* trailerEnd) {
242 SkPdfObject xref; 241 SkPdfNativeObject xref;
243 const unsigned char* current = nextObject(0, xrefStart, trailerEnd, &xref, N ULL, NULL); 242 const unsigned char* current = nextObject(0, xrefStart, trailerEnd, &xref, N ULL, NULL);
244 243
245 if (!xref.isKeyword("xref")) { 244 if (!xref.isKeyword("xref")) {
246 return trailerEnd; 245 return trailerEnd;
247 } 246 }
248 247
249 SkPdfObject token; 248 SkPdfNativeObject token;
250 while (current < trailerEnd) { 249 while (current < trailerEnd) {
251 token.reset(); 250 token.reset();
252 const unsigned char* previous = current; 251 const unsigned char* previous = current;
253 current = nextObject(0, current, trailerEnd, &token, NULL, NULL); 252 current = nextObject(0, current, trailerEnd, &token, NULL, NULL);
254 if (!token.isInteger()) { 253 if (!token.isInteger()) {
255 return previous; 254 return previous;
256 } 255 }
257 256
258 int startId = (int)token.intValue(); 257 int startId = (int)token.intValue();
259 token.reset(); 258 token.reset();
(...skipping 30 matching lines...) Expand all
290 return current; 289 return current;
291 } 290 }
292 291
293 addCrossSectionInfo(startId + i, generation, offset, *token.c_str() == 'f'); 292 addCrossSectionInfo(startId + i, generation, offset, *token.c_str() == 'f');
294 } 293 }
295 } 294 }
296 // TODO(edisonn): it should never get here? there is no trailer? 295 // TODO(edisonn): it should never get here? there is no trailer?
297 return current; 296 return current;
298 } 297 }
299 298
300 const unsigned char* SkNativeParsedPDF::readTrailer(const unsigned char* trailer Start, const unsigned char* trailerEnd, bool storeCatalog, long* prev, bool skip Keyword) { 299 const unsigned char* SkPdfNativeDoc::readTrailer(const unsigned char* trailerSta rt, const unsigned char* trailerEnd, bool storeCatalog, long* prev, bool skipKey word) {
301 *prev = -1; 300 *prev = -1;
302 301
303 const unsigned char* current = trailerStart; 302 const unsigned char* current = trailerStart;
304 if (!skipKeyword) { 303 if (!skipKeyword) {
305 SkPdfObject trailerKeyword; 304 SkPdfNativeObject trailerKeyword;
306 // TODO(edisonn): use null allocator, and let it just fail if memory 305 // TODO(edisonn): use null allocator, and let it just fail if memory
307 // needs allocated (but no crash)! 306 // needs allocated (but no crash)!
308 current = nextObject(0, current, trailerEnd, &trailerKeyword, NULL, NULL ); 307 current = nextObject(0, current, trailerEnd, &trailerKeyword, NULL, NULL );
309 308
310 if (!trailerKeyword.isKeyword() || strlen("trailer") != trailerKeyword.l enstr() || 309 if (!trailerKeyword.isKeyword() || strlen("trailer") != trailerKeyword.l enstr() ||
311 strncmp(trailerKeyword.c_str(), "trailer", strlen("trailer")) != 0) { 310 strncmp(trailerKeyword.c_str(), "trailer", strlen("trailer")) != 0) {
312 // TODO(edisonn): report warning, rebuild trailer from objects. 311 // TODO(edisonn): report warning, rebuild trailer from objects.
313 return current; 312 return current;
314 } 313 }
315 } 314 }
316 315
317 SkPdfObject token; 316 SkPdfNativeObject token;
318 current = nextObject(0, current, trailerEnd, &token, fAllocator, NULL); 317 current = nextObject(0, current, trailerEnd, &token, fAllocator, NULL);
319 if (!token.isDictionary()) { 318 if (!token.isDictionary()) {
320 return current; 319 return current;
321 } 320 }
322 SkPdfFileTrailerDictionary* trailer = (SkPdfFileTrailerDictionary*)&token; 321 SkPdfFileTrailerDictionary* trailer = (SkPdfFileTrailerDictionary*)&token;
323 if (!trailer->valid()) { 322 if (!trailer->valid()) {
324 return current; 323 return current;
325 } 324 }
326 325
327 if (storeCatalog) { 326 if (storeCatalog) {
328 SkPdfObject* ref = trailer->Root(NULL); 327 SkPdfNativeObject* ref = trailer->Root(NULL);
329 if (ref == NULL || !ref->isReference()) { 328 if (ref == NULL || !ref->isReference()) {
330 // TODO(edisonn): oops, we have to fix the corrup pdf file 329 // TODO(edisonn): oops, we have to fix the corrup pdf file
331 return current; 330 return current;
332 } 331 }
333 fRootCatalogRef = ref; 332 fRootCatalogRef = ref;
334 } 333 }
335 334
336 if (trailer->has_Prev()) { 335 if (trailer->has_Prev()) {
337 *prev = (long)trailer->Prev(NULL); 336 *prev = (long)trailer->Prev(NULL);
338 } 337 }
339 338
340 return current; 339 return current;
341 } 340 }
342 341
343 void SkNativeParsedPDF::addCrossSectionInfo(int id, int generation, int offset, bool isFreed) { 342 void SkPdfNativeDoc::addCrossSectionInfo(int id, int generation, int offset, boo l isFreed) {
344 // TODO(edisonn): security here 343 // TODO(edisonn): security here
345 while (fObjects.count() < id + 1) { 344 while (fObjects.count() < id + 1) {
346 reset(fObjects.append()); 345 reset(fObjects.append());
347 } 346 }
348 347
349 fObjects[id].fOffset = offset; 348 fObjects[id].fOffset = offset;
350 fObjects[id].fObj = NULL; 349 fObjects[id].fObj = NULL;
351 fObjects[id].fResolvedReference = NULL; 350 fObjects[id].fResolvedReference = NULL;
352 } 351 }
353 352
354 SkPdfObject* SkNativeParsedPDF::readObject(int id/*, int expectedGeneration*/) { 353 SkPdfNativeObject* SkPdfNativeDoc::readObject(int id/*, int expectedGeneration*/ ) {
355 long startOffset = fObjects[id].fOffset; 354 long startOffset = fObjects[id].fOffset;
356 //long endOffset = fObjects[id].fOffsetEnd; 355 //long endOffset = fObjects[id].fOffsetEnd;
357 // TODO(edisonn): use hinted endOffset 356 // TODO(edisonn): use hinted endOffset
358 // TODO(edisonn): current implementation will result in a lot of memory usag e 357 // TODO(edisonn): current implementation will result in a lot of memory usag e
359 // to decrease memory usage, we wither need to be smart and know where objec ts end, and we will 358 // to decrease memory usage, we wither need to be smart and know where objec ts end, and we will
360 // alocate only the chancks needed, or the tokenizer will not make copies, b ut then it needs to 359 // alocate only the chancks needed, or the tokenizer will not make copies, b ut then it needs to
361 // cache the results so it does not go twice on the same buffer 360 // cache the results so it does not go twice on the same buffer
362 const unsigned char* current = fFileContent + startOffset; 361 const unsigned char* current = fFileContent + startOffset;
363 const unsigned char* end = fFileContent + fContentLength; 362 const unsigned char* end = fFileContent + fContentLength;
364 363
365 SkPdfNativeTokenizer tokenizer(current, end - current, fMapper, fAllocator, this); 364 SkPdfNativeTokenizer tokenizer(current, end - current, fMapper, fAllocator, this);
366 365
367 SkPdfObject idObj; 366 SkPdfNativeObject idObj;
368 SkPdfObject generationObj; 367 SkPdfNativeObject generationObj;
369 SkPdfObject objKeyword; 368 SkPdfNativeObject objKeyword;
370 SkPdfObject* dict = fAllocator->allocObject(); 369 SkPdfNativeObject* dict = fAllocator->allocObject();
371 370
372 current = nextObject(0, current, end, &idObj, NULL, NULL); 371 current = nextObject(0, current, end, &idObj, NULL, NULL);
373 if (current >= end) { 372 if (current >= end) {
374 // TODO(edisonn): report warning/error 373 // TODO(edisonn): report warning/error
375 return NULL; 374 return NULL;
376 } 375 }
377 376
378 current = nextObject(0, current, end, &generationObj, NULL, NULL); 377 current = nextObject(0, current, end, &generationObj, NULL, NULL);
379 if (current >= end) { 378 if (current >= end) {
380 // TODO(edisonn): report warning/error 379 // TODO(edisonn): report warning/error
(...skipping 14 matching lines...) Expand all
395 // TODO(edisonn): report warning/error 394 // TODO(edisonn): report warning/error
396 } 395 }
397 396
398 current = nextObject(1, current, end, dict, fAllocator, this); 397 current = nextObject(1, current, end, dict, fAllocator, this);
399 398
400 // TODO(edisonn): report warning/error - verify last token is endobj 399 // TODO(edisonn): report warning/error - verify last token is endobj
401 400
402 return dict; 401 return dict;
403 } 402 }
404 403
405 void SkNativeParsedPDF::fillPages(SkPdfPageTreeNodeDictionary* tree) { 404 void SkPdfNativeDoc::fillPages(SkPdfPageTreeNodeDictionary* tree) {
406 SkPdfArray* kids = tree->Kids(this); 405 SkPdfArray* kids = tree->Kids(this);
407 if (kids == NULL) { 406 if (kids == NULL) {
408 *fPages.append() = (SkPdfPageObjectDictionary*)tree; 407 *fPages.append() = (SkPdfPageObjectDictionary*)tree;
409 return; 408 return;
410 } 409 }
411 410
412 int cnt = kids->size(); 411 int cnt = kids->size();
413 for (int i = 0; i < cnt; i++) { 412 for (int i = 0; i < cnt; i++) {
414 SkPdfObject* obj = resolveReference(kids->objAtAIndex(i)); 413 SkPdfNativeObject* obj = resolveReference(kids->objAtAIndex(i));
415 if (fMapper->mapPageObjectDictionary(obj) != kPageObjectDictionary_SkPdf ObjectType) { 414 if (fMapper->mapPageObjectDictionary(obj) != kPageObjectDictionary_SkPdf NativeObjectType) {
416 *fPages.append() = (SkPdfPageObjectDictionary*)obj; 415 *fPages.append() = (SkPdfPageObjectDictionary*)obj;
417 } else { 416 } else {
418 // TODO(edisonn): verify that it is a page tree indeed 417 // TODO(edisonn): verify that it is a page tree indeed
419 fillPages((SkPdfPageTreeNodeDictionary*)obj); 418 fillPages((SkPdfPageTreeNodeDictionary*)obj);
420 } 419 }
421 } 420 }
422 } 421 }
423 422
424 int SkNativeParsedPDF::pages() const { 423 int SkPdfNativeDoc::pages() const {
425 return fPages.count(); 424 return fPages.count();
426 } 425 }
427 426
428 SkPdfPageObjectDictionary* SkNativeParsedPDF::page(int page) { 427 SkPdfPageObjectDictionary* SkPdfNativeDoc::page(int page) {
429 SkASSERT(page >= 0 && page < fPages.count()); 428 SkASSERT(page >= 0 && page < fPages.count());
430 return fPages[page]; 429 return fPages[page];
431 } 430 }
432 431
433 432
434 SkPdfResourceDictionary* SkNativeParsedPDF::pageResources(int page) { 433 SkPdfResourceDictionary* SkPdfNativeDoc::pageResources(int page) {
435 SkASSERT(page >= 0 && page < fPages.count()); 434 SkASSERT(page >= 0 && page < fPages.count());
436 return fPages[page]->Resources(this); 435 return fPages[page]->Resources(this);
437 } 436 }
438 437
439 // TODO(edisonn): Partial implemented. Move the logics directly in the code gene rator for inheritable and default value? 438 // TODO(edisonn): Partial implemented. Move the logics directly in the code gene rator for inheritable and default value?
440 SkRect SkNativeParsedPDF::MediaBox(int page) { 439 SkRect SkPdfNativeDoc::MediaBox(int page) {
441 SkPdfPageObjectDictionary* current = fPages[page]; 440 SkPdfPageObjectDictionary* current = fPages[page];
442 while (!current->has_MediaBox() && current->has_Parent()) { 441 while (!current->has_MediaBox() && current->has_Parent()) {
443 current = (SkPdfPageObjectDictionary*)current->Parent(this); 442 current = (SkPdfPageObjectDictionary*)current->Parent(this);
444 } 443 }
445 if (current) { 444 if (current) {
446 return current->MediaBox(this); 445 return current->MediaBox(this);
447 } 446 }
448 return SkRect::MakeEmpty(); 447 return SkRect::MakeEmpty();
449 } 448 }
450 449
451 // TODO(edisonn): stream or array ... ? for now only array 450 // TODO(edisonn): stream or array ... ? for now only array
452 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfPage(int page, 451 SkPdfNativeTokenizer* SkPdfNativeDoc::tokenizerOfPage(int page,
453 SkPdfAllocator* allocat or) { 452 SkPdfAllocator* allocat or) {
454 if (fPages[page]->isContentsAStream(this)) { 453 if (fPages[page]->isContentsAStream(this)) {
455 return tokenizerOfStream(fPages[page]->getContentsAsStream(this), alloca tor); 454 return tokenizerOfStream(fPages[page]->getContentsAsStream(this), alloca tor);
456 } else { 455 } else {
457 // TODO(edisonn): NYI, we need to concatenate all streams in the array o r make the tokenizer smart 456 // TODO(edisonn): NYI, we need to concatenate all streams in the array o r make the tokenizer smart
458 // so we don't allocate new memory 457 // so we don't allocate new memory
459 return NULL; 458 return NULL;
460 } 459 }
461 } 460 }
462 461
463 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfStream(SkPdfObject* stream, 462 SkPdfNativeTokenizer* SkPdfNativeDoc::tokenizerOfStream(SkPdfNativeObject* strea m,
464 SkPdfAllocator* alloc ator) { 463 SkPdfAllocator* alloc ator) {
465 if (stream == NULL) { 464 if (stream == NULL) {
466 return NULL; 465 return NULL;
467 } 466 }
468 467
469 return new SkPdfNativeTokenizer(stream, fMapper, allocator, this); 468 return new SkPdfNativeTokenizer(stream, fMapper, allocator, this);
470 } 469 }
471 470
472 // TODO(edisonn): NYI 471 // TODO(edisonn): NYI
473 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfBuffer(const unsigned char* buffer, size_t len, 472 SkPdfNativeTokenizer* SkPdfNativeDoc::tokenizerOfBuffer(const unsigned char* buf fer, size_t len,
474 SkPdfAllocator* alloc ator) { 473 SkPdfAllocator* alloc ator) {
475 // warning does not track two calls in the same buffer! the buffer is update d! 474 // warning does not track two calls in the same buffer! the buffer is update d!
476 // make a clean copy if needed! 475 // make a clean copy if needed!
477 return new SkPdfNativeTokenizer(buffer, len, fMapper, allocator, this); 476 return new SkPdfNativeTokenizer(buffer, len, fMapper, allocator, this);
478 } 477 }
479 478
480 size_t SkNativeParsedPDF::objects() const { 479 size_t SkPdfNativeDoc::objects() const {
481 return fObjects.count(); 480 return fObjects.count();
482 } 481 }
483 482
484 SkPdfObject* SkNativeParsedPDF::object(int i) { 483 SkPdfNativeObject* SkPdfNativeDoc::object(int i) {
485 SkASSERT(!(i < 0 || i > fObjects.count())); 484 SkASSERT(!(i < 0 || i > fObjects.count()));
486 485
487 if (i < 0 || i > fObjects.count()) { 486 if (i < 0 || i > fObjects.count()) {
488 return NULL; 487 return NULL;
489 } 488 }
490 489
491 if (fObjects[i].fObj == NULL) { 490 if (fObjects[i].fObj == NULL) {
492 // TODO(edisonn): when we read the cross reference sections, store the s tart of the next object 491 // TODO(edisonn): when we read the cross reference sections, store the s tart of the next object
493 // and fill fOffsetEnd 492 // and fill fOffsetEnd
494 fObjects[i].fObj = readObject(i); 493 fObjects[i].fObj = readObject(i);
495 } 494 }
496 495
497 return fObjects[i].fObj; 496 return fObjects[i].fObj;
498 } 497 }
499 498
500 const SkPdfMapper* SkNativeParsedPDF::mapper() const { 499 const SkPdfMapper* SkPdfNativeDoc::mapper() const {
501 return fMapper; 500 return fMapper;
502 } 501 }
503 502
504 SkPdfReal* SkNativeParsedPDF::createReal(double value) const { 503 SkPdfReal* SkPdfNativeDoc::createReal(double value) const {
505 SkPdfObject* obj = fAllocator->allocObject(); 504 SkPdfNativeObject* obj = fAllocator->allocObject();
506 SkPdfObject::makeReal(value, obj); 505 SkPdfNativeObject::makeReal(value, obj);
507 return (SkPdfReal*)obj; 506 return (SkPdfReal*)obj;
508 } 507 }
509 508
510 SkPdfInteger* SkNativeParsedPDF::createInteger(int value) const { 509 SkPdfInteger* SkPdfNativeDoc::createInteger(int value) const {
511 SkPdfObject* obj = fAllocator->allocObject(); 510 SkPdfNativeObject* obj = fAllocator->allocObject();
512 SkPdfObject::makeInteger(value, obj); 511 SkPdfNativeObject::makeInteger(value, obj);
513 return (SkPdfInteger*)obj; 512 return (SkPdfInteger*)obj;
514 } 513 }
515 514
516 SkPdfString* SkNativeParsedPDF::createString(const unsigned char* sz, size_t len ) const { 515 SkPdfString* SkPdfNativeDoc::createString(const unsigned char* sz, size_t len) c onst {
517 SkPdfObject* obj = fAllocator->allocObject(); 516 SkPdfNativeObject* obj = fAllocator->allocObject();
518 SkPdfObject::makeString(sz, len, obj); 517 SkPdfNativeObject::makeString(sz, len, obj);
519 return (SkPdfString*)obj; 518 return (SkPdfString*)obj;
520 } 519 }
521 520
522 SkPdfAllocator* SkNativeParsedPDF::allocator() const { 521 SkPdfAllocator* SkPdfNativeDoc::allocator() const {
523 return fAllocator; 522 return fAllocator;
524 } 523 }
525 524
526 // TODO(edisonn): fix infinite loop if ref to itself! 525 // TODO(edisonn): fix infinite loop if ref to itself!
527 // TODO(edisonn): perf, fix refs at load, and resolve will simply return fResolv edReference? 526 // TODO(edisonn): perf, fix refs at load, and resolve will simply return fResolv edReference?
528 SkPdfObject* SkNativeParsedPDF::resolveReference(SkPdfObject* ref) { 527 SkPdfNativeObject* SkPdfNativeDoc::resolveReference(SkPdfNativeObject* ref) {
529 if (ref && ref->isReference()) { 528 if (ref && ref->isReference()) {
530 int id = ref->referenceId(); 529 int id = ref->referenceId();
531 // TODO(edisonn): generation/updates not supported now 530 // TODO(edisonn): generation/updates not supported now
532 //int gen = ref->referenceGeneration(); 531 //int gen = ref->referenceGeneration();
533 532
534 // TODO(edisonn): verify id and gen expected 533 // TODO(edisonn): verify id and gen expected
535 if (id < 0 || id >= fObjects.count()) { 534 if (id < 0 || id >= fObjects.count()) {
536 // TODO(edisonn): report error/warning 535 // TODO(edisonn): report error/warning
537 return NULL; 536 return NULL;
538 } 537 }
(...skipping 18 matching lines...) Expand all
557 fObjects[id].fResolvedReference = resolveReference(fObjects[id]. fObj); 556 fObjects[id].fResolvedReference = resolveReference(fObjects[id]. fObj);
558 } 557 }
559 } 558 }
560 559
561 #ifdef PDF_TRACE 560 #ifdef PDF_TRACE
562 printf("\nresolve(%s) = %s\n", ref->toString(0).c_str(), fObjects[id].fR esolvedReference->toString(0, ref->toString().size() + 13).c_str()); 561 printf("\nresolve(%s) = %s\n", ref->toString(0).c_str(), fObjects[id].fR esolvedReference->toString(0, ref->toString().size() + 13).c_str());
563 #endif 562 #endif
564 return fObjects[id].fResolvedReference; 563 return fObjects[id].fResolvedReference;
565 } 564 }
566 565
567
568
569 // TODO(edisonn): fix the mess with const, probably we need to remove it pre tty much everywhere 566 // TODO(edisonn): fix the mess with const, probably we need to remove it pre tty much everywhere
570 return (SkPdfObject*)ref; 567 return (SkPdfNativeObject*)ref;
571 } 568 }
572 569
573 size_t SkNativeParsedPDF::bytesUsed() const { 570 size_t SkPdfNativeDoc::bytesUsed() const {
574 return fAllocator->bytesUsed() + 571 return fAllocator->bytesUsed() +
575 fContentLength + 572 fContentLength +
576 fObjects.count() * sizeof(PublicObjectEntry) + 573 fObjects.count() * sizeof(PublicObjectEntry) +
577 fPages.count() * sizeof(SkPdfPageObjectDictionary*) + 574 fPages.count() * sizeof(SkPdfPageObjectDictionary*) +
578 sizeof(*this); 575 sizeof(*this);
579 } 576 }
OLDNEW
« no previous file with comments | « experimental/PdfViewer/pdfparser/native/SkPdfNativeDoc.h ('k') | experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698