Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cfx_agg_bitmapcomposer.cpp
Go to the documentation of this file.
1// Copyright 2017 The PDFium Authors
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/agg/cfx_agg_bitmapcomposer.h"
8
9#include <stddef.h>
10
11#include "core/fxcrt/check_op.h"
12#include "core/fxcrt/compiler_specific.h"
13#include "core/fxcrt/fx_2d_size.h"
14#include "core/fxcrt/fx_coordinates.h"
15#include "core/fxcrt/fx_safe_types.h"
16#include "core/fxcrt/fx_system.h"
17#include "core/fxcrt/stl_util.h"
18#include "core/fxge/agg/cfx_agg_cliprgn.h"
19#include "core/fxge/dib/cfx_dibitmap.h"
20
21CFX_AggBitmapComposer::CFX_AggBitmapComposer() = default;
22
23CFX_AggBitmapComposer::~CFX_AggBitmapComposer() = default;
24
25void CFX_AggBitmapComposer::Compose(const RetainPtr<CFX_DIBitmap>& pDest,
26 const CFX_AggClipRgn* pClipRgn,
27 float alpha,
28 uint32_t mask_color,
29 const FX_RECT& dest_rect,
30 bool bVertical,
31 bool bFlipX,
32 bool bFlipY,
33 bool bRgbByteOrder,
34 BlendMode blend_mode) {
35 m_pBitmap = pDest;
36 m_pClipRgn = pClipRgn;
37 m_DestLeft = dest_rect.left;
38 m_DestTop = dest_rect.top;
39 m_DestWidth = dest_rect.Width();
40 m_DestHeight = dest_rect.Height();
41 m_Alpha = alpha;
42 m_MaskColor = mask_color;
43 m_pClipMask = nullptr;
44 if (pClipRgn && pClipRgn->GetType() != CFX_AggClipRgn::kRectI) {
45 m_pClipMask = pClipRgn->GetMask();
46 }
47 m_bVertical = bVertical;
48 m_bFlipX = bFlipX;
49 m_bFlipY = bFlipY;
50 m_bRgbByteOrder = bRgbByteOrder;
51 m_BlendMode = blend_mode;
52}
53
54bool CFX_AggBitmapComposer::SetInfo(int width,
55 int height,
56 FXDIB_Format src_format,
57 DataVector<uint32_t> src_palette) {
60 m_SrcFormat = src_format;
61 if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, src_palette,
62 m_MaskColor, m_BlendMode, m_bRgbByteOrder)) {
63 return false;
64 }
65 if (m_bVertical) {
66 m_pScanlineV.resize(m_pBitmap->GetBPP() / 8 * width + 4);
67 m_pClipScanV.resize(m_pBitmap->GetHeight());
68 }
69 if (m_Alpha != 1.0f) {
70 m_pAddClipScan.resize(m_bVertical ? m_pBitmap->GetHeight()
71 : m_pBitmap->GetWidth());
72 }
73 return true;
74}
75
76void CFX_AggBitmapComposer::DoCompose(pdfium::span<uint8_t> dest_scan,
77 pdfium::span<const uint8_t> src_scan,
78 int dest_width,
79 pdfium::span<const uint8_t> clip_scan) {
80 if (m_Alpha != 1.0f) {
81 if (!clip_scan.empty()) {
82 for (int i = 0; i < dest_width; ++i) {
83 m_pAddClipScan[i] = clip_scan[i] * m_Alpha;
84 }
85 } else {
86 fxcrt::Fill(pdfium::make_span(m_pAddClipScan).first(dest_width),
87 FXSYS_roundf(m_Alpha * 255));
88 }
89 clip_scan = m_pAddClipScan;
90 }
91 if (m_SrcFormat == FXDIB_Format::k8bppMask) {
92 m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width,
93 clip_scan);
94 } else if (m_SrcFormat == FXDIB_Format::k8bppRgb) {
95 m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width,
96 clip_scan);
97 } else {
98 m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width,
99 clip_scan);
100 }
101}
102
103void CFX_AggBitmapComposer::ComposeScanline(
104 int line,
105 pdfium::span<const uint8_t> scanline) {
106 if (m_bVertical) {
107 ComposeScanlineV(line, scanline);
108 return;
109 }
110 pdfium::span<const uint8_t> clip_scan;
111 if (m_pClipMask) {
112 clip_scan =
113 m_pClipMask
114 ->GetWritableScanline(m_DestTop + line - m_pClipRgn->GetBox().top)
115 .subspan(m_DestLeft - m_pClipRgn->GetBox().left);
116 }
117 pdfium::span<uint8_t> dest_scan =
118 m_pBitmap->GetWritableScanline(line + m_DestTop);
119 if (!dest_scan.empty()) {
120 FX_SAFE_UINT32 offset = m_DestLeft;
121 offset *= m_pBitmap->GetBPP();
122 offset /= 8;
123 if (!offset.IsValid())
124 return;
125
126 dest_scan = dest_scan.subspan(offset.ValueOrDie());
127 }
128 DoCompose(dest_scan, scanline, m_DestWidth, clip_scan);
129}
130
131void CFX_AggBitmapComposer::ComposeScanlineV(
132 int line,
133 pdfium::span<const uint8_t> scanline) {
134 const int bytes_per_pixel = m_pBitmap->GetBPP() / 8;
135 int dest_pitch = m_pBitmap->GetPitch();
136 int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line);
137 pdfium::span<uint8_t> dest_span = m_pBitmap->GetWritableBuffer();
138 if (!dest_span.empty()) {
139 const size_t dest_x_offset = Fx2DSizeOrDie(dest_x, bytes_per_pixel);
140 const size_t dest_y_offset = Fx2DSizeOrDie(m_DestTop, dest_pitch);
141 dest_span = dest_span.subspan(dest_y_offset).subspan(dest_x_offset);
142 if (m_bFlipY) {
143 const size_t dest_flip_offset =
144 Fx2DSizeOrDie(dest_pitch, m_DestHeight - 1);
145 dest_span = dest_span.subspan(dest_flip_offset);
146 }
147 }
148 uint8_t* dest_buf = dest_span.data();
149 const int y_step = m_bFlipY ? -dest_pitch : dest_pitch;
150 uint8_t* src_scan = m_pScanlineV.data();
151 uint8_t* dest_scan = dest_buf;
153 for (int i = 0; i < m_DestHeight; ++i) {
154 for (int j = 0; j < bytes_per_pixel; ++j) {
155 *src_scan++ = dest_scan[j];
156 }
157 dest_scan += y_step;
158 }
159 pdfium::span<uint8_t> clip_scan;
160 if (m_pClipMask) {
161 clip_scan = m_pClipScanV;
162 int clip_pitch = m_pClipMask->GetPitch();
163 const uint8_t* src_clip =
164 m_pClipMask->GetScanline(m_DestTop - m_pClipRgn->GetBox().top)
165 .subspan(dest_x - m_pClipRgn->GetBox().left)
166 .data();
167 if (m_bFlipY) {
168 src_clip += Fx2DSizeOrDie(clip_pitch, m_DestHeight - 1);
169 clip_pitch = -clip_pitch;
170 }
171 for (int i = 0; i < m_DestHeight; ++i) {
172 clip_scan[i] = *src_clip;
173 src_clip += clip_pitch;
174 }
175 }
176 DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan);
177 src_scan = m_pScanlineV.data();
178 dest_scan = dest_buf;
179 for (int i = 0; i < m_DestHeight; ++i) {
180 for (int j = 0; j < bytes_per_pixel; ++j) {
181 dest_scan[j] = *src_scan++;
182 }
183 dest_scan += y_step;
184 }
185 });
186}
#define DCHECK_NE(x, y)
Definition check_op.h:18
void ComposeScanline(int line, pdfium::span< const uint8_t > scanline) override
bool SetInfo(int width, int height, FXDIB_Format src_format, DataVector< uint32_t > src_palette) override
~CFX_AggBitmapComposer() override
void Compose(const RetainPtr< CFX_DIBitmap > &pDest, const CFX_AggClipRgn *pClipRgn, float alpha, uint32_t mask_color, const FX_RECT &dest_rect, bool bVertical, bool bFlipX, bool bFlipY, bool bRgbByteOrder, BlendMode blend_mode)
ClipType GetType() const
#define UNSAFE_TODO(...)
BlendMode
Definition fx_dib.h:119
FXDIB_Format
Definition fx_dib.h:21
pdfium::CheckedNumeric< uint32_t > FX_SAFE_UINT32
int Height() const
int Width() const
int32_t top
int32_t left