| OLD | NEW |
| 1 #include "SkNativeParsedPDF.h" | 1 #include "SkNativeParsedPDF.h" |
| 2 #include "SkPdfNativeTokenizer.h" | 2 #include "SkPdfNativeTokenizer.h" |
| 3 #include "SkPdfBasics.h" | 3 #include "SkPdfBasics.h" |
| 4 #include "SkPdfParser.h" | |
| 5 #include "SkPdfObject.h" | 4 #include "SkPdfObject.h" |
| 6 | 5 |
| 7 #include <stdio.h> | 6 #include <stdio.h> |
| 8 #include <string.h> | 7 #include <string.h> |
| 9 #include <sys/types.h> | 8 #include <sys/types.h> |
| 10 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 11 | 10 |
| 12 #include "SkPdfFileTrailerDictionary_autogen.h" | 11 #include "SkPdfFileTrailerDictionary_autogen.h" |
| 13 #include "SkPdfCatalogDictionary_autogen.h" | 12 #include "SkPdfCatalogDictionary_autogen.h" |
| 14 #include "SkPdfPageObjectDictionary_autogen.h" | 13 #include "SkPdfPageObjectDictionary_autogen.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 |
| 61 SkNativeParsedPDF* gDoc = NULL; |
| 62 | 62 |
| 63 // TODO(edisonn): NYI | 63 // TODO(edisonn): NYI |
| 64 // TODO(edisonn): 3 constructuctors from URL, from stream, from file ... | 64 // TODO(edisonn): 3 constructuctors from URL, from stream, from file ... |
| 65 // 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 |
| 66 // TODO(edisonn): testing: | 66 // TODO(edisonn): testing: |
| 67 // 1) run on a lot of file | 67 // 1) run on a lot of file |
| 68 // 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, ... |
| 69 // 3) irrecoverable corrupt file | 69 // 3) irrecoverable corrupt file |
| 70 SkNativeParsedPDF::SkNativeParsedPDF(const char* path) : fAllocator(new SkPdfAll
ocator()) { | 70 SkNativeParsedPDF::SkNativeParsedPDF(const char* path) : fAllocator(new SkPdfAll
ocator()) { |
| 71 gDoc = this; |
| 71 FILE* file = fopen(path, "r"); | 72 FILE* file = fopen(path, "r"); |
| 72 fContentLength = getFileSize(path); | 73 fContentLength = getFileSize(path); |
| 73 fFileContent = new unsigned char[fContentLength]; | 74 fFileContent = new unsigned char[fContentLength + 1]; |
| 74 fread(fFileContent, fContentLength, 1, file); | 75 fread(fFileContent, fContentLength, 1, file); |
| 76 fFileContent[fContentLength] = '\0'; |
| 75 fclose(file); | 77 fclose(file); |
| 76 file = NULL; | 78 file = NULL; |
| 77 | 79 |
| 78 unsigned char* eofLine = lineHome(fFileContent, fFileContent + fContentLengt
h - 1); | 80 unsigned char* eofLine = lineHome(fFileContent, fFileContent + fContentLengt
h - 1); |
| 79 unsigned char* xrefByteOffsetLine = previousLineHome(fFileContent, eofLine); | 81 unsigned char* xrefByteOffsetLine = previousLineHome(fFileContent, eofLine); |
| 80 unsigned char* xrefstartKeywordLine = previousLineHome(fFileContent, xrefByt
eOffsetLine); | 82 unsigned char* xrefstartKeywordLine = previousLineHome(fFileContent, xrefByt
eOffsetLine); |
| 81 | 83 |
| 82 if (strcmp((char*)xrefstartKeywordLine, "startxref") != 0) { | 84 if (strcmp((char*)xrefstartKeywordLine, "startxref") != 0) { |
| 83 // TODO(edisonn): report/issue | 85 // TODO(edisonn): report/issue |
| 84 } | 86 } |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 SkPdfObject::makeInteger(value, obj); | 350 SkPdfObject::makeInteger(value, obj); |
| 349 return (SkPdfInteger*)obj; | 351 return (SkPdfInteger*)obj; |
| 350 } | 352 } |
| 351 | 353 |
| 352 SkPdfString* SkNativeParsedPDF::createString(unsigned char* sz, size_t len) cons
t { | 354 SkPdfString* SkNativeParsedPDF::createString(unsigned char* sz, size_t len) cons
t { |
| 353 SkPdfObject* obj = fAllocator->allocObject(); | 355 SkPdfObject* obj = fAllocator->allocObject(); |
| 354 SkPdfObject::makeString(sz, len, obj); | 356 SkPdfObject::makeString(sz, len, obj); |
| 355 return (SkPdfString*)obj; | 357 return (SkPdfString*)obj; |
| 356 } | 358 } |
| 357 | 359 |
| 358 PdfContext* gPdfContext = NULL; | |
| 359 | |
| 360 void SkNativeParsedPDF::drawPage(int page, SkCanvas* canvas) { | |
| 361 SkPdfNativeTokenizer* tokenizer = tokenizerOfPage(page); | |
| 362 | |
| 363 PdfContext pdfContext(this); | |
| 364 pdfContext.fOriginalMatrix = SkMatrix::I(); | |
| 365 pdfContext.fGraphicsState.fResources = pageResources(page); | |
| 366 | |
| 367 gPdfContext = &pdfContext; | |
| 368 | |
| 369 // TODO(edisonn): get matrix stuff right. | |
| 370 // TODO(edisonn): add DPI/scale/zoom. | |
| 371 SkScalar z = SkIntToScalar(0); | |
| 372 SkRect rect = MediaBox(page); | |
| 373 SkScalar w = rect.width(); | |
| 374 SkScalar h = rect.height(); | |
| 375 | |
| 376 SkPoint pdfSpace[4] = {SkPoint::Make(z, z), SkPoint::Make(w, z), SkPoint::Ma
ke(w, h), SkPoint::Make(z, h)}; | |
| 377 // SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w,
h), SkPoint::Make(w, z), SkPoint::Make(z, z)}; | |
| 378 | |
| 379 // TODO(edisonn): add flag for this app to create sourunding buffer zone | |
| 380 // TODO(edisonn): add flagg for no clipping. | |
| 381 // Use larger image to make sure we do not draw anything outside of page | |
| 382 // could be used in tests. | |
| 383 | |
| 384 #ifdef PDF_DEBUG_3X | |
| 385 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)}; | |
| 386 #else | |
| 387 SkPoint skiaSpace[4] = {SkPoint::Make(z, h), SkPoint::Make(w, h), SkPoint::M
ake(w, z), SkPoint::Make(z, z)}; | |
| 388 #endif | |
| 389 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(w, h)}; | |
| 390 //SkPoint skiaSpace[2] = {SkPoint::Make(w, z), SkPoint::Make(z, h)}; | |
| 391 | |
| 392 //SkPoint pdfSpace[2] = {SkPoint::Make(z, z), SkPoint::Make(z, h)}; | |
| 393 //SkPoint skiaSpace[2] = {SkPoint::Make(z, h), SkPoint::Make(z, z)}; | |
| 394 | |
| 395 //SkPoint pdfSpace[3] = {SkPoint::Make(z, z), SkPoint::Make(z, h), SkPoint::
Make(w, h)}; | |
| 396 //SkPoint skiaSpace[3] = {SkPoint::Make(z, h), SkPoint::Make(z, z), SkPoint:
:Make(w, 0)}; | |
| 397 | |
| 398 SkAssertResult(pdfContext.fOriginalMatrix.setPolyToPoly(pdfSpace, skiaSpace,
4)); | |
| 399 SkTraceMatrix(pdfContext.fOriginalMatrix, "Original matrix"); | |
| 400 | |
| 401 | |
| 402 pdfContext.fGraphicsState.fMatrix = pdfContext.fOriginalMatrix; | |
| 403 pdfContext.fGraphicsState.fMatrixTm = pdfContext.fGraphicsState.fMatrix; | |
| 404 pdfContext.fGraphicsState.fMatrixTlm = pdfContext.fGraphicsState.fMatrix; | |
| 405 | |
| 406 canvas->setMatrix(pdfContext.fOriginalMatrix); | |
| 407 | |
| 408 #ifndef PDF_DEBUG_NO_PAGE_CLIPING | |
| 409 canvas->clipRect(SkRect::MakeXYWH(z, z, w, h), SkRegion::kIntersect_Op, true
); | |
| 410 #endif | |
| 411 | |
| 412 // erase with red before? | |
| 413 // SkPaint paint; | |
| 414 // paint.setColor(SK_ColorRED); | |
| 415 // canvas->drawRect(rect, paint); | |
| 416 | |
| 417 PdfMainLooper looper(NULL, tokenizer, &pdfContext, canvas); | |
| 418 looper.loop(); | |
| 419 | |
| 420 delete tokenizer; | |
| 421 | |
| 422 canvas->flush(); | |
| 423 } | |
| 424 | |
| 425 SkPdfAllocator* SkNativeParsedPDF::allocator() const { | 360 SkPdfAllocator* SkNativeParsedPDF::allocator() const { |
| 426 return fAllocator; | 361 return fAllocator; |
| 427 } | 362 } |
| 428 | 363 |
| 429 SkPdfObject* SkNativeParsedPDF::resolveReference(SkPdfObject* ref) const { | 364 SkPdfObject* SkNativeParsedPDF::resolveReference(SkPdfObject* ref) const { |
| 430 return (SkPdfObject*)resolveReference((const SkPdfObject*)ref); | 365 return (SkPdfObject*)resolveReference((const SkPdfObject*)ref); |
| 431 } | 366 } |
| 432 | 367 |
| 433 // TODO(edisonn): fix infinite loop if ref to itself! | 368 // TODO(edisonn): fix infinite loop if ref to itself! |
| 434 // TODO(edisonn): perf, fix refs at load, and resolve will simply return fResolv
edReference? | 369 // TODO(edisonn): perf, fix refs at load, and resolve will simply return fResolv
edReference? |
| (...skipping 25 matching lines...) Expand all Loading... |
| 460 } else { | 395 } else { |
| 461 fObjects[id].fResolvedReference = resolveReference(fObjects[id].
fObj); | 396 fObjects[id].fResolvedReference = resolveReference(fObjects[id].
fObj); |
| 462 } | 397 } |
| 463 } | 398 } |
| 464 | 399 |
| 465 return fObjects[id].fResolvedReference; | 400 return fObjects[id].fResolvedReference; |
| 466 } | 401 } |
| 467 // TODO(edisonn): fix the mess with const, probably we need to remove it pre
tty much everywhere | 402 // TODO(edisonn): fix the mess with const, probably we need to remove it pre
tty much everywhere |
| 468 return (SkPdfObject*)ref; | 403 return (SkPdfObject*)ref; |
| 469 } | 404 } |
| OLD | NEW |