diff options
Diffstat (limited to 'core/fxge/win32')
-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 |
3 files changed, 231 insertions, 7 deletions
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_ |