OLD | NEW |
---|---|
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 Loading... | |
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_ | |
OLD | NEW |