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 |