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