From d1c9b45aa2dc3a3d6824059e1e8f1f046c59a4f3 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Fri, 5 May 2017 17:21:36 -0700 Subject: Add raw PostScript output to pdfium_test on Windows. Activated by --ps2 and --ps3 for PostScript level 2 and 3, respectively. The raw output is not formatted in a way for most PostScript processing tools to recognize as actually PostScript. Also fix the type of the parameter to FPDF_SetPrintPostscriptLevel() even though it ends up being a no-op. Change-Id: Iaa34fd3dfaedad2b016fefe1227cbed9c974ae2a Reviewed-on: https://pdfium-review.googlesource.com/4996 Commit-Queue: dsinclair Reviewed-by: dsinclair --- samples/pdfium_test.cc | 76 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) (limited to 'samples/pdfium_test.cc') diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc index d2b3c01196..fa57d65b9e 100644 --- a/samples/pdfium_test.cc +++ b/samples/pdfium_test.cc @@ -60,6 +60,8 @@ enum OutputFormat { #ifdef _WIN32 OUTPUT_BMP, OUTPUT_EMF, + OUTPUT_PS2, + OUTPUT_PS3, #endif #ifdef PDF_ENABLE_SKIA OUTPUT_SKP, @@ -274,14 +276,13 @@ static std::string WriteBmp(const char* pdf_name, } void WriteEmf(FPDF_PAGE page, const char* pdf_name, int num) { - int width = static_cast(FPDF_GetPageWidth(page)); - int height = static_cast(FPDF_GetPageHeight(page)); - char filename[256]; snprintf(filename, sizeof(filename), "%s.%d.emf", pdf_name, num); HDC dc = CreateEnhMetaFileA(nullptr, filename, nullptr, nullptr); + int width = static_cast(FPDF_GetPageWidth(page)); + int height = static_cast(FPDF_GetPageHeight(page)); HRGN rgn = CreateRectRgn(0, 0, width, height); SelectClipRgn(dc, rgn); DeleteObject(rgn); @@ -296,7 +297,48 @@ void WriteEmf(FPDF_PAGE page, const char* pdf_name, int num) { DeleteEnhMetaFile(CloseEnhMetaFile(dc)); } -#endif + +int CALLBACK EnhMetaFileProc(HDC hdc, + HANDLETABLE* handle_table, + const ENHMETARECORD* record, + int objects_count, + LPARAM param) { + std::vector& items = + *reinterpret_cast*>(param); + items.push_back(record); + return 1; +} + +void WritePS(FPDF_PAGE page, const char* pdf_name, int num) { + char filename[256]; + snprintf(filename, sizeof(filename), "%s.%d.ps", pdf_name, num); + FILE* fp = fopen(filename, "wb"); + if (!fp) + return; + + HDC dc = CreateEnhMetaFileA(nullptr, nullptr, nullptr, nullptr); + + int width = static_cast(FPDF_GetPageWidth(page)); + int height = static_cast(FPDF_GetPageHeight(page)); + FPDF_RenderPage(dc, page, 0, 0, width, height, 0, + FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH); + + HENHMETAFILE emf = CloseEnhMetaFile(dc); + std::vector items; + EnumEnhMetaFile(nullptr, emf, &EnhMetaFileProc, &items, nullptr); + for (const ENHMETARECORD* record : items) { + if (record->iType != EMR_GDICOMMENT) + continue; + + const auto* comment = reinterpret_cast(record); + const char* data = reinterpret_cast(comment->Data); + uint16_t size = *reinterpret_cast(data); + fwrite(data + sizeof(uint16_t), size, 1, fp); + } + fclose(fp); + DeleteEnhMetaFile(emf); +} +#endif // _WIN32 #ifdef PDF_ENABLE_SKIA static std::string WriteSkp(const char* pdf_name, @@ -474,6 +516,18 @@ bool ParseCommandLine(const std::vector& args, return false; } options->output_format = OUTPUT_EMF; + } else if (cur_arg == "--ps2") { + if (options->output_format != OUTPUT_NONE) { + fprintf(stderr, "Duplicate or conflicting --ps2 argument\n"); + return false; + } + options->output_format = OUTPUT_PS2; + } else if (cur_arg == "--ps3") { + if (options->output_format != OUTPUT_NONE) { + fprintf(stderr, "Duplicate or conflicting --ps3 argument\n"); + return false; + } + options->output_format = OUTPUT_PS3; } else if (cur_arg == "--bmp") { if (options->output_format != OUTPUT_NONE) { fprintf(stderr, "Duplicate or conflicting --bmp argument\n"); @@ -736,6 +790,11 @@ bool RenderPage(const std::string& name, case OUTPUT_EMF: WriteEmf(page.get(), name.c_str(), page_index); break; + + case OUTPUT_PS2: + case OUTPUT_PS3: + WritePS(page.get(), name.c_str(), page_index); + break; #endif case OUTPUT_TEXT: WriteText(page.get(), name.c_str(), page_index); @@ -898,6 +957,13 @@ void RenderPdf(const std::string& name, FORM_DoDocumentJSAction(form.get()); FORM_DoDocumentOpenAction(form.get()); +#if _WIN32 + if (options.output_format == OUTPUT_PS2) + FPDF_SetPrintPostscriptLevel(2); + else if (options.output_format == OUTPUT_PS3) + FPDF_SetPrintPostscriptLevel(3); +#endif + int page_count = FPDF_GetPageCount(doc.get()); int rendered_pages = 0; int bad_pages = 0; @@ -966,6 +1032,8 @@ static const char kUsageString[] = #ifdef _WIN32 " --bmp - write page images ..bmp\n" " --emf - write page meta files ..emf\n" + " --ps2 - write page raw PostScript (Lvl 2) ..ps\n" + " --ps3 - write page raw PostScript (Lvl 3) ..ps\n" #endif // _WIN32 " --txt - write page text in UTF32-LE ..txt\n" " --png - write page images ..png\n" -- cgit v1.2.3