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/ge/cfx_cliprgn.h" 8 9 CFX_ClipRgn::CFX_ClipRgn(int width, int height) 10 : m_Type(RectI), m_Box(0, 0, width, height) {} 11 12 CFX_ClipRgn::CFX_ClipRgn(const CFX_ClipRgn& src) { 13 m_Type = src.m_Type; 14 m_Box = src.m_Box; 15 m_Mask = src.m_Mask; 16 } 17 18 CFX_ClipRgn::~CFX_ClipRgn() {} 19 20 void CFX_ClipRgn::Reset(const FX_RECT& rect) { 21 m_Type = RectI; 22 m_Box = rect; 23 m_Mask.SetNull(); 24 } 25 26 void CFX_ClipRgn::IntersectRect(const FX_RECT& rect) { 27 if (m_Type == RectI) { 28 m_Box.Intersect(rect); 29 return; 30 } 31 if (m_Type == MaskF) { 32 IntersectMaskRect(rect, m_Box, m_Mask); 33 return; 34 } 35 } 36 37 void CFX_ClipRgn::IntersectMaskRect(FX_RECT rect, 38 FX_RECT mask_rect, 39 CFX_DIBitmapRef Mask) { 40 const CFX_DIBitmap* mask_dib = Mask.GetObject(); 41 m_Type = MaskF; 42 m_Box = rect; 43 m_Box.Intersect(mask_rect); 44 if (m_Box.IsEmpty()) { 45 m_Type = RectI; 46 return; 47 } 48 if (m_Box == mask_rect) { 49 m_Mask = Mask; 50 return; 51 } 52 CFX_DIBitmap* new_dib = m_Mask.Emplace(); 53 new_dib->Create(m_Box.Width(), m_Box.Height(), FXDIB_8bppMask); 54 for (int row = m_Box.top; row < m_Box.bottom; row++) { 55 uint8_t* dest_scan = 56 new_dib->GetBuffer() + new_dib->GetPitch() * (row - m_Box.top); 57 uint8_t* src_scan = 58 mask_dib->GetBuffer() + mask_dib->GetPitch() * (row - mask_rect.top); 59 for (int col = m_Box.left; col < m_Box.right; col++) 60 dest_scan[col - m_Box.left] = src_scan[col - mask_rect.left]; 61 } 62 } 63 64 void CFX_ClipRgn::IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask) { 65 const CFX_DIBitmap* mask_dib = Mask.GetObject(); 66 ASSERT(mask_dib->GetFormat() == FXDIB_8bppMask); 67 FX_RECT mask_box(left, top, left + mask_dib->GetWidth(), 68 top + mask_dib->GetHeight()); 69 if (m_Type == RectI) { 70 IntersectMaskRect(m_Box, mask_box, Mask); 71 return; 72 } 73 if (m_Type == MaskF) { 74 FX_RECT new_box = m_Box; 75 new_box.Intersect(mask_box); 76 if (new_box.IsEmpty()) { 77 m_Type = RectI; 78 m_Mask.SetNull(); 79 m_Box = new_box; 80 return; 81 } 82 CFX_DIBitmapRef new_mask; 83 CFX_DIBitmap* new_dib = new_mask.Emplace(); 84 new_dib->Create(new_box.Width(), new_box.Height(), FXDIB_8bppMask); 85 const CFX_DIBitmap* old_dib = m_Mask.GetObject(); 86 for (int row = new_box.top; row < new_box.bottom; row++) { 87 uint8_t* old_scan = 88 old_dib->GetBuffer() + (row - m_Box.top) * old_dib->GetPitch(); 89 uint8_t* mask_scan = 90 mask_dib->GetBuffer() + (row - top) * mask_dib->GetPitch(); 91 uint8_t* new_scan = 92 new_dib->GetBuffer() + (row - new_box.top) * new_dib->GetPitch(); 93 for (int col = new_box.left; col < new_box.right; col++) { 94 new_scan[col - new_box.left] = 95 old_scan[col - m_Box.left] * mask_scan[col - left] / 255; 96 } 97 } 98 m_Box = new_box; 99 m_Mask = new_mask; 100 return; 101 } 102 ASSERT(false); 103 } 104