diff options
author | rbpotter <rbpotter@chromium.org> | 2017-07-11 10:04:29 -0700 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-07-11 17:22:12 +0000 |
commit | e8468c43cb3b14f4440456d19cb047150509949d (patch) | |
tree | c11fc22bfe770abf5321fceb32644dca5c34faa1 /core | |
parent | 00c3cfdbae074a379cab4edad0e4fa75d6127797 (diff) | |
download | pdfium-e8468c43cb3b14f4440456d19cb047150509949d.tar.xz |
Add Windows generic / text only printer driver support.
BUG=chromium:734850
Change-Id: Icc0947e2e99e77a36d8963fcf0b6d3deea161d3e
Reviewed-on: https://pdfium-review.googlesource.com/7194
Commit-Queue: Rebekah Potter <rbpotter@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/fpdfapi/render/cpdf_charposlist.cpp | 3 | ||||
-rw-r--r-- | core/fxge/cfx_renderdevice.cpp | 3 | ||||
-rw-r--r-- | core/fxge/cfx_renderdevice.h | 1 | ||||
-rw-r--r-- | core/fxge/cfx_windowsrenderdevice.h | 9 | ||||
-rw-r--r-- | core/fxge/win32/fx_win32_device.cpp | 20 | ||||
-rw-r--r-- | core/fxge/win32/fx_win32_print.cpp | 156 | ||||
-rw-r--r-- | core/fxge/win32/win32_int.h | 62 |
7 files changed, 244 insertions, 10 deletions
diff --git a/core/fpdfapi/render/cpdf_charposlist.cpp b/core/fpdfapi/render/cpdf_charposlist.cpp index 68df46bdad..a87fc3334e 100644 --- a/core/fpdfapi/render/cpdf_charposlist.cpp +++ b/core/fpdfapi/render/cpdf_charposlist.cpp @@ -37,7 +37,8 @@ void CPDF_CharPosList::Load(const std::vector<uint32_t>& charCodes, FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; if (pCIDFont) charpos.m_bFontStyle = true; - + CFX_WideString unicode = pFont->UnicodeFromCharCode(CharCode); + charpos.m_Unicode = !unicode.IsEmpty() ? unicode.GetAt(0) : CharCode; charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); uint32_t GlyphID = charpos.m_GlyphIndex; #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp index 266ae50e78..e1c6a65034 100644 --- a/core/fxge/cfx_renderdevice.cpp +++ b/core/fxge/cfx_renderdevice.cpp @@ -348,7 +348,8 @@ bool ShouldDrawDeviceText(const CFX_Font* pFont, uint32_t text_flags) { } // namespace FXTEXT_CHARPOS::FXTEXT_CHARPOS() - : m_GlyphIndex(0), + : m_Unicode(0), + m_GlyphIndex(0), m_FontCharWidth(0), #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ m_ExtGID(0), diff --git a/core/fxge/cfx_renderdevice.h b/core/fxge/cfx_renderdevice.h index f33da57cc9..165b729541 100644 --- a/core/fxge/cfx_renderdevice.h +++ b/core/fxge/cfx_renderdevice.h @@ -71,6 +71,7 @@ class FXTEXT_CHARPOS { float m_AdjustMatrix[4]; CFX_PointF m_Origin; + uint32_t m_Unicode; uint32_t m_GlyphIndex; int32_t m_FontCharWidth; #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ diff --git a/core/fxge/cfx_windowsrenderdevice.h b/core/fxge/cfx_windowsrenderdevice.h index 7156dcdc4e..f1e0cbdb7a 100644 --- a/core/fxge/cfx_windowsrenderdevice.h +++ b/core/fxge/cfx_windowsrenderdevice.h @@ -14,6 +14,13 @@ #include "core/fxge/cfx_renderdevice.h" +enum WindowsPrintMode { + kModeEmf = 0, + kModeTextOnly = 1, + kModePostScript2 = 2, + kModePostScript3 = 3, +}; + class IFX_RenderDeviceDriver; #if defined(PDFIUM_PRINT_TEXT_WITH_GDI) @@ -25,7 +32,7 @@ extern bool g_pdfium_print_text_with_gdi; extern PDFiumEnsureTypefaceCharactersAccessible g_pdfium_typeface_accessible_func; #endif -extern int g_pdfium_print_postscript_level; +extern int g_pdfium_print_mode; class CFX_WindowsRenderDevice : public CFX_RenderDevice { public: diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp index ef3a7f2f8e..4427755cf5 100644 --- a/core/fxge/win32/fx_win32_device.cpp +++ b/core/fxge/win32/fx_win32_device.cpp @@ -689,7 +689,7 @@ bool CFX_Win32FontInfo::GetFontCharset(void* hFont, int* charset) { } // namespace -int g_pdfium_print_postscript_level = 0; +int g_pdfium_print_mode = WindowsPrintMode::kModeEmf; std::unique_ptr<IFX_SystemFontInfo> IFX_SystemFontInfo::CreateDefault( const char** pUnused) { @@ -1370,14 +1370,20 @@ IFX_RenderDeviceDriver* CFX_WindowsRenderDevice::CreateDriver(HDC hDC) { int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY); int obj_type = ::GetObjectType(hDC); bool use_printer = device_type == DT_RASPRINTER || - device_type == DT_PLOTTER || obj_type == OBJ_ENHMETADC; + device_type == DT_PLOTTER || + device_type == DT_CHARSTREAM || obj_type == OBJ_ENHMETADC; if (!use_printer) return new CGdiDisplayDriver(hDC); - if (g_pdfium_print_postscript_level == 2 || - g_pdfium_print_postscript_level == 3) { - return new CPSPrinterDriver(hDC, g_pdfium_print_postscript_level, false); - } - return new CGdiPrinterDriver(hDC); + if (g_pdfium_print_mode == WindowsPrintMode::kModeEmf) + return new CGdiPrinterDriver(hDC); + + if (g_pdfium_print_mode == WindowsPrintMode::kModeTextOnly) + return new CTextOnlyPrinterDriver(hDC); + + // Should be PostScript + ASSERT(g_pdfium_print_mode == WindowsPrintMode::kModePostScript2 || + g_pdfium_print_mode == WindowsPrintMode::kModePostScript3); + return new CPSPrinterDriver(hDC, g_pdfium_print_mode, false); } diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp index d7444f43a1..cae3859406 100644 --- a/core/fxge/win32/fx_win32_print.cpp +++ b/core/fxge/win32/fx_win32_print.cpp @@ -492,3 +492,159 @@ bool CPSPrinterDriver::DrawDeviceText(int nChars, return m_PSRenderer.DrawText(nChars, pCharPos, pFont, pObject2Device, font_size, color); } + +CTextOnlyPrinterDriver::CTextOnlyPrinterDriver(HDC hDC) + : m_hDC(hDC), + m_Width(INT_MAX), + m_Height(INT_MAX), + m_HorzSize(INT_MAX), + m_VertSize(INT_MAX), + m_OriginY(0.0f), + m_SetOrigin(false) { + m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); +} + +CTextOnlyPrinterDriver::~CTextOnlyPrinterDriver() { + EndRendering(); +} + +int CTextOnlyPrinterDriver::GetDeviceCaps(int caps_id) const { + switch (caps_id) { + case FXDC_DEVICE_CLASS: + return FXDC_PRINTER; + case FXDC_PIXEL_WIDTH: + return m_Width; + case FXDC_PIXEL_HEIGHT: + return m_Height; + case FXDC_BITS_PIXEL: + return m_nBitsPerPixel; + case FXDC_RENDER_CAPS: + return 0; + case FXDC_HORZ_SIZE: + return m_HorzSize; + case FXDC_VERT_SIZE: + return m_VertSize; + } + return 0; +} + +bool CTextOnlyPrinterDriver::SetClip_PathFill(const CFX_PathData* pPathData, + const CFX_Matrix* pObject2Device, + int fill_mode) { + return true; +} + +bool CTextOnlyPrinterDriver::SetClip_PathStroke( + const CFX_PathData* pPathData, + const CFX_Matrix* pObject2Device, + const CFX_GraphStateData* pGraphState) { + return false; +} + +bool CTextOnlyPrinterDriver::DrawPath(const CFX_PathData* pPathData, + const CFX_Matrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + uint32_t fill_color, + uint32_t stroke_color, + int fill_mode, + int blend_type) { + return false; +} + +bool CTextOnlyPrinterDriver::SetDIBits( + const CFX_RetainPtr<CFX_DIBSource>& pBitmap, + uint32_t color, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type) { + return false; +} + +bool CTextOnlyPrinterDriver::GetClipBox(FX_RECT* pRect) { + pRect->left = 0; + pRect->right = m_Width; + pRect->top = 0; + pRect->bottom = m_Height; + return true; +} + +bool CTextOnlyPrinterDriver::StretchDIBits( + const CFX_RetainPtr<CFX_DIBSource>& pBitmap, + uint32_t color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + uint32_t flags, + int blend_type) { + return false; +} + +bool CTextOnlyPrinterDriver::StartDIBits( + const CFX_RetainPtr<CFX_DIBSource>& pBitmap, + int bitmap_alpha, + uint32_t color, + const CFX_Matrix* pMatrix, + uint32_t render_flags, + std::unique_ptr<CFX_ImageRenderer>* handle, + int blend_type) { + return false; +} + +bool CTextOnlyPrinterDriver::DrawDeviceText(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + const CFX_Matrix* pObject2Device, + float font_size, + uint32_t color) { + if (g_pdfium_print_mode != 1) + return false; + if (nChars < 1 || !pFont || !pFont->IsEmbedded() || !pFont->IsTTFont()) + return false; + + // Scale factor used to minimize the kerning problems caused by rounding + // errors below. Value chosen based on the title of https://crbug.com/18383 + const double kScaleFactor = 10; + + CFX_WideString wsText; + int totalLength = nChars; + + // Detect new lines and add a space. Was likely removed by SkPDF if this is + // just text, and spaces seem to be ignored by label printers that use this + // driver. + if (m_SetOrigin && + FXSYS_round(m_OriginY) != FXSYS_round(pObject2Device->f * kScaleFactor)) { + wsText += L" "; + totalLength++; + } + m_OriginY = pObject2Device->f * kScaleFactor; + m_SetOrigin = true; + + // Text + for (int i = 0; i < nChars; ++i) { + // Only works with PDFs from Skia's PDF generator. Cannot handle arbitrary + // values from PDFs. + const FXTEXT_CHARPOS& charpos = pCharPos[i]; + ASSERT(charpos.m_AdjustMatrix[0] == 0); + ASSERT(charpos.m_AdjustMatrix[1] == 0); + ASSERT(charpos.m_AdjustMatrix[2] == 0); + ASSERT(charpos.m_AdjustMatrix[3] == 0); + ASSERT(charpos.m_Origin.y == 0); + + wsText += charpos.m_Unicode; + } + size_t len = totalLength; + CFX_ByteString text = CFX_ByteString::FromUnicode(wsText); + while (len > 0) { + char buffer[1026]; + size_t send_len = std::min(len, static_cast<size_t>(1024)); + *(reinterpret_cast<uint16_t*>(buffer)) = send_len; + memcpy(buffer + 2, text.c_str(), send_len); + ::GdiComment(m_hDC, send_len + 2, reinterpret_cast<const BYTE*>(buffer)); + len -= send_len; + text.Right(len); + } + return true; +} diff --git a/core/fxge/win32/win32_int.h b/core/fxge/win32/win32_int.h index d92d3b333c..c51bae7f67 100644 --- a/core/fxge/win32/win32_int.h +++ b/core/fxge/win32/win32_int.h @@ -333,4 +333,66 @@ class CPSPrinterDriver : public IFX_RenderDeviceDriver { CFX_PSRenderer m_PSRenderer; }; +class CTextOnlyPrinterDriver : public IFX_RenderDeviceDriver { + public: + explicit CTextOnlyPrinterDriver(HDC hDC); + ~CTextOnlyPrinterDriver() override; + + protected: + // IFX_RenderDeviceDriver + int GetDeviceCaps(int caps_id) const override; + void SaveState() override{}; + void RestoreState(bool bKeepSaved) override{}; + bool SetClip_PathFill(const CFX_PathData* pPathData, + const CFX_Matrix* pObject2Device, + int fill_mode) override; + bool SetClip_PathStroke(const CFX_PathData* pPathData, + const CFX_Matrix* pObject2Device, + const CFX_GraphStateData* pGraphState) override; + bool DrawPath(const CFX_PathData* pPathData, + const CFX_Matrix* pObject2Device, + const CFX_GraphStateData* pGraphState, + uint32_t fill_color, + uint32_t stroke_color, + int fill_mode, + int blend_type) override; + bool GetClipBox(FX_RECT* pRect) override; + bool SetDIBits(const CFX_RetainPtr<CFX_DIBSource>& pBitmap, + uint32_t color, + const FX_RECT* pSrcRect, + int left, + int top, + int blend_type) override; + bool StretchDIBits(const CFX_RetainPtr<CFX_DIBSource>& pBitmap, + uint32_t color, + int dest_left, + int dest_top, + int dest_width, + int dest_height, + const FX_RECT* pClipRect, + uint32_t flags, + int blend_type) override; + bool StartDIBits(const CFX_RetainPtr<CFX_DIBSource>& pBitmap, + int bitmap_alpha, + uint32_t color, + const CFX_Matrix* pMatrix, + uint32_t render_flags, + std::unique_ptr<CFX_ImageRenderer>* handle, + int blend_type) override; + bool DrawDeviceText(int nChars, + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + const CFX_Matrix* pObject2Device, + float font_size, + uint32_t color) override; + + HDC m_hDC; + int m_Width; + int m_Height; + int m_nBitsPerPixel; + int m_HorzSize; + int m_VertSize; + float m_OriginY; + bool m_SetOrigin; +}; #endif // CORE_FXGE_WIN32_WIN32_INT_H_ |