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