• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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/dib/cfx_bitmapcomposer.h"
8 
9 #include "core/fxge/cfx_cliprgn.h"
10 #include "core/fxge/dib/cfx_dibitmap.h"
11 
CFX_BitmapComposer()12 CFX_BitmapComposer::CFX_BitmapComposer()
13     : m_bRgbByteOrder(false), m_BlendType(FXDIB_BLEND_NORMAL) {}
14 
~CFX_BitmapComposer()15 CFX_BitmapComposer::~CFX_BitmapComposer() {}
16 
Compose(const RetainPtr<CFX_DIBitmap> & pDest,const CFX_ClipRgn * pClipRgn,int bitmap_alpha,uint32_t mask_color,const FX_RECT & dest_rect,bool bVertical,bool bFlipX,bool bFlipY,bool bRgbByteOrder,int alpha_flag,int blend_type)17 void CFX_BitmapComposer::Compose(const RetainPtr<CFX_DIBitmap>& pDest,
18                                  const CFX_ClipRgn* pClipRgn,
19                                  int bitmap_alpha,
20                                  uint32_t mask_color,
21                                  const FX_RECT& dest_rect,
22                                  bool bVertical,
23                                  bool bFlipX,
24                                  bool bFlipY,
25                                  bool bRgbByteOrder,
26                                  int alpha_flag,
27                                  int blend_type) {
28   m_pBitmap = pDest;
29   m_pClipRgn = pClipRgn;
30   m_DestLeft = dest_rect.left;
31   m_DestTop = dest_rect.top;
32   m_DestWidth = dest_rect.Width();
33   m_DestHeight = dest_rect.Height();
34   m_BitmapAlpha = bitmap_alpha;
35   m_MaskColor = mask_color;
36   m_pClipMask = nullptr;
37   if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI)
38     m_pClipMask = pClipRgn->GetMask();
39   m_bVertical = bVertical;
40   m_bFlipX = bFlipX;
41   m_bFlipY = bFlipY;
42   m_AlphaFlag = alpha_flag;
43   m_bRgbByteOrder = bRgbByteOrder;
44   m_BlendType = blend_type;
45 }
46 
SetInfo(int width,int height,FXDIB_Format src_format,uint32_t * pSrcPalette)47 bool CFX_BitmapComposer::SetInfo(int width,
48                                  int height,
49                                  FXDIB_Format src_format,
50                                  uint32_t* pSrcPalette) {
51   m_SrcFormat = src_format;
52   if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette,
53                          m_MaskColor, FXDIB_BLEND_NORMAL,
54                          m_pClipMask != nullptr || (m_BitmapAlpha < 255),
55                          m_bRgbByteOrder, m_AlphaFlag)) {
56     return false;
57   }
58   if (m_bVertical) {
59     m_pScanlineV.resize(m_pBitmap->GetBPP() / 8 * width + 4);
60     m_pClipScanV.resize(m_pBitmap->GetHeight());
61     if (m_pBitmap->m_pAlphaMask)
62       m_pScanlineAlphaV.resize(width + 4);
63   }
64   if (m_BitmapAlpha < 255) {
65     m_pAddClipScan.resize(m_bVertical ? m_pBitmap->GetHeight()
66                                       : m_pBitmap->GetWidth());
67   }
68   return true;
69 }
70 
DoCompose(uint8_t * dest_scan,const uint8_t * src_scan,int dest_width,const uint8_t * clip_scan,const uint8_t * src_extra_alpha,uint8_t * dst_extra_alpha)71 void CFX_BitmapComposer::DoCompose(uint8_t* dest_scan,
72                                    const uint8_t* src_scan,
73                                    int dest_width,
74                                    const uint8_t* clip_scan,
75                                    const uint8_t* src_extra_alpha,
76                                    uint8_t* dst_extra_alpha) {
77   uint8_t* pAddClipScan = m_pAddClipScan.data();
78   if (m_BitmapAlpha < 255) {
79     if (clip_scan) {
80       for (int i = 0; i < dest_width; ++i)
81         pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255;
82     } else {
83       memset(pAddClipScan, m_BitmapAlpha, dest_width);
84     }
85     clip_scan = pAddClipScan;
86   }
87   if (m_SrcFormat == FXDIB_8bppMask) {
88     m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width,
89                                        clip_scan, dst_extra_alpha);
90   } else if ((m_SrcFormat & 0xff) == 8) {
91     m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width,
92                                         clip_scan, src_extra_alpha,
93                                         dst_extra_alpha);
94   } else {
95     m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width,
96                                         clip_scan, src_extra_alpha,
97                                         dst_extra_alpha);
98   }
99 }
100 
ComposeScanline(int line,const uint8_t * scanline,const uint8_t * scan_extra_alpha)101 void CFX_BitmapComposer::ComposeScanline(int line,
102                                          const uint8_t* scanline,
103                                          const uint8_t* scan_extra_alpha) {
104   if (m_bVertical) {
105     ComposeScanlineV(line, scanline, scan_extra_alpha);
106     return;
107   }
108   const uint8_t* clip_scan = nullptr;
109   if (m_pClipMask) {
110     clip_scan = m_pClipMask->GetBuffer() +
111                 (m_DestTop + line - m_pClipRgn->GetBox().top) *
112                     m_pClipMask->GetPitch() +
113                 (m_DestLeft - m_pClipRgn->GetBox().left);
114   }
115   uint8_t* dest_scan =
116       const_cast<uint8_t*>(m_pBitmap->GetScanline(line + m_DestTop)) +
117       m_DestLeft * m_pBitmap->GetBPP() / 8;
118   uint8_t* dest_alpha_scan =
119       m_pBitmap->m_pAlphaMask
120           ? const_cast<uint8_t*>(
121                 m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop)) +
122                 m_DestLeft
123           : nullptr;
124   DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha,
125             dest_alpha_scan);
126 }
127 
ComposeScanlineV(int line,const uint8_t * scanline,const uint8_t * scan_extra_alpha)128 void CFX_BitmapComposer::ComposeScanlineV(int line,
129                                           const uint8_t* scanline,
130                                           const uint8_t* scan_extra_alpha) {
131   int Bpp = m_pBitmap->GetBPP() / 8;
132   int dest_pitch = m_pBitmap->GetPitch();
133   int dest_alpha_pitch =
134       m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0;
135   int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line);
136   uint8_t* dest_buf =
137       m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch;
138   uint8_t* dest_alpha_buf = m_pBitmap->m_pAlphaMask
139                                 ? m_pBitmap->m_pAlphaMask->GetBuffer() +
140                                       dest_x + m_DestTop * dest_alpha_pitch
141                                 : nullptr;
142   if (m_bFlipY) {
143     dest_buf += dest_pitch * (m_DestHeight - 1);
144     dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1);
145   }
146   int y_step = dest_pitch;
147   int y_alpha_step = dest_alpha_pitch;
148   if (m_bFlipY) {
149     y_step = -y_step;
150     y_alpha_step = -y_alpha_step;
151   }
152   uint8_t* src_scan = m_pScanlineV.data();
153   uint8_t* dest_scan = dest_buf;
154   for (int i = 0; i < m_DestHeight; ++i) {
155     for (int j = 0; j < Bpp; ++j)
156       *src_scan++ = dest_scan[j];
157     dest_scan += y_step;
158   }
159   uint8_t* src_alpha_scan = m_pScanlineAlphaV.data();
160   uint8_t* dest_alpha_scan = dest_alpha_buf;
161   if (dest_alpha_scan) {
162     for (int i = 0; i < m_DestHeight; ++i) {
163       *src_alpha_scan++ = *dest_alpha_scan;
164       dest_alpha_scan += y_alpha_step;
165     }
166   }
167   uint8_t* clip_scan = nullptr;
168   if (m_pClipMask) {
169     clip_scan = m_pClipScanV.data();
170     int clip_pitch = m_pClipMask->GetPitch();
171     const uint8_t* src_clip =
172         m_pClipMask->GetBuffer() +
173         (m_DestTop - m_pClipRgn->GetBox().top) * clip_pitch +
174         (dest_x - m_pClipRgn->GetBox().left);
175     if (m_bFlipY) {
176       src_clip += clip_pitch * (m_DestHeight - 1);
177       clip_pitch = -clip_pitch;
178     }
179     for (int i = 0; i < m_DestHeight; ++i) {
180       clip_scan[i] = *src_clip;
181       src_clip += clip_pitch;
182     }
183   }
184   DoCompose(m_pScanlineV.data(), scanline, m_DestHeight, clip_scan,
185             scan_extra_alpha, m_pScanlineAlphaV.data());
186   src_scan = m_pScanlineV.data();
187   dest_scan = dest_buf;
188   for (int i = 0; i < m_DestHeight; ++i) {
189     for (int j = 0; j < Bpp; ++j)
190       dest_scan[j] = *src_scan++;
191     dest_scan += y_step;
192   }
193   src_alpha_scan = m_pScanlineAlphaV.data();
194   dest_alpha_scan = dest_alpha_buf;
195   if (!dest_alpha_scan)
196     return;
197   for (int i = 0; i < m_DestHeight; ++i) {
198     *dest_alpha_scan = *src_alpha_scan++;
199     dest_alpha_scan += y_alpha_step;
200   }
201 }
202