1 // Copyright 2016 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "core/fxge/cfx_cliprgn.h" 8 9 #include <utility> 10 11 #include "core/fxge/dib/cfx_dibitmap.h" 12 #include "third_party/base/logging.h" 13 14 CFX_ClipRgn::CFX_ClipRgn(int width, int height) 15 : m_Type(RectI), m_Box(0, 0, width, height) {} 16 17 CFX_ClipRgn::CFX_ClipRgn(const CFX_ClipRgn& src) { 18 m_Type = src.m_Type; 19 m_Box = src.m_Box; 20 m_Mask = src.m_Mask; 21 } 22 23 CFX_ClipRgn::~CFX_ClipRgn() {} 24 25 void CFX_ClipRgn::Reset(const FX_RECT& rect) { 26 m_Type = RectI; 27 m_Box = rect; 28 m_Mask = nullptr; 29 } 30 31 void CFX_ClipRgn::IntersectRect(const FX_RECT& rect) { 32 if (m_Type == RectI) { 33 m_Box.Intersect(rect); 34 return; 35 } 36 if (m_Type == MaskF) { 37 IntersectMaskRect(rect, m_Box, m_Mask); 38 return; 39 } 40 } 41 42 void CFX_ClipRgn::IntersectMaskRect(FX_RECT rect, 43 FX_RECT mask_rect, 44 const RetainPtr<CFX_DIBitmap>& pMask) { 45 m_Type = MaskF; 46 m_Box = rect; 47 m_Box.Intersect(mask_rect); 48 if (m_Box.IsEmpty()) { 49 m_Type = RectI; 50 return; 51 } 52 if (m_Box == mask_rect) { 53 m_Mask = pMask; 54 return; 55 } 56 RetainPtr<CFX_DIBitmap> pOldMask(pMask); 57 m_Mask = pdfium::MakeRetain<CFX_DIBitmap>(); 58 m_Mask->Create(m_Box.Width(), m_Box.Height(), FXDIB_8bppMask); 59 for (int row = m_Box.top; row < m_Box.bottom; row++) { 60 uint8_t* dest_scan = 61 m_Mask->GetBuffer() + m_Mask->GetPitch() * (row - m_Box.top); 62 uint8_t* src_scan = 63 pOldMask->GetBuffer() + pOldMask->GetPitch() * (row - mask_rect.top); 64 for (int col = m_Box.left; col < m_Box.right; col++) 65 dest_scan[col - m_Box.left] = src_scan[col - mask_rect.left]; 66 } 67 } 68 69 void CFX_ClipRgn::IntersectMaskF(int left, 70 int top, 71 const RetainPtr<CFX_DIBitmap>& pMask) { 72 ASSERT(pMask->GetFormat() == FXDIB_8bppMask); 73 FX_RECT mask_box(left, top, left + pMask->GetWidth(), 74 top + pMask->GetHeight()); 75 if (m_Type == RectI) { 76 IntersectMaskRect(m_Box, mask_box, pMask); 77 return; 78 } 79 if (m_Type == MaskF) { 80 FX_RECT new_box = m_Box; 81 new_box.Intersect(mask_box); 82 if (new_box.IsEmpty()) { 83 m_Type = RectI; 84 m_Mask = nullptr; 85 m_Box = new_box; 86 return; 87 } 88 auto new_dib = pdfium::MakeRetain<CFX_DIBitmap>(); 89 new_dib->Create(new_box.Width(), new_box.Height(), FXDIB_8bppMask); 90 for (int row = new_box.top; row < new_box.bottom; row++) { 91 uint8_t* old_scan = 92 m_Mask->GetBuffer() + (row - m_Box.top) * m_Mask->GetPitch(); 93 uint8_t* mask_scan = pMask->GetBuffer() + (row - top) * pMask->GetPitch(); 94 uint8_t* new_scan = 95 new_dib->GetBuffer() + (row - new_box.top) * new_dib->GetPitch(); 96 for (int col = new_box.left; col < new_box.right; col++) { 97 new_scan[col - new_box.left] = 98 old_scan[col - m_Box.left] * mask_scan[col - left] / 255; 99 } 100 } 101 m_Box = new_box; 102 m_Mask = std::move(new_dib); 103 return; 104 } 105 NOTREACHED(); 106 } 107