X-Git-Url: http://downloads.foxitsoftware.com/web/?p=pdfium.git;a=blobdiff_plain;f=samples%2Fpdfium_test.cc;h=840e1400400d76bf1a0d844b0c7c21d8e11ad622;hp=0d76b63f26cb866d78372b0e6c05d78b0ee66cf0;hb=b0337e68fb84c807e0d898aecaad0074444d62e0;hpb=281d1d293dab54cadd214e5a1c098583fbbe0788 diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc index 0d76b63..840e140 100644 --- a/samples/pdfium_test.cc +++ b/samples/pdfium_test.cc @@ -18,15 +18,16 @@ #include "../public/fpdf_formfill.h" #include "../public/fpdf_text.h" #include "../public/fpdfview.h" +#include "../testing/test_support.h" #include "image_diff_png.h" + +#ifdef PDF_ENABLE_V8 #include "v8/include/libplatform/libplatform.h" #include "v8/include/v8.h" +#endif #ifdef _WIN32 #define snprintf _snprintf -#define PATH_SEPARATOR '\\' -#else -#define PATH_SEPARATOR '/' #endif enum OutputFormat { @@ -46,74 +47,9 @@ struct Options { std::string scale_factor_as_string; std::string exe_path; std::string bin_directory; + std::string font_directory; }; -// Reads the entire contents of a file into a newly malloc'd buffer. -static char* GetFileContents(const char* filename, size_t* retlen) { - FILE* file = fopen(filename, "rb"); - if (!file) { - fprintf(stderr, "Failed to open: %s\n", filename); - return NULL; - } - (void) fseek(file, 0, SEEK_END); - size_t file_length = ftell(file); - if (!file_length) { - return NULL; - } - (void) fseek(file, 0, SEEK_SET); - char* buffer = (char*) malloc(file_length); - if (!buffer) { - return NULL; - } - size_t bytes_read = fread(buffer, 1, file_length, file); - (void) fclose(file); - if (bytes_read != file_length) { - fprintf(stderr, "Failed to read: %s\n", filename); - free(buffer); - return NULL; - } - *retlen = bytes_read; - return buffer; -} - -#ifdef V8_USE_EXTERNAL_STARTUP_DATA -// Returns the full path for an external V8 data file based on either -// the currect exectuable path or an explicit override. -static std::string GetFullPathForSnapshotFile(const Options& options, - const std::string& filename) { - std::string result; - if (!options.bin_directory.empty()) { - result = options.bin_directory; - if (*options.bin_directory.rbegin() != PATH_SEPARATOR) { - result += PATH_SEPARATOR; - } - } else if (!options.exe_path.empty()) { - size_t last_separator = options.exe_path.rfind(PATH_SEPARATOR); - if (last_separator != std::string::npos) { - result = options.exe_path.substr(0, last_separator + 1); - } - } - result += filename; - return result; -} - -// Reads an extenal V8 data file from the |options|-indicated location, -// returing true on success and false on error. -static bool GetExternalData(const Options& options, - const std::string& bin_filename, - v8::StartupData* result_data) { - std::string full_path = GetFullPathForSnapshotFile(options, bin_filename); - size_t data_length = 0; - char* data_buffer = GetFileContents(full_path.c_str(), &data_length); - if (!data_buffer) { - return false; - } - result_data->data = const_cast(data_buffer); - result_data->raw_size = static_cast(data_length); - return true; -} -#endif // V8_USE_EXTERNAL_STARTUP_DATA - static bool CheckDimensions(int stride, int width, int height) { if (stride < 0 || width < 0 || height < 0) return false; @@ -143,22 +79,20 @@ static void WritePpm(const char* pdf_name, int num, const void* buffer_void, // Source data is B, G, R, unused. // Dest data is R, G, B. char* result = new char[out_len]; - if (result) { - for (int h = 0; h < height; ++h) { - const char* src_line = buffer + (stride * h); - char* dest_line = result + (width * h * 3); - for (int w = 0; w < width; ++w) { - // R - dest_line[w * 3] = src_line[(w * 4) + 2]; - // G - dest_line[(w * 3) + 1] = src_line[(w * 4) + 1]; - // B - dest_line[(w * 3) + 2] = src_line[w * 4]; - } + for (int h = 0; h < height; ++h) { + const char* src_line = buffer + (stride * h); + char* dest_line = result + (width * h * 3); + for (int w = 0; w < width; ++w) { + // R + dest_line[w * 3] = src_line[(w * 4) + 2]; + // G + dest_line[(w * 3) + 1] = src_line[(w * 4) + 1]; + // B + dest_line[(w * 3) + 2] = src_line[w * 4]; } - fwrite(result, out_len, 1, fp); - delete [] result; } + fwrite(result, out_len, 1, fp); + delete[] result; fclose(fp); } @@ -195,7 +129,7 @@ static void WritePng(const char* pdf_name, int num, const void* buffer_void, if (bytes_written != png_encoding.size()) fprintf(stderr, "Failed to write to %s\n", filename); - (void) fclose(fp); + (void)fclose(fp); } #ifdef _WIN32 @@ -242,7 +176,7 @@ void WriteEmf(FPDF_PAGE page, const char* pdf_name, int num) { char filename[256]; snprintf(filename, sizeof(filename), "%s.%d.emf", pdf_name, num); - HDC dc = CreateEnhMetaFileA(NULL, filename, NULL, NULL); + HDC dc = CreateEnhMetaFileA(nullptr, filename, nullptr, nullptr); HRGN rgn = CreateRectRgn(0, 0, width, height); SelectClipRgn(dc, rgn); @@ -268,7 +202,7 @@ int ExampleAppAlert(IPDF_JSPLATFORM*, FPDF_WIDESTRING msg, FPDF_WIDESTRING, ++characters; } wchar_t* platform_string = - (wchar_t*)malloc((characters + 1) * sizeof(wchar_t)); + static_cast(malloc((characters + 1) * sizeof(wchar_t))); for (size_t i = 0; i < characters + 1; ++i) { unsigned char* ptr = (unsigned char*)&msg[i]; platform_string[i] = ptr[0] + 256 * ptr[1]; @@ -347,7 +281,15 @@ bool ParseCommandLine(const std::vector& args, return false; } options->output_format = OUTPUT_PNG; + } else if (cur_arg.size() > 11 && + cur_arg.compare(0, 11, "--font-dir=") == 0) { + if (!options->font_directory.empty()) { + fprintf(stderr, "Duplicate --font-dir argument\n"); + return false; + } + options->font_directory = cur_arg.substr(11); } + #ifdef _WIN32 else if (cur_arg == "--emf") { if (options->output_format != OUTPUT_NONE) { @@ -364,6 +306,7 @@ bool ParseCommandLine(const std::vector& args, options->output_format = OUTPUT_BMP; } #endif // _WIN32 +#ifdef PDF_ENABLE_V8 #ifdef V8_USE_EXTERNAL_STARTUP_DATA else if (cur_arg.size() > 10 && cur_arg.compare(0, 10, "--bin-dir=") == 0) { if (!options->bin_directory.empty()) { @@ -373,6 +316,7 @@ bool ParseCommandLine(const std::vector& args, options->bin_directory = cur_arg.substr(10); } #endif // V8_USE_EXTERNAL_STARTUP_DATA +#endif // PDF_ENABLE_V8 else if (cur_arg.size() > 8 && cur_arg.compare(0, 8, "--scale=") == 0) { if (!options->scale_factor_as_string.empty()) { fprintf(stderr, "Duplicate --scale argument\n"); @@ -393,26 +337,6 @@ bool ParseCommandLine(const std::vector& args, return true; } -class TestLoader { - public: - TestLoader(const char* pBuf, size_t len); - - const char* m_pBuf; - size_t m_Len; -}; - -TestLoader::TestLoader(const char* pBuf, size_t len) - : m_pBuf(pBuf), m_Len(len) { -} - -int Get_Block(void* param, unsigned long pos, unsigned char* pBuf, - unsigned long size) { - TestLoader* pLoader = (TestLoader*) param; - if (pos + size < pos || pos + size > pLoader->m_Len) return 0; - memcpy(pBuf, pLoader->m_pBuf + pos, size); - return 1; -} - FPDF_BOOL Is_Data_Avail(FX_FILEAVAIL* pThis, size_t offset, size_t size) { return true; } @@ -426,7 +350,7 @@ void RenderPdf(const std::string& name, const char* pBuf, size_t len, IPDF_JSPLATFORM platform_callbacks; memset(&platform_callbacks, '\0', sizeof(platform_callbacks)); - platform_callbacks.version = 2; + platform_callbacks.version = 3; platform_callbacks.app_alert = ExampleAppAlert; platform_callbacks.Doc_gotoPage = ExampleDocGotoPage; @@ -436,11 +360,10 @@ void RenderPdf(const std::string& name, const char* pBuf, size_t len, form_callbacks.m_pJsPlatform = &platform_callbacks; TestLoader loader(pBuf, len); - FPDF_FILEACCESS file_access; memset(&file_access, '\0', sizeof(file_access)); file_access.m_FileLen = static_cast(len); - file_access.m_GetBlock = Get_Block; + file_access.m_GetBlock = TestLoader::GetBlock; file_access.m_Param = &loader; FX_FILEAVAIL file_avail; @@ -456,29 +379,60 @@ void RenderPdf(const std::string& name, const char* pBuf, size_t len, FPDF_DOCUMENT doc; FPDF_AVAIL pdf_avail = FPDFAvail_Create(&file_avail, &file_access); - (void) FPDFAvail_IsDocAvail(pdf_avail, &hints); + (void)FPDFAvail_IsDocAvail(pdf_avail, &hints); + + if (FPDFAvail_IsLinearized(pdf_avail)) + doc = FPDFAvail_GetDocument(pdf_avail, nullptr); + else + doc = FPDF_LoadCustomDocument(&file_access, nullptr); - if (!FPDFAvail_IsLinearized(pdf_avail)) { - fprintf(stderr, "Non-linearized path...\n"); - doc = FPDF_LoadCustomDocument(&file_access, NULL); - } else { - fprintf(stderr, "Linearized path...\n"); - doc = FPDFAvail_GetDocument(pdf_avail, NULL); + if (!doc) { + unsigned long err = FPDF_GetLastError(); + fprintf(stderr, "Load pdf docs unsuccessful: "); + switch (err) { + case FPDF_ERR_SUCCESS: + fprintf(stderr, "Success"); + break; + case FPDF_ERR_UNKNOWN: + fprintf(stderr, "Unknown error"); + break; + case FPDF_ERR_FILE: + fprintf(stderr, "File not found or could not be opened"); + break; + case FPDF_ERR_FORMAT: + fprintf(stderr, "File not in PDF format or corrupted"); + break; + case FPDF_ERR_PASSWORD: + fprintf(stderr, "Password required or incorrect password"); + break; + case FPDF_ERR_SECURITY: + fprintf(stderr, "Unsupported security scheme"); + break; + case FPDF_ERR_PAGE: + fprintf(stderr, "Page not found or content error"); + break; + default: + fprintf(stderr, "Unknown error %ld", err); + } + fprintf(stderr, ".\n"); + + FPDFAvail_Destroy(pdf_avail); + return; } - (void) FPDF_GetDocPermissions(doc); - (void) FPDFAvail_IsFormAvail(pdf_avail, &hints); + (void)FPDF_GetDocPermissions(doc); + (void)FPDFAvail_IsFormAvail(pdf_avail, &hints); FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnvironment(doc, &form_callbacks); FPDF_SetFormFieldHighlightColor(form, 0, 0xFFE4DD); FPDF_SetFormFieldHighlightAlpha(form, 100); int first_page = FPDFAvail_GetFirstPageNum(doc); - (void) FPDFAvail_IsPageAvail(pdf_avail, first_page, &hints); + (void)FPDFAvail_IsPageAvail(pdf_avail, first_page, &hints); int page_count = FPDF_GetPageCount(doc); for (int i = 0; i < page_count; ++i) { - (void) FPDFAvail_IsPageAvail(pdf_avail, i, &hints); + (void)FPDFAvail_IsPageAvail(pdf_avail, i, &hints); } FORM_DoDocumentJSAction(form); @@ -489,8 +443,8 @@ void RenderPdf(const std::string& name, const char* pBuf, size_t len, for (int i = 0; i < page_count; ++i) { FPDF_PAGE page = FPDF_LoadPage(doc, i); if (!page) { - bad_pages ++; - continue; + ++bad_pages; + continue; } FPDF_TEXTPAGE text_page = FPDFText_LoadPage(page); FORM_OnAfterLoadPage(page, form); @@ -512,7 +466,7 @@ void RenderPdf(const std::string& name, const char* pBuf, size_t len, FPDFBitmap_FillRect(bitmap, 0, 0, width, height, 0xFFFFFFFF); FPDF_RenderPageBitmap(bitmap, page, 0, 0, width, height, 0, 0); - rendered_pages ++; + ++rendered_pages; FPDF_FFLDraw(form, bitmap, page, 0, 0, width, height, 0, 0); int stride = FPDFBitmap_GetStride(bitmap); @@ -560,8 +514,9 @@ void RenderPdf(const std::string& name, const char* pBuf, size_t len, static const char usage_string[] = "Usage: pdfium_test [OPTION] [FILE]...\n" - " --bin-dir= - override path to v8 external data\n" - " --scale= - scale output size by number (e.g. 0.5)\n" + " --bin-dir= - override path to v8 external data\n" + " --font-dir= - override path to external fonts\n" + " --scale= - scale output size by number (e.g. 0.5)\n" #ifdef _WIN32 " --bmp - write page images ..bmp\n" " --emf - write page meta files ..emf\n" @@ -578,28 +533,31 @@ int main(int argc, const char* argv[]) { return 1; } - v8::V8::InitializeICU(); - v8::Platform* platform = v8::platform::CreateDefaultPlatform(); - v8::V8::InitializePlatform(platform); - v8::V8::Initialize(); - - // By enabling predictable mode, V8 won't post any background tasks. - static const char predictable_flag[] = "--predictable"; - v8::V8::SetFlagsFromString(predictable_flag, - static_cast(strlen(predictable_flag))); - +#ifdef PDF_ENABLE_V8 + v8::Platform* platform; #ifdef V8_USE_EXTERNAL_STARTUP_DATA v8::StartupData natives; v8::StartupData snapshot; - if (!GetExternalData(options, "natives_blob.bin", &natives) || - !GetExternalData(options, "snapshot_blob.bin", &snapshot)) { - return 1; - } - v8::V8::SetNativesDataBlob(&natives); - v8::V8::SetSnapshotDataBlob(&snapshot); + InitializeV8ForPDFium(options.exe_path, options.bin_directory, &natives, + &snapshot, &platform); +#else // V8_USE_EXTERNAL_STARTUP_DATA + InitializeV8ForPDFium(&platform); #endif // V8_USE_EXTERNAL_STARTUP_DATA - - FPDF_InitLibrary(); +#endif // PDF_ENABLE_V8 + + FPDF_LIBRARY_CONFIG config; + config.version = 2; + config.m_pUserFontPaths = nullptr; + config.m_pIsolate = nullptr; + config.m_v8EmbedderSlot = 0; + + const char* path_array[2]; + if (!options.font_directory.empty()) { + path_array[0] = options.font_directory.c_str(); + path_array[1] = nullptr; + config.m_pUserFontPaths = path_array; + } + FPDF_InitLibraryWithConfig(&config); UNSUPPORT_INFO unsuppored_info; memset(&unsuppored_info, '\0', sizeof(unsuppored_info)); @@ -620,8 +578,10 @@ int main(int argc, const char* argv[]) { } FPDF_DestroyLibrary(); +#ifdef PDF_ENABLE_V8 v8::V8::ShutdownPlatform(); delete platform; +#endif // PDF_ENABLE_V8 return 0; }