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

Side by Side 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, 5 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 unified diff | Download patch
« no previous file with comments | « no previous file | core/fxge/win32/win32_int.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "core/fxge/include/fx_ge.h" 7 #include "core/fxge/include/fx_ge.h"
8 8
9 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ 9 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
10 10
11 #include <windows.h> 11 #include <windows.h>
12 12
13 #include <algorithm>
14
13 #include "core/fxge/dib/dib_int.h" 15 #include "core/fxge/dib/dib_int.h"
14 #include "core/fxge/ge/fx_text_int.h" 16 #include "core/fxge/ge/fx_text_int.h"
15 #include "core/fxge/include/fx_freetype.h" 17 #include "core/fxge/include/fx_freetype.h"
16 #include "core/fxge/include/fx_ge_win32.h" 18 #include "core/fxge/include/fx_ge_win32.h"
17 #include "core/fxge/win32/win32_int.h" 19 #include "core/fxge/win32/win32_int.h"
18 20
21 // Set to true to enable printing text with GDI.
22 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
23
24 // Pointer to a helper function to make |font| with |text| of |text_length|
25 // accessible when printing text with GDI. This is useful in sandboxed
26 // environments where PDFium's access to GDI may be restricted.
27 typedef void (*PDFiumEnsureTypefaceCharactersAccessible)(const LOGFONT& font,
28 const wchar_t* text,
29 size_t text_length);
30 PDFiumEnsureTypefaceCharactersAccessible g_pdfium_typeface_accessible_func =
31 nullptr;
32
19 CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC) 33 CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC)
20 : CGdiDeviceDriver(hDC, FXDC_PRINTER), 34 : CGdiDeviceDriver(hDC, FXDC_PRINTER),
21 m_HorzSize(::GetDeviceCaps(m_hDC, HORZSIZE)), 35 m_HorzSize(::GetDeviceCaps(m_hDC, HORZSIZE)),
22 m_VertSize(::GetDeviceCaps(m_hDC, VERTSIZE)) {} 36 m_VertSize(::GetDeviceCaps(m_hDC, VERTSIZE)) {}
23 37
24 CGdiPrinterDriver::~CGdiPrinterDriver() {} 38 CGdiPrinterDriver::~CGdiPrinterDriver() {}
25 39
26 int CGdiPrinterDriver::GetDeviceCaps(int caps_id) const { 40 int CGdiPrinterDriver::GetDeviceCaps(int caps_id) const {
27 if (caps_id == FXDC_HORZ_SIZE) 41 if (caps_id == FXDC_HORZ_SIZE)
28 return m_HorzSize; 42 return m_HorzSize;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 FXSYS_fabs(pMatrix->c) < 0.5f && pMatrix->d != 0) { 153 FXSYS_fabs(pMatrix->c) < 0.5f && pMatrix->d != 0) {
140 FX_BOOL bFlipX = pMatrix->a < 0; 154 FX_BOOL bFlipX = pMatrix->a < 0;
141 FX_BOOL bFlipY = pMatrix->d > 0; 155 FX_BOOL bFlipY = pMatrix->d > 0;
142 return StretchDIBits(pSource, color, 156 return StretchDIBits(pSource, color,
143 bFlipX ? full_rect.right : full_rect.left, 157 bFlipX ? full_rect.right : full_rect.left,
144 bFlipY ? full_rect.bottom : full_rect.top, 158 bFlipY ? full_rect.bottom : full_rect.top,
145 bFlipX ? -full_rect.Width() : full_rect.Width(), 159 bFlipX ? -full_rect.Width() : full_rect.Width(),
146 bFlipY ? -full_rect.Height() : full_rect.Height(), 160 bFlipY ? -full_rect.Height() : full_rect.Height(),
147 nullptr, 0, blend_type); 161 nullptr, 0, blend_type);
148 } 162 }
149 if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) { 163 if (FXSYS_fabs(pMatrix->a) >= 0.5f || FXSYS_fabs(pMatrix->d) >= 0.5f)
150 std::unique_ptr<CFX_DIBitmap> pTransformed( 164 return FALSE;
151 pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0));
152 if (!pTransformed)
153 return FALSE;
154 165
155 return StretchDIBits(pTransformed.get(), color, full_rect.left, 166 std::unique_ptr<CFX_DIBitmap> pTransformed(
156 full_rect.top, full_rect.Width(), full_rect.Height(), 167 pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0));
157 nullptr, 0, blend_type); 168 if (!pTransformed)
158 } 169 return FALSE;
159 return FALSE; 170
171 return StretchDIBits(pTransformed.get(), color, full_rect.left, full_rect.top,
172 full_rect.Width(), full_rect.Height(), nullptr, 0,
173 blend_type);
160 } 174 }
161 175
162 #endif 176 FX_BOOL CGdiPrinterDriver::DrawDeviceText(int nChars,
177 const FXTEXT_CHARPOS* pCharPos,
178 CFX_Font* pFont,
179 CFX_FontCache* pCache,
180 const CFX_Matrix* pObject2Device,
181 FX_FLOAT font_size,
182 uint32_t color) {
183 if (!g_pdfium_print_text_with_gdi)
184 return FALSE;
185
186 if (nChars < 1 || !pFont || !pFont->IsEmbedded() || !pFont->IsTTFont())
187 return FALSE;
188
189 // Font
190 //
191 // 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.
192 // but unfortunately AddFontMemResourceEx() does not seem to cooperate.
193 // Loading font data to memory seems to work, but then enumerating the fonts
194 // fails to find it. This requires more investigation. In the meanwhile,
195 // assume the printing is happening on the machine that generated the PDF, so
196 // the embedded font is available through GDI anyway.
197 LOGFONT lf = {};
198 lf.lfHeight = -font_size;
199 lf.lfWeight = pFont->IsBold() ? FW_BOLD : FW_NORMAL;
200 lf.lfItalic = pFont->IsItalic();
201 lf.lfCharSet = DEFAULT_CHARSET;
202
203 const CFX_WideString wsName = pFont->GetFaceName().UTF8Decode();
204 int len = std::min(wsName.GetLength(), LF_FACESIZE - 1);
205 memcpy(lf.lfFaceName, wsName.c_str(), sizeof(lf.lfFaceName[0]) * len);
206 lf.lfFaceName[len] = 0;
207
208 HFONT font = CreateFontIndirect(&lf);
209 if (!font)
210 return FALSE;
211
212 int dc = SaveDC(m_hDC);
213 HGDIOBJ old_font = SelectObject(m_hDC, font);
214
215 // Transforms
216 //
217 // This is known to work with PDFs generated via Skia's PDF generator. It
218 // 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.
219 ASSERT(pObject2Device->GetB() == 0);
220 ASSERT(pObject2Device->GetC() == 0);
221 ASSERT(pObject2Device->GetA() == -pObject2Device->GetD());
222 SetGraphicsMode(m_hDC, GM_ADVANCED);
223 XFORM xform = {};
224 xform.eM11 = pObject2Device->GetA();
225 xform.eM22 = pObject2Device->GetA();
226 xform.eDx = pObject2Device->GetE();
227 xform.eDy = pObject2Device->GetF();
228 ModifyWorldTransform(m_hDC, &xform, MWT_LEFTMULTIPLY);
229
230 // Color
231 int unused_alpha;
232 FX_COLORREF rgb;
233 ArgbDecode(color, unused_alpha, rgb);
234 SetTextColor(m_hDC, rgb);
235 SetBkMode(m_hDC, TRANSPARENT);
236
237 // Text
238 CFX_WideString wstr;
239 for (int i = 0; i < nChars; ++i) {
240 // Same as above. Only works with PDFs from Skia's PDF generator.
241 const FXTEXT_CHARPOS& charpos = pCharPos[i];
242 ASSERT(charpos.m_OriginX == 0);
243 ASSERT(charpos.m_OriginY == 0);
244 ASSERT(charpos.m_AdjustMatrix[0] == 0);
245 ASSERT(charpos.m_AdjustMatrix[1] == 0);
246 ASSERT(charpos.m_AdjustMatrix[2] == 0);
247 ASSERT(charpos.m_AdjustMatrix[3] == 0);
248 wstr += charpos.m_GlyphIndex;
249 }
250
251 // Draw
252 SetTextAlign(m_hDC, TA_LEFT | TA_BASELINE);
253 BOOL ret = ExtTextOutW(m_hDC, 0, 0, ETO_GLYPH_INDEX, nullptr, wstr.c_str(),
254 nChars, nullptr);
255 if (!ret) {
256 if (g_pdfium_typeface_accessible_func) {
257 g_pdfium_typeface_accessible_func(lf, wstr.c_str(), nChars);
258 ret = ExtTextOutW(m_hDC, 0, 0, ETO_GLYPH_INDEX, nullptr, wstr.c_str(),
259 nChars, nullptr);
260 }
261 }
262
263 SelectObject(m_hDC, old_font);
264 DeleteObject(font);
265 RestoreDC(m_hDC, dc);
266 return ret;
267 }
268
269 #endif // _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
OLDNEW
« 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