5#include "core/fxge/dib/cfx_scanlinecompositor.h"
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"
17using testing::ElementsAreArray;
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},
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},
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},
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},
63 pdfium::span<
const FX_BGRA_STRUCT<uint8_t>> src_span,
64 pdfium::span<
const FX_BGRA_STRUCT<uint8_t>> expectations) {
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));
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);
80void UnPreMultiplyScanLine(pdfium::span<FX_BGRA_STRUCT<uint8_t>> scanline) {
81 for (
auto& pixel : scanline) {
82 pixel = UnPreMultiplyColor(pixel);
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));
108 return lhs.blue == rhs.blue && lhs.green == rhs.green && lhs.red == rhs.red &&
109 lhs.alpha == rhs.alpha;
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},
131 RunTest(compositor, kSrcScan1, kExpectations1);
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},
142 RunTest(compositor, kSrcScan2, kExpectations2);
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},
153 RunTest(compositor, kSrcScan3, kExpectations3);
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},
175 RunTest(compositor, kSrcScan1, kExpectations1);
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},
186 RunTest(compositor, kSrcScan2, kExpectations2);
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},
197 RunTest(compositor, kSrcScan3, kExpectations3);
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},
219 RunTest(compositor, kSrcScan1, kExpectations1);
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},
230 RunTest(compositor, kSrcScan2, kExpectations2);
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},
241 RunTest(compositor, kSrcScan3, kExpectations3);
244#if defined(PDF_USE_SKIA)
245TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulNormal) {
246 CFX_ScanlineCompositor compositor;
247 ASSERT_TRUE(compositor.Init(FXDIB_Format::kBgraPremul,
248 FXDIB_Format::kBgraPremul,
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},
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},
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},
286 RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3);
289TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulDarken) {
290 CFX_ScanlineCompositor compositor;
291 ASSERT_TRUE(compositor.Init(FXDIB_Format::kBgraPremul,
292 FXDIB_Format::kBgraPremul,
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},
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},
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},
330 RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3);
333TEST(ScanlineCompositorTest, CompositeRgbBitmapLineBgraPremulHue) {
334 CFX_ScanlineCompositor compositor;
335 ASSERT_TRUE(compositor.Init(FXDIB_Format::kBgraPremul,
336 FXDIB_Format::kBgraPremul,
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},
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},
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},
374 RunPreMultiplyTest(compositor, kSrcScan3, kExpectations3);
bool operator==(const FX_BGRA_STRUCT< uint8_t > &lhs, const FX_BGRA_STRUCT< uint8_t > &rhs)
TEST(FXCRYPT, MD5GenerateEmtpyData)