From 9ed6bd7150a9333cb28d149c98e3d316c3ededdf Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 25 Apr 2018 21:10:05 +0000 Subject: Add PostScript PASSTHROUGH options to FPDF_SetPrintMode(). The existing PostScript modes write data into EMF comments. This satisfies Chromium's use case, but other embedders want to write data out via ExtEscape() in PASSTHROUGH mode. BUG=pdfium:1068 Change-Id: I998035e99fbb84b16dcd244b750b476cecc3bd22 Reviewed-on: https://pdfium-review.googlesource.com/31299 Commit-Queue: Lei Zhang Reviewed-by: dsinclair Reviewed-by: Rebekah Potter --- core/fxge/cfx_windowsrenderdevice.h | 2 ++ core/fxge/win32/cpsoutput.cpp | 13 +++++++++---- core/fxge/win32/cpsoutput.h | 5 ++++- core/fxge/win32/fx_win32_print.cpp | 18 ++++++++++++++---- fpdfsdk/fpdf_view.cpp | 10 +++++++++- public/fpdf_edit.h | 2 ++ public/fpdfview.h | 10 ++++++++-- 7 files changed, 48 insertions(+), 12 deletions(-) diff --git a/core/fxge/cfx_windowsrenderdevice.h b/core/fxge/cfx_windowsrenderdevice.h index bbe13415c6..9701ca5186 100644 --- a/core/fxge/cfx_windowsrenderdevice.h +++ b/core/fxge/cfx_windowsrenderdevice.h @@ -19,6 +19,8 @@ enum WindowsPrintMode { kModeTextOnly = 1, kModePostScript2 = 2, kModePostScript3 = 3, + kModePostScript2PassThrough = 4, + kModePostScript3PassThrough = 5, }; class RenderDeviceDriverIface; diff --git a/core/fxge/win32/cpsoutput.cpp b/core/fxge/win32/cpsoutput.cpp index 83f2fc09c6..5c734aa57a 100644 --- a/core/fxge/win32/cpsoutput.cpp +++ b/core/fxge/win32/cpsoutput.cpp @@ -10,7 +10,7 @@ #include "core/fxcrt/fx_system.h" -CPSOutput::CPSOutput(HDC hDC) : m_hDC(hDC) {} +CPSOutput::CPSOutput(HDC hDC, OutputMode mode) : m_hDC(hDC), m_mode(mode) {} CPSOutput::~CPSOutput() {} @@ -22,9 +22,14 @@ bool CPSOutput::WriteBlock(const void* str, size_t len) { *(reinterpret_cast(buffer)) = send_len; memcpy(buffer + 2, static_cast(str) + sent_len, send_len); - // TODO(thestig/rbpotter): Do PASSTHROUGH for non-Chromium usage. - // ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, buffer, 0, nullptr); - ::GdiComment(m_hDC, send_len + 2, reinterpret_cast(buffer)); + switch (m_mode) { + case OutputMode::kExtEscape: + ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, buffer, 0, nullptr); + break; + case OutputMode::kGdiComment: + GdiComment(m_hDC, send_len + 2, reinterpret_cast(buffer)); + break; + } sent_len += send_len; len -= send_len; } diff --git a/core/fxge/win32/cpsoutput.h b/core/fxge/win32/cpsoutput.h index d140de95f4..49317a64a5 100644 --- a/core/fxge/win32/cpsoutput.h +++ b/core/fxge/win32/cpsoutput.h @@ -14,7 +14,9 @@ class CPSOutput : public IFX_WriteStream { public: - explicit CPSOutput(HDC hDC); + enum class OutputMode { kExtEscape, kGdiComment }; + + CPSOutput(HDC hDC, OutputMode mode); ~CPSOutput() override; // IFX_Writestream @@ -23,6 +25,7 @@ class CPSOutput : public IFX_WriteStream { private: HDC m_hDC; + const OutputMode m_mode; }; #endif // CORE_FXGE_WIN32_CPSOUTPUT_H_ diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp index da40b8a762..f36fa84364 100644 --- a/core/fxge/win32/fx_win32_print.cpp +++ b/core/fxge/win32/fx_win32_print.cpp @@ -334,8 +334,18 @@ CPSPrinterDriver::CPSPrinterDriver(HDC hDC, : m_hDC(hDC), m_bCmykOutput(bCmykOutput) { // |mode| should be PostScript. ASSERT(mode == WindowsPrintMode::kModePostScript2 || - mode == WindowsPrintMode::kModePostScript3); - int pslevel = mode == WindowsPrintMode::kModePostScript2 ? 2 : 3; + mode == WindowsPrintMode::kModePostScript3 || + mode == WindowsPrintMode::kModePostScript2PassThrough || + mode == WindowsPrintMode::kModePostScript3PassThrough); + int pslevel = (mode == WindowsPrintMode::kModePostScript2 || + mode == WindowsPrintMode::kModePostScript2PassThrough) + ? 2 + : 3; + CPSOutput::OutputMode output_mode = + (mode == WindowsPrintMode::kModePostScript2 || + mode == WindowsPrintMode::kModePostScript3) + ? CPSOutput::OutputMode::kGdiComment + : CPSOutput::OutputMode::kExtEscape; m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); @@ -343,8 +353,8 @@ CPSPrinterDriver::CPSPrinterDriver(HDC hDC, m_Height = ::GetDeviceCaps(m_hDC, VERTRES); m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); - m_PSRenderer.Init(pdfium::MakeRetain(m_hDC), pslevel, m_Width, - m_Height, bCmykOutput); + m_PSRenderer.Init(pdfium::MakeRetain(m_hDC, output_mode), pslevel, + m_Width, m_Height, bCmykOutput); HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1); int ret = ::GetClipRgn(hDC, hRgn); if (ret == 1) { diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp index 60be46b977..28e42a8e81 100644 --- a/fpdfsdk/fpdf_view.cpp +++ b/fpdfsdk/fpdf_view.cpp @@ -59,6 +59,12 @@ static_assert(WindowsPrintMode::kModePostScript2 == FPDF_PRINTMODE_POSTSCRIPT2, "WindowsPrintMode::kModePostScript2 value mismatch"); static_assert(WindowsPrintMode::kModePostScript3 == FPDF_PRINTMODE_POSTSCRIPT3, "WindowsPrintMode::kModePostScript3 value mismatch"); +static_assert(WindowsPrintMode::kModePostScript2PassThrough == + FPDF_PRINTMODE_POSTSCRIPT2_PASSTHROUGH, + "WindowsPrintMode::kModePostScript2PassThrough value mismatch"); +static_assert(WindowsPrintMode::kModePostScript3PassThrough == + FPDF_PRINTMODE_POSTSCRIPT3_PASSTHROUGH, + "WindowsPrintMode::kModePostScript3PassThrough value mismatch"); #endif namespace { @@ -210,8 +216,10 @@ FPDF_EXPORT void FPDF_CALLCONV FPDF_SetPrintTextWithGDI(FPDF_BOOL use_gdi) { #endif // PDFIUM_PRINT_TEXT_WITH_GDI FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_SetPrintMode(int mode) { - if (mode < FPDF_PRINTMODE_EMF || mode > FPDF_PRINTMODE_POSTSCRIPT3) + if (mode < FPDF_PRINTMODE_EMF || + mode > FPDF_PRINTMODE_POSTSCRIPT3_PASSTHROUGH) { return FALSE; + } g_pdfium_print_mode = static_cast(mode); return TRUE; } diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h index 023d955d00..74c2700733 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -66,6 +66,8 @@ #define FPDF_PRINTMODE_TEXTONLY 1 #define FPDF_PRINTMODE_POSTSCRIPT2 2 #define FPDF_PRINTMODE_POSTSCRIPT3 3 +#define FPDF_PRINTMODE_POSTSCRIPT2_PASSTHROUGH 4 +#define FPDF_PRINTMODE_POSTSCRIPT3_PASSTHROUGH 5 typedef struct FPDF_IMAGEOBJ_METADATA { // The image width in pixels. diff --git a/public/fpdfview.h b/public/fpdfview.h index 2c93e962f3..20f710f3c6 100644 --- a/public/fpdfview.h +++ b/public/fpdfview.h @@ -274,8 +274,14 @@ FPDF_EXPORT void FPDF_CALLCONV FPDF_SetPrintTextWithGDI(FPDF_BOOL use_gdi); // mode - FPDF_PRINTMODE_EMF to output EMF (default) // FPDF_PRINTMODE_TEXTONLY to output text only (for charstream // devices) -// FPDF_PRINTMODE_POSTSCRIPT2 to output level 2 postscript -// FPDF_PRINTMODE_POSTSCRIPT3 to output level 3 postscript +// FPDF_PRINTMODE_POSTSCRIPT2 to output level 2 PostScript into +// EMF as a series of GDI comments. +// FPDF_PRINTMODE_POSTSCRIPT3 to output level 3 PostScript into +// EMF as a series of GDI comments. +// FPDF_PRINTMODE_POSTSCRIPT2_PASSTHROUGH to output level 2 +// PostScript via ExtEscape() in PASSTHROUGH mode. +// FPDF_PRINTMODE_POSTSCRIPT3_PASSTHROUGH to output level 3 +// PostScript via ExtEscape() in PASSTHROUGH mode. // Return value: // True if successful, false if unsuccessful (typically invalid input). FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_SetPrintMode(int mode); -- cgit v1.2.3