| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits.h> | 5 #include <limits.h> |
| 6 #include <stdio.h> | 6 #include <stdio.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 #include <wchar.h> | 9 #include <wchar.h> |
| 10 | 10 |
| 11 #include <list> | 11 #include <list> |
| 12 #include <sstream> | 12 #include <sstream> |
| 13 #include <string> | 13 #include <string> |
| 14 #include <utility> | 14 #include <utility> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "../public/fpdf_dataavail.h" | 17 #include "../public/fpdf_dataavail.h" |
| 18 #include "../public/fpdf_ext.h" | 18 #include "../public/fpdf_ext.h" |
| 19 #include "../public/fpdf_formfill.h" | 19 #include "../public/fpdf_formfill.h" |
| 20 #include "../public/fpdf_text.h" | 20 #include "../public/fpdf_text.h" |
| 21 #include "../public/fpdfview.h" | 21 #include "../public/fpdfview.h" |
| 22 #include "../testing/test_support.h" |
| 22 #include "image_diff_png.h" | 23 #include "image_diff_png.h" |
| 24 |
| 23 #ifdef PDF_ENABLE_V8 | 25 #ifdef PDF_ENABLE_V8 |
| 24 #include "v8/include/libplatform/libplatform.h" | 26 #include "v8/include/libplatform/libplatform.h" |
| 25 #include "v8/include/v8.h" | 27 #include "v8/include/v8.h" |
| 26 #endif | 28 #endif |
| 27 | 29 |
| 28 #ifdef _WIN32 | 30 #ifdef _WIN32 |
| 29 #define snprintf _snprintf | 31 #define snprintf _snprintf |
| 30 #define PATH_SEPARATOR '\\' | |
| 31 #else | |
| 32 #define PATH_SEPARATOR '/' | |
| 33 #endif | 32 #endif |
| 34 | 33 |
| 35 enum OutputFormat { | 34 enum OutputFormat { |
| 36 OUTPUT_NONE, | 35 OUTPUT_NONE, |
| 37 OUTPUT_PPM, | 36 OUTPUT_PPM, |
| 38 OUTPUT_PNG, | 37 OUTPUT_PNG, |
| 39 #ifdef _WIN32 | 38 #ifdef _WIN32 |
| 40 OUTPUT_BMP, | 39 OUTPUT_BMP, |
| 41 OUTPUT_EMF, | 40 OUTPUT_EMF, |
| 42 #endif | 41 #endif |
| 43 }; | 42 }; |
| 44 | 43 |
| 45 struct Options { | 44 struct Options { |
| 46 Options() : output_format(OUTPUT_NONE) { } | 45 Options() : output_format(OUTPUT_NONE) { } |
| 47 | 46 |
| 48 OutputFormat output_format; | 47 OutputFormat output_format; |
| 49 std::string scale_factor_as_string; | 48 std::string scale_factor_as_string; |
| 50 std::string exe_path; | 49 std::string exe_path; |
| 51 std::string bin_directory; | 50 std::string bin_directory; |
| 52 std::string font_directory; | 51 std::string font_directory; |
| 53 }; | 52 }; |
| 54 | 53 |
| 55 // Reads the entire contents of a file into a newly malloc'd buffer. | |
| 56 static char* GetFileContents(const char* filename, size_t* retlen) { | |
| 57 FILE* file = fopen(filename, "rb"); | |
| 58 if (!file) { | |
| 59 fprintf(stderr, "Failed to open: %s\n", filename); | |
| 60 return nullptr; | |
| 61 } | |
| 62 (void)fseek(file, 0, SEEK_END); | |
| 63 size_t file_length = ftell(file); | |
| 64 if (!file_length) { | |
| 65 (void)fclose(file); | |
| 66 return nullptr; | |
| 67 } | |
| 68 (void)fseek(file, 0, SEEK_SET); | |
| 69 char* buffer = static_cast<char*>(malloc(file_length)); | |
| 70 if (!buffer) { | |
| 71 (void)fclose(file); | |
| 72 return nullptr; | |
| 73 } | |
| 74 size_t bytes_read = fread(buffer, 1, file_length, file); | |
| 75 (void)fclose(file); | |
| 76 if (bytes_read != file_length) { | |
| 77 fprintf(stderr, "Failed to read: %s\n", filename); | |
| 78 free(buffer); | |
| 79 return nullptr; | |
| 80 } | |
| 81 *retlen = bytes_read; | |
| 82 return buffer; | |
| 83 } | |
| 84 | |
| 85 #ifdef PDF_ENABLE_V8 | |
| 86 #ifdef V8_USE_EXTERNAL_STARTUP_DATA | |
| 87 // Returns the full path for an external V8 data file based on either | |
| 88 // the currect exectuable path or an explicit override. | |
| 89 static std::string GetFullPathForSnapshotFile(const Options& options, | |
| 90 const std::string& filename) { | |
| 91 std::string result; | |
| 92 if (!options.bin_directory.empty()) { | |
| 93 result = options.bin_directory; | |
| 94 if (*options.bin_directory.rbegin() != PATH_SEPARATOR) { | |
| 95 result += PATH_SEPARATOR; | |
| 96 } | |
| 97 } else if (!options.exe_path.empty()) { | |
| 98 size_t last_separator = options.exe_path.rfind(PATH_SEPARATOR); | |
| 99 if (last_separator != std::string::npos) { | |
| 100 result = options.exe_path.substr(0, last_separator + 1); | |
| 101 } | |
| 102 } | |
| 103 result += filename; | |
| 104 return result; | |
| 105 } | |
| 106 | |
| 107 // Reads an extenal V8 data file from the |options|-indicated location, | |
| 108 // returing true on success and false on error. | |
| 109 static bool GetExternalData(const Options& options, | |
| 110 const std::string& bin_filename, | |
| 111 v8::StartupData* result_data) { | |
| 112 std::string full_path = GetFullPathForSnapshotFile(options, bin_filename); | |
| 113 size_t data_length = 0; | |
| 114 char* data_buffer = GetFileContents(full_path.c_str(), &data_length); | |
| 115 if (!data_buffer) { | |
| 116 return false; | |
| 117 } | |
| 118 result_data->data = const_cast<const char*>(data_buffer); | |
| 119 result_data->raw_size = data_length; | |
| 120 return true; | |
| 121 } | |
| 122 #endif // V8_USE_EXTERNAL_STARTUP_DATA | |
| 123 #endif // PDF_ENABLE_V8 | |
| 124 | |
| 125 static bool CheckDimensions(int stride, int width, int height) { | 54 static bool CheckDimensions(int stride, int width, int height) { |
| 126 if (stride < 0 || width < 0 || height < 0) | 55 if (stride < 0 || width < 0 || height < 0) |
| 127 return false; | 56 return false; |
| 128 if (height > 0 && width > INT_MAX / height) | 57 if (height > 0 && width > INT_MAX / height) |
| 129 return false; | 58 return false; |
| 130 return true; | 59 return true; |
| 131 } | 60 } |
| 132 | 61 |
| 133 static void WritePpm(const char* pdf_name, int num, const void* buffer_void, | 62 static void WritePpm(const char* pdf_name, int num, const void* buffer_void, |
| 134 int stride, int width, int height) { | 63 int stride, int width, int height) { |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 if (cur_idx >= args.size()) { | 329 if (cur_idx >= args.size()) { |
| 401 fprintf(stderr, "No input files.\n"); | 330 fprintf(stderr, "No input files.\n"); |
| 402 return false; | 331 return false; |
| 403 } | 332 } |
| 404 for (size_t i = cur_idx; i < args.size(); i++) { | 333 for (size_t i = cur_idx; i < args.size(); i++) { |
| 405 files->push_back(args[i]); | 334 files->push_back(args[i]); |
| 406 } | 335 } |
| 407 return true; | 336 return true; |
| 408 } | 337 } |
| 409 | 338 |
| 410 class TestLoader { | |
| 411 public: | |
| 412 TestLoader(const char* pBuf, size_t len); | |
| 413 | |
| 414 const char* m_pBuf; | |
| 415 size_t m_Len; | |
| 416 }; | |
| 417 | |
| 418 TestLoader::TestLoader(const char* pBuf, size_t len) | |
| 419 : m_pBuf(pBuf), m_Len(len) { | |
| 420 } | |
| 421 | |
| 422 int GetBlock(void* param, | |
| 423 unsigned long pos, | |
| 424 unsigned char* pBuf, | |
| 425 unsigned long size) { | |
| 426 TestLoader* pLoader = static_cast<TestLoader*>(param); | |
| 427 if (pos + size < pos || pos + size > pLoader->m_Len) return 0; | |
| 428 memcpy(pBuf, pLoader->m_pBuf + pos, size); | |
| 429 return 1; | |
| 430 } | |
| 431 | |
| 432 FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { | 339 FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { |
| 433 return true; | 340 return true; |
| 434 } | 341 } |
| 435 | 342 |
| 436 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) { | 343 void Add_Segment(FX_DOWNLOADHINTS* pThis, size_t offset, size_t size) { |
| 437 } | 344 } |
| 438 | 345 |
| 439 void RenderPdf(const std::string& name, const char* pBuf, size_t len, | 346 void RenderPdf(const std::string& name, const char* pBuf, size_t len, |
| 440 const Options& options) { | 347 const Options& options) { |
| 441 fprintf(stderr, "Rendering PDF file %s.\n", name.c_str()); | 348 fprintf(stderr, "Rendering PDF file %s.\n", name.c_str()); |
| 442 | 349 |
| 443 IPDF_JSPLATFORM platform_callbacks; | 350 IPDF_JSPLATFORM platform_callbacks; |
| 444 memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); | 351 memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); |
| 445 platform_callbacks.version = 3; | 352 platform_callbacks.version = 3; |
| 446 platform_callbacks.app_alert = ExampleAppAlert; | 353 platform_callbacks.app_alert = ExampleAppAlert; |
| 447 platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; | 354 platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; |
| 448 | 355 |
| 449 FPDF_FORMFILLINFO form_callbacks; | 356 FPDF_FORMFILLINFO form_callbacks; |
| 450 memset(&form_callbacks, '\0', sizeof(form_callbacks)); | 357 memset(&form_callbacks, '\0', sizeof(form_callbacks)); |
| 451 form_callbacks.version = 2; | 358 form_callbacks.version = 2; |
| 452 form_callbacks.m_pJsPlatform = &platform_callbacks; | 359 form_callbacks.m_pJsPlatform = &platform_callbacks; |
| 453 | 360 |
| 454 TestLoader loader(pBuf, len); | 361 TestLoader loader(pBuf, len); |
| 455 | |
| 456 FPDF_FILEACCESS file_access; | 362 FPDF_FILEACCESS file_access; |
| 457 memset(&file_access, '\0', sizeof(file_access)); | 363 memset(&file_access, '\0', sizeof(file_access)); |
| 458 file_access.m_FileLen = static_cast<unsigned long>(len); | 364 file_access.m_FileLen = static_cast<unsigned long>(len); |
| 459 file_access.m_GetBlock = GetBlock; | 365 file_access.m_GetBlock = TestLoader::GetBlock; |
| 460 file_access.m_Param = &loader; | 366 file_access.m_Param = &loader; |
| 461 | 367 |
| 462 FX_FILEAVAIL file_avail; | 368 FX_FILEAVAIL file_avail; |
| 463 memset(&file_avail, '\0', sizeof(file_avail)); | 369 memset(&file_avail, '\0', sizeof(file_avail)); |
| 464 file_avail.version = 1; | 370 file_avail.version = 1; |
| 465 file_avail.IsDataAvail = Is_Data_Avail; | 371 file_avail.IsDataAvail = Is_Data_Avail; |
| 466 | 372 |
| 467 FX_DOWNLOADHINTS hints; | 373 FX_DOWNLOADHINTS hints; |
| 468 memset(&hints, '\0', sizeof(hints)); | 374 memset(&hints, '\0', sizeof(hints)); |
| 469 hints.version = 1; | 375 hints.version = 1; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 int main(int argc, const char* argv[]) { | 510 int main(int argc, const char* argv[]) { |
| 605 std::vector<std::string> args(argv, argv + argc); | 511 std::vector<std::string> args(argv, argv + argc); |
| 606 Options options; | 512 Options options; |
| 607 std::list<std::string> files; | 513 std::list<std::string> files; |
| 608 if (!ParseCommandLine(args, &options, &files)) { | 514 if (!ParseCommandLine(args, &options, &files)) { |
| 609 fprintf(stderr, "%s", usage_string); | 515 fprintf(stderr, "%s", usage_string); |
| 610 return 1; | 516 return 1; |
| 611 } | 517 } |
| 612 | 518 |
| 613 #ifdef PDF_ENABLE_V8 | 519 #ifdef PDF_ENABLE_V8 |
| 614 v8::V8::InitializeICU(); | 520 v8::Platform* platform; |
| 615 v8::Platform* platform = v8::platform::CreateDefaultPlatform(); | |
| 616 v8::V8::InitializePlatform(platform); | |
| 617 v8::V8::Initialize(); | |
| 618 | |
| 619 #ifdef V8_USE_EXTERNAL_STARTUP_DATA | 521 #ifdef V8_USE_EXTERNAL_STARTUP_DATA |
| 620 v8::StartupData natives; | 522 v8::StartupData natives; |
| 621 v8::StartupData snapshot; | 523 v8::StartupData snapshot; |
| 622 if (!GetExternalData(options, "natives_blob.bin", &natives) || | 524 InitializeV8ForPDFium(options.exe_path, options.bin_directory, &natives, |
| 623 !GetExternalData(options, "snapshot_blob.bin", &snapshot)) { | 525 &snapshot, &platform); |
| 624 return 1; | 526 #else // V8_USE_EXTERNAL_STARTUP_DATA |
| 625 } | 527 InitializeV8ForPDFium(&platform); |
| 626 v8::V8::SetNativesDataBlob(&natives); | |
| 627 v8::V8::SetSnapshotDataBlob(&snapshot); | |
| 628 #endif // V8_USE_EXTERNAL_STARTUP_DATA | 528 #endif // V8_USE_EXTERNAL_STARTUP_DATA |
| 629 #endif // PDF_ENABLE_V8 | 529 #endif // PDF_ENABLE_V8 |
| 630 | 530 |
| 631 FPDF_LIBRARY_CONFIG config; | 531 FPDF_LIBRARY_CONFIG config; |
| 632 config.version = 2; | 532 config.version = 2; |
| 633 config.m_pUserFontPaths = nullptr; | 533 config.m_pUserFontPaths = nullptr; |
| 634 config.m_pIsolate = nullptr; | 534 config.m_pIsolate = nullptr; |
| 635 config.m_v8EmbedderSlot = 0; | 535 config.m_v8EmbedderSlot = 0; |
| 636 | 536 |
| 637 const char* path_array[2]; | 537 const char* path_array[2]; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 661 } | 561 } |
| 662 | 562 |
| 663 FPDF_DestroyLibrary(); | 563 FPDF_DestroyLibrary(); |
| 664 #ifdef PDF_ENABLE_V8 | 564 #ifdef PDF_ENABLE_V8 |
| 665 v8::V8::ShutdownPlatform(); | 565 v8::V8::ShutdownPlatform(); |
| 666 delete platform; | 566 delete platform; |
| 667 #endif // PDF_ENABLE_V8 | 567 #endif // PDF_ENABLE_V8 |
| 668 | 568 |
| 669 return 0; | 569 return 0; |
| 670 } | 570 } |
| OLD | NEW |