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 <dsinclair@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/public/fpdfview.h b/public/fpdfview.h
index 0ed9187..13e4f1f 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -248,8 +248,7 @@
// All other values are invalid.
// Return value:
// True if successful, false if unsucessful (typically invalid input).
-DLLEXPORT FPDF_BOOL STDCALL
-FPDF_SetPrintPostscriptLevel(FPDF_BOOL postscript_level);
+DLLEXPORT FPDF_BOOL STDCALL FPDF_SetPrintPostscriptLevel(int postscript_level);
#endif // defined(_WIN32)
// Function: FPDF_LoadDocument
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index d2b3c01..fa57d65 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -60,6 +60,8 @@
#ifdef _WIN32
OUTPUT_BMP,
OUTPUT_EMF,
+ OUTPUT_PS2,
+ OUTPUT_PS3,
#endif
#ifdef PDF_ENABLE_SKIA
OUTPUT_SKP,
@@ -274,14 +276,13 @@
}
void WriteEmf(FPDF_PAGE page, const char* pdf_name, int num) {
- int width = static_cast<int>(FPDF_GetPageWidth(page));
- int height = static_cast<int>(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<int>(FPDF_GetPageWidth(page));
+ int height = static_cast<int>(FPDF_GetPageHeight(page));
HRGN rgn = CreateRectRgn(0, 0, width, height);
SelectClipRgn(dc, rgn);
DeleteObject(rgn);
@@ -296,7 +297,48 @@
DeleteEnhMetaFile(CloseEnhMetaFile(dc));
}
-#endif
+
+int CALLBACK EnhMetaFileProc(HDC hdc,
+ HANDLETABLE* handle_table,
+ const ENHMETARECORD* record,
+ int objects_count,
+ LPARAM param) {
+ std::vector<const ENHMETARECORD*>& items =
+ *reinterpret_cast<std::vector<const ENHMETARECORD*>*>(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<int>(FPDF_GetPageWidth(page));
+ int height = static_cast<int>(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<const ENHMETARECORD*> items;
+ EnumEnhMetaFile(nullptr, emf, &EnhMetaFileProc, &items, nullptr);
+ for (const ENHMETARECORD* record : items) {
+ if (record->iType != EMR_GDICOMMENT)
+ continue;
+
+ const auto* comment = reinterpret_cast<const EMRGDICOMMENT*>(record);
+ const char* data = reinterpret_cast<const char*>(comment->Data);
+ uint16_t size = *reinterpret_cast<const uint16_t*>(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 @@
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 @@
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 @@
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 @@
#ifdef _WIN32
" --bmp - write page images <pdf-name>.<page-number>.bmp\n"
" --emf - write page meta files <pdf-name>.<page-number>.emf\n"
+ " --ps2 - write page raw PostScript (Lvl 2) <pdf-name>.<page-number>.ps\n"
+ " --ps3 - write page raw PostScript (Lvl 3) <pdf-name>.<page-number>.ps\n"
#endif // _WIN32
" --txt - write page text in UTF32-LE <pdf-name>.<page-number>.txt\n"
" --png - write page images <pdf-name>.<page-number>.png\n"