Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Unified Diff: core/fxge/win32/fx_win32_print.cpp

Issue 2113563003: Implement CGdiPrinterDriver::DrawDeviceText(). (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | core/fxge/win32/win32_int.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: core/fxge/win32/fx_win32_print.cpp
diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp
index aef6062e73ec12ca290b7605f1e8a88054d6315c..7185a4e1469c574f2f2d3a52a88a7cd4588500ce 100644
--- a/core/fxge/win32/fx_win32_print.cpp
+++ b/core/fxge/win32/fx_win32_print.cpp
@@ -10,12 +10,26 @@
#include <windows.h>
+#include <algorithm>
+
#include "core/fxge/dib/dib_int.h"
#include "core/fxge/ge/fx_text_int.h"
#include "core/fxge/include/fx_freetype.h"
#include "core/fxge/include/fx_ge_win32.h"
#include "core/fxge/win32/win32_int.h"
+// Set to true to enable printing text with GDI.
+bool g_pdfium_print_text_with_gdi = false;
Lei Zhang 2016/06/30 07:54:08 dsinclair: Given the somewhat experimental status,
dsinclair 2016/06/30 13:31:57 Why not make it a compile option that's off by def
Lei Zhang 2016/06/30 22:20:09 It's more complicated, but done in patch set 2. Th
+
+// Pointer to a helper function to make |font| with |text| of |text_length|
+// accessible when printing text with GDI. This is useful in sandboxed
+// environments where PDFium's access to GDI may be restricted.
+typedef void (*PDFiumEnsureTypefaceCharactersAccessible)(const LOGFONT& font,
+ const wchar_t* text,
+ size_t text_length);
+PDFiumEnsureTypefaceCharactersAccessible g_pdfium_typeface_accessible_func =
+ nullptr;
+
CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC)
: CGdiDeviceDriver(hDC, FXDC_PRINTER),
m_HorzSize(::GetDeviceCaps(m_hDC, HORZSIZE)),
@@ -146,17 +160,110 @@ FX_BOOL CGdiPrinterDriver::StartDIBits(const CFX_DIBSource* pSource,
bFlipY ? -full_rect.Height() : full_rect.Height(),
nullptr, 0, blend_type);
}
- if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) {
- std::unique_ptr<CFX_DIBitmap> pTransformed(
- pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0));
- if (!pTransformed)
- return FALSE;
+ if (FXSYS_fabs(pMatrix->a) >= 0.5f || FXSYS_fabs(pMatrix->d) >= 0.5f)
+ return FALSE;
- return StretchDIBits(pTransformed.get(), color, full_rect.left,
- full_rect.top, full_rect.Width(), full_rect.Height(),
- nullptr, 0, blend_type);
+ std::unique_ptr<CFX_DIBitmap> pTransformed(
+ pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0));
+ if (!pTransformed)
+ return FALSE;
+
+ return StretchDIBits(pTransformed.get(), color, full_rect.left, full_rect.top,
+ full_rect.Width(), full_rect.Height(), nullptr, 0,
+ blend_type);
+}
+
+FX_BOOL CGdiPrinterDriver::DrawDeviceText(int nChars,
+ const FXTEXT_CHARPOS* pCharPos,
+ CFX_Font* pFont,
+ CFX_FontCache* pCache,
+ const CFX_Matrix* pObject2Device,
+ FX_FLOAT font_size,
+ uint32_t color) {
+ if (!g_pdfium_print_text_with_gdi)
+ return FALSE;
+
+ if (nChars < 1 || !pFont || !pFont->IsEmbedded() || !pFont->IsTTFont())
+ return FALSE;
+
+ // Font
+ //
+ // Note that |pFont| has the actual font to render with embedded within, but
dsinclair 2016/06/30 13:31:56 This sounds like more of a TODO?
Lei Zhang 2016/06/30 22:20:09 Done.
+ // but unfortunately AddFontMemResourceEx() does not seem to cooperate.
+ // Loading font data to memory seems to work, but then enumerating the fonts
+ // fails to find it. This requires more investigation. In the meanwhile,
+ // assume the printing is happening on the machine that generated the PDF, so
+ // the embedded font is available through GDI anyway.
+ LOGFONT lf = {};
+ lf.lfHeight = -font_size;
+ lf.lfWeight = pFont->IsBold() ? FW_BOLD : FW_NORMAL;
+ lf.lfItalic = pFont->IsItalic();
+ lf.lfCharSet = DEFAULT_CHARSET;
+
+ const CFX_WideString wsName = pFont->GetFaceName().UTF8Decode();
+ int len = std::min(wsName.GetLength(), LF_FACESIZE - 1);
+ memcpy(lf.lfFaceName, wsName.c_str(), sizeof(lf.lfFaceName[0]) * len);
+ lf.lfFaceName[len] = 0;
+
+ HFONT font = CreateFontIndirect(&lf);
+ if (!font)
+ return FALSE;
+
+ int dc = SaveDC(m_hDC);
+ HGDIOBJ old_font = SelectObject(m_hDC, font);
+
+ // Transforms
+ //
+ // This is known to work with PDFs generated via Skia's PDF generator. It
+ // obviously do not work for arbitrary PDFs.
dsinclair 2016/06/30 13:31:57 nit: s/do/does/
Lei Zhang 2016/06/30 22:20:09 Done.
+ ASSERT(pObject2Device->GetB() == 0);
+ ASSERT(pObject2Device->GetC() == 0);
+ ASSERT(pObject2Device->GetA() == -pObject2Device->GetD());
+ SetGraphicsMode(m_hDC, GM_ADVANCED);
+ XFORM xform = {};
+ xform.eM11 = pObject2Device->GetA();
+ xform.eM22 = pObject2Device->GetA();
+ xform.eDx = pObject2Device->GetE();
+ xform.eDy = pObject2Device->GetF();
+ ModifyWorldTransform(m_hDC, &xform, MWT_LEFTMULTIPLY);
+
+ // Color
+ int unused_alpha;
+ FX_COLORREF rgb;
+ ArgbDecode(color, unused_alpha, rgb);
+ SetTextColor(m_hDC, rgb);
+ SetBkMode(m_hDC, TRANSPARENT);
+
+ // Text
+ CFX_WideString wstr;
+ for (int i = 0; i < nChars; ++i) {
+ // Same as above. Only works with PDFs from Skia's PDF generator.
+ const FXTEXT_CHARPOS& charpos = pCharPos[i];
+ ASSERT(charpos.m_OriginX == 0);
+ ASSERT(charpos.m_OriginY == 0);
+ ASSERT(charpos.m_AdjustMatrix[0] == 0);
+ ASSERT(charpos.m_AdjustMatrix[1] == 0);
+ ASSERT(charpos.m_AdjustMatrix[2] == 0);
+ ASSERT(charpos.m_AdjustMatrix[3] == 0);
+ wstr += charpos.m_GlyphIndex;
+ }
+
+ // Draw
+ SetTextAlign(m_hDC, TA_LEFT | TA_BASELINE);
+ BOOL ret = ExtTextOutW(m_hDC, 0, 0, ETO_GLYPH_INDEX, nullptr, wstr.c_str(),
+ nChars, nullptr);
+ if (!ret) {
+ if (g_pdfium_typeface_accessible_func) {
+ g_pdfium_typeface_accessible_func(lf, wstr.c_str(), nChars);
+ ret = ExtTextOutW(m_hDC, 0, 0, ETO_GLYPH_INDEX, nullptr, wstr.c_str(),
+ nChars, nullptr);
+ }
}
- return FALSE;
+
+ SelectObject(m_hDC, old_font);
+ DeleteObject(font);
+ RestoreDC(m_hDC, dc);
+ return ret;
}
-#endif
+#endif // _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
« no previous file with comments | « no previous file | core/fxge/win32/win32_int.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698