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_scanlinecompositor_unittest.cpp
Go to the documentation of this file.
1// Copyright 2024 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#include "core/fxge/dib/cfx_scanlinecompositor.h"
6
7#include <stdint.h>
8
9#include <array>
10
11#include "core/fxcrt/span.h"
12#include "core/fxcrt/stl_util.h"
13#include "core/fxge/dib/fx_dib.h"
14#include "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17using testing::ElementsAreArray;
18
19namespace {
20
21constexpr FX_BGRA_STRUCT<uint8_t> kDestScan[] = {
22 {.blue = 255, .green = 100, .red = 0, .alpha = 0},
23 {.blue = 255, .green = 100, .red = 0, .alpha = 0},
24 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
25 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
26 {.blue = 255, .green = 100, .red = 0, .alpha = 100},
27 {.blue = 255, .green = 100, .red = 0, .alpha = 100},
28 {.blue = 255, .green = 100, .red = 0, .alpha = 200},
29 {.blue = 255, .green = 100, .red = 0, .alpha = 200},
30};
31constexpr FX_BGRA_STRUCT<uint8_t> kSrcScan1[] = {
32 {.blue = 255, .green = 100, .red = 0, .alpha = 0},
33 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
34 {.blue = 255, .green = 100, .red = 0, .alpha = 0},
35 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
36 {.blue = 255, .green = 100, .red = 0, .alpha = 100},
37 {.blue = 255, .green = 100, .red = 0, .alpha = 200},
38 {.blue = 255, .green = 100, .red = 0, .alpha = 100},
39 {.blue = 255, .green = 100, .red = 0, .alpha = 200},
40};
41constexpr FX_BGRA_STRUCT<uint8_t> kSrcScan2[] = {
42 {.blue = 100, .green = 0, .red = 255, .alpha = 0},
43 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
44 {.blue = 100, .green = 0, .red = 255, .alpha = 0},
45 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
46 {.blue = 100, .green = 0, .red = 255, .alpha = 100},
47 {.blue = 100, .green = 0, .red = 255, .alpha = 200},
48 {.blue = 100, .green = 0, .red = 255, .alpha = 100},
49 {.blue = 100, .green = 0, .red = 255, .alpha = 200},
50};
51constexpr FX_BGRA_STRUCT<uint8_t> kSrcScan3[] = {
52 {.blue = 0, .green = 255, .red = 100, .alpha = 0},
53 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
54 {.blue = 0, .green = 255, .red = 100, .alpha = 0},
55 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
56 {.blue = 0, .green = 255, .red = 100, .alpha = 100},
57 {.blue = 0, .green = 255, .red = 100, .alpha = 200},
58 {.blue = 0, .green = 255, .red = 100, .alpha = 100},
59 {.blue = 0, .green = 255, .red = 100, .alpha = 200},
60};
61
62void RunTest(CFX_ScanlineCompositor& compositor,
63 pdfium::span<const FX_BGRA_STRUCT<uint8_t>> src_span,
64 pdfium::span<const FX_BGRA_STRUCT<uint8_t>> expectations) {
65 std::array<FX_BGRA_STRUCT<uint8_t>, 8> dest_scan;
66 fxcrt::Copy(kDestScan, dest_scan);
67 compositor.CompositeRgbBitmapLine(pdfium::as_writable_byte_span(dest_scan),
68 pdfium::as_bytes(src_span),
69 dest_scan.size(), {});
70 EXPECT_THAT(dest_scan, ElementsAreArray(expectations));
71}
72
73#if defined(PDF_USE_SKIA)
74void PreMultiplyScanLine(pdfium::span<FX_BGRA_STRUCT<uint8_t>> scanline) {
75 for (auto& pixel : scanline) {
76 pixel = PreMultiplyColor(pixel);
77 }
78}
79
80void UnPreMultiplyScanLine(pdfium::span<FX_BGRA_STRUCT<uint8_t>> scanline) {
81 for (auto& pixel : scanline) {
82 pixel = UnPreMultiplyColor(pixel);
83 }
84}
85
86void RunPreMultiplyTest(
87 CFX_ScanlineCompositor& compositor,
88 pdfium::span<const FX_BGRA_STRUCT<uint8_t>> src_span,
89 pdfium::span<const FX_BGRA_STRUCT<uint8_t>> expectations) {
90 std::array<FX_BGRA_STRUCT<uint8_t>, 8> dest_scan;
91 fxcrt::Copy(kDestScan, dest_scan);
92 PreMultiplyScanLine(dest_scan);
93 std::array<FX_BGRA_STRUCT<uint8_t>, 8> src_scan;
94 fxcrt::Copy(src_span, src_scan);
95 PreMultiplyScanLine(src_scan);
96 compositor.CompositeRgbBitmapLine(pdfium::as_writable_byte_span(dest_scan),
97 pdfium::as_byte_span(src_scan),
98 dest_scan.size(), {});
99 UnPreMultiplyScanLine(dest_scan);
100 EXPECT_THAT(dest_scan, ElementsAreArray(expectations));
101}
102#endif // defined(PDF_USE_SKIA)
103
104} // namespace
105
106inline bool operator==(const FX_BGRA_STRUCT<uint8_t>& lhs,
107 const FX_BGRA_STRUCT<uint8_t>& rhs) {
108 return lhs.blue == rhs.blue && lhs.green == rhs.green && lhs.red == rhs.red &&
109 lhs.alpha == rhs.alpha;
110}
111
113 CFX_ScanlineCompositor compositor;
114 ASSERT_TRUE(compositor.Init(/*dest_format=*/FXDIB_Format::kBgra,
115 /*src_format=*/FXDIB_Format::kBgra,
116 /*src_palette=*/{},
117 /*mask_color=*/0,
118 /*blend_type=*/BlendMode::kNormal,
119 /*bRgbByteOrder=*/false));
120
121 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations1[] = {
122 {.blue = 255, .green = 100, .red = 0, .alpha = 0},
123 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
124 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
125 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
126 {.blue = 255, .green = 100, .red = 0, .alpha = 161},
127 {.blue = 255, .green = 100, .red = 0, .alpha = 222},
128 {.blue = 255, .green = 100, .red = 0, .alpha = 222},
129 {.blue = 255, .green = 100, .red = 0, .alpha = 244},
130 };
131 RunTest(compositor, kSrcScan1, kExpectations1);
132 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = {
133 {.blue = 100, .green = 0, .red = 255, .alpha = 0},
134 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
135 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
136 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
137 {.blue = 158, .green = 38, .red = 158, .alpha = 161},
138 {.blue = 115, .green = 10, .red = 229, .alpha = 222},
139 {.blue = 185, .green = 55, .red = 114, .alpha = 222},
140 {.blue = 127, .green = 18, .red = 209, .alpha = 244},
141 };
142 RunTest(compositor, kSrcScan2, kExpectations2);
143 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = {
144 {.blue = 0, .green = 255, .red = 100, .alpha = 0},
145 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
146 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
147 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
148 {.blue = 97, .green = 196, .red = 61, .alpha = 161},
149 {.blue = 26, .green = 239, .red = 89, .alpha = 222},
150 {.blue = 141, .green = 169, .red = 44, .alpha = 222},
151 {.blue = 46, .green = 227, .red = 81, .alpha = 244},
152 };
153 RunTest(compositor, kSrcScan3, kExpectations3);
154}
155
157 CFX_ScanlineCompositor compositor;
158 ASSERT_TRUE(compositor.Init(/*dest_format=*/FXDIB_Format::kBgra,
159 /*src_format=*/FXDIB_Format::kBgra,
160 /*src_palette=*/{},
161 /*mask_color=*/0,
162 /*blend_type=*/BlendMode::kDarken,
163 /*bRgbByteOrder=*/false));
164
165 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations1[] = {
166 {.blue = 255, .green = 100, .red = 0, .alpha = 0},
167 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
168 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
169 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
170 {.blue = 255, .green = 100, .red = 0, .alpha = 161},
171 {.blue = 255, .green = 100, .red = 0, .alpha = 222},
172 {.blue = 255, .green = 100, .red = 0, .alpha = 222},
173 {.blue = 255, .green = 100, .red = 0, .alpha = 244},
174 };
175 RunTest(compositor, kSrcScan1, kExpectations1);
176 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = {
177 {.blue = 100, .green = 0, .red = 255, .alpha = 0},
178 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
179 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
180 {.blue = 100, .green = 0, .red = 0, .alpha = 255},
181 {.blue = 158, .green = 38, .red = 96, .alpha = 161},
182 {.blue = 115, .green = 10, .red = 139, .alpha = 222},
183 {.blue = 185, .green = 55, .red = 24, .alpha = 222},
184 {.blue = 127, .green = 18, .red = 45, .alpha = 244},
185 };
186 RunTest(compositor, kSrcScan2, kExpectations2);
187 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = {
188 {.blue = 0, .green = 255, .red = 100, .alpha = 0},
189 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
190 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
191 {.blue = 0, .green = 100, .red = 0, .alpha = 255},
192 {.blue = 97, .green = 158, .red = 37, .alpha = 161},
193 {.blue = 26, .green = 184, .red = 53, .alpha = 222},
194 {.blue = 141, .green = 114, .red = 9, .alpha = 222},
195 {.blue = 46, .green = 127, .red = 17, .alpha = 244},
196 };
197 RunTest(compositor, kSrcScan3, kExpectations3);
198}
199
201 CFX_ScanlineCompositor compositor;
202 ASSERT_TRUE(compositor.Init(/*dest_format=*/FXDIB_Format::kBgra,
203 /*src_format=*/FXDIB_Format::kBgra,
204 /*src_palette=*/{},
205 /*mask_color=*/0,
206 /*blend_type=*/BlendMode::kHue,
207 /*bRgbByteOrder=*/false));
208
209 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations1[] = {
210 {.blue = 255, .green = 100, .red = 0, .alpha = 0},
211 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
212 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
213 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
214 {.blue = 255, .green = 100, .red = 0, .alpha = 161},
215 {.blue = 255, .green = 100, .red = 0, .alpha = 222},
216 {.blue = 255, .green = 100, .red = 0, .alpha = 222},
217 {.blue = 255, .green = 100, .red = 0, .alpha = 244},
218 };
219 RunTest(compositor, kSrcScan1, kExpectations1);
220 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = {
221 {.blue = 100, .green = 0, .red = 255, .alpha = 0},
222 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
223 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
224 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
225 {.blue = 158, .green = 38, .red = 158, .alpha = 161},
226 {.blue = 115, .green = 10, .red = 229, .alpha = 222},
227 {.blue = 185, .green = 55, .red = 114, .alpha = 222},
228 {.blue = 127, .green = 18, .red = 209, .alpha = 244},
229 };
230 RunTest(compositor, kSrcScan2, kExpectations2);
231 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = {
232 {.blue = 0, .green = 255, .red = 100, .alpha = 0},
233 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
234 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
235 {.blue = 0, .green = 123, .red = 49, .alpha = 255},
236 {.blue = 97, .green = 163, .red = 49, .alpha = 161},
237 {.blue = 26, .green = 192, .red = 71, .alpha = 222},
238 {.blue = 141, .green = 122, .red = 26, .alpha = 222},
239 {.blue = 46, .green = 141, .red = 49, .alpha = 244},
240 };
241 RunTest(compositor, kSrcScan3, kExpectations3);
242}
243
244#if defined(PDF_USE_SKIA)
245TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulNormal) {
246 CFX_ScanlineCompositor compositor;
247 ASSERT_TRUE(compositor.Init(/*dest_format=*/FXDIB_Format::kBgraPremul,
248 /*src_format=*/FXDIB_Format::kBgraPremul,
249 /*src_palette=*/{},
250 /*mask_color=*/0,
251 /*blend_type=*/BlendMode::kNormal,
252 /*bRgbByteOrder=*/false));
253
254 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations1[] = {
255 {.blue = 0, .green = 0, .red = 0, .alpha = 0},
256 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
257 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
258 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
259 {.blue = 253, .green = 98, .red = 0, .alpha = 161},
260 {.blue = 253, .green = 98, .red = 0, .alpha = 222},
261 {.blue = 253, .green = 98, .red = 0, .alpha = 222},
262 {.blue = 253, .green = 98, .red = 0, .alpha = 244},
263 };
264 RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1);
265 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = {
266 {.blue = 0, .green = 0, .red = 0, .alpha = 0},
267 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
268 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
269 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
270 {.blue = 156, .green = 36, .red = 158, .alpha = 161},
271 {.blue = 113, .green = 9, .red = 229, .alpha = 222},
272 {.blue = 183, .green = 53, .red = 114, .alpha = 222},
273 {.blue = 126, .green = 16, .red = 209, .alpha = 244},
274 };
275 RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2);
276 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = {
277 {.blue = 0, .green = 0, .red = 0, .alpha = 0},
278 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
279 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
280 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
281 {.blue = 95, .green = 194, .red = 61, .alpha = 161},
282 {.blue = 24, .green = 238, .red = 89, .alpha = 222},
283 {.blue = 138, .green = 168, .red = 44, .alpha = 222},
284 {.blue = 44, .green = 225, .red = 81, .alpha = 244},
285 };
286 RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3);
287}
288
289TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulDarken) {
290 CFX_ScanlineCompositor compositor;
291 ASSERT_TRUE(compositor.Init(/*dest_format=*/FXDIB_Format::kBgraPremul,
292 /*src_format=*/FXDIB_Format::kBgraPremul,
293 /*src_palette=*/{},
294 /*mask_color=*/0,
295 /*blend_type=*/BlendMode::kDarken,
296 /*bRgbByteOrder=*/false));
297
298 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations1[] = {
299 {.blue = 0, .green = 0, .red = 0, .alpha = 0},
300 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
301 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
302 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
303 {.blue = 253, .green = 98, .red = 0, .alpha = 161},
304 {.blue = 253, .green = 97, .red = 0, .alpha = 222},
305 {.blue = 253, .green = 97, .red = 0, .alpha = 222},
306 {.blue = 252, .green = 98, .red = 0, .alpha = 244},
307 };
308 RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1);
309 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = {
310 {.blue = 0, .green = 0, .red = 0, .alpha = 0},
311 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
312 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
313 {.blue = 100, .green = 0, .red = 0, .alpha = 255},
314 {.blue = 156, .green = 36, .red = 95, .alpha = 161},
315 {.blue = 112, .green = 9, .red = 138, .alpha = 222},
316 {.blue = 182, .green = 53, .red = 24, .alpha = 222},
317 {.blue = 125, .green = 16, .red = 44, .alpha = 244},
318 };
319 RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2);
320 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = {
321 {.blue = 0, .green = 0, .red = 0, .alpha = 0},
322 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
323 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
324 {.blue = 0, .green = 100, .red = 0, .alpha = 255},
325 {.blue = 95, .green = 156, .red = 36, .alpha = 161},
326 {.blue = 24, .green = 182, .red = 53, .alpha = 222},
327 {.blue = 138, .green = 112, .red = 9, .alpha = 222},
328 {.blue = 44, .green = 125, .red = 16, .alpha = 244},
329 };
330 RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3);
331}
332
333TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulHue) {
334 CFX_ScanlineCompositor compositor;
335 ASSERT_TRUE(compositor.Init(/*dest_format=*/FXDIB_Format::kBgraPremul,
336 /*src_format=*/FXDIB_Format::kBgraPremul,
337 /*src_palette=*/{},
338 /*mask_color=*/0,
339 /*blend_type=*/BlendMode::kHue,
340 /*bRgbByteOrder=*/false));
341
342 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations1[] = {
343 {.blue = 0, .green = 0, .red = 0, .alpha = 0},
344 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
345 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
346 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
347 {.blue = 253, .green = 98, .red = 0, .alpha = 161},
348 {.blue = 253, .green = 97, .red = 0, .alpha = 222},
349 {.blue = 253, .green = 97, .red = 0, .alpha = 222},
350 {.blue = 252, .green = 98, .red = 0, .alpha = 244},
351 };
352 RunPreMultiplyTest(compositor, kSrcScan1, kExpectations1);
353 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations2[] = {
354 {.blue = 0, .green = 0, .red = 0, .alpha = 0},
355 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
356 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
357 {.blue = 100, .green = 0, .red = 255, .alpha = 255},
358 {.blue = 156, .green = 36, .red = 156, .alpha = 161},
359 {.blue = 112, .green = 9, .red = 228, .alpha = 222},
360 {.blue = 182, .green = 53, .red = 113, .alpha = 222},
361 {.blue = 125, .green = 16, .red = 207, .alpha = 244},
362 };
363 RunPreMultiplyTest(compositor, kSrcScan2, kExpectations2);
364 constexpr FX_BGRA_STRUCT<uint8_t> kExpectations3[] = {
365 {.blue = 0, .green = 0, .red = 0, .alpha = 0},
366 {.blue = 0, .green = 255, .red = 100, .alpha = 255},
367 {.blue = 255, .green = 100, .red = 0, .alpha = 255},
368 {.blue = 0, .green = 123, .red = 49, .alpha = 255},
369 {.blue = 95, .green = 161, .red = 49, .alpha = 161},
370 {.blue = 24, .green = 189, .red = 71, .alpha = 222},
371 {.blue = 138, .green = 119, .red = 26, .alpha = 222},
372 {.blue = 44, .green = 140, .red = 48, .alpha = 244},
373 };
374 RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3);
375}
376#endif // defined(PDF_USE_SKIA)
bool operator==(const FX_BGRA_STRUCT< uint8_t > &lhs, const FX_BGRA_STRUCT< uint8_t > &rhs)
TEST(FXCRYPT, MD5GenerateEmtpyData)
BlendMode
Definition fx_dib.h:119
@ kNormal
Definition fx_dib.h:120
@ kDarken
Definition fx_dib.h:124
FXDIB_Format
Definition fx_dib.h:21