| 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 | 11 |
| 11 #include "core/fxcrt/fx_system.h" | 12 #include "core/fxcrt/fx_system.h" |
| 12 #include "core/fxge/cfx_gemodule.h" | 13 #include "core/fxge/cfx_gemodule.h" |
| 13 #include "core/fxge/cfx_graphstatedata.h" | 14 #include "core/fxge/cfx_graphstatedata.h" |
| 14 #include "core/fxge/cfx_pathdata.h" | 15 #include "core/fxge/cfx_pathdata.h" |
| 15 #include "core/fxge/win32/cfx_windowsdib.h" | 16 #include "core/fxge/win32/cfx_windowsdib.h" |
| 16 #include "core/fxge/win32/win32_int.h" | 17 #include "core/fxge/win32/win32_int.h" |
| 18 #include "third_party/base/ptr_util.h" |
| 17 | 19 |
| 18 // Has to come before gdiplus.h | 20 // Has to come before gdiplus.h |
| 19 namespace Gdiplus { | 21 namespace Gdiplus { |
| 20 using std::min; | 22 using std::min; |
| 21 using std::max; | 23 using std::max; |
| 22 } // namespace Gdiplus | 24 } // namespace Gdiplus |
| 23 | 25 |
| 24 #include <gdiplus.h> // NOLINT | 26 #include <gdiplus.h> // NOLINT |
| 25 | 27 |
| 26 using namespace Gdiplus; // NOLINT | 28 using namespace Gdiplus; // NOLINT |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 m_pGdiRemoveFontMemResourseEx((HANDLE)handle); | 453 m_pGdiRemoveFontMemResourseEx((HANDLE)handle); |
| 452 } | 454 } |
| 453 | 455 |
| 454 static GpBrush* _GdipCreateBrush(DWORD argb) { | 456 static GpBrush* _GdipCreateBrush(DWORD argb) { |
| 455 CGdiplusExt& GdiplusExt = | 457 CGdiplusExt& GdiplusExt = |
| 456 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; | 458 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; |
| 457 GpSolidFill* solidBrush = nullptr; | 459 GpSolidFill* solidBrush = nullptr; |
| 458 CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); | 460 CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush); |
| 459 return solidBrush; | 461 return solidBrush; |
| 460 } | 462 } |
| 461 static CFX_DIBitmap* _StretchMonoToGray(int dest_width, | 463 |
| 462 int dest_height, | 464 static std::unique_ptr<CFX_DIBitmap> StretchMonoToGray( |
| 463 const CFX_DIBitmap* pSource, | 465 int dest_width, |
| 464 FX_RECT* pClipRect) { | 466 int dest_height, |
| 467 const CFX_DIBitmap* pSource, |
| 468 FX_RECT* pClipRect) { |
| 465 bool bFlipX = dest_width < 0; | 469 bool bFlipX = dest_width < 0; |
| 466 if (bFlipX) { | 470 if (bFlipX) |
| 467 dest_width = -dest_width; | 471 dest_width = -dest_width; |
| 468 } | 472 |
| 469 bool bFlipY = dest_height < 0; | 473 bool bFlipY = dest_height < 0; |
| 470 if (bFlipY) { | 474 if (bFlipY) |
| 471 dest_height = -dest_height; | 475 dest_height = -dest_height; |
| 472 } | 476 |
| 473 int result_width = pClipRect->Width(); | 477 int result_width = pClipRect->Width(); |
| 474 int result_height = pClipRect->Height(); | 478 int result_height = pClipRect->Height(); |
| 475 int result_pitch = (result_width + 3) / 4 * 4; | 479 int result_pitch = (result_width + 3) / 4 * 4; |
| 476 CFX_DIBitmap* pStretched = new CFX_DIBitmap; | 480 auto pStretched = pdfium::MakeUnique<CFX_DIBitmap>(); |
| 477 if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) { | 481 if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) |
| 478 delete pStretched; | |
| 479 return nullptr; | 482 return nullptr; |
| 480 } | 483 |
| 481 LPBYTE dest_buf = pStretched->GetBuffer(); | 484 LPBYTE dest_buf = pStretched->GetBuffer(); |
| 482 int src_width = pSource->GetWidth(); | 485 int src_width = pSource->GetWidth(); |
| 483 int src_height = pSource->GetHeight(); | 486 int src_height = pSource->GetHeight(); |
| 484 int y_unit = src_height / dest_height; | 487 int y_unit = src_height / dest_height; |
| 485 int x_unit = src_width / dest_width; | 488 int x_unit = src_width / dest_width; |
| 486 int area_unit = y_unit * x_unit; | 489 int area_unit = y_unit * x_unit; |
| 487 LPBYTE src_buf = pSource->GetBuffer(); | 490 LPBYTE src_buf = pSource->GetBuffer(); |
| 488 int src_pitch = pSource->GetPitch(); | 491 int src_pitch = pSource->GetPitch(); |
| 489 for (int dest_y = 0; dest_y < result_height; dest_y++) { | 492 for (int dest_y = 0; dest_y < result_height; dest_y++) { |
| 490 LPBYTE dest_scan = dest_buf + dest_y * result_pitch; | 493 LPBYTE dest_scan = dest_buf + dest_y * result_pitch; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 505 sum += 255; | 508 sum += 255; |
| 506 } | 509 } |
| 507 } | 510 } |
| 508 src_line += src_pitch; | 511 src_line += src_pitch; |
| 509 } | 512 } |
| 510 dest_scan[dest_x] = 255 - sum / area_unit; | 513 dest_scan[dest_x] = 255 - sum / area_unit; |
| 511 } | 514 } |
| 512 } | 515 } |
| 513 return pStretched; | 516 return pStretched; |
| 514 } | 517 } |
| 518 |
| 515 static void OutputImageMask(GpGraphics* pGraphics, | 519 static void OutputImageMask(GpGraphics* pGraphics, |
| 516 BOOL bMonoDevice, | 520 BOOL bMonoDevice, |
| 517 const CFX_DIBitmap* pBitmap, | 521 const CFX_DIBitmap* pBitmap, |
| 518 int dest_left, | 522 int dest_left, |
| 519 int dest_top, | 523 int dest_top, |
| 520 int dest_width, | 524 int dest_width, |
| 521 int dest_height, | 525 int dest_height, |
| 522 FX_ARGB argb, | 526 FX_ARGB argb, |
| 523 const FX_RECT* pClipRect) { | 527 const FX_RECT* pClipRect) { |
| 524 ASSERT(pBitmap->GetBPP() == 1); | 528 ASSERT(pBitmap->GetBPP() == 1); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 551 abs(dest_height) < src_height) { | 555 abs(dest_height) < src_height) { |
| 552 FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, | 556 FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, |
| 553 dest_top + dest_height); | 557 dest_top + dest_height); |
| 554 image_rect.Normalize(); | 558 image_rect.Normalize(); |
| 555 FX_RECT image_clip = image_rect; | 559 FX_RECT image_clip = image_rect; |
| 556 image_clip.Intersect(*pClipRect); | 560 image_clip.Intersect(*pClipRect); |
| 557 if (image_clip.IsEmpty()) { | 561 if (image_clip.IsEmpty()) { |
| 558 return; | 562 return; |
| 559 } | 563 } |
| 560 image_clip.Offset(-image_rect.left, -image_rect.top); | 564 image_clip.Offset(-image_rect.left, -image_rect.top); |
| 561 CFX_DIBitmap* pStretched = nullptr; | 565 std::unique_ptr<CFX_DIBitmap> pStretched; |
| 562 if (src_width * src_height > 10000) { | 566 if (src_width * src_height > 10000) { |
| 563 pStretched = | 567 pStretched = |
| 564 _StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip); | 568 StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip); |
| 565 } else { | 569 } else { |
| 566 pStretched = | 570 pStretched = |
| 567 pBitmap->StretchTo(dest_width, dest_height, false, &image_clip); | 571 pBitmap->StretchTo(dest_width, dest_height, false, &image_clip); |
| 568 } | 572 } |
| 569 GpBitmap* bitmap; | 573 GpBitmap* bitmap; |
| 570 CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(), | 574 CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(), |
| 571 (image_clip.Width() + 3) / 4 * 4, | 575 (image_clip.Width() + 3) / 4 * 4, |
| 572 PixelFormat8bppIndexed, | 576 PixelFormat8bppIndexed, |
| 573 pStretched->GetBuffer(), &bitmap); | 577 pStretched->GetBuffer(), &bitmap); |
| 574 int a, r, g, b; | 578 int a, r, g, b; |
| 575 ArgbDecode(argb, a, r, g, b); | 579 ArgbDecode(argb, a, r, g, b); |
| 576 UINT pal[258]; | 580 UINT pal[258]; |
| 577 pal[0] = 0; | 581 pal[0] = 0; |
| 578 pal[1] = 256; | 582 pal[1] = 256; |
| 579 for (int i = 0; i < 256; i++) { | 583 for (int i = 0; i < 256; i++) { |
| 580 pal[i + 2] = ArgbEncode(i * a / 255, r, g, b); | 584 pal[i + 2] = ArgbEncode(i * a / 255, r, g, b); |
| 581 } | 585 } |
| 582 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal); | 586 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal); |
| 583 CallFunc(GdipDrawImageI)(pGraphics, bitmap, | 587 CallFunc(GdipDrawImageI)(pGraphics, bitmap, |
| 584 image_rect.left + image_clip.left, | 588 image_rect.left + image_clip.left, |
| 585 image_rect.top + image_clip.top); | 589 image_rect.top + image_clip.top); |
| 586 CallFunc(GdipDisposeImage)(bitmap); | 590 CallFunc(GdipDisposeImage)(bitmap); |
| 587 delete pStretched; | |
| 588 return; | 591 return; |
| 589 } | 592 } |
| 590 GpBitmap* bitmap; | 593 GpBitmap* bitmap; |
| 591 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, | 594 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, |
| 592 PixelFormat1bppIndexed, scan0, &bitmap); | 595 PixelFormat1bppIndexed, scan0, &bitmap); |
| 593 UINT palette[4] = {PaletteFlagsHasAlpha, 2, 0, argb}; | 596 UINT palette[4] = {PaletteFlagsHasAlpha, 2, 0, argb}; |
| 594 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette); | 597 CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette); |
| 595 Point destinationPoints[] = {Point(dest_left, dest_top), | 598 Point destinationPoints[] = {Point(dest_left, dest_top), |
| 596 Point(dest_left + dest_width, dest_top), | 599 Point(dest_left + dest_width, dest_top), |
| 597 Point(dest_left, dest_top + dest_height)}; | 600 Point(dest_left, dest_top + dest_height)}; |
| 598 CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3); | 601 CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3); |
| 599 CallFunc(GdipDisposeImage)(bitmap); | 602 CallFunc(GdipDisposeImage)(bitmap); |
| 600 } | 603 } |
| 601 static void OutputImage(GpGraphics* pGraphics, | 604 static void OutputImage(GpGraphics* pGraphics, |
| 602 const CFX_DIBitmap* pBitmap, | 605 const CFX_DIBitmap* pBitmap, |
| 603 const FX_RECT* pSrcRect, | 606 const FX_RECT* pSrcRect, |
| 604 int dest_left, | 607 int dest_left, |
| 605 int dest_top, | 608 int dest_top, |
| 606 int dest_width, | 609 int dest_width, |
| 607 int dest_height) { | 610 int dest_height) { |
| 608 int src_width = pSrcRect->Width(), src_height = pSrcRect->Height(); | 611 int src_width = pSrcRect->Width(), src_height = pSrcRect->Height(); |
| 609 CGdiplusExt& GdiplusExt = | 612 CGdiplusExt& GdiplusExt = |
| 610 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; | 613 ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; |
| 611 if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) { | 614 if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) { |
| 612 FX_RECT new_rect(0, 0, src_width, src_height); | 615 FX_RECT new_rect(0, 0, src_width, src_height); |
| 613 CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect); | 616 std::unique_ptr<CFX_DIBitmap> pCloned = pBitmap->Clone(pSrcRect); |
| 614 if (!pCloned) { | 617 if (!pCloned) |
| 615 return; | 618 return; |
| 616 } | 619 OutputImage(pGraphics, pCloned.get(), &new_rect, dest_left, dest_top, |
| 617 OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_width, | 620 dest_width, dest_height); |
| 618 dest_height); | |
| 619 delete pCloned; | |
| 620 return; | 621 return; |
| 621 } | 622 } |
| 622 int src_pitch = pBitmap->GetPitch(); | 623 int src_pitch = pBitmap->GetPitch(); |
| 623 uint8_t* scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + | 624 uint8_t* scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + |
| 624 pBitmap->GetBPP() * pSrcRect->left / 8; | 625 pBitmap->GetBPP() * pSrcRect->left / 8; |
| 625 GpBitmap* bitmap = nullptr; | 626 GpBitmap* bitmap = nullptr; |
| 626 switch (pBitmap->GetFormat()) { | 627 switch (pBitmap->GetFormat()) { |
| 627 case FXDIB_Argb: | 628 case FXDIB_Argb: |
| 628 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, | 629 CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, |
| 629 PixelFormat32bppARGB, scan0, &bitmap); | 630 PixelFormat32bppARGB, scan0, &bitmap); |
| (...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 FXSYS_memcpy(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, | 1515 FXSYS_memcpy(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, |
| 1515 dest_pitch); | 1516 dest_pitch); |
| 1516 } | 1517 } |
| 1517 } | 1518 } |
| 1518 CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf( | 1519 CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf( |
| 1519 pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32); | 1520 pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32); |
| 1520 FX_Free(pData); | 1521 FX_Free(pData); |
| 1521 FreeDIBitmap(pInfo); | 1522 FreeDIBitmap(pInfo); |
| 1522 return pDIBitmap; | 1523 return pDIBitmap; |
| 1523 } | 1524 } |
| OLD | NEW |