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 <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "core/fxcrt/fx_system.h" | 13 #include "core/fxcrt/fx_system.h" |
14 #include "core/fxge/cfx_renderdevice.h" | 14 #include "core/fxge/cfx_renderdevice.h" |
15 #include "core/fxge/cfx_windowsdevice.h" | 15 #include "core/fxge/cfx_windowsdevice.h" |
16 #include "core/fxge/dib/dib_int.h" | 16 #include "core/fxge/dib/dib_int.h" |
17 #include "core/fxge/fx_freetype.h" | 17 #include "core/fxge/fx_freetype.h" |
18 #include "core/fxge/ge/fx_text_int.h" | 18 #include "core/fxge/ge/fx_text_int.h" |
19 #include "core/fxge/win32/win32_int.h" | 19 #include "core/fxge/win32/win32_int.h" |
| 20 #include "third_party/base/ptr_util.h" |
20 | 21 |
21 #if defined(PDFIUM_PRINT_TEXT_WITH_GDI) | 22 #if defined(PDFIUM_PRINT_TEXT_WITH_GDI) |
22 namespace { | 23 namespace { |
23 | 24 |
24 class ScopedState { | 25 class ScopedState { |
25 public: | 26 public: |
26 ScopedState(HDC hDC, HFONT hFont) : m_hDC(hDC) { | 27 ScopedState(HDC hDC, HFONT hFont) : m_hDC(hDC) { |
27 m_iState = SaveDC(m_hDC); | 28 m_iState = SaveDC(m_hDC); |
28 m_hFont = SelectObject(m_hDC, hFont); | 29 m_hFont = SelectObject(m_hDC, hFont); |
29 } | 30 } |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 return false; | 320 return false; |
320 | 321 |
321 // Try to get the font and draw again. | 322 // Try to get the font and draw again. |
322 g_pdfium_typeface_accessible_func(&lf, wsText.c_str(), nChars); | 323 g_pdfium_typeface_accessible_func(&lf, wsText.c_str(), nChars); |
323 return !!ExtTextOutW(m_hDC, 0, 0, ETO_GLYPH_INDEX, nullptr, wsText.c_str(), | 324 return !!ExtTextOutW(m_hDC, 0, 0, ETO_GLYPH_INDEX, nullptr, wsText.c_str(), |
324 nChars, nChars > 1 ? &spacing[1] : nullptr); | 325 nChars, nChars > 1 ? &spacing[1] : nullptr); |
325 #else | 326 #else |
326 return false; | 327 return false; |
327 #endif | 328 #endif |
328 } | 329 } |
| 330 |
| 331 CPSOutput::CPSOutput(HDC hDC) { |
| 332 m_hDC = hDC; |
| 333 } |
| 334 |
| 335 CPSOutput::~CPSOutput() {} |
| 336 |
| 337 void CPSOutput::Release() { |
| 338 delete this; |
| 339 } |
| 340 |
| 341 void CPSOutput::OutputPS(const FX_CHAR* str, int len) { |
| 342 if (len < 0) { |
| 343 len = (int)FXSYS_strlen(str); |
| 344 } |
| 345 |
| 346 int sent_len = 0; |
| 347 while (len > 0) { |
| 348 FX_CHAR buffer[1026]; |
| 349 int send_len = len > 1024 ? 1024 : len; |
| 350 *(uint16_t*)buffer = send_len; |
| 351 FXSYS_memcpy(buffer + 2, str + sent_len, send_len); |
| 352 |
| 353 // ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, buffer, 0, NULL); |
| 354 ::GdiComment(m_hDC, send_len + 2, reinterpret_cast<const BYTE*>(buffer)); |
| 355 sent_len += send_len; |
| 356 len -= send_len; |
| 357 } |
| 358 } |
| 359 |
| 360 CPSPrinterDriver::CPSPrinterDriver(HDC hDC, int pslevel, bool bCmykOutput) { |
| 361 m_hDC = hDC; |
| 362 m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); |
| 363 m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); |
| 364 m_Width = ::GetDeviceCaps(m_hDC, HORZRES); |
| 365 m_Height = ::GetDeviceCaps(m_hDC, VERTRES); |
| 366 m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); |
| 367 m_pPSOutput = pdfium::MakeUnique<CPSOutput>(m_hDC); |
| 368 m_PSRenderer.Init(m_pPSOutput.get(), pslevel, m_Width, m_Height, bCmykOutput); |
| 369 m_bCmykOutput = bCmykOutput; |
| 370 HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1); |
| 371 int ret = ::GetClipRgn(hDC, hRgn); |
| 372 if (ret == 1) { |
| 373 ret = ::GetRegionData(hRgn, 0, NULL); |
| 374 if (ret) { |
| 375 RGNDATA* pData = (RGNDATA*)FX_Alloc(uint8_t, ret); |
| 376 ret = ::GetRegionData(hRgn, ret, pData); |
| 377 if (ret) { |
| 378 CFX_PathData path; |
| 379 path.AllocPointCount(pData->rdh.nCount * 5); |
| 380 for (uint32_t i = 0; i < pData->rdh.nCount; i++) { |
| 381 RECT* pRect = (RECT*)(pData->Buffer + pData->rdh.nRgnSize * i); |
| 382 path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom, |
| 383 (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top); |
| 384 } |
| 385 m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING); |
| 386 } |
| 387 FX_Free(pData); |
| 388 } |
| 389 } |
| 390 ::DeleteObject(hRgn); |
| 391 } |
| 392 |
| 393 CPSPrinterDriver::~CPSPrinterDriver() { |
| 394 EndRendering(); |
| 395 } |
| 396 |
| 397 int CPSPrinterDriver::GetDeviceCaps(int caps_id) const { |
| 398 switch (caps_id) { |
| 399 case FXDC_DEVICE_CLASS: |
| 400 return FXDC_PRINTER; |
| 401 case FXDC_PIXEL_WIDTH: |
| 402 return m_Width; |
| 403 case FXDC_PIXEL_HEIGHT: |
| 404 return m_Height; |
| 405 case FXDC_BITS_PIXEL: |
| 406 return m_nBitsPerPixel; |
| 407 case FXDC_RENDER_CAPS: |
| 408 return m_bCmykOutput ? FXRC_BIT_MASK | FXRC_CMYK_OUTPUT : FXRC_BIT_MASK; |
| 409 case FXDC_HORZ_SIZE: |
| 410 return m_HorzSize; |
| 411 case FXDC_VERT_SIZE: |
| 412 return m_VertSize; |
| 413 } |
| 414 return 0; |
| 415 } |
| 416 |
| 417 bool CPSPrinterDriver::StartRendering() { |
| 418 return m_PSRenderer.StartRendering(); |
| 419 } |
| 420 |
| 421 void CPSPrinterDriver::EndRendering() { |
| 422 m_PSRenderer.EndRendering(); |
| 423 } |
| 424 |
| 425 void CPSPrinterDriver::SaveState() { |
| 426 m_PSRenderer.SaveState(); |
| 427 } |
| 428 |
| 429 void CPSPrinterDriver::RestoreState(bool bKeepSaved) { |
| 430 m_PSRenderer.RestoreState(bKeepSaved); |
| 431 } |
| 432 |
| 433 bool CPSPrinterDriver::SetClip_PathFill(const CFX_PathData* pPathData, |
| 434 const CFX_Matrix* pObject2Device, |
| 435 int fill_mode) { |
| 436 m_PSRenderer.SetClip_PathFill(pPathData, pObject2Device, fill_mode); |
| 437 return true; |
| 438 } |
| 439 |
| 440 bool CPSPrinterDriver::SetClip_PathStroke( |
| 441 const CFX_PathData* pPathData, |
| 442 const CFX_Matrix* pObject2Device, |
| 443 const CFX_GraphStateData* pGraphState) { |
| 444 m_PSRenderer.SetClip_PathStroke(pPathData, pObject2Device, pGraphState); |
| 445 return true; |
| 446 } |
| 447 |
| 448 bool CPSPrinterDriver::DrawPath(const CFX_PathData* pPathData, |
| 449 const CFX_Matrix* pObject2Device, |
| 450 const CFX_GraphStateData* pGraphState, |
| 451 FX_ARGB fill_color, |
| 452 FX_ARGB stroke_color, |
| 453 int fill_mode, |
| 454 int blend_type) { |
| 455 if (blend_type != FXDIB_BLEND_NORMAL) { |
| 456 return false; |
| 457 } |
| 458 return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState, |
| 459 fill_color, stroke_color, fill_mode & 3); |
| 460 } |
| 461 |
| 462 bool CPSPrinterDriver::GetClipBox(FX_RECT* pRect) { |
| 463 *pRect = m_PSRenderer.GetClipBox(); |
| 464 return true; |
| 465 } |
| 466 |
| 467 bool CPSPrinterDriver::SetDIBits(const CFX_DIBSource* pBitmap, |
| 468 uint32_t color, |
| 469 const FX_RECT* pSrcRect, |
| 470 int left, |
| 471 int top, |
| 472 int blend_type) { |
| 473 if (blend_type != FXDIB_BLEND_NORMAL) |
| 474 return false; |
| 475 return m_PSRenderer.SetDIBits(pBitmap, color, left, top); |
| 476 } |
| 477 |
| 478 bool CPSPrinterDriver::StretchDIBits(const CFX_DIBSource* pBitmap, |
| 479 uint32_t color, |
| 480 int dest_left, |
| 481 int dest_top, |
| 482 int dest_width, |
| 483 int dest_height, |
| 484 const FX_RECT* pClipRect, |
| 485 uint32_t flags, |
| 486 int blend_type) { |
| 487 if (blend_type != FXDIB_BLEND_NORMAL) |
| 488 return false; |
| 489 return m_PSRenderer.StretchDIBits(pBitmap, color, dest_left, dest_top, |
| 490 dest_width, dest_height, flags); |
| 491 } |
| 492 |
| 493 bool CPSPrinterDriver::StartDIBits(const CFX_DIBSource* pBitmap, |
| 494 int bitmap_alpha, |
| 495 uint32_t color, |
| 496 const CFX_Matrix* pMatrix, |
| 497 uint32_t render_flags, |
| 498 void*& handle, |
| 499 int blend_type) { |
| 500 if (blend_type != FXDIB_BLEND_NORMAL) |
| 501 return false; |
| 502 |
| 503 if (bitmap_alpha < 255) |
| 504 return false; |
| 505 |
| 506 handle = nullptr; |
| 507 return m_PSRenderer.DrawDIBits(pBitmap, color, pMatrix, render_flags); |
| 508 } |
| 509 |
| 510 bool CPSPrinterDriver::DrawDeviceText(int nChars, |
| 511 const FXTEXT_CHARPOS* pCharPos, |
| 512 CFX_Font* pFont, |
| 513 const CFX_Matrix* pObject2Device, |
| 514 FX_FLOAT font_size, |
| 515 uint32_t color) { |
| 516 return m_PSRenderer.DrawText(nChars, pCharPos, pFont, pObject2Device, |
| 517 font_size, color); |
| 518 } |
| 519 |
| 520 void* CPSPrinterDriver::GetPlatformSurface() const { |
| 521 return (void*)m_hDC; |
| 522 } |
OLD | NEW |