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
qcompositionfunctions.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <qglobal.h>
5
7#include "qrgba64_p.h"
8#include "qrgbafloat.h"
9
11
12/* The constant alpha factor describes an alpha factor that gets applied
13 to the result of the composition operation combining it with the destination.
14
15 The intent is that if const_alpha == 0. we get back dest, and if const_alpha == 1.
16 we get the unmodified operation
17
18 result = src op dest
19 dest = result * const_alpha + dest * (1. - const_alpha)
20
21 This means that in the comments below, the first line is the const_alpha==255 case, the
22 second line the general one.
23
24 In the lines below:
25 s == src, sa == alpha(src), sia = 1 - alpha(src)
26 d == dest, da == alpha(dest), dia = 1 - alpha(dest)
27 ca = const_alpha, cia = 1 - const_alpha
28
29 The methods exist in two variants. One where we have a constant source, the other
30 where the source is an array of pixels.
31*/
32
34{
35 typedef QRgb Type;
36 typedef quint8 Scalar;
39
40 static const Type clear;
41 static bool isOpaque(Type val)
42 { return qAlpha(val) == 255; }
43 static bool isTransparent(Type val)
44 { return qAlpha(val) == 0; }
45 static Scalar scalarFrom8bit(uint8_t a)
46 { return a; }
47 static void memfill(Type *ptr, Type value, qsizetype len)
48 { qt_memfill32(ptr, value, len); }
49 static void memcpy(Type *Q_DECL_RESTRICT dest, const Type *Q_DECL_RESTRICT src, qsizetype len)
50 { ::memcpy(dest, src, len * sizeof(Type)); }
51
52 static OptimalType load(const Type *ptr)
53 { return *ptr; }
54 static OptimalType convert(const Type &val)
55 { return val; }
56 static void store(Type *ptr, OptimalType value)
57 { *ptr = value; }
59 { return a + b; }
61 { return a + b; }
63 { return comp_func_Plus_one_pixel(a, b); }
65 { return qAlpha(val); }
67 { return 255 - c; }
69 { return alpha(~val); }
71 { return v; }
73 { return BYTE_MUL(val, a); }
74 static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
75 { return INTERPOLATE_PIXEL_255(x, a1, y, a2); }
77 { return BYTE_MUL(val, a); }
79 { return qt_div_255(val * a); }
81 { return INTERPOLATE_PIXEL_255(x, a1, y, a2); }
82};
83
85
87
89{
90 typedef QRgba64 Type;
91 typedef quint16 Scalar;
92
93 static const Type clear;
94
95 static bool isOpaque(Type val)
96 { return val.isOpaque(); }
97 static bool isTransparent(Type val)
98 { return val.isTransparent(); }
99 static Scalar scalarFrom8bit(uint8_t a)
100 { return a * 257; }
101
102 static void memfill(Type *ptr, Type value, qsizetype len)
103 { qt_memfill64((quint64*)ptr, value, len); }
104 static void memcpy(Type *Q_DECL_RESTRICT dest, const Type *Q_DECL_RESTRICT src, qsizetype len)
105 { ::memcpy(dest, src, len * sizeof(Type)); }
106};
107
108#if QT_CONFIG(raster_64bit)
109const Rgba64OperationsBase::Type Rgba64OperationsBase::clear = QRgba64::fromRgba64(0);
110
111struct Rgba64OperationsC : public Rgba64OperationsBase
112{
113 typedef QRgba64 OptimalType;
114 typedef quint16 OptimalScalar;
115
116 static OptimalType load(const Type *ptr)
117 { return *ptr; }
118 static OptimalType convert(const Type &val)
119 { return val; }
120 static void store(Type *ptr, OptimalType value)
121 { *ptr = value; }
122 static OptimalType add(OptimalType a, OptimalType b)
123 { return QRgba64::fromRgba64((quint64)a + (quint64)b); }
124 static OptimalScalar add(OptimalScalar a, OptimalScalar b)
125 { return a + b; }
126 static OptimalType plus(OptimalType a, OptimalType b)
127 { return addWithSaturation(a, b); }
128 static OptimalScalar alpha(OptimalType val)
129 { return val.alpha(); }
130 static OptimalScalar invAlpha(Scalar c)
131 { return 65535 - c; }
132 static OptimalScalar invAlpha(OptimalType val)
133 { return 65535 - alpha(val); }
134 static OptimalScalar scalar(Scalar v)
135 { return v; }
136 static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
137 { return multiplyAlpha255(val, a); }
138 static OptimalScalar multiplyAlpha8bit(OptimalScalar val, uint8_t a)
139 { return qt_div_255(val * a); }
140 static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
141 { return interpolate255(x, a1, y, a2); }
142 static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
143 { return multiplyAlpha65535(val, a); }
144 static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, OptimalScalar a2)
145 { return interpolate65535(x, a1, y, a2); }
146};
147
148#if defined(__SSE2__)
149struct Rgba64OperationsSSE2 : public Rgba64OperationsBase
150{
151 typedef __m128i OptimalType;
152 typedef __m128i OptimalScalar;
153
154 static OptimalType load(const Type *ptr)
155 {
156 return _mm_loadl_epi64(reinterpret_cast<const __m128i *>(ptr));
157 }
158 static OptimalType convert(const Type &value)
159 {
160#ifdef Q_PROCESSOR_X86_64
161 return _mm_cvtsi64_si128(value);
162#else
163 return load(&value);
164#endif
165 }
166 static void store(Type *ptr, OptimalType value)
167 {
168 _mm_storel_epi64(reinterpret_cast<__m128i *>(ptr), value);
169 }
170 static OptimalType add(OptimalType a, OptimalType b)
171 {
172 return _mm_add_epi16(a, b);
173 }
174// same as above:
175// static OptimalScalar add(OptimalScalar a, OptimalScalar b)
176 static OptimalType plus(OptimalType a, OptimalType b)
177 {
178 return _mm_adds_epu16(a, b);
179 }
180 static OptimalScalar alpha(OptimalType c)
181 {
182 return _mm_shufflelo_epi16(c, _MM_SHUFFLE(3, 3, 3, 3));
183 }
184 static OptimalScalar invAlpha(Scalar c)
185 {
186 return scalar(65535 - c);
187 }
188 static OptimalScalar invAlpha(OptimalType c)
189 {
190 return _mm_xor_si128(_mm_set1_epi16(-1), alpha(c));
191 }
192 static OptimalScalar scalar(Scalar n)
193 {
194 return _mm_shufflelo_epi16(_mm_cvtsi32_si128(n), _MM_SHUFFLE(0, 0, 0, 0));
195 }
196 static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
197 {
198 return multiplyAlpha255(val, a);
199 }
200// same as above:
201// static OptimalScalar multiplyAlpha8bit(OptimalScalar a, uint8_t a)
202 static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
203 {
204 return interpolate255(x, a1, y, a2);
205 }
206 static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
207 {
208 return multiplyAlpha65535(val, a);
209 }
210 // a2 is const-ref because otherwise MSVC2015@x86 complains that it can't 16-byte align the argument.
211 static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, const OptimalScalar &a2)
212 {
213 return interpolate65535(x, a1, y, a2);
214 }
215};
216#endif
217
218#if defined(__ARM_NEON__)
219struct Rgba64OperationsNEON : public Rgba64OperationsBase
220{
221 typedef uint16x4_t OptimalType;
222 typedef uint16x4_t OptimalScalar;
223
224 static OptimalType load(const Type *ptr)
225 {
226 return vreinterpret_u16_u64(vld1_u64(reinterpret_cast<const uint64_t *>(ptr)));
227 }
228 static OptimalType convert(const Type &val)
229 {
230 return vreinterpret_u16_u64(vmov_n_u64(val));
231 }
232 static void store(Type *ptr, OptimalType value)
233 {
234 vst1_u64(reinterpret_cast<uint64_t *>(ptr), vreinterpret_u64_u16(value));
235 }
236 static OptimalType add(OptimalType a, OptimalType b)
237 {
238 return vadd_u16(a, b);
239 }
240// same as above:
241// static OptimalScalar add(OptimalScalar a, OptimalScalar b)
242 static OptimalType plus(OptimalType a, OptimalType b)
243 {
244 return vqadd_u16(a, b);
245 }
246 static OptimalScalar alpha(OptimalType c)
247 {
248 return vdup_lane_u16(c, 3);
249 }
250 static OptimalScalar invAlpha(Scalar c)
251 {
252 return scalar(65535 - c);
253 }
254 static OptimalScalar invAlpha(OptimalType c)
255 {
256 return vmvn_u16(alpha(c));
257 }
258 static OptimalScalar scalar(Scalar n)
259 {
260 return vdup_n_u16(n);
261 }
262 static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
263 {
264 return multiplyAlpha255(val, a);
265 }
266// same as above:
267// static OptimalScalar multiplyAlpha8bit(OptimalScalar a, uint8_t a)
268 static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
269 {
270 return interpolate255(x, a1, y, a2);
271 }
272 static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
273 {
274 return multiplyAlpha65535(val, a);
275 }
276 static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, OptimalScalar a2)
277 {
278 return interpolate65535(x, a1, y, a2);
279 }
280};
281#endif
282
283#if defined(__loongarch_sx)
284struct Rgba64OperationsLSX : public Rgba64OperationsBase
285{
286 typedef __m128i OptimalType;
287 typedef __m128i OptimalScalar;
288 static OptimalType load(const Type *ptr)
289 {
290 return __lsx_vilvl_d(__lsx_vldi(0), __lsx_vldrepl_d(reinterpret_cast<const __m128i *>(ptr), 0));
291 }
292 static OptimalType convert(const Type &value)
293 {
294 return __lsx_vinsgr2vr_d(__lsx_vldi(0), value, 0);
295 }
296 static void store(Type *ptr, OptimalType value)
297 {
298 __lsx_vstelm_d(value, reinterpret_cast<const __m128i *>(ptr), 0, 0);
299 }
300 static OptimalType add(OptimalType a, OptimalType b)
301 {
302 return __lsx_vadd_h(a, b);
303 }
304// same as above:
305// static OptimalScalar add(OptimalScalar a, OptimalScalar b)
306 static OptimalType plus(OptimalType a, OptimalType b)
307 {
308 return __lsx_vsadd_hu(a, b);
309 }
310 static OptimalScalar alpha(OptimalType c)
311 {
312 const __m128i shuffleMask = (__m128i)(v8i16){3, 3, 3, 3, 4, 5, 6, 7};
313 return __lsx_vshuf_h(shuffleMask, __lsx_vldi(0), c);
314 }
315 static OptimalScalar invAlpha(Scalar c)
316 {
317 return scalar(65535 - c);
318 }
319 static OptimalScalar invAlpha(OptimalType c)
320 {
321 return __lsx_vxor_v(__lsx_vreplgr2vr_h(-1), alpha(c));
322 }
323 static OptimalScalar scalar(Scalar n)
324 {
325 const __m128i shuffleMask = (__m128i)(v8i16){0, 0, 0, 0, 4, 5, 6, 7};
326 return __lsx_vshuf_h(shuffleMask, __lsx_vldi(0), __lsx_vinsgr2vr_w(__lsx_vldi(0), n, 0));
327 }
328 static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
329 {
330 return multiplyAlpha255(val, a);
331 }
332// same as above:
333// static OptimalScalar multiplyAlpha8bit(OptimalScalar a, uint8_t a)
334 static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
335 {
336 return interpolate255(x, a1, y, a2);
337 }
338 static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
339 {
340 return multiplyAlpha65535(val, a);
341 }
342 static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, const OptimalScalar &a2)
343 {
344 return interpolate65535(x, a1, y, a2);
345 }
346};
347#endif
348
349#if defined(__SSE2__)
350typedef Rgba64OperationsSSE2 Rgba64Operations;
351#elif defined(__ARM_NEON__)
352typedef Rgba64OperationsNEON Rgba64Operations;
353#elif defined(__loongarch_sx)
354typedef Rgba64OperationsLSX Rgba64Operations;
355#else
356typedef Rgba64OperationsC Rgba64Operations;
357#endif
358
359#endif // QT_CONFIG(raster_64bit)
360
361#if QT_CONFIG(raster_fp)
362
363static inline QRgbaFloat32 qRgbaFloat32(float r, float g, float b, float a)
364{
365 return QRgbaFloat32{r, g, b, a};
366}
367
368struct RgbaFPOperationsBase
369{
370 typedef QRgbaFloat32 Type;
371 typedef float Scalar;
372
373 static inline constexpr Type clear = { 0, 0, 0, 0 };
374
375 static bool isOpaque(Type val)
376 { return val.a >= 1.0f; }
377 static bool isTransparent(Type val)
378 { return val.a <= 0.0f; }
379 static Scalar scalarFrom8bit(uint8_t a)
380 { return a * (1.0f / 255.0f); }
381
382 static void memfill(Type *ptr, Type value, qsizetype len)
383 {
384 for (qsizetype i = 0; i < len; ++i)
385 ptr[i] = value;
386 }
387 static void memcpy(Type *Q_DECL_RESTRICT dest, const Type *Q_DECL_RESTRICT src, qsizetype len)
388 { ::memcpy(dest, src, len * sizeof(Type)); }
389};
390
391struct RgbaFPOperationsC : RgbaFPOperationsBase
392{
393 typedef QRgbaFloat32 OptimalType;
394 typedef float OptimalScalar;
395
396 static OptimalType load(const Type *ptr)
397 {
398 return QRgbaFloat32 { ptr->r, ptr->g, ptr->b, ptr->a };
399 }
400 static OptimalType convert(const Type &val)
401 {
402 return QRgbaFloat32 { val.r, val.g, val.b, val.a };
403 }
404 static void store(Type *ptr, OptimalType value)
405 {
406 ptr->r = value.r;
407 ptr->g = value.g;
408 ptr->b = value.b;
409 ptr->a = value.a;
410 }
411 static OptimalType add(OptimalType a, OptimalType b)
412 {
413 a.r += b.r;
414 a.g += b.g;
415 a.b += b.b;
416 a.a += b.a;
417 return a;
418 }
419 static OptimalScalar add(OptimalScalar a, OptimalScalar b)
420 { return a + b; }
421 static OptimalType plus(OptimalType a, OptimalType b)
422 {
423 a = add(a, b); // no saturation on color values
424 if (a.a < 0.0f) a.a = 0.0f;
425 else if (a.a > 1.0f) a.a = 1.0f;
426 return a;
427 }
428 static OptimalScalar alpha(OptimalType val)
429 { return val.a; }
430 static OptimalScalar invAlpha(OptimalScalar c)
431 { return 1.0f - c; }
432 static OptimalScalar invAlpha(OptimalType val)
433 { return 1.0f - val.a; }
434 static OptimalScalar scalar(Scalar v)
435 { return v; }
436 static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
437 {
438 val.r *= a;
439 val.g *= a;
440 val.b *= a;
441 val.a *= a;
442 return val;
443 }
444 static OptimalScalar multiplyAlpha8bit(OptimalScalar val, uint8_t a)
445 {
446 return val * a * (1.0f / 255.0f);
447 }
448 static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, OptimalScalar a2)
449 {
450 return add(multiplyAlpha(x, a1), multiplyAlpha(y, a2));
451 }
452 static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
453 {
454 return multiplyAlpha(val, a * (1.0f / 255.0f));
455 }
456 static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
457 {
458 return add(multiplyAlpha8bit(x, a1), multiplyAlpha8bit(y, a2));
459 }
460};
461
462#if defined(__SSE2__)
463struct RgbaFPOperationsSSE2 : public RgbaFPOperationsBase
464{
465 typedef __m128 OptimalType;
466 typedef __m128 OptimalScalar;
467
468 static OptimalType Q_DECL_VECTORCALL load(const Type *ptr)
469 {
470 return _mm_loadu_ps(reinterpret_cast<const float *>(ptr));
471 }
472 static OptimalType Q_DECL_VECTORCALL convert(const Type &value)
473 {
474 return load(&value);
475 }
476 static void Q_DECL_VECTORCALL store(Type *ptr, OptimalType value)
477 {
478 _mm_storeu_ps(reinterpret_cast<float *>(ptr), value);
479 }
480 static OptimalType Q_DECL_VECTORCALL add(OptimalType a, OptimalType b)
481 {
482 return _mm_add_ps(a, b);
483 }
484// same as above:
485// static OptimalScalar add(OptimalScalar a, OptimalScalar b)
486 static OptimalType Q_DECL_VECTORCALL plus(OptimalType a, OptimalType b)
487 {
488 a = _mm_add_ps(a, b);
489 __m128 aa = _mm_min_ps(a, _mm_set1_ps(1.0f));
490 aa = _mm_max_ps(aa, _mm_set1_ps(0.0f));
491 // An indirect insert using only SSE2:
492 aa = _mm_shuffle_ps(aa, a, _MM_SHUFFLE(2, 2, 3, 3));
493 a = _mm_shuffle_ps(a, aa, _MM_SHUFFLE(0, 2, 1, 0));
494 return a;
495 }
496 static OptimalScalar Q_DECL_VECTORCALL alpha(OptimalType c)
497 {
498 return _mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3));
499 }
500 static OptimalScalar Q_DECL_VECTORCALL invAlpha(Scalar c)
501 {
502 return _mm_set1_ps(1.0f - float(c));
503 }
504 static OptimalScalar Q_DECL_VECTORCALL invAlpha(OptimalType c)
505 {
506 return _mm_sub_ps(_mm_set1_ps(1.0f), alpha(c));
507 }
508 static OptimalScalar Q_DECL_VECTORCALL scalar(Scalar n)
509 {
510 return _mm_set1_ps(float(n));
511 }
512 static OptimalType Q_DECL_VECTORCALL multiplyAlpha(OptimalType val, OptimalScalar a)
513 {
514 return _mm_mul_ps(val, a);
515 }
516 static OptimalType Q_DECL_VECTORCALL interpolate(OptimalType x, OptimalScalar a1, OptimalType y, OptimalScalar a2)
517 {
518 return add(multiplyAlpha(x, a1), multiplyAlpha(y, a2));
519 }
520 static OptimalType Q_DECL_VECTORCALL multiplyAlpha8bit(OptimalType val, uint8_t a)
521 {
522 return multiplyAlpha(val, _mm_set1_ps(a * (1.0f / 255.0f)));
523 }
524// same as above:
525// static OptimalScalar multiplyAlpha8bit(OptimalScalar a, uint8_t a)
526 static OptimalType Q_DECL_VECTORCALL interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
527 {
528 return add(multiplyAlpha8bit(x, a1), multiplyAlpha8bit(y, a2));
529 }
530};
531#endif
532
533#if defined(__SSE2__)
534typedef RgbaFPOperationsSSE2 RgbaFPOperations;
535#else
536typedef RgbaFPOperationsC RgbaFPOperations;
537#endif
538
539#endif // QT_CONFIG(raster_fp)
540
541/*
542 result = 0
543 d = d * cia
544*/
545template<class Ops>
546inline static void comp_func_Clear_template(typename Ops::Type *dest, int length, uint const_alpha)
547{
548 if (const_alpha == 255)
549 Ops::memfill(dest, Ops::clear, length);
550 else {
551 uint ialpha = 255 - const_alpha;
552 for (int i = 0; i < length; ++i) {
553 Ops::store(&dest[i], Ops::multiplyAlpha8bit(Ops::load(&dest[i]), ialpha));
554 }
555 }
556}
557
558void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha)
559{
560 comp_func_Clear_template<Argb32Operations>(dest, length, const_alpha);
561}
562
563void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha)
564{
565 comp_func_Clear_template<Argb32Operations>(dest, length, const_alpha);
566}
567
568#if QT_CONFIG(raster_64bit)
569void QT_FASTCALL comp_func_solid_Clear_rgb64(QRgba64 *dest, int length, QRgba64, uint const_alpha)
570{
571 comp_func_Clear_template<Rgba64Operations>(dest, length, const_alpha);
572}
573
574void QT_FASTCALL comp_func_Clear_rgb64(QRgba64 *dest, const QRgba64 *, int length, uint const_alpha)
575{
576 comp_func_Clear_template<Rgba64Operations>(dest, length, const_alpha);
577}
578#endif
579
580#if QT_CONFIG(raster_fp)
581void QT_FASTCALL comp_func_solid_Clear_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32, uint const_alpha)
582{
583 comp_func_Clear_template<RgbaFPOperations>(dest, length, const_alpha);
584}
585
586void QT_FASTCALL comp_func_Clear_rgbafp(QRgbaFloat32 *dest, const QRgbaFloat32 *, int length, uint const_alpha)
587{
588 comp_func_Clear_template<RgbaFPOperations>(dest, length, const_alpha);
589}
590#endif
591
592/*
593 result = s
594 dest = s * ca + d * cia
595*/
596template<class Ops>
597inline static void comp_func_solid_Source_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
598{
599 if (const_alpha == 255)
600 Ops::memfill(dest, color, length);
601 else {
602 const uint ialpha = 255 - const_alpha;
603 auto s = Ops::multiplyAlpha8bit(Ops::convert(color), const_alpha);
604 for (int i = 0; i < length; ++i) {
605 auto d = Ops::multiplyAlpha8bit(Ops::load(&dest[i]), ialpha);
606 Ops::store(&dest[i], Ops::add(s, d));
607 }
608 }
609}
610
611template<class Ops>
612inline static void comp_func_Source_template(typename Ops::Type *Q_DECL_RESTRICT dest,
613 const typename Ops::Type *Q_DECL_RESTRICT src,
614 int length, uint const_alpha)
615{
616 if (const_alpha == 255)
617 Ops::memcpy(dest, src, length);
618 else {
619 const uint ialpha = 255 - const_alpha;
620 for (int i = 0; i < length; ++i) {
621 auto s = Ops::load(src + i);
622 auto d = Ops::load(dest + i);
623 Ops::store(&dest[i], Ops::interpolate8bit(s, const_alpha, d, ialpha));
624 }
625 }
626}
627
628void QT_FASTCALL comp_func_solid_Source(uint *dest, int length, uint color, uint const_alpha)
629{
630 comp_func_solid_Source_template<Argb32Operations>(dest, length, color, const_alpha);
631}
632
633void QT_FASTCALL comp_func_Source(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
634{
635 comp_func_Source_template<Argb32Operations>(dest, src, length, const_alpha);
636}
637
638#if QT_CONFIG(raster_64bit)
639void QT_FASTCALL comp_func_solid_Source_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
640{
641 comp_func_solid_Source_template<Rgba64Operations>(dest, length, color, const_alpha);
642}
643
644void QT_FASTCALL comp_func_Source_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
645{
646 comp_func_Source_template<Rgba64Operations>(dest, src, length, const_alpha);
647}
648#endif
649
650#if QT_CONFIG(raster_fp)
651void QT_FASTCALL comp_func_solid_Source_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
652{
653 comp_func_solid_Source_template<RgbaFPOperations>(dest, length, color, const_alpha);
654}
655
656void QT_FASTCALL comp_func_Source_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
657{
658 comp_func_Source_template<RgbaFPOperations>(dest, src, length, const_alpha);
659}
660#endif
661
662void QT_FASTCALL comp_func_solid_Destination(uint *, int, uint, uint)
663{
664}
665
666void QT_FASTCALL comp_func_Destination(uint *, const uint *, int, uint)
667{
668}
669
670#if QT_CONFIG(raster_64bit)
671void QT_FASTCALL comp_func_solid_Destination_rgb64(QRgba64 *, int, QRgba64, uint)
672{
673}
674
675void QT_FASTCALL comp_func_Destination_rgb64(QRgba64 *, const QRgba64 *, int, uint)
676{
677}
678#endif
679
680#if QT_CONFIG(raster_fp)
681void QT_FASTCALL comp_func_solid_Destination_rgbafp(QRgbaFloat32 *, int, QRgbaFloat32, uint)
682{
683}
684
685void QT_FASTCALL comp_func_Destination_rgbafp(QRgbaFloat32 *, const QRgbaFloat32 *, int, uint)
686{
687}
688#endif
689
690/*
691 result = s + d * sia
692 dest = (s + d * sia) * ca + d * cia
693 = s * ca + d * (sia * ca + cia)
694 = s * ca + d * (1 - sa*ca)
695*/
696template<class Ops>
697inline static void comp_func_solid_SourceOver_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
698{
699 if (const_alpha == 255 && Ops::isOpaque(color))
700 Ops::memfill(dest, color, length);
701 else {
702 auto c = Ops::convert(color);
703 if (const_alpha != 255)
704 c = Ops::multiplyAlpha8bit(c, const_alpha);
705 auto cAlpha = Ops::invAlpha(c);
706 for (int i = 0; i < length; ++i) {
707 auto d = Ops::multiplyAlpha(Ops::load(&dest[i]), cAlpha);
708 Ops::store(&dest[i], Ops::add(c, d));
709 }
710 }
711}
712
713template<class Ops>
714inline static void comp_func_SourceOver_template(typename Ops::Type *Q_DECL_RESTRICT dest,
715 const typename Ops::Type *Q_DECL_RESTRICT src,
716 int length, uint const_alpha)
717{
718 if (const_alpha == 255) {
719 for (int i = 0; i < length; ++i) {
720 auto c = src[i];
721 if (Ops::isOpaque(c))
722 Ops::store(&dest[i], Ops::convert(c));
723 else if (!Ops::isTransparent(c)) {
724 auto s = Ops::convert(c);
725 auto d = Ops::multiplyAlpha(Ops::load(&dest[i]), Ops::invAlpha(s));
726 Ops::store(&dest[i], Ops::add(s, d));
727 }
728 }
729 } else {
730 for (int i = 0; i < length; ++i) {
731 auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
732 auto d = Ops::multiplyAlpha(Ops::load(&dest[i]), Ops::invAlpha(s));
733 Ops::store(&dest[i], Ops::add(s, d));
734 }
735 }
736}
737
738void QT_FASTCALL comp_func_solid_SourceOver(uint *dest, int length, uint color, uint const_alpha)
739{
740 comp_func_solid_SourceOver_template<Argb32Operations>(dest, length, color, const_alpha);
741}
742
743void QT_FASTCALL comp_func_SourceOver(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
744{
745 comp_func_SourceOver_template<Argb32Operations>(dest, src, length, const_alpha);
746}
747
748#if QT_CONFIG(raster_64bit)
749void QT_FASTCALL comp_func_solid_SourceOver_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
750{
751 comp_func_solid_SourceOver_template<Rgba64Operations>(dest, length, color, const_alpha);
752}
753
754void QT_FASTCALL comp_func_SourceOver_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
755{
756 comp_func_SourceOver_template<Rgba64Operations>(dest, src, length, const_alpha);
757}
758#endif
759
760#if QT_CONFIG(raster_fp)
761void QT_FASTCALL comp_func_solid_SourceOver_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
762{
763 comp_func_solid_SourceOver_template<RgbaFPOperations>(dest, length, color, const_alpha);
764}
765
766
767void QT_FASTCALL comp_func_SourceOver_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
768{
769 comp_func_SourceOver_template<RgbaFPOperations>(dest, src, length, const_alpha);
770}
771#endif
772
773/*
774 result = d + s * dia
775 dest = (d + s * dia) * ca + d * cia
776 = d + s * dia * ca
777*/
778template<class Ops>
779inline static void comp_func_solid_DestinationOver_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
780{
781 auto c = Ops::convert(color);
782 if (const_alpha != 255)
783 c = Ops::multiplyAlpha8bit(c, const_alpha);
784 for (int i = 0; i < length; ++i) {
785 auto d = Ops::load(&dest[i]);
786 auto s = Ops::multiplyAlpha(c, Ops::invAlpha(d));
787 Ops::store(&dest[i], Ops::add(s, d));
788 }
789}
790
791template<class Ops>
792inline static void comp_func_DestinationOver_template(typename Ops::Type *Q_DECL_RESTRICT dest,
793 const typename Ops::Type *Q_DECL_RESTRICT src,
794 int length, uint const_alpha)
795{
796 if (const_alpha == 255) {
797 for (int i = 0; i < length; ++i) {
798 auto d = Ops::load(&dest[i]);
799 auto s = Ops::multiplyAlpha(Ops::load(&src[i]), Ops::invAlpha(d));
800 Ops::store(&dest[i], Ops::add(s, d));
801 }
802 } else {
803 for (int i = 0; i < length; ++i) {
804 auto d = Ops::load(&dest[i]);
805 auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
806 s = Ops::multiplyAlpha(s, Ops::invAlpha(d));
807 Ops::store(&dest[i], Ops::add(s, d));
808 }
809 }
810}
811
812void QT_FASTCALL comp_func_solid_DestinationOver(uint *dest, int length, uint color, uint const_alpha)
813{
814 comp_func_solid_DestinationOver_template<Argb32Operations>(dest, length, color, const_alpha);
815}
816
817void QT_FASTCALL comp_func_DestinationOver(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
818{
819 comp_func_DestinationOver_template<Argb32Operations>(dest, src, length, const_alpha);
820}
821
822#if QT_CONFIG(raster_64bit)
823void QT_FASTCALL comp_func_solid_DestinationOver_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
824{
825 comp_func_solid_DestinationOver_template<Rgba64Operations>(dest, length, color, const_alpha);
826}
827
828void QT_FASTCALL comp_func_DestinationOver_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
829{
830 comp_func_DestinationOver_template<Rgba64Operations>(dest, src, length, const_alpha);
831}
832#endif
833
834#if QT_CONFIG(raster_fp)
835void QT_FASTCALL comp_func_solid_DestinationOver_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
836{
837 comp_func_solid_DestinationOver_template<RgbaFPOperations>(dest, length, color, const_alpha);
838}
839
840void QT_FASTCALL comp_func_DestinationOver_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
841{
842 comp_func_DestinationOver_template<RgbaFPOperations>(dest, src, length, const_alpha);
843}
844#endif
845
846/*
847 result = s * da
848 dest = s * da * ca + d * cia
849*/
850template<class Ops>
851inline static void comp_func_solid_SourceIn_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
852{
853 if (const_alpha == 255) {
854 auto c = Ops::convert(color);
855 for (int i = 0; i < length; ++i) {
856 Ops::store(&dest[i], Ops::multiplyAlpha(c, Ops::alpha(Ops::load(&dest[i]))));
857 }
858 } else {
859 auto c = Ops::multiplyAlpha8bit(Ops::convert(color), const_alpha);
860 auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
861 for (int i = 0; i < length; ++i) {
862 auto d = Ops::load(&dest[i]);
863 Ops::store(&dest[i], Ops::interpolate(c, Ops::alpha(d), d, cia));
864 }
865 }
866}
867
868template<class Ops>
869inline static void comp_func_SourceIn_template(typename Ops::Type *Q_DECL_RESTRICT dest,
870 const typename Ops::Type *Q_DECL_RESTRICT src,
871 int length, uint const_alpha)
872{
873 if (const_alpha == 255) {
874 for (int i = 0; i < length; ++i) {
875 auto s = Ops::load(&src[i]);
876 Ops::store(&dest[i], Ops::multiplyAlpha(s, Ops::alpha(Ops::load(&dest[i]))));
877 }
878 } else {
879 auto ca = Ops::scalarFrom8bit(const_alpha);
880 auto cia = Ops::invAlpha(ca);
881 auto cav = Ops::scalar(ca);
882 for (int i = 0; i < length; ++i) {
883 auto d = Ops::load(&dest[i]);
884 auto s = Ops::multiplyAlpha(Ops::load(&src[i]), cav);
885 Ops::store(&dest[i], Ops::interpolate(s, Ops::alpha(d), d, cia));
886 }
887 }
888}
889
890void QT_FASTCALL comp_func_solid_SourceIn(uint *dest, int length, uint color, uint const_alpha)
891{
892 comp_func_solid_SourceIn_template<Argb32Operations>(dest, length, color, const_alpha);
893}
894
895void QT_FASTCALL comp_func_SourceIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
896{
897 comp_func_SourceIn_template<Argb32Operations>(dest, src, length, const_alpha);
898}
899
900#if QT_CONFIG(raster_64bit)
901void QT_FASTCALL comp_func_solid_SourceIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
902{
903 comp_func_solid_SourceIn_template<Rgba64Operations>(dest, length, color, const_alpha);
904}
905
906void QT_FASTCALL comp_func_SourceIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
907{
908 comp_func_SourceIn_template<Rgba64Operations>(dest, src, length, const_alpha);
909}
910#endif
911
912#if QT_CONFIG(raster_fp)
913void QT_FASTCALL comp_func_solid_SourceIn_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
914{
915 comp_func_solid_SourceIn_template<RgbaFPOperations>(dest, length, color, const_alpha);
916}
917
918void QT_FASTCALL comp_func_SourceIn_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
919{
920 comp_func_SourceIn_template<RgbaFPOperations>(dest, src, length, const_alpha);
921}
922#endif
923
924/*
925 result = d * sa
926 dest = d * sa * ca + d * cia
927 = d * (sa * ca + cia)
928*/
929template<class Ops>
930inline static void comp_func_solid_DestinationIn_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
931{
932 auto sa = Ops::alpha(Ops::convert(color));
933 if (const_alpha != 255) {
934 sa = Ops::multiplyAlpha8bit(sa, const_alpha);
935 sa = Ops::add(sa, Ops::invAlpha(Ops::scalarFrom8bit(const_alpha)));
936 }
937
938 for (int i = 0; i < length; ++i) {
939 Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sa));
940 }
941}
942
943template<class Ops>
944inline static void comp_func_DestinationIn_template(typename Ops::Type *Q_DECL_RESTRICT dest,
945 const typename Ops::Type *Q_DECL_RESTRICT src,
946 int length, uint const_alpha)
947{
948 if (const_alpha == 255) {
949 for (int i = 0; i < length; ++i) {
950 auto a = Ops::alpha(Ops::load(&src[i]));
951 Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), a));
952 }
953 } else {
954 auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
955 for (int i = 0; i < length; ++i) {
956 auto sa = Ops::multiplyAlpha8bit(Ops::alpha(Ops::load(&src[i])), const_alpha);
957 sa = Ops::add(sa, cia);
958 Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sa));
959 }
960 }
961}
962
963void QT_FASTCALL comp_func_solid_DestinationIn(uint *dest, int length, uint color, uint const_alpha)
964{
965 comp_func_solid_DestinationIn_template<Argb32Operations>(dest, length, color, const_alpha);
966}
967
968void QT_FASTCALL comp_func_DestinationIn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
969{
970 comp_func_DestinationIn_template<Argb32Operations>(dest, src, length, const_alpha);
971}
972
973#if QT_CONFIG(raster_64bit)
974void QT_FASTCALL comp_func_solid_DestinationIn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
975{
976 comp_func_solid_DestinationIn_template<Rgba64Operations>(dest, length, color, const_alpha);
977}
978
979void QT_FASTCALL comp_func_DestinationIn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
980{
981 comp_func_DestinationIn_template<Rgba64Operations>(dest, src, length, const_alpha);
982}
983#endif
984
985#if QT_CONFIG(raster_fp)
986void QT_FASTCALL comp_func_solid_DestinationIn_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
987{
988 comp_func_solid_DestinationIn_template<RgbaFPOperations>(dest, length, color, const_alpha);
989}
990
991void QT_FASTCALL comp_func_DestinationIn_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
992{
993 comp_func_DestinationIn_template<RgbaFPOperations>(dest, src, length, const_alpha);
994}
995#endif
996
997/*
998 result = s * dia
999 dest = s * dia * ca + d * cia
1000*/
1001template<class Ops>
1002inline static void comp_func_solid_SourceOut_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
1003{
1004 auto c = Ops::convert(color);
1005 if (const_alpha == 255) {
1006 for (int i = 0; i < length; ++i)
1007 Ops::store(&dest[i], Ops::multiplyAlpha(c, Ops::invAlpha(Ops::load(&dest[i]))));
1008 } else {
1009 auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
1010 c = Ops::multiplyAlpha8bit(c, const_alpha);
1011 for (int i = 0; i < length; ++i) {
1012 auto d = Ops::load(&dest[i]);
1013 Ops::store(&dest[i], Ops::interpolate(c, Ops::invAlpha(d), d, cia));
1014 }
1015 }
1016}
1017
1018template<class Ops>
1019inline static void comp_func_SourceOut_template(typename Ops::Type *Q_DECL_RESTRICT dest,
1020 const typename Ops::Type *Q_DECL_RESTRICT src,
1021 int length, uint const_alpha)
1022{
1023 if (const_alpha == 255) {
1024 for (int i = 0; i < length; ++i) {
1025 auto s = Ops::load(&src[i]);
1026 auto d = Ops::load(&dest[i]);
1027 Ops::store(&dest[i], Ops::multiplyAlpha(s, Ops::invAlpha(d)));
1028 }
1029 } else {
1030 auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
1031 for (int i = 0; i < length; ++i) {
1032 auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
1033 auto d = Ops::load(&dest[i]);
1034 Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, cia));
1035 }
1036 }
1037}
1038
1039void QT_FASTCALL comp_func_solid_SourceOut(uint *dest, int length, uint color, uint const_alpha)
1040{
1041 comp_func_solid_SourceOut_template<Argb32Operations>(dest, length, color, const_alpha);
1042}
1043
1044void QT_FASTCALL comp_func_SourceOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
1045{
1046 comp_func_SourceOut_template<Argb32Operations>(dest, src, length, const_alpha);
1047}
1048
1049#if QT_CONFIG(raster_64bit)
1050void QT_FASTCALL comp_func_solid_SourceOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
1051{
1052 comp_func_solid_SourceOut_template<Rgba64Operations>(dest, length, color, const_alpha);
1053}
1054
1055void QT_FASTCALL comp_func_SourceOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1056{
1057 comp_func_SourceOut_template<Rgba64Operations>(dest, src, length, const_alpha);
1058}
1059#endif
1060
1061#if QT_CONFIG(raster_fp)
1062void QT_FASTCALL comp_func_solid_SourceOut_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
1063{
1064 comp_func_solid_SourceOut_template<RgbaFPOperations>(dest, length, color, const_alpha);
1065}
1066
1067void QT_FASTCALL comp_func_SourceOut_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1068{
1069 comp_func_SourceOut_template<RgbaFPOperations>(dest, src, length, const_alpha);
1070}
1071#endif
1072
1073/*
1074 result = d * sia
1075 dest = d * sia * ca + d * cia
1076 = d * (sia * ca + cia)
1077*/
1078template<class Ops>
1079inline static void comp_func_solid_DestinationOut_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
1080{
1081 auto sai = Ops::invAlpha(Ops::convert(color));
1082 if (const_alpha != 255) {
1083 sai = Ops::multiplyAlpha8bit(sai, const_alpha);
1084 sai = Ops::add(sai, Ops::invAlpha(Ops::scalarFrom8bit(const_alpha)));
1085 }
1086
1087 for (int i = 0; i < length; ++i) {
1088 Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sai));
1089 }
1090}
1091
1092template<class Ops>
1093inline static void comp_func_DestinationOut_template(typename Ops::Type *Q_DECL_RESTRICT dest,
1094 const typename Ops::Type *Q_DECL_RESTRICT src,
1095 int length, uint const_alpha)
1096{
1097 if (const_alpha == 255) {
1098 for (int i = 0; i < length; ++i) {
1099 auto sia = Ops::invAlpha(Ops::load(&src[i]));
1100 Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sia));
1101 }
1102 } else {
1103 auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
1104 for (int i = 0; i < length; ++i) {
1105 auto sia = Ops::multiplyAlpha8bit(Ops::invAlpha(Ops::load(&src[i])), const_alpha);
1106 sia = Ops::add(sia, cia);
1107 Ops::store(&dest[i], Ops::multiplyAlpha(Ops::load(&dest[i]), sia));
1108 }
1109 }
1110}
1111
1112void QT_FASTCALL comp_func_solid_DestinationOut(uint *dest, int length, uint color, uint const_alpha)
1113{
1114 comp_func_solid_DestinationOut_template<Argb32Operations>(dest, length, color, const_alpha);
1115}
1116
1117void QT_FASTCALL comp_func_DestinationOut(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
1118{
1119 comp_func_DestinationOut_template<Argb32Operations>(dest, src, length, const_alpha);
1120}
1121
1122#if QT_CONFIG(raster_64bit)
1123void QT_FASTCALL comp_func_solid_DestinationOut_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
1124{
1125 comp_func_solid_DestinationOut_template<Rgba64Operations>(dest, length, color, const_alpha);
1126}
1127
1128void QT_FASTCALL comp_func_DestinationOut_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1129{
1130 comp_func_DestinationOut_template<Rgba64Operations>(dest, src, length, const_alpha);
1131}
1132#endif
1133
1134#if QT_CONFIG(raster_fp)
1135void QT_FASTCALL comp_func_solid_DestinationOut_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
1136{
1137 comp_func_solid_DestinationOut_template<RgbaFPOperations>(dest, length, color, const_alpha);
1138}
1139
1140void QT_FASTCALL comp_func_DestinationOut_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1141{
1142 comp_func_DestinationOut_template<RgbaFPOperations>(dest, src, length, const_alpha);
1143}
1144#endif
1145
1146/*
1147 result = s*da + d*sia
1148 dest = s*da*ca + d*sia*ca + d *cia
1149 = s*ca * da + d * (sia*ca + cia)
1150 = s*ca * da + d * (1 - sa*ca)
1151*/
1152template<class Ops>
1153inline static void comp_func_solid_SourceAtop_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
1154{
1155 auto c = Ops::convert(color);
1156 if (const_alpha != 255)
1157 c = Ops::multiplyAlpha8bit(c, const_alpha);
1158 auto sia = Ops::invAlpha(c);
1159 for (int i = 0; i < length; ++i) {
1160 auto d = Ops::load(&dest[i]);
1161 Ops::store(&dest[i], Ops::interpolate(c, Ops::alpha(d), d, sia));
1162 }
1163}
1164
1165template<class Ops>
1166inline static void comp_func_SourceAtop_template(typename Ops::Type *Q_DECL_RESTRICT dest,
1167 const typename Ops::Type *Q_DECL_RESTRICT src,
1168 int length, uint const_alpha)
1169{
1170 if (const_alpha == 255) {
1171 for (int i = 0; i < length; ++i) {
1172 auto s = Ops::load(&src[i]);
1173 auto d = Ops::load(&dest[i]);
1174 Ops::store(&dest[i], Ops::interpolate(s, Ops::alpha(d), d, Ops::invAlpha(s)));
1175 }
1176 } else {
1177 for (int i = 0; i < length; ++i) {
1178 auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
1179 auto d = Ops::load(&dest[i]);
1180 Ops::store(&dest[i], Ops::interpolate(s, Ops::alpha(d), d, Ops::invAlpha(s)));
1181 }
1182 }
1183}
1184
1185void QT_FASTCALL comp_func_solid_SourceAtop(uint *dest, int length, uint color, uint const_alpha)
1186{
1187 comp_func_solid_SourceAtop_template<Argb32Operations>(dest, length, color, const_alpha);
1188}
1189
1190void QT_FASTCALL comp_func_SourceAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
1191{
1192 comp_func_SourceAtop_template<Argb32Operations>(dest, src, length, const_alpha);
1193}
1194
1195#if QT_CONFIG(raster_64bit)
1196void QT_FASTCALL comp_func_solid_SourceAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
1197{
1198 comp_func_solid_SourceAtop_template<Rgba64Operations>(dest, length, color, const_alpha);
1199}
1200
1201void QT_FASTCALL comp_func_SourceAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1202{
1203 comp_func_SourceAtop_template<Rgba64Operations>(dest, src, length, const_alpha);
1204}
1205#endif
1206
1207#if QT_CONFIG(raster_fp)
1208void QT_FASTCALL comp_func_solid_SourceAtop_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
1209{
1210 comp_func_solid_SourceAtop_template<RgbaFPOperations>(dest, length, color, const_alpha);
1211}
1212
1213void QT_FASTCALL comp_func_SourceAtop_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1214{
1215 comp_func_SourceAtop_template<RgbaFPOperations>(dest, src, length, const_alpha);
1216}
1217#endif
1218
1219/*
1220 result = d*sa + s*dia
1221 dest = d*sa*ca + s*dia*ca + d *cia
1222 = s*ca * dia + d * (sa*ca + cia)
1223*/
1224template<class Ops>
1225inline static void comp_func_solid_DestinationAtop_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
1226{
1227 auto c = Ops::convert(color);
1228 auto sa = Ops::alpha(c);
1229 if (const_alpha != 255) {
1230 c = Ops::multiplyAlpha8bit(c, const_alpha);
1231 auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
1232 sa = Ops::add(Ops::alpha(c), cia);
1233 }
1234
1235 for (int i = 0; i < length; ++i) {
1236 auto d = Ops::load(&dest[i]);
1237 Ops::store(&dest[i], Ops::interpolate(c, Ops::invAlpha(d), d, sa));
1238 }
1239}
1240
1241template<class Ops>
1242inline static void comp_func_DestinationAtop_template(typename Ops::Type *Q_DECL_RESTRICT dest,
1243 const typename Ops::Type *Q_DECL_RESTRICT src,
1244 int length, uint const_alpha)
1245{
1246 if (const_alpha == 255) {
1247 for (int i = 0; i < length; ++i) {
1248 auto s = Ops::load(&src[i]);
1249 auto d = Ops::load(&dest[i]);
1250 Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, Ops::alpha(s)));
1251 }
1252 } else {
1253 auto cia = Ops::invAlpha(Ops::scalarFrom8bit(const_alpha));
1254 for (int i = 0; i < length; ++i) {
1255 auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
1256 auto d = Ops::load(&dest[i]);
1257 auto sa = Ops::add(Ops::alpha(s), cia);
1258 Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, sa));
1259 }
1260 }
1261}
1262
1263void QT_FASTCALL comp_func_solid_DestinationAtop(uint *dest, int length, uint color, uint const_alpha)
1264{
1265 comp_func_solid_DestinationAtop_template<Argb32Operations>(dest, length, color, const_alpha);
1266}
1267
1268void QT_FASTCALL comp_func_DestinationAtop(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
1269{
1270 comp_func_DestinationAtop_template<Argb32Operations>(dest, src, length, const_alpha);
1271}
1272
1273#if QT_CONFIG(raster_64bit)
1274void QT_FASTCALL comp_func_solid_DestinationAtop_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
1275{
1276 comp_func_solid_DestinationAtop_template<Rgba64Operations>(dest, length, color, const_alpha);
1277}
1278
1279void QT_FASTCALL comp_func_DestinationAtop_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1280{
1281 comp_func_DestinationAtop_template<Rgba64Operations>(dest, src, length, const_alpha);
1282}
1283#endif
1284
1285#if QT_CONFIG(raster_fp)
1286void QT_FASTCALL comp_func_solid_DestinationAtop_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
1287{
1288 comp_func_solid_DestinationAtop_template<RgbaFPOperations>(dest, length, color, const_alpha);
1289}
1290
1291void QT_FASTCALL comp_func_DestinationAtop_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1292{
1293 comp_func_DestinationAtop_template<RgbaFPOperations>(dest, src, length, const_alpha);
1294}
1295#endif
1296
1297/*
1298 result = d*sia + s*dia
1299 dest = d*sia*ca + s*dia*ca + d *cia
1300 = s*ca * dia + d * (sia*ca + cia)
1301 = s*ca * dia + d * (1 - sa*ca)
1302*/
1303template<class Ops>
1304inline static void comp_func_solid_XOR_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
1305{
1306 auto c = Ops::convert(color);
1307 if (const_alpha != 255)
1308 c = Ops::multiplyAlpha8bit(c, const_alpha);
1309
1310 auto sia = Ops::invAlpha(c);
1311 for (int i = 0; i < length; ++i) {
1312 auto d = Ops::load(&dest[i]);
1313 Ops::store(&dest[i], Ops::interpolate(c, Ops::invAlpha(d), d, sia));
1314 }
1315}
1316
1317template<class Ops>
1318inline static void comp_func_XOR_template(typename Ops::Type *Q_DECL_RESTRICT dest,
1319 const typename Ops::Type *Q_DECL_RESTRICT src,
1320 int length, uint const_alpha)
1321{
1322 if (const_alpha == 255) {
1323 for (int i = 0; i < length; ++i) {
1324 auto d = Ops::load(&dest[i]);
1325 auto s = Ops::load(&src[i]);
1326 Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, Ops::invAlpha(s)));
1327 }
1328 } else {
1329 for (int i = 0; i < length; ++i) {
1330 auto d = Ops::load(&dest[i]);
1331 auto s = Ops::multiplyAlpha8bit(Ops::load(&src[i]), const_alpha);
1332 Ops::store(&dest[i], Ops::interpolate(s, Ops::invAlpha(d), d, Ops::invAlpha(s)));
1333 }
1334 }
1335}
1336
1337void QT_FASTCALL comp_func_solid_XOR(uint *dest, int length, uint color, uint const_alpha)
1338{
1339 comp_func_solid_XOR_template<Argb32Operations>(dest, length, color, const_alpha);
1340}
1341
1342void QT_FASTCALL comp_func_XOR(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
1343{
1344 comp_func_XOR_template<Argb32Operations>(dest, src, length, const_alpha);
1345}
1346
1347#if QT_CONFIG(raster_64bit)
1348void QT_FASTCALL comp_func_solid_XOR_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
1349{
1350 comp_func_solid_XOR_template<Rgba64Operations>(dest, length, color, const_alpha);
1351}
1352
1353void QT_FASTCALL comp_func_XOR_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1354{
1355 comp_func_XOR_template<Rgba64Operations>(dest, src, length, const_alpha);
1356}
1357#endif
1358
1359#if QT_CONFIG(raster_fp)
1360void QT_FASTCALL comp_func_solid_XOR_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
1361{
1362 comp_func_solid_XOR_template<RgbaFPOperations>(dest, length, color, const_alpha);
1363}
1364
1365void QT_FASTCALL comp_func_XOR_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1366{
1367 comp_func_XOR_template<RgbaFPOperations>(dest, src, length, const_alpha);
1368}
1369#endif
1370
1372 inline void store(uint *dest, const uint src) const
1373 {
1374 *dest = src;
1375 }
1376#if QT_CONFIG(raster_64bit)
1377 inline void store(QRgba64 *dest, const QRgba64 src) const
1378 {
1379 *dest = src;
1380 }
1381#endif
1382#if QT_CONFIG(raster_fp)
1383 inline void store(QRgbaFloat32 *dest, const QRgbaFloat32 src) const
1384 {
1385 *dest = src;
1386 }
1387#endif
1388};
1389
1391 inline QPartialCoverage(uint const_alpha)
1392 : ca(const_alpha)
1393 , ica(255 - const_alpha)
1394 {
1395 }
1396
1397 template<typename Op>
1398 inline void store_template(typename Op::Type *dest, const typename Op::Type src) const
1399 {
1400 Op::store(dest, Op::interpolate8bit(Op::convert(src), ca, Op::load(dest), ica));
1401 }
1402 inline void store(uint *dest, const uint src) const
1403 {
1404 store_template<Argb32Operations>(dest, src);
1405 }
1406#if QT_CONFIG(raster_64bit)
1407 inline void store(QRgba64 *dest, const QRgba64 src) const
1408 {
1410 }
1411#endif
1412#if QT_CONFIG(raster_fp)
1413 inline void store(QRgbaFloat32 *dest, const QRgbaFloat32 src) const
1414 {
1416 }
1417#endif
1418
1419private:
1420 const uint ca;
1421 const uint ica;
1422};
1423
1424static inline int mix_alpha(int da, int sa)
1425{
1426 return 255 - qt_div_255((255 - sa) * (255 - da));
1427}
1428
1429#if QT_CONFIG(raster_64bit)
1430static inline uint mix_alpha_rgb64(uint da, uint sa)
1431{
1432 return 65535U - qt_div_65535((65535U - sa) * (65535U - da));
1433}
1434#endif
1435
1436#if QT_CONFIG(raster_fp)
1437static inline float mix_alpha_rgbafp(float da, float sa)
1438{
1439 return 1.0f - (1.0f - sa) * (1.0f - da);
1440}
1441#endif
1442
1443/*
1444 Dca' = Sca.Da + Dca.Sa + Sca.(1 - Da) + Dca.(1 - Sa)
1445 = Sca + Dca
1446*/
1447template<class Ops>
1448inline static void comp_func_solid_Plus_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
1449{
1450 auto c = Ops::convert(color);
1451 if (const_alpha == 255) {
1452 for (int i = 0; i < length; ++i) {
1453 auto d = Ops::load(&dest[i]);
1454 d = Ops::plus(d, c);
1455 Ops::store(&dest[i], d);
1456 }
1457 } else {
1458 uint ia = 255 - const_alpha;
1459 for (int i = 0; i < length; ++i) {
1460 auto d = Ops::load(&dest[i]);
1461 d = Ops::interpolate8bit(Ops::plus(d, c), const_alpha, d, ia);
1462 Ops::store(&dest[i], d);
1463 }
1464 }
1465}
1466
1467template<class Ops>
1468inline static void comp_func_Plus_template(typename Ops::Type *Q_DECL_RESTRICT dest,
1469 const typename Ops::Type *Q_DECL_RESTRICT src,
1470 int length, uint const_alpha)
1471{
1472 if (const_alpha == 255) {
1473 for (int i = 0; i < length; ++i) {
1474 auto d = Ops::load(&dest[i]);
1475 auto s = Ops::load(&src[i]);
1476 d = Ops::plus(d, s);
1477 Ops::store(&dest[i], d);
1478 }
1479 } else {
1480 uint ia = 255 - const_alpha;
1481 for (int i = 0; i < length; ++i) {
1482 auto d = Ops::load(&dest[i]);
1483 auto s = Ops::load(&src[i]);
1484 d = Ops::interpolate8bit(Ops::plus(d, s), const_alpha, d, ia);
1485 Ops::store(&dest[i], d);
1486 }
1487 }
1488}
1489
1490void QT_FASTCALL comp_func_solid_Plus(uint *dest, int length, uint color, uint const_alpha)
1491{
1492 comp_func_solid_Plus_template<Argb32Operations>(dest, length, color, const_alpha);
1493}
1494
1495void QT_FASTCALL comp_func_Plus(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
1496{
1497 comp_func_Plus_template<Argb32Operations>(dest, src, length, const_alpha);
1498}
1499
1500#if QT_CONFIG(raster_64bit)
1501void QT_FASTCALL comp_func_solid_Plus_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
1502{
1503 comp_func_solid_Plus_template<Rgba64Operations>(dest, length, color, const_alpha);
1504}
1505
1506void QT_FASTCALL comp_func_Plus_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1507{
1508 comp_func_Plus_template<Rgba64Operations>(dest, src, length, const_alpha);
1509}
1510#endif
1511
1512#if QT_CONFIG(raster_fp)
1513void QT_FASTCALL comp_func_solid_Plus_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
1514{
1515 comp_func_solid_Plus_template<RgbaFPOperations>(dest, length, color, const_alpha);
1516}
1517
1518void QT_FASTCALL comp_func_Plus_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1519{
1520 comp_func_Plus_template<RgbaFPOperations>(dest, src, length, const_alpha);
1521}
1522#endif
1523
1524/*
1525 Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
1526*/
1527static inline int multiply_op(int dst, int src, int da, int sa)
1528{
1529 return qt_div_255(src * dst + src * (255 - da) + dst * (255 - sa));
1530}
1531
1532template <typename T>
1533static inline void comp_func_solid_Multiply_impl(uint *dest, int length, uint color, const T &coverage)
1534{
1535 int sa = qAlpha(color);
1536 int sr = qRed(color);
1537 int sg = qGreen(color);
1538 int sb = qBlue(color);
1539
1540 for (int i = 0; i < length; ++i) {
1541 uint d = dest[i];
1542 int da = qAlpha(d);
1543
1544#define OP(a, b) multiply_op(a, b, da, sa)
1545 int r = OP( qRed(d), sr);
1546 int b = OP( qBlue(d), sb);
1547 int g = OP(qGreen(d), sg);
1548 int a = mix_alpha(da, sa);
1549#undef OP
1550
1551 coverage.store(&dest[i], qRgba(r, g, b, a));
1552 }
1553}
1554
1555void QT_FASTCALL comp_func_solid_Multiply(uint *dest, int length, uint color, uint const_alpha)
1556{
1557 if (const_alpha == 255)
1558 comp_func_solid_Multiply_impl(dest, length, color, QFullCoverage());
1559 else
1560 comp_func_solid_Multiply_impl(dest, length, color, QPartialCoverage(const_alpha));
1561}
1562
1563#if QT_CONFIG(raster_64bit)
1564static inline uint multiply_op_rgb64(uint dst, uint src, uint da, uint sa)
1565{
1566 return qt_div_65535(src * dst + src * (65535U - da) + dst * (65535U - sa));
1567}
1568
1569template <typename T>
1570static inline void comp_func_solid_Multiply_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
1571{
1572 uint sa = color.alpha();
1573 uint sr = color.red();
1574 uint sg = color.green();
1575 uint sb = color.blue();
1576
1577 for (int i = 0; i < length; ++i) {
1578 QRgba64 d = dest[i];
1579 uint da = d.alpha();
1580
1581#define OP(a, b) multiply_op_rgb64(a, b, da, sa)
1582 uint r = OP( d.red(), sr);
1583 uint b = OP( d.blue(), sb);
1584 uint g = OP(d.green(), sg);
1585 uint a = mix_alpha_rgb64(da, sa);
1586#undef OP
1587
1588 coverage.store(&dest[i], qRgba64(r, g, b, a));
1589 }
1590}
1591
1592void QT_FASTCALL comp_func_solid_Multiply_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
1593{
1594 if (const_alpha == 255)
1595 comp_func_solid_Multiply_impl(dest, length, color, QFullCoverage());
1596 else
1597 comp_func_solid_Multiply_impl(dest, length, color, QPartialCoverage(const_alpha));
1598}
1599#endif
1600
1601#if QT_CONFIG(raster_fp)
1602static inline float multiply_op_rgbafp(float dst, float src, float da, float sa)
1603{
1604 return src * dst + src * (1.0f - da) + dst * (1.0f - sa);
1605}
1606
1607template <typename T>
1608static inline void comp_func_solid_Multiply_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
1609{
1610 float sa = color.alpha();
1611 float sr = color.red();
1612 float sg = color.green();
1613 float sb = color.blue();
1614
1615 for (int i = 0; i < length; ++i) {
1616 QRgbaFloat32 d = dest[i];
1617 float da = d.alpha();
1618
1619#define OP(a, b) multiply_op_rgbafp(a, b, da, sa)
1620 float r = OP( d.red(), sr);
1621 float b = OP( d.blue(), sb);
1622 float g = OP(d.green(), sg);
1623 float a = mix_alpha_rgbafp(da, sa);
1624#undef OP
1625
1626 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
1627 }
1628}
1629
1630void QT_FASTCALL comp_func_solid_Multiply_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
1631{
1632 if (const_alpha == 255)
1633 comp_func_solid_Multiply_impl(dest, length, color, QFullCoverage());
1634 else
1635 comp_func_solid_Multiply_impl(dest, length, color, QPartialCoverage(const_alpha));
1636}
1637#endif
1638
1639
1640template <typename T>
1641static inline void comp_func_Multiply_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
1642{
1643 for (int i = 0; i < length; ++i) {
1644 uint d = dest[i];
1645 uint s = src[i];
1646
1647 int da = qAlpha(d);
1648 int sa = qAlpha(s);
1649
1650#define OP(a, b) multiply_op(a, b, da, sa)
1651 int r = OP( qRed(d), qRed(s));
1652 int b = OP( qBlue(d), qBlue(s));
1653 int g = OP(qGreen(d), qGreen(s));
1654 int a = mix_alpha(da, sa);
1655#undef OP
1656
1657 coverage.store(&dest[i], qRgba(r, g, b, a));
1658 }
1659}
1660
1661void QT_FASTCALL comp_func_Multiply(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
1662{
1663 if (const_alpha == 255)
1664 comp_func_Multiply_impl(dest, src, length, QFullCoverage());
1665 else
1666 comp_func_Multiply_impl(dest, src, length, QPartialCoverage(const_alpha));
1667}
1668
1669#if QT_CONFIG(raster_64bit)
1670template <typename T>
1671static inline void comp_func_Multiply_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
1672{
1673 for (int i = 0; i < length; ++i) {
1674 QRgba64 d = dest[i];
1675 QRgba64 s = src[i];
1676
1677 uint da = d.alpha();
1678 uint sa = s.alpha();
1679
1680#define OP(a, b) multiply_op_rgb64(a, b, da, sa)
1681 uint r = OP( d.red(), s.red());
1682 uint b = OP( d.blue(), s.blue());
1683 uint g = OP(d.green(), s.green());
1684 uint a = mix_alpha_rgb64(da, sa);
1685#undef OP
1686
1687 coverage.store(&dest[i], qRgba64(r, g, b, a));
1688 }
1689}
1690
1691void QT_FASTCALL comp_func_Multiply_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1692{
1693 if (const_alpha == 255)
1694 comp_func_Multiply_impl(dest, src, length, QFullCoverage());
1695 else
1696 comp_func_Multiply_impl(dest, src, length, QPartialCoverage(const_alpha));
1697}
1698#endif
1699
1700#if QT_CONFIG(raster_fp)
1701template <typename T>
1702static inline void comp_func_Multiply_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
1703{
1704 for (int i = 0; i < length; ++i) {
1705 QRgbaFloat32 d = dest[i];
1706 QRgbaFloat32 s = src[i];
1707
1708 float da = d.alpha();
1709 float sa = s.alpha();
1710
1711#define OP(a, b) multiply_op_rgbafp(a, b, da, sa)
1712 float r = OP( d.red(), s.red());
1713 float b = OP( d.blue(), s.blue());
1714 float g = OP(d.green(), s.green());
1715 float a = mix_alpha_rgbafp(da, sa);
1716#undef OP
1717
1718 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
1719 }
1720}
1721
1722void QT_FASTCALL comp_func_Multiply_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
1723{
1724 if (const_alpha == 255)
1725 comp_func_Multiply_impl(dest, src, length, QFullCoverage());
1726 else
1727 comp_func_Multiply_impl(dest, src, length, QPartialCoverage(const_alpha));
1728}
1729#endif
1730
1731/*
1732 Dca' = (Sca.Da + Dca.Sa - Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
1733 = Sca + Dca - Sca.Dca
1734*/
1735template <typename T>
1736static inline void comp_func_solid_Screen_impl(uint *dest, int length, uint color, const T &coverage)
1737{
1738 int sa = qAlpha(color);
1739 int sr = qRed(color);
1740 int sg = qGreen(color);
1741 int sb = qBlue(color);
1742
1743 for (int i = 0; i < length; ++i) {
1744 uint d = dest[i];
1745 int da = qAlpha(d);
1746
1747#define OP(a, b) 255 - qt_div_255((255-a) * (255-b))
1748 int r = OP( qRed(d), sr);
1749 int b = OP( qBlue(d), sb);
1750 int g = OP(qGreen(d), sg);
1751 int a = mix_alpha(da, sa);
1752#undef OP
1753
1754 coverage.store(&dest[i], qRgba(r, g, b, a));
1755 }
1756}
1757
1758void QT_FASTCALL comp_func_solid_Screen(uint *dest, int length, uint color, uint const_alpha)
1759{
1760 if (const_alpha == 255)
1761 comp_func_solid_Screen_impl(dest, length, color, QFullCoverage());
1762 else
1763 comp_func_solid_Screen_impl(dest, length, color, QPartialCoverage(const_alpha));
1764}
1765
1766#if QT_CONFIG(raster_64bit)
1767template <typename T>
1768static inline void comp_func_solid_Screen_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
1769{
1770 uint sa = color.alpha();
1771 uint sr = color.red();
1772 uint sg = color.green();
1773 uint sb = color.blue();
1774
1775 for (int i = 0; i < length; ++i) {
1776 QRgba64 d = dest[i];
1777 uint da = d.alpha();
1778
1779#define OP(a, b) 65535 - qt_div_65535((65535U-a) * (65535U-b))
1780 uint r = OP( d.red(), sr);
1781 uint b = OP( d.blue(), sb);
1782 uint g = OP(d.green(), sg);
1783 uint a = mix_alpha_rgb64(da, sa);
1784#undef OP
1785
1786 coverage.store(&dest[i], qRgba64(r, g, b, a));
1787 }
1788}
1789
1790void QT_FASTCALL comp_func_solid_Screen_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
1791{
1792 if (const_alpha == 255)
1793 comp_func_solid_Screen_impl(dest, length, color, QFullCoverage());
1794 else
1795 comp_func_solid_Screen_impl(dest, length, color, QPartialCoverage(const_alpha));
1796}
1797#endif
1798
1799#if QT_CONFIG(raster_fp)
1800template <typename T>
1801static inline void comp_func_solid_Screen_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
1802{
1803 float sa = color.alpha();
1804 float sr = color.red();
1805 float sg = color.green();
1806 float sb = color.blue();
1807
1808 for (int i = 0; i < length; ++i) {
1809 QRgbaFloat32 d = dest[i];
1810 float da = d.alpha();
1811
1812#define OP(a, b) (1.0f - ((1.0f - a) * (1.0f - b)))
1813 float r = OP( d.red(), sr);
1814 float b = OP( d.blue(), sb);
1815 float g = OP(d.green(), sg);
1816 float a = mix_alpha_rgbafp(da, sa);
1817#undef OP
1818
1819 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
1820 }
1821}
1822
1823void QT_FASTCALL comp_func_solid_Screen_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
1824{
1825 if (const_alpha == 255)
1826 comp_func_solid_Screen_impl(dest, length, color, QFullCoverage());
1827 else
1828 comp_func_solid_Screen_impl(dest, length, color, QPartialCoverage(const_alpha));
1829}
1830#endif
1831
1832template <typename T>
1833static inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
1834{
1835 for (int i = 0; i < length; ++i) {
1836 uint d = dest[i];
1837 uint s = src[i];
1838
1839 int da = qAlpha(d);
1840 int sa = qAlpha(s);
1841
1842#define OP(a, b) 255 - qt_div_255((255-a) * (255-b))
1843 int r = OP( qRed(d), qRed(s));
1844 int b = OP( qBlue(d), qBlue(s));
1845 int g = OP(qGreen(d), qGreen(s));
1846 int a = mix_alpha(da, sa);
1847#undef OP
1848
1849 coverage.store(&dest[i], qRgba(r, g, b, a));
1850 }
1851}
1852
1853void QT_FASTCALL comp_func_Screen(uint *dest, const uint *src, int length, uint const_alpha)
1854{
1855 if (const_alpha == 255)
1856 comp_func_Screen_impl(dest, src, length, QFullCoverage());
1857 else
1858 comp_func_Screen_impl(dest, src, length, QPartialCoverage(const_alpha));
1859}
1860
1861#if QT_CONFIG(raster_64bit)
1862template <typename T>
1863static inline void comp_func_Screen_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
1864{
1865 for (int i = 0; i < length; ++i) {
1866 QRgba64 d = dest[i];
1867 QRgba64 s = src[i];
1868
1869 uint da = d.alpha();
1870 uint sa = s.alpha();
1871
1872#define OP(a, b) 65535U - qt_div_65535((65535U-a) * (65535U-b))
1873 uint r = OP( d.red(), s.red());
1874 uint b = OP( d.blue(), s.blue());
1875 uint g = OP(d.green(), s.green());
1876 uint a = mix_alpha_rgb64(da, sa);
1877#undef OP
1878
1879 coverage.store(&dest[i], qRgba64(r, g, b, a));
1880 }
1881}
1882
1883void QT_FASTCALL comp_func_Screen_rgb64(QRgba64 *dest, const QRgba64 *src, int length, uint const_alpha)
1884{
1885 if (const_alpha == 255)
1886 comp_func_Screen_impl(dest, src, length, QFullCoverage());
1887 else
1888 comp_func_Screen_impl(dest, src, length, QPartialCoverage(const_alpha));
1889}
1890#endif
1891
1892#if QT_CONFIG(raster_fp)
1893template <typename T>
1894static inline void comp_func_Screen_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
1895{
1896 for (int i = 0; i < length; ++i) {
1897 QRgbaFloat32 d = dest[i];
1898 QRgbaFloat32 s = src[i];
1899
1900 float da = d.alpha();
1901 float sa = s.alpha();
1902
1903#define OP(a, b) (1.0f - ((1.0f - a) * (1.0f - b)))
1904 float r = OP( d.red(), s.red());
1905 float b = OP( d.blue(), s.blue());
1906 float g = OP(d.green(), s.green());
1907 float a = mix_alpha_rgbafp(da, sa);
1908#undef OP
1909
1910 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
1911 }
1912}
1913
1914void QT_FASTCALL comp_func_Screen_rgbafp(QRgbaFloat32 *dest, const QRgbaFloat32 *src, int length, uint const_alpha)
1915{
1916 if (const_alpha == 255)
1917 comp_func_Screen_impl(dest, src, length, QFullCoverage());
1918 else
1919 comp_func_Screen_impl(dest, src, length, QPartialCoverage(const_alpha));
1920}
1921#endif
1922
1923/*
1924 if 2.Dca < Da
1925 Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
1926 otherwise
1927 Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
1928*/
1929static inline int overlay_op(int dst, int src, int da, int sa)
1930{
1931 const int temp = src * (255 - da) + dst * (255 - sa);
1932 if (2 * dst < da)
1933 return qt_div_255(2 * src * dst + temp);
1934 else
1935 return qt_div_255(sa * da - 2 * (da - dst) * (sa - src) + temp);
1936}
1937
1938template <typename T>
1939static inline void comp_func_solid_Overlay_impl(uint *dest, int length, uint color, const T &coverage)
1940{
1941 int sa = qAlpha(color);
1942 int sr = qRed(color);
1943 int sg = qGreen(color);
1944 int sb = qBlue(color);
1945
1946 for (int i = 0; i < length; ++i) {
1947 uint d = dest[i];
1948 int da = qAlpha(d);
1949
1950#define OP(a, b) overlay_op(a, b, da, sa)
1951 int r = OP( qRed(d), sr);
1952 int b = OP( qBlue(d), sb);
1953 int g = OP(qGreen(d), sg);
1954 int a = mix_alpha(da, sa);
1955#undef OP
1956
1957 coverage.store(&dest[i], qRgba(r, g, b, a));
1958 }
1959}
1960
1961void QT_FASTCALL comp_func_solid_Overlay(uint *dest, int length, uint color, uint const_alpha)
1962{
1963 if (const_alpha == 255)
1964 comp_func_solid_Overlay_impl(dest, length, color, QFullCoverage());
1965 else
1966 comp_func_solid_Overlay_impl(dest, length, color, QPartialCoverage(const_alpha));
1967}
1968
1969#if QT_CONFIG(raster_64bit)
1970static inline uint overlay_op_rgb64(uint dst, uint src, uint da, uint sa)
1971{
1972 const uint temp = src * (65535U - da) + dst * (65535U - sa);
1973 if (2 * dst < da)
1974 return qt_div_65535(2 * src * dst + temp);
1975 else
1976 return qt_div_65535(sa * da - 2 * (da - dst) * (sa - src) + temp);
1977}
1978
1979template <typename T>
1980static inline void comp_func_solid_Overlay_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
1981{
1982 uint sa = color.alpha();
1983 uint sr = color.red();
1984 uint sg = color.green();
1985 uint sb = color.blue();
1986
1987 for (int i = 0; i < length; ++i) {
1988 QRgba64 d = dest[i];
1989 uint da = d.alpha();
1990
1991#define OP(a, b) overlay_op_rgb64(a, b, da, sa)
1992 uint r = OP( d.red(), sr);
1993 uint b = OP( d.blue(), sb);
1994 uint g = OP(d.green(), sg);
1995 uint a = mix_alpha_rgb64(da, sa);
1996#undef OP
1997
1998 coverage.store(&dest[i], qRgba64(r, g, b, a));
1999 }
2000}
2001
2002void QT_FASTCALL comp_func_solid_Overlay_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
2003{
2004 if (const_alpha == 255)
2005 comp_func_solid_Overlay_impl(dest, length, color, QFullCoverage());
2006 else
2007 comp_func_solid_Overlay_impl(dest, length, color, QPartialCoverage(const_alpha));
2008}
2009#endif
2010
2011#if QT_CONFIG(raster_fp)
2012static inline float overlay_op_rgbafp(float dst, float src, float da, float sa)
2013{
2014 const float temp = src * (1.0f - da) + dst * (1.0f - sa);
2015 if (2 * dst < da)
2016 return 2 * src * dst + temp;
2017 else
2018 return sa * da - 2 * (da - dst) * (sa - src) + temp;
2019}
2020
2021template <typename T>
2022static inline void comp_func_solid_Overlay_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
2023{
2024 float sa = color.alpha();
2025 float sr = color.red();
2026 float sg = color.green();
2027 float sb = color.blue();
2028
2029 for (int i = 0; i < length; ++i) {
2030 QRgbaFloat32 d = dest[i];
2031 float da = d.alpha();
2032
2033#define OP(a, b) overlay_op_rgbafp(a, b, da, sa)
2034 float r = OP( d.red(), sr);
2035 float b = OP( d.blue(), sb);
2036 float g = OP(d.green(), sg);
2037 float a = mix_alpha_rgbafp(da, sa);
2038#undef OP
2039
2040 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
2041 }
2042}
2043
2044void QT_FASTCALL comp_func_solid_Overlay_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
2045{
2046 if (const_alpha == 255)
2047 comp_func_solid_Overlay_impl(dest, length, color, QFullCoverage());
2048 else
2049 comp_func_solid_Overlay_impl(dest, length, color, QPartialCoverage(const_alpha));
2050}
2051#endif
2052
2053template <typename T>
2054static inline void comp_func_Overlay_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
2055{
2056 for (int i = 0; i < length; ++i) {
2057 uint d = dest[i];
2058 uint s = src[i];
2059
2060 int da = qAlpha(d);
2061 int sa = qAlpha(s);
2062
2063#define OP(a, b) overlay_op(a, b, da, sa)
2064 int r = OP( qRed(d), qRed(s));
2065 int b = OP( qBlue(d), qBlue(s));
2066 int g = OP(qGreen(d), qGreen(s));
2067 int a = mix_alpha(da, sa);
2068#undef OP
2069
2070 coverage.store(&dest[i], qRgba(r, g, b, a));
2071 }
2072}
2073
2074void QT_FASTCALL comp_func_Overlay(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
2075{
2076 if (const_alpha == 255)
2077 comp_func_Overlay_impl(dest, src, length, QFullCoverage());
2078 else
2079 comp_func_Overlay_impl(dest, src, length, QPartialCoverage(const_alpha));
2080}
2081
2082#if QT_CONFIG(raster_64bit)
2083template <typename T>
2084static inline void comp_func_Overlay_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
2085{
2086 for (int i = 0; i < length; ++i) {
2087 QRgba64 d = dest[i];
2088 QRgba64 s = src[i];
2089
2090 uint da = d.alpha();
2091 uint sa = s.alpha();
2092
2093#define OP(a, b) overlay_op_rgb64(a, b, da, sa)
2094 uint r = OP( d.red(), s.red());
2095 uint b = OP( d.blue(), s.blue());
2096 uint g = OP(d.green(), s.green());
2097 uint a = mix_alpha_rgb64(da, sa);
2098#undef OP
2099
2100 coverage.store(&dest[i], qRgba64(r, g, b, a));
2101 }
2102}
2103
2104void QT_FASTCALL comp_func_Overlay_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
2105{
2106 if (const_alpha == 255)
2107 comp_func_Overlay_impl(dest, src, length, QFullCoverage());
2108 else
2109 comp_func_Overlay_impl(dest, src, length, QPartialCoverage(const_alpha));
2110}
2111#endif
2112
2113#if QT_CONFIG(raster_fp)
2114template <typename T>
2115static inline void comp_func_Overlay_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
2116{
2117 for (int i = 0; i < length; ++i) {
2118 QRgbaFloat32 d = dest[i];
2119 QRgbaFloat32 s = src[i];
2120
2121 float da = d.alpha();
2122 float sa = s.alpha();
2123
2124#define OP(a, b) overlay_op_rgbafp(a, b, da, sa)
2125 float r = OP( d.red(), s.red());
2126 float b = OP( d.blue(), s.blue());
2127 float g = OP(d.green(), s.green());
2128 float a = mix_alpha_rgbafp(da, sa);
2129#undef OP
2130
2131 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
2132 }
2133}
2134
2135void QT_FASTCALL comp_func_Overlay_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
2136{
2137 if (const_alpha == 255)
2138 comp_func_Overlay_impl(dest, src, length, QFullCoverage());
2139 else
2140 comp_func_Overlay_impl(dest, src, length, QPartialCoverage(const_alpha));
2141}
2142#endif
2143
2144/*
2145 Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
2146 Da' = Sa + Da - Sa.Da
2147*/
2148static inline int darken_op(int dst, int src, int da, int sa)
2149{
2150 return qt_div_255(qMin(src * da, dst * sa) + src * (255 - da) + dst * (255 - sa));
2151}
2152
2153template <typename T>
2154static inline void comp_func_solid_Darken_impl(uint *dest, int length, uint color, const T &coverage)
2155{
2156 int sa = qAlpha(color);
2157 int sr = qRed(color);
2158 int sg = qGreen(color);
2159 int sb = qBlue(color);
2160
2161 for (int i = 0; i < length; ++i) {
2162 uint d = dest[i];
2163 int da = qAlpha(d);
2164
2165#define OP(a, b) darken_op(a, b, da, sa)
2166 int r = OP( qRed(d), sr);
2167 int b = OP( qBlue(d), sb);
2168 int g = OP(qGreen(d), sg);
2169 int a = mix_alpha(da, sa);
2170#undef OP
2171
2172 coverage.store(&dest[i], qRgba(r, g, b, a));
2173 }
2174}
2175
2176void QT_FASTCALL comp_func_solid_Darken(uint *dest, int length, uint color, uint const_alpha)
2177{
2178 if (const_alpha == 255)
2179 comp_func_solid_Darken_impl(dest, length, color, QFullCoverage());
2180 else
2181 comp_func_solid_Darken_impl(dest, length, color, QPartialCoverage(const_alpha));
2182}
2183
2184#if QT_CONFIG(raster_64bit)
2185static inline uint darken_op_rgb64(uint dst, uint src, uint da, uint sa)
2186{
2187 return qt_div_65535(qMin(src * da, dst * sa) + src * (65535U - da) + dst * (65535U - sa));
2188}
2189
2190template <typename T>
2191static inline void comp_func_solid_Darken_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
2192{
2193 uint sa = color.alpha();
2194 uint sr = color.red();
2195 uint sg = color.green();
2196 uint sb = color.blue();
2197
2198 for (int i = 0; i < length; ++i) {
2199 QRgba64 d = dest[i];
2200 uint da = d.alpha();
2201
2202#define OP(a, b) darken_op_rgb64(a, b, da, sa)
2203 uint r = OP( d.red(), sr);
2204 uint b = OP( d.blue(), sb);
2205 uint g = OP(d.green(), sg);
2206 uint a = mix_alpha_rgb64(da, sa);
2207#undef OP
2208
2209 coverage.store(&dest[i], qRgba64(r, g, b, a));
2210 }
2211}
2212
2213void QT_FASTCALL comp_func_solid_Darken_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
2214{
2215 if (const_alpha == 255)
2216 comp_func_solid_Darken_impl(dest, length, color, QFullCoverage());
2217 else
2218 comp_func_solid_Darken_impl(dest, length, color, QPartialCoverage(const_alpha));
2219}
2220#endif
2221
2222#if QT_CONFIG(raster_fp)
2223static inline float darken_op_rgbafp(float dst, float src, float da, float sa)
2224{
2225 return qMin(src * da, dst * sa) + src * (1.0f - da) + dst * (1.0f - sa);
2226}
2227
2228template <typename T>
2229static inline void comp_func_solid_Darken_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
2230{
2231 float sa = color.alpha();
2232 float sr = color.red();
2233 float sg = color.green();
2234 float sb = color.blue();
2235
2236 for (int i = 0; i < length; ++i) {
2237 QRgbaFloat32 d = dest[i];
2238 float da = d.alpha();
2239
2240#define OP(a, b) darken_op_rgbafp(a, b, da, sa)
2241 float r = OP( d.red(), sr);
2242 float b = OP( d.blue(), sb);
2243 float g = OP(d.green(), sg);
2244 float a = mix_alpha_rgbafp(da, sa);
2245#undef OP
2246
2247 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
2248 }
2249}
2250
2251void QT_FASTCALL comp_func_solid_Darken_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
2252{
2253 if (const_alpha == 255)
2254 comp_func_solid_Darken_impl(dest, length, color, QFullCoverage());
2255 else
2256 comp_func_solid_Darken_impl(dest, length, color, QPartialCoverage(const_alpha));
2257}
2258#endif
2259
2260template <typename T>
2261static inline void comp_func_Darken_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
2262{
2263 for (int i = 0; i < length; ++i) {
2264 uint d = dest[i];
2265 uint s = src[i];
2266
2267 int da = qAlpha(d);
2268 int sa = qAlpha(s);
2269
2270#define OP(a, b) darken_op(a, b, da, sa)
2271 int r = OP( qRed(d), qRed(s));
2272 int b = OP( qBlue(d), qBlue(s));
2273 int g = OP(qGreen(d), qGreen(s));
2274 int a = mix_alpha(da, sa);
2275#undef OP
2276
2277 coverage.store(&dest[i], qRgba(r, g, b, a));
2278 }
2279}
2280
2281void QT_FASTCALL comp_func_Darken(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
2282{
2283 if (const_alpha == 255)
2284 comp_func_Darken_impl(dest, src, length, QFullCoverage());
2285 else
2286 comp_func_Darken_impl(dest, src, length, QPartialCoverage(const_alpha));
2287}
2288
2289#if QT_CONFIG(raster_64bit)
2290template <typename T>
2291static inline void comp_func_Darken_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
2292{
2293 for (int i = 0; i < length; ++i) {
2294 QRgba64 d = dest[i];
2295 QRgba64 s = src[i];
2296
2297 uint da = d.alpha();
2298 uint sa = s.alpha();
2299
2300#define OP(a, b) darken_op_rgb64(a, b, da, sa)
2301 uint r = OP( d.red(), s.red());
2302 uint b = OP( d.blue(), s.blue());
2303 uint g = OP(d.green(), s.green());
2304 uint a = mix_alpha_rgb64(da, sa);
2305#undef OP
2306
2307 coverage.store(&dest[i], qRgba64(r, g, b, a));
2308 }
2309}
2310
2311void QT_FASTCALL comp_func_Darken_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
2312{
2313 if (const_alpha == 255)
2314 comp_func_Darken_impl(dest, src, length, QFullCoverage());
2315 else
2316 comp_func_Darken_impl(dest, src, length, QPartialCoverage(const_alpha));
2317}
2318#endif
2319
2320#if QT_CONFIG(raster_fp)
2321template <typename T>
2322static inline void comp_func_Darken_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
2323{
2324 for (int i = 0; i < length; ++i) {
2325 QRgbaFloat32 d = dest[i];
2326 QRgbaFloat32 s = src[i];
2327
2328 float da = d.alpha();
2329 float sa = s.alpha();
2330
2331#define OP(a, b) darken_op_rgbafp(a, b, da, sa)
2332 float r = OP( d.red(), s.red());
2333 float b = OP( d.blue(), s.blue());
2334 float g = OP(d.green(), s.green());
2335 float a = mix_alpha_rgbafp(da, sa);
2336#undef OP
2337
2338 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
2339 }
2340}
2341
2342void QT_FASTCALL comp_func_Darken_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
2343{
2344 if (const_alpha == 255)
2345 comp_func_Darken_impl(dest, src, length, QFullCoverage());
2346 else
2347 comp_func_Darken_impl(dest, src, length, QPartialCoverage(const_alpha));
2348}
2349#endif
2350
2351/*
2352 Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
2353 Da' = Sa + Da - Sa.Da
2354*/
2355static inline int lighten_op(int dst, int src, int da, int sa)
2356{
2357 return qt_div_255(qMax(src * da, dst * sa) + src * (255 - da) + dst * (255 - sa));
2358}
2359
2360template <typename T>
2361static inline void comp_func_solid_Lighten_impl(uint *dest, int length, uint color, const T &coverage)
2362{
2363 int sa = qAlpha(color);
2364 int sr = qRed(color);
2365 int sg = qGreen(color);
2366 int sb = qBlue(color);
2367
2368 for (int i = 0; i < length; ++i) {
2369 uint d = dest[i];
2370 int da = qAlpha(d);
2371
2372#define OP(a, b) lighten_op(a, b, da, sa)
2373 int r = OP( qRed(d), sr);
2374 int b = OP( qBlue(d), sb);
2375 int g = OP(qGreen(d), sg);
2376 int a = mix_alpha(da, sa);
2377#undef OP
2378
2379 coverage.store(&dest[i], qRgba(r, g, b, a));
2380 }
2381}
2382
2383void QT_FASTCALL comp_func_solid_Lighten(uint *dest, int length, uint color, uint const_alpha)
2384{
2385 if (const_alpha == 255)
2386 comp_func_solid_Lighten_impl(dest, length, color, QFullCoverage());
2387 else
2388 comp_func_solid_Lighten_impl(dest, length, color, QPartialCoverage(const_alpha));
2389}
2390
2391
2392#if QT_CONFIG(raster_64bit)
2393static inline uint lighten_op_rgb64(uint dst, uint src, uint da, uint sa)
2394{
2395 return qt_div_65535(qMax(src * da, dst * sa) + src * (65535U - da) + dst * (65535U - sa));
2396}
2397
2398template <typename T>
2399static inline void comp_func_solid_Lighten_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
2400{
2401 uint sa = color.alpha();
2402 uint sr = color.red();
2403 uint sg = color.green();
2404 uint sb = color.blue();
2405
2406 for (int i = 0; i < length; ++i) {
2407 QRgba64 d = dest[i];
2408 uint da = d.alpha();
2409
2410#define OP(a, b) lighten_op_rgb64(a, b, da, sa)
2411 uint r = OP( d.red(), sr);
2412 uint b = OP( d.blue(), sb);
2413 uint g = OP(d.green(), sg);
2414 uint a = mix_alpha_rgb64(da, sa);
2415#undef OP
2416
2417 coverage.store(&dest[i], qRgba64(r, g, b, a));
2418 }
2419}
2420
2421void QT_FASTCALL comp_func_solid_Lighten_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
2422{
2423 if (const_alpha == 255)
2424 comp_func_solid_Lighten_impl(dest, length, color, QFullCoverage());
2425 else
2426 comp_func_solid_Lighten_impl(dest, length, color, QPartialCoverage(const_alpha));
2427}
2428#endif
2429
2430#if QT_CONFIG(raster_fp)
2431static inline float lighten_op_rgbafp(float dst, float src, float da, float sa)
2432{
2433 return qMax(src * da, dst * sa) + src * (1.0f - da) + dst * (1.0f - sa);
2434}
2435
2436template <typename T>
2437static inline void comp_func_solid_Lighten_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
2438{
2439 float sa = color.alpha();
2440 float sr = color.red();
2441 float sg = color.green();
2442 float sb = color.blue();
2443
2444 for (int i = 0; i < length; ++i) {
2445 QRgbaFloat32 d = dest[i];
2446 float da = d.alpha();
2447
2448#define OP(a, b) lighten_op_rgbafp(a, b, da, sa)
2449 float r = OP( d.red(), sr);
2450 float b = OP( d.blue(), sb);
2451 float g = OP(d.green(), sg);
2452 float a = mix_alpha_rgbafp(da, sa);
2453#undef OP
2454
2455 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
2456 }
2457}
2458
2459void QT_FASTCALL comp_func_solid_Lighten_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
2460{
2461 if (const_alpha == 255)
2462 comp_func_solid_Lighten_impl(dest, length, color, QFullCoverage());
2463 else
2464 comp_func_solid_Lighten_impl(dest, length, color, QPartialCoverage(const_alpha));
2465}
2466#endif
2467
2468template <typename T>
2469static inline void comp_func_Lighten_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
2470{
2471 for (int i = 0; i < length; ++i) {
2472 uint d = dest[i];
2473 uint s = src[i];
2474
2475 int da = qAlpha(d);
2476 int sa = qAlpha(s);
2477
2478#define OP(a, b) lighten_op(a, b, da, sa)
2479 int r = OP( qRed(d), qRed(s));
2480 int b = OP( qBlue(d), qBlue(s));
2481 int g = OP(qGreen(d), qGreen(s));
2482 int a = mix_alpha(da, sa);
2483#undef OP
2484
2485 coverage.store(&dest[i], qRgba(r, g, b, a));
2486 }
2487}
2488
2489void QT_FASTCALL comp_func_Lighten(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
2490{
2491 if (const_alpha == 255)
2492 comp_func_Lighten_impl(dest, src, length, QFullCoverage());
2493 else
2494 comp_func_Lighten_impl(dest, src, length, QPartialCoverage(const_alpha));
2495}
2496
2497#if QT_CONFIG(raster_64bit)
2498template <typename T>
2499static inline void comp_func_Lighten_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
2500{
2501 for (int i = 0; i < length; ++i) {
2502 QRgba64 d = dest[i];
2503 QRgba64 s = src[i];
2504
2505 uint da = d.alpha();
2506 uint sa = s.alpha();
2507
2508#define OP(a, b) lighten_op_rgb64(a, b, da, sa)
2509 uint r = OP( d.red(), s.red());
2510 uint b = OP( d.blue(), s.blue());
2511 uint g = OP(d.green(), s.green());
2512 uint a = mix_alpha_rgb64(da, sa);
2513#undef OP
2514
2515 coverage.store(&dest[i], qRgba64(r, g, b, a));
2516 }
2517}
2518
2519void QT_FASTCALL comp_func_Lighten_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
2520{
2521 if (const_alpha == 255)
2522 comp_func_Lighten_impl(dest, src, length, QFullCoverage());
2523 else
2524 comp_func_Lighten_impl(dest, src, length, QPartialCoverage(const_alpha));
2525}
2526#endif
2527
2528#if QT_CONFIG(raster_fp)
2529template <typename T>
2530static inline void comp_func_Lighten_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
2531{
2532 for (int i = 0; i < length; ++i) {
2533 QRgbaFloat32 d = dest[i];
2534 QRgbaFloat32 s = src[i];
2535
2536 float da = d.alpha();
2537 float sa = s.alpha();
2538
2539#define OP(a, b) lighten_op_rgbafp(a, b, da, sa)
2540 float r = OP( d.red(), s.red());
2541 float b = OP( d.blue(), s.blue());
2542 float g = OP(d.green(), s.green());
2543 float a = mix_alpha_rgbafp(da, sa);
2544#undef OP
2545
2546 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
2547 }
2548}
2549
2550void QT_FASTCALL comp_func_Lighten_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
2551{
2552 if (const_alpha == 255)
2553 comp_func_Lighten_impl(dest, src, length, QFullCoverage());
2554 else
2555 comp_func_Lighten_impl(dest, src, length, QPartialCoverage(const_alpha));
2556}
2557#endif
2558
2559/*
2560 if Sca.Da + Dca.Sa > Sa.Da
2561 Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa)
2562 else if Sca == Sa
2563 Dca' = Dca.Sa + Sca.(1 - Da) + Dca.(1 - Sa)
2564 otherwise
2565 Dca' = Dca.Sa/(1-Sca/Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
2566*/
2567static inline int color_dodge_op(int dst, int src, int da, int sa)
2568{
2569 const int sa_da = sa * da;
2570 const int dst_sa = dst * sa;
2571 const int src_da = src * da;
2572
2573 const int temp = src * (255 - da) + dst * (255 - sa);
2574 if (src_da + dst_sa > sa_da)
2575 return qt_div_255(sa_da + temp);
2576 else if (src == sa || sa == 0)
2577 return qt_div_255(temp);
2578 else
2579 return qt_div_255(255 * dst_sa / (255 - 255 * src / sa) + temp);
2580}
2581
2582template <typename T>
2583static inline void comp_func_solid_ColorDodge_impl(uint *dest, int length, uint color, const T &coverage)
2584{
2585 int sa = qAlpha(color);
2586 int sr = qRed(color);
2587 int sg = qGreen(color);
2588 int sb = qBlue(color);
2589
2590 for (int i = 0; i < length; ++i) {
2591 uint d = dest[i];
2592 int da = qAlpha(d);
2593
2594#define OP(a,b) color_dodge_op(a, b, da, sa)
2595 int r = OP( qRed(d), sr);
2596 int b = OP( qBlue(d), sb);
2597 int g = OP(qGreen(d), sg);
2598 int a = mix_alpha(da, sa);
2599#undef OP
2600
2601 coverage.store(&dest[i], qRgba(r, g, b, a));
2602 }
2603}
2604
2605void QT_FASTCALL comp_func_solid_ColorDodge(uint *dest, int length, uint color, uint const_alpha)
2606{
2607 if (const_alpha == 255)
2608 comp_func_solid_ColorDodge_impl(dest, length, color, QFullCoverage());
2609 else
2610 comp_func_solid_ColorDodge_impl(dest, length, color, QPartialCoverage(const_alpha));
2611}
2612
2613#if QT_CONFIG(raster_64bit)
2614static inline uint color_dodge_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 sa)
2615{
2616 const qint64 sa_da = sa * da;
2617 const qint64 dst_sa = dst * sa;
2618 const qint64 src_da = src * da;
2619
2620 const qint64 temp = src * (65535U - da) + dst * (65535U - sa);
2621 if (src_da + dst_sa > sa_da)
2622 return qt_div_65535(sa_da + temp);
2623 else if (src == sa || sa == 0)
2624 return qt_div_65535(temp);
2625 else
2626 return qt_div_65535(65535U * dst_sa / (65535U - 65535U * src / sa) + temp);
2627}
2628
2629template <typename T>
2630static inline void comp_func_solid_ColorDodge_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
2631{
2632 uint sa = color.alpha();
2633 uint sr = color.red();
2634 uint sg = color.green();
2635 uint sb = color.blue();
2636
2637 for (int i = 0; i < length; ++i) {
2638 QRgba64 d = dest[i];
2639 uint da = d.alpha();
2640
2641#define OP(a,b) color_dodge_op_rgb64(a, b, da, sa)
2642 uint r = OP( d.red(), sr);
2643 uint b = OP( d.blue(), sb);
2644 uint g = OP(d.green(), sg);
2645 uint a = mix_alpha_rgb64(da, sa);
2646#undef OP
2647
2648 coverage.store(&dest[i], qRgba64(r, g, b, a));
2649 }
2650}
2651
2652void QT_FASTCALL comp_func_solid_ColorDodge_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
2653{
2654 if (const_alpha == 255)
2655 comp_func_solid_ColorDodge_impl(dest, length, color, QFullCoverage());
2656 else
2657 comp_func_solid_ColorDodge_impl(dest, length, color, QPartialCoverage(const_alpha));
2658}
2659#endif
2660
2661#if QT_CONFIG(raster_fp)
2662static inline float color_dodge_op_rgbafp(float dst, float src, float da, float sa)
2663{
2664 const float sa_da = sa * da;
2665 const float dst_sa = dst * sa;
2666 const float src_da = src * da;
2667
2668 const float temp = src * (1.0f - da) + dst * (1.0f - sa);
2669 if (src_da + dst_sa > sa_da)
2670 return sa_da + temp;
2671 else if (src == sa || sa == 0.0f)
2672 return temp;
2673 else
2674 return dst_sa / (1.0f - src / sa) + temp;
2675}
2676
2677template <typename T>
2678static inline void comp_func_solid_ColorDodge_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
2679{
2680 float sa = color.alpha();
2681 float sr = color.red();
2682 float sg = color.green();
2683 float sb = color.blue();
2684
2685 for (int i = 0; i < length; ++i) {
2686 QRgbaFloat32 d = dest[i];
2687 float da = d.alpha();
2688
2689#define OP(a,b) color_dodge_op_rgbafp(a, b, da, sa)
2690 float r = OP( d.red(), sr);
2691 float b = OP( d.blue(), sb);
2692 float g = OP(d.green(), sg);
2693 float a = mix_alpha_rgbafp(da, sa);
2694#undef OP
2695
2696 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
2697 }
2698}
2699
2700void QT_FASTCALL comp_func_solid_ColorDodge_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
2701{
2702 if (const_alpha == 255)
2703 comp_func_solid_ColorDodge_impl(dest, length, color, QFullCoverage());
2704 else
2705 comp_func_solid_ColorDodge_impl(dest, length, color, QPartialCoverage(const_alpha));
2706}
2707#endif
2708
2709template <typename T>
2710static inline void comp_func_ColorDodge_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
2711{
2712 for (int i = 0; i < length; ++i) {
2713 uint d = dest[i];
2714 uint s = src[i];
2715
2716 int da = qAlpha(d);
2717 int sa = qAlpha(s);
2718
2719#define OP(a, b) color_dodge_op(a, b, da, sa)
2720 int r = OP( qRed(d), qRed(s));
2721 int b = OP( qBlue(d), qBlue(s));
2722 int g = OP(qGreen(d), qGreen(s));
2723 int a = mix_alpha(da, sa);
2724#undef OP
2725
2726 coverage.store(&dest[i], qRgba(r, g, b, a));
2727 }
2728}
2729
2730void QT_FASTCALL comp_func_ColorDodge(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
2731{
2732 if (const_alpha == 255)
2733 comp_func_ColorDodge_impl(dest, src, length, QFullCoverage());
2734 else
2735 comp_func_ColorDodge_impl(dest, src, length, QPartialCoverage(const_alpha));
2736}
2737
2738#if QT_CONFIG(raster_64bit)
2739template <typename T>
2740static inline void comp_func_ColorDodge_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
2741{
2742 for (int i = 0; i < length; ++i) {
2743 QRgba64 d = dest[i];
2744 QRgba64 s = src[i];
2745
2746 uint da = d.alpha();
2747 uint sa = s.alpha();
2748
2749#define OP(a, b) color_dodge_op_rgb64(a, b, da, sa)
2750 uint r = OP( d.red(), s.red());
2751 uint b = OP( d.blue(), s.blue());
2752 uint g = OP(d.green(), s.green());
2753 uint a = mix_alpha_rgb64(da, sa);
2754#undef OP
2755
2756 coverage.store(&dest[i], qRgba64(r, g, b, a));
2757 }
2758}
2759
2760void QT_FASTCALL comp_func_ColorDodge_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
2761{
2762 if (const_alpha == 255)
2763 comp_func_ColorDodge_impl(dest, src, length, QFullCoverage());
2764 else
2765 comp_func_ColorDodge_impl(dest, src, length, QPartialCoverage(const_alpha));
2766}
2767#endif
2768
2769#if QT_CONFIG(raster_fp)
2770template <typename T>
2771static inline void comp_func_ColorDodge_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
2772{
2773 for (int i = 0; i < length; ++i) {
2774 QRgbaFloat32 d = dest[i];
2775 QRgbaFloat32 s = src[i];
2776
2777 float da = d.alpha();
2778 float sa = s.alpha();
2779
2780#define OP(a, b) color_dodge_op_rgbafp(a, b, da, sa)
2781 float r = OP( d.red(), s.red());
2782 float b = OP( d.blue(), s.blue());
2783 float g = OP(d.green(), s.green());
2784 float a = mix_alpha_rgbafp(da, sa);
2785#undef OP
2786
2787 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
2788 }
2789}
2790
2791void QT_FASTCALL comp_func_ColorDodge_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
2792{
2793 if (const_alpha == 255)
2794 comp_func_ColorDodge_impl(dest, src, length, QFullCoverage());
2795 else
2796 comp_func_ColorDodge_impl(dest, src, length, QPartialCoverage(const_alpha));
2797}
2798#endif
2799
2800/*
2801 if Sca.Da + Dca.Sa < Sa.Da
2802 Dca' = Sca.(1 - Da) + Dca.(1 - Sa)
2803 else if Sca == 0
2804 Dca' = Dca.Sa + Sca.(1 - Da) + Dca.(1 - Sa)
2805 otherwise
2806 Dca' = Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa)
2807*/
2808static inline int color_burn_op(int dst, int src, int da, int sa)
2809{
2810 const int src_da = src * da;
2811 const int dst_sa = dst * sa;
2812 const int sa_da = sa * da;
2813
2814 const int temp = src * (255 - da) + dst * (255 - sa);
2815
2816 if (src_da + dst_sa < sa_da)
2817 return qt_div_255(temp);
2818 else if (src == 0)
2819 return qt_div_255(dst_sa + temp);
2820 return qt_div_255(sa * (src_da + dst_sa - sa_da) / src + temp);
2821}
2822
2823template <typename T>
2824static inline void comp_func_solid_ColorBurn_impl(uint *dest, int length, uint color, const T &coverage)
2825{
2826 int sa = qAlpha(color);
2827 int sr = qRed(color);
2828 int sg = qGreen(color);
2829 int sb = qBlue(color);
2830
2831 for (int i = 0; i < length; ++i) {
2832 uint d = dest[i];
2833 int da = qAlpha(d);
2834
2835#define OP(a, b) color_burn_op(a, b, da, sa)
2836 int r = OP( qRed(d), sr);
2837 int b = OP( qBlue(d), sb);
2838 int g = OP(qGreen(d), sg);
2839 int a = mix_alpha(da, sa);
2840#undef OP
2841
2842 coverage.store(&dest[i], qRgba(r, g, b, a));
2843 }
2844}
2845
2846void QT_FASTCALL comp_func_solid_ColorBurn(uint *dest, int length, uint color, uint const_alpha)
2847{
2848 if (const_alpha == 255)
2849 comp_func_solid_ColorBurn_impl(dest, length, color, QFullCoverage());
2850 else
2851 comp_func_solid_ColorBurn_impl(dest, length, color, QPartialCoverage(const_alpha));
2852}
2853
2854#if QT_CONFIG(raster_64bit)
2855static inline uint color_burn_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 sa)
2856{
2857 const qint64 src_da = src * da;
2858 const qint64 dst_sa = dst * sa;
2859 const qint64 sa_da = sa * da;
2860
2861 const qint64 temp = src * (65535U - da) + dst * (65535U - sa);
2862
2863 if (src_da + dst_sa < sa_da)
2864 return qt_div_65535(temp);
2865 else if (src == 0)
2866 return qt_div_65535(dst_sa + temp);
2867 return qt_div_65535(sa * (src_da + dst_sa - sa_da) / src + temp);
2868}
2869
2870template <typename T>
2871static inline void comp_func_solid_ColorBurn_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
2872{
2873 uint sa = color.alpha();
2874 uint sr = color.red();
2875 uint sg = color.green();
2876 uint sb = color.blue();
2877
2878 for (int i = 0; i < length; ++i) {
2879 QRgba64 d = dest[i];
2880 uint da = d.alpha();
2881
2882#define OP(a, b) color_burn_op_rgb64(a, b, da, sa)
2883 uint r = OP( d.red(), sr);
2884 uint b = OP( d.blue(), sb);
2885 uint g = OP(d.green(), sg);
2886 uint a = mix_alpha_rgb64(da, sa);
2887#undef OP
2888
2889 coverage.store(&dest[i], qRgba64(r, g, b, a));
2890 }
2891}
2892
2893void QT_FASTCALL comp_func_solid_ColorBurn_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
2894{
2895 if (const_alpha == 255)
2896 comp_func_solid_ColorBurn_impl(dest, length, color, QFullCoverage());
2897 else
2898 comp_func_solid_ColorBurn_impl(dest, length, color, QPartialCoverage(const_alpha));
2899}
2900#endif
2901
2902#if QT_CONFIG(raster_fp)
2903static inline float color_burn_op_rgbafp(float dst, float src, float da, float sa)
2904{
2905 const float src_da = src * da;
2906 const float dst_sa = dst * sa;
2907 const float sa_da = sa * da;
2908
2909 const float temp = src * (1.0f - da) + dst * (1.0f - sa);
2910
2911 if (src_da + dst_sa < sa_da)
2912 return temp;
2913 else if (src == 0)
2914 return dst_sa + temp;
2915 return sa * (src_da + dst_sa - sa_da) / src + temp;
2916}
2917
2918template <typename T>
2919static inline void comp_func_solid_ColorBurn_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
2920{
2921 float sa = color.alpha();
2922 float sr = color.red();
2923 float sg = color.green();
2924 float sb = color.blue();
2925
2926 for (int i = 0; i < length; ++i) {
2927 QRgbaFloat32 d = dest[i];
2928 float da = d.alpha();
2929
2930#define OP(a, b) color_burn_op_rgbafp(a, b, da, sa)
2931 float r = OP( d.red(), sr);
2932 float b = OP( d.blue(), sb);
2933 float g = OP(d.green(), sg);
2934 float a = mix_alpha_rgbafp(da, sa);
2935#undef OP
2936
2937 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
2938 }
2939}
2940
2941void QT_FASTCALL comp_func_solid_ColorBurn_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
2942{
2943 if (const_alpha == 255)
2944 comp_func_solid_ColorBurn_impl(dest, length, color, QFullCoverage());
2945 else
2946 comp_func_solid_ColorBurn_impl(dest, length, color, QPartialCoverage(const_alpha));
2947}
2948#endif
2949
2950template <typename T>
2951static inline void comp_func_ColorBurn_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
2952{
2953 for (int i = 0; i < length; ++i) {
2954 uint d = dest[i];
2955 uint s = src[i];
2956
2957 int da = qAlpha(d);
2958 int sa = qAlpha(s);
2959
2960#define OP(a, b) color_burn_op(a, b, da, sa)
2961 int r = OP( qRed(d), qRed(s));
2962 int b = OP( qBlue(d), qBlue(s));
2963 int g = OP(qGreen(d), qGreen(s));
2964 int a = mix_alpha(da, sa);
2965#undef OP
2966
2967 coverage.store(&dest[i], qRgba(r, g, b, a));
2968 }
2969}
2970
2971void QT_FASTCALL comp_func_ColorBurn(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
2972{
2973 if (const_alpha == 255)
2974 comp_func_ColorBurn_impl(dest, src, length, QFullCoverage());
2975 else
2976 comp_func_ColorBurn_impl(dest, src, length, QPartialCoverage(const_alpha));
2977}
2978
2979#if QT_CONFIG(raster_64bit)
2980template <typename T>
2981static inline void comp_func_ColorBurn_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
2982{
2983 for (int i = 0; i < length; ++i) {
2984 QRgba64 d = dest[i];
2985 QRgba64 s = src[i];
2986
2987 uint da = d.alpha();
2988 uint sa = s.alpha();
2989
2990#define OP(a, b) color_burn_op_rgb64(a, b, da, sa)
2991 uint r = OP( d.red(), s.red());
2992 uint b = OP( d.blue(), s.blue());
2993 uint g = OP(d.green(), s.green());
2994 uint a = mix_alpha_rgb64(da, sa);
2995#undef OP
2996
2997 coverage.store(&dest[i], qRgba64(r, g, b, a));
2998 }
2999}
3000
3001void QT_FASTCALL comp_func_ColorBurn_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3002{
3003 if (const_alpha == 255)
3004 comp_func_ColorBurn_impl(dest, src, length, QFullCoverage());
3005 else
3006 comp_func_ColorBurn_impl(dest, src, length, QPartialCoverage(const_alpha));
3007}
3008#endif
3009
3010#if QT_CONFIG(raster_fp)
3011template <typename T>
3012static inline void comp_func_ColorBurn_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
3013{
3014 for (int i = 0; i < length; ++i) {
3015 QRgbaFloat32 d = dest[i];
3016 QRgbaFloat32 s = src[i];
3017
3018 float da = d.alpha();
3019 float sa = s.alpha();
3020
3021#define OP(a, b) color_burn_op_rgbafp(a, b, da, sa)
3022 float r = OP( d.red(), s.red());
3023 float b = OP( d.blue(), s.blue());
3024 float g = OP(d.green(), s.green());
3025 float a = mix_alpha_rgbafp(da, sa);
3026#undef OP
3027
3028 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
3029 }
3030}
3031
3032void QT_FASTCALL comp_func_ColorBurn_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3033{
3034 if (const_alpha == 255)
3035 comp_func_ColorBurn_impl(dest, src, length, QFullCoverage());
3036 else
3037 comp_func_ColorBurn_impl(dest, src, length, QPartialCoverage(const_alpha));
3038}
3039#endif
3040
3041/*
3042 if 2.Sca < Sa
3043 Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
3044 otherwise
3045 Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
3046*/
3047static inline uint hardlight_op(int dst, int src, int da, int sa)
3048{
3049 const uint temp = src * (255 - da) + dst * (255 - sa);
3050
3051 if (2 * src < sa)
3052 return qt_div_255(2 * src * dst + temp);
3053 else
3054 return qt_div_255(sa * da - 2 * (da - dst) * (sa - src) + temp);
3055}
3056
3057template <typename T>
3058static inline void comp_func_solid_HardLight_impl(uint *dest, int length, uint color, const T &coverage)
3059{
3060 int sa = qAlpha(color);
3061 int sr = qRed(color);
3062 int sg = qGreen(color);
3063 int sb = qBlue(color);
3064
3065 for (int i = 0; i < length; ++i) {
3066 uint d = dest[i];
3067 int da = qAlpha(d);
3068
3069#define OP(a, b) hardlight_op(a, b, da, sa)
3070 int r = OP( qRed(d), sr);
3071 int b = OP( qBlue(d), sb);
3072 int g = OP(qGreen(d), sg);
3073 int a = mix_alpha(da, sa);
3074#undef OP
3075
3076 coverage.store(&dest[i], qRgba(r, g, b, a));
3077 }
3078}
3079
3080void QT_FASTCALL comp_func_solid_HardLight(uint *dest, int length, uint color, uint const_alpha)
3081{
3082 if (const_alpha == 255)
3083 comp_func_solid_HardLight_impl(dest, length, color, QFullCoverage());
3084 else
3085 comp_func_solid_HardLight_impl(dest, length, color, QPartialCoverage(const_alpha));
3086}
3087
3088#if QT_CONFIG(raster_64bit)
3089static inline uint hardlight_op_rgb64(uint dst, uint src, uint da, uint sa)
3090{
3091 const uint temp = src * (65535U - da) + dst * (65535U - sa);
3092
3093 if (2 * src < sa)
3094 return qt_div_65535(2 * src * dst + temp);
3095 else
3096 return qt_div_65535(sa * da - 2 * (da - dst) * (sa - src) + temp);
3097}
3098
3099template <typename T>
3100static inline void comp_func_solid_HardLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
3101{
3102 uint sa = color.alpha();
3103 uint sr = color.red();
3104 uint sg = color.green();
3105 uint sb = color.blue();
3106
3107 for (int i = 0; i < length; ++i) {
3108 QRgba64 d = dest[i];
3109 uint da = d.alpha();
3110
3111#define OP(a, b) hardlight_op_rgb64(a, b, da, sa)
3112 uint r = OP( d.red(), sr);
3113 uint b = OP( d.blue(), sb);
3114 uint g = OP(d.green(), sg);
3115 uint a = mix_alpha_rgb64(da, sa);
3116#undef OP
3117
3118 coverage.store(&dest[i], qRgba64(r, g, b, a));
3119 }
3120}
3121
3122void QT_FASTCALL comp_func_solid_HardLight_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
3123{
3124 if (const_alpha == 255)
3125 comp_func_solid_HardLight_impl(dest, length, color, QFullCoverage());
3126 else
3127 comp_func_solid_HardLight_impl(dest, length, color, QPartialCoverage(const_alpha));
3128}
3129#endif
3130
3131#if QT_CONFIG(raster_fp)
3132static inline float hardlight_op_rgbafp(float dst, float src, float da, float sa)
3133{
3134 const float temp = src * (1.0f - da) + dst * (1.0f - sa);
3135
3136 if (2 * src < sa)
3137 return 2 * src * dst + temp;
3138 else
3139 return sa * da - 2 * (da - dst) * (sa - src) + temp;
3140}
3141
3142template <typename T>
3143static inline void comp_func_solid_HardLight_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
3144{
3145 float sa = color.alpha();
3146 float sr = color.red();
3147 float sg = color.green();
3148 float sb = color.blue();
3149
3150 for (int i = 0; i < length; ++i) {
3151 QRgbaFloat32 d = dest[i];
3152 float da = d.alpha();
3153
3154#define OP(a, b) hardlight_op_rgbafp(a, b, da, sa)
3155 float r = OP( d.red(), sr);
3156 float b = OP( d.blue(), sb);
3157 float g = OP(d.green(), sg);
3158 float a = mix_alpha_rgbafp(da, sa);
3159#undef OP
3160
3161 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
3162 }
3163}
3164
3165void QT_FASTCALL comp_func_solid_HardLight_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
3166{
3167 if (const_alpha == 255)
3168 comp_func_solid_HardLight_impl(dest, length, color, QFullCoverage());
3169 else
3170 comp_func_solid_HardLight_impl(dest, length, color, QPartialCoverage(const_alpha));
3171}
3172#endif
3173
3174template <typename T>
3175static inline void comp_func_HardLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
3176{
3177 for (int i = 0; i < length; ++i) {
3178 uint d = dest[i];
3179 uint s = src[i];
3180
3181 int da = qAlpha(d);
3182 int sa = qAlpha(s);
3183
3184#define OP(a, b) hardlight_op(a, b, da, sa)
3185 int r = OP( qRed(d), qRed(s));
3186 int b = OP( qBlue(d), qBlue(s));
3187 int g = OP(qGreen(d), qGreen(s));
3188 int a = mix_alpha(da, sa);
3189#undef OP
3190
3191 coverage.store(&dest[i], qRgba(r, g, b, a));
3192 }
3193}
3194
3195void QT_FASTCALL comp_func_HardLight(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
3196{
3197 if (const_alpha == 255)
3198 comp_func_HardLight_impl(dest, src, length, QFullCoverage());
3199 else
3200 comp_func_HardLight_impl(dest, src, length, QPartialCoverage(const_alpha));
3201}
3202
3203#if QT_CONFIG(raster_64bit)
3204template <typename T>
3205static inline void comp_func_HardLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
3206{
3207 for (int i = 0; i < length; ++i) {
3208 QRgba64 d = dest[i];
3209 QRgba64 s = src[i];
3210
3211 uint da = d.alpha();
3212 uint sa = s.alpha();
3213
3214#define OP(a, b) hardlight_op_rgb64(a, b, da, sa)
3215 uint r = OP( d.red(), s.red());
3216 uint b = OP( d.blue(), s.blue());
3217 uint g = OP(d.green(), s.green());
3218 uint a = mix_alpha_rgb64(da, sa);
3219#undef OP
3220
3221 coverage.store(&dest[i], qRgba64(r, g, b, a));
3222 }
3223}
3224
3225void QT_FASTCALL comp_func_HardLight_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3226{
3227 if (const_alpha == 255)
3228 comp_func_HardLight_impl(dest, src, length, QFullCoverage());
3229 else
3230 comp_func_HardLight_impl(dest, src, length, QPartialCoverage(const_alpha));
3231}
3232#endif
3233
3234#if QT_CONFIG(raster_fp)
3235template <typename T>
3236static inline void comp_func_HardLight_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
3237{
3238 for (int i = 0; i < length; ++i) {
3239 QRgbaFloat32 d = dest[i];
3240 QRgbaFloat32 s = src[i];
3241
3242 float da = d.alpha();
3243 float sa = s.alpha();
3244
3245#define OP(a, b) hardlight_op_rgbafp(a, b, da, sa)
3246 float r = OP( d.red(), s.red());
3247 float b = OP( d.blue(), s.blue());
3248 float g = OP(d.green(), s.green());
3249 float a = mix_alpha_rgbafp(da, sa);
3250#undef OP
3251
3252 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
3253 }
3254}
3255
3256void QT_FASTCALL comp_func_HardLight_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3257{
3258 if (const_alpha == 255)
3259 comp_func_HardLight_impl(dest, src, length, QFullCoverage());
3260 else
3261 comp_func_HardLight_impl(dest, src, length, QPartialCoverage(const_alpha));
3262}
3263#endif
3264
3265/*
3266 if 2.Sca <= Sa
3267 Dca' = Dca.(Sa + (2.Sca - Sa).(1 - Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
3268 otherwise if 2.Sca > Sa and 4.Dca <= Da
3269 Dca' = Dca.Sa + Da.(2.Sca - Sa).(4.Dca/Da.(4.Dca/Da + 1).(Dca/Da - 1) + 7.Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
3270 otherwise if 2.Sca > Sa and 4.Dca > Da
3271 Dca' = Dca.Sa + Da.(2.Sca - Sa).((Dca/Da)^0.5 - Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
3272*/
3273static inline int soft_light_op(int dst, int src, int da, int sa)
3274{
3275 const int src2 = src << 1;
3276 const int dst_np = da != 0 ? (255 * dst) / da : 0;
3277 const int temp = (src * (255 - da) + dst * (255 - sa)) * 255;
3278
3279 if (src2 < sa)
3280 return (dst * (sa * 255 + (src2 - sa) * (255 - dst_np)) + temp) / 65025;
3281 else if (4 * dst <= da)
3282 return (dst * sa * 255 + da * (src2 - sa) * ((((16 * dst_np - 12 * 255) * dst_np + 3 * 65025) * dst_np) / 65025) + temp) / 65025;
3283 else {
3284 return (dst * sa * 255 + da * (src2 - sa) * (int(qSqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025;
3285 }
3286}
3287
3288template <typename T>
3289static inline void comp_func_solid_SoftLight_impl(uint *dest, int length, uint color, const T &coverage)
3290{
3291 int sa = qAlpha(color);
3292 int sr = qRed(color);
3293 int sg = qGreen(color);
3294 int sb = qBlue(color);
3295
3296 for (int i = 0; i < length; ++i) {
3297 uint d = dest[i];
3298 int da = qAlpha(d);
3299
3300#define OP(a, b) soft_light_op(a, b, da, sa)
3301 int r = OP( qRed(d), sr);
3302 int b = OP( qBlue(d), sb);
3303 int g = OP(qGreen(d), sg);
3304 int a = mix_alpha(da, sa);
3305#undef OP
3306
3307 coverage.store(&dest[i], qRgba(r, g, b, a));
3308 }
3309}
3310
3311void QT_FASTCALL comp_func_solid_SoftLight(uint *dest, int length, uint color, uint const_alpha)
3312{
3313 if (const_alpha == 255)
3314 comp_func_solid_SoftLight_impl(dest, length, color, QFullCoverage());
3315 else
3316 comp_func_solid_SoftLight_impl(dest, length, color, QPartialCoverage(const_alpha));
3317}
3318
3319#if QT_CONFIG(raster_64bit)
3320static inline uint soft_light_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 sa)
3321{
3322 const qint64 src2 = src << 1;
3323 const qint64 dst_np = da != 0 ? (65535U * dst) / da : 0;
3324 const qint64 temp = (src * (65535U - da) + dst * (65535U - sa)) * 65535U;
3325 const qint64 factor = Q_UINT64_C(65535) * 65535U;
3326
3327 if (src2 < sa)
3328 return (dst * (sa * 65535U + (src2 - sa) * (65535U - dst_np)) + temp) / factor;
3329 else if (4 * dst <= da)
3330 return (dst * sa * 65535U + da * (src2 - sa) * ((((16 * dst_np - 12 * 65535U) * dst_np + 3 * factor) * dst_np) / factor) + temp) / factor;
3331 else {
3332 return (dst * sa * 65535U + da * (src2 - sa) * (int(qSqrt(qreal(dst_np * 65535U))) - dst_np) + temp) / factor;
3333 }
3334}
3335
3336template <typename T>
3337static inline void comp_func_solid_SoftLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
3338{
3339 uint sa = color.alpha();
3340 uint sr = color.red();
3341 uint sg = color.green();
3342 uint sb = color.blue();
3343
3344 for (int i = 0; i < length; ++i) {
3345 QRgba64 d = dest[i];
3346 uint da = d.alpha();
3347
3348#define OP(a, b) soft_light_op_rgb64(a, b, da, sa)
3349 uint r = OP( d.red(), sr);
3350 uint b = OP( d.blue(), sb);
3351 uint g = OP(d.green(), sg);
3352 uint a = mix_alpha_rgb64(da, sa);
3353#undef OP
3354
3355 coverage.store(&dest[i], qRgba64(r, g, b, a));
3356 }
3357}
3358
3359void QT_FASTCALL comp_func_solid_SoftLight_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
3360{
3361 if (const_alpha == 255)
3362 comp_func_solid_SoftLight_impl(dest, length, color, QFullCoverage());
3363 else
3364 comp_func_solid_SoftLight_impl(dest, length, color, QPartialCoverage(const_alpha));
3365}
3366
3367#endif
3368
3369#if QT_CONFIG(raster_fp)
3370static inline float soft_light_op_rgbafp(float dst, float src, float da, float sa)
3371{
3372 const float src2 = src * 2;
3373 const float dst_np = da != 0.0f ? (dst / da) : 0.0f;
3374 const float temp = src * (1.0f - da) + dst * (1.0f - sa);
3375
3376 if (src2 < sa)
3377 return dst * (sa + (src2 - sa) * (1.0f - dst_np)) + temp;
3378 else if (4 * dst <= da)
3379 return dst * sa + da * (src2 - sa) * (((16 * dst_np - 12) * dst_np + 3) * dst_np) + temp;
3380 else {
3381 return dst * sa + da * (src2 - sa) * (qSqrt(qreal(dst_np)) - dst_np) + temp;
3382 }
3383}
3384
3385template <typename T>
3386static inline void comp_func_solid_SoftLight_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
3387{
3388 float sa = color.alpha();
3389 float sr = color.red();
3390 float sg = color.green();
3391 float sb = color.blue();
3392
3393 for (int i = 0; i < length; ++i) {
3394 QRgbaFloat32 d = dest[i];
3395 float da = d.alpha();
3396
3397#define OP(a, b) soft_light_op_rgbafp(a, b, da, sa)
3398 float r = OP( d.red(), sr);
3399 float b = OP( d.blue(), sb);
3400 float g = OP(d.green(), sg);
3401 float a = mix_alpha_rgbafp(da, sa);
3402#undef OP
3403
3404 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
3405 }
3406}
3407
3408void QT_FASTCALL comp_func_solid_SoftLight_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
3409{
3410 if (const_alpha == 255)
3411 comp_func_solid_SoftLight_impl(dest, length, color, QFullCoverage());
3412 else
3413 comp_func_solid_SoftLight_impl(dest, length, color, QPartialCoverage(const_alpha));
3414}
3415#endif
3416
3417template <typename T>
3418static inline void comp_func_SoftLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
3419{
3420 for (int i = 0; i < length; ++i) {
3421 uint d = dest[i];
3422 uint s = src[i];
3423
3424 int da = qAlpha(d);
3425 int sa = qAlpha(s);
3426
3427#define OP(a, b) soft_light_op(a, b, da, sa)
3428 int r = OP( qRed(d), qRed(s));
3429 int b = OP( qBlue(d), qBlue(s));
3430 int g = OP(qGreen(d), qGreen(s));
3431 int a = mix_alpha(da, sa);
3432#undef OP
3433
3434 coverage.store(&dest[i], qRgba(r, g, b, a));
3435 }
3436}
3437
3438void QT_FASTCALL comp_func_SoftLight(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
3439{
3440 if (const_alpha == 255)
3441 comp_func_SoftLight_impl(dest, src, length, QFullCoverage());
3442 else
3443 comp_func_SoftLight_impl(dest, src, length, QPartialCoverage(const_alpha));
3444}
3445
3446#if QT_CONFIG(raster_64bit)
3447template <typename T>
3448static inline void comp_func_SoftLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
3449{
3450 for (int i = 0; i < length; ++i) {
3451 QRgba64 d = dest[i];
3452 QRgba64 s = src[i];
3453
3454 uint da = d.alpha();
3455 uint sa = s.alpha();
3456
3457#define OP(a, b) soft_light_op_rgb64(a, b, da, sa)
3458 uint r = OP( d.red(), s.red());
3459 uint b = OP( d.blue(), s.blue());
3460 uint g = OP(d.green(), s.green());
3461 uint a = mix_alpha_rgb64(da, sa);
3462#undef OP
3463
3464 coverage.store(&dest[i], qRgba64(r, g, b, a));
3465 }
3466}
3467
3468void QT_FASTCALL comp_func_SoftLight_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3469{
3470 if (const_alpha == 255)
3471 comp_func_SoftLight_impl(dest, src, length, QFullCoverage());
3472 else
3473 comp_func_SoftLight_impl(dest, src, length, QPartialCoverage(const_alpha));
3474}
3475#endif
3476
3477#if QT_CONFIG(raster_fp)
3478template <typename T>
3479static inline void comp_func_SoftLight_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
3480{
3481 for (int i = 0; i < length; ++i) {
3482 QRgbaFloat32 d = dest[i];
3483 QRgbaFloat32 s = src[i];
3484
3485 float da = d.alpha();
3486 float sa = s.alpha();
3487
3488#define OP(a, b) soft_light_op_rgbafp(a, b, da, sa)
3489 float r = OP( d.red(), s.red());
3490 float b = OP( d.blue(), s.blue());
3491 float g = OP(d.green(), s.green());
3492 float a = mix_alpha_rgbafp(da, sa);
3493#undef OP
3494
3495 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
3496 }
3497}
3498
3499void QT_FASTCALL comp_func_SoftLight_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3500{
3501 if (const_alpha == 255)
3502 comp_func_SoftLight_impl(dest, src, length, QFullCoverage());
3503 else
3504 comp_func_SoftLight_impl(dest, src, length, QPartialCoverage(const_alpha));
3505}
3506#endif
3507
3508/*
3509 Dca' = abs(Dca.Sa - Sca.Da) + Sca.(1 - Da) + Dca.(1 - Sa)
3510 = Sca + Dca - 2.min(Sca.Da, Dca.Sa)
3511*/
3512static inline int difference_op(int dst, int src, int da, int sa)
3513{
3514 return src + dst - qt_div_255(2 * qMin(src * da, dst * sa));
3515}
3516
3517template <typename T>
3518static inline void comp_func_solid_Difference_impl(uint *dest, int length, uint color, const T &coverage)
3519{
3520 int sa = qAlpha(color);
3521 int sr = qRed(color);
3522 int sg = qGreen(color);
3523 int sb = qBlue(color);
3524
3525 for (int i = 0; i < length; ++i) {
3526 uint d = dest[i];
3527 int da = qAlpha(d);
3528
3529#define OP(a, b) difference_op(a, b, da, sa)
3530 int r = OP( qRed(d), sr);
3531 int b = OP( qBlue(d), sb);
3532 int g = OP(qGreen(d), sg);
3533 int a = mix_alpha(da, sa);
3534#undef OP
3535
3536 coverage.store(&dest[i], qRgba(r, g, b, a));
3537 }
3538}
3539
3540void QT_FASTCALL comp_func_solid_Difference(uint *dest, int length, uint color, uint const_alpha)
3541{
3542 if (const_alpha == 255)
3543 comp_func_solid_Difference_impl(dest, length, color, QFullCoverage());
3544 else
3545 comp_func_solid_Difference_impl(dest, length, color, QPartialCoverage(const_alpha));
3546}
3547
3548#if QT_CONFIG(raster_64bit)
3549static inline uint difference_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 sa)
3550{
3551 return src + dst - qt_div_65535(2 * qMin(src * da, dst * sa));
3552}
3553
3554template <typename T>
3555static inline void comp_func_solid_Difference_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
3556{
3557 uint sa = color.alpha();
3558 uint sr = color.red();
3559 uint sg = color.green();
3560 uint sb = color.blue();
3561
3562 for (int i = 0; i < length; ++i) {
3563 QRgba64 d = dest[i];
3564 uint da = d.alpha();
3565
3566#define OP(a, b) difference_op_rgb64(a, b, da, sa)
3567 uint r = OP( d.red(), sr);
3568 uint b = OP( d.blue(), sb);
3569 uint g = OP(d.green(), sg);
3570 uint a = mix_alpha_rgb64(da, sa);
3571#undef OP
3572
3573 coverage.store(&dest[i], qRgba64(r, g, b, a));
3574 }
3575}
3576
3577void QT_FASTCALL comp_func_solid_Difference_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
3578{
3579 if (const_alpha == 255)
3580 comp_func_solid_Difference_impl(dest, length, color, QFullCoverage());
3581 else
3582 comp_func_solid_Difference_impl(dest, length, color, QPartialCoverage(const_alpha));
3583}
3584#endif
3585
3586#if QT_CONFIG(raster_fp)
3587static inline float difference_op_rgbafp(float dst, float src, float da, float sa)
3588{
3589 return src + dst - (2 * qMin(src * da, dst * sa));
3590}
3591
3592template <typename T>
3593static inline void comp_func_solid_Difference_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
3594{
3595 float sa = color.alpha();
3596 float sr = color.red();
3597 float sg = color.green();
3598 float sb = color.blue();
3599
3600 for (int i = 0; i < length; ++i) {
3601 QRgbaFloat32 d = dest[i];
3602 float da = d.alpha();
3603
3604#define OP(a, b) difference_op_rgbafp(a, b, da, sa)
3605 float r = OP( d.red(), sr);
3606 float b = OP( d.blue(), sb);
3607 float g = OP(d.green(), sg);
3608 float a = mix_alpha_rgbafp(da, sa);
3609#undef OP
3610
3611 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
3612 }
3613}
3614
3615void QT_FASTCALL comp_func_solid_Difference_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
3616{
3617 if (const_alpha == 255)
3618 comp_func_solid_Difference_impl(dest, length, color, QFullCoverage());
3619 else
3620 comp_func_solid_Difference_impl(dest, length, color, QPartialCoverage(const_alpha));
3621}
3622#endif
3623
3624template <typename T>
3625static inline void comp_func_Difference_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
3626{
3627 for (int i = 0; i < length; ++i) {
3628 uint d = dest[i];
3629 uint s = src[i];
3630
3631 int da = qAlpha(d);
3632 int sa = qAlpha(s);
3633
3634#define OP(a, b) difference_op(a, b, da, sa)
3635 int r = OP( qRed(d), qRed(s));
3636 int b = OP( qBlue(d), qBlue(s));
3637 int g = OP(qGreen(d), qGreen(s));
3638 int a = mix_alpha(da, sa);
3639#undef OP
3640
3641 coverage.store(&dest[i], qRgba(r, g, b, a));
3642 }
3643}
3644
3645void QT_FASTCALL comp_func_Difference(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
3646{
3647 if (const_alpha == 255)
3648 comp_func_Difference_impl(dest, src, length, QFullCoverage());
3649 else
3650 comp_func_Difference_impl(dest, src, length, QPartialCoverage(const_alpha));
3651}
3652
3653#if QT_CONFIG(raster_64bit)
3654template <typename T>
3655static inline void comp_func_Difference_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
3656{
3657 for (int i = 0; i < length; ++i) {
3658 QRgba64 d = dest[i];
3659 QRgba64 s = src[i];
3660
3661 uint da = d.alpha();
3662 uint sa = s.alpha();
3663
3664#define OP(a, b) difference_op_rgb64(a, b, da, sa)
3665 uint r = OP( d.red(), s.red());
3666 uint b = OP( d.blue(), s.blue());
3667 uint g = OP(d.green(), s.green());
3668 uint a = mix_alpha_rgb64(da, sa);
3669#undef OP
3670
3671 coverage.store(&dest[i], qRgba64(r, g, b, a));
3672 }
3673}
3674
3675void QT_FASTCALL comp_func_Difference_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3676{
3677 if (const_alpha == 255)
3678 comp_func_Difference_impl(dest, src, length, QFullCoverage());
3679 else
3680 comp_func_Difference_impl(dest, src, length, QPartialCoverage(const_alpha));
3681}
3682#endif
3683
3684#if QT_CONFIG(raster_fp)
3685template <typename T>
3686static inline void comp_func_Difference_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
3687{
3688 for (int i = 0; i < length; ++i) {
3689 QRgbaFloat32 d = dest[i];
3690 QRgbaFloat32 s = src[i];
3691
3692 float da = d.alpha();
3693 float sa = s.alpha();
3694
3695#define OP(a, b) difference_op_rgbafp(a, b, da, sa)
3696 float r = OP( d.red(), s.red());
3697 float b = OP( d.blue(), s.blue());
3698 float g = OP(d.green(), s.green());
3699 float a = mix_alpha_rgbafp(da, sa);
3700#undef OP
3701
3702 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
3703 }
3704}
3705
3706void QT_FASTCALL comp_func_Difference_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3707{
3708 if (const_alpha == 255)
3709 comp_func_Difference_impl(dest, src, length, QFullCoverage());
3710 else
3711 comp_func_Difference_impl(dest, src, length, QPartialCoverage(const_alpha));
3712}
3713#endif
3714
3715/*
3716 Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
3717*/
3718template <typename T>
3719static inline void QT_FASTCALL comp_func_solid_Exclusion_impl(uint *dest, int length, uint color, const T &coverage)
3720{
3721 int sa = qAlpha(color);
3722 int sr = qRed(color);
3723 int sg = qGreen(color);
3724 int sb = qBlue(color);
3725
3726 for (int i = 0; i < length; ++i) {
3727 uint d = dest[i];
3728 int da = qAlpha(d);
3729
3730#define OP(a, b) (a + b - qt_div_255(2*(a*b)))
3731 int r = OP( qRed(d), sr);
3732 int b = OP( qBlue(d), sb);
3733 int g = OP(qGreen(d), sg);
3734 int a = mix_alpha(da, sa);
3735#undef OP
3736
3737 coverage.store(&dest[i], qRgba(r, g, b, a));
3738 }
3739}
3740
3741void QT_FASTCALL comp_func_solid_Exclusion(uint *dest, int length, uint color, uint const_alpha)
3742{
3743 if (const_alpha == 255)
3744 comp_func_solid_Exclusion_impl(dest, length, color, QFullCoverage());
3745 else
3746 comp_func_solid_Exclusion_impl(dest, length, color, QPartialCoverage(const_alpha));
3747}
3748
3749#if QT_CONFIG(raster_64bit)
3750template <typename T>
3751static inline void QT_FASTCALL comp_func_solid_Exclusion_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage)
3752{
3753 uint sa = color.alpha();
3754 uint sr = color.red();
3755 uint sg = color.green();
3756 uint sb = color.blue();
3757
3758 for (int i = 0; i < length; ++i) {
3759 QRgba64 d = dest[i];
3760 uint da = d.alpha();
3761
3762#define OP(a, b) (a + b - qt_div_65535(2*(qint64(a)*b)))
3763 uint r = OP( d.red(), sr);
3764 uint b = OP( d.blue(), sb);
3765 uint g = OP(d.green(), sg);
3766 uint a = mix_alpha_rgb64(da, sa);
3767#undef OP
3768
3769 coverage.store(&dest[i], qRgba64(r, g, b, a));
3770 }
3771}
3772
3773void QT_FASTCALL comp_func_solid_Exclusion_rgb64(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
3774{
3775 if (const_alpha == 255)
3776 comp_func_solid_Exclusion_impl(dest, length, color, QFullCoverage());
3777 else
3778 comp_func_solid_Exclusion_impl(dest, length, color, QPartialCoverage(const_alpha));
3779}
3780#endif
3781
3782#if QT_CONFIG(raster_fp)
3783template <typename T>
3784static inline void QT_FASTCALL comp_func_solid_Exclusion_impl(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, const T &coverage)
3785{
3786 float sa = color.alpha();
3787 float sr = color.red();
3788 float sg = color.green();
3789 float sb = color.blue();
3790
3791 for (int i = 0; i < length; ++i) {
3792 QRgbaFloat32 d = dest[i];
3793 float da = d.alpha();
3794
3795#define OP(a, b) (a + b - (2.0f * a * b))
3796 float r = OP( d.red(), sr);
3797 float b = OP( d.blue(), sb);
3798 float g = OP(d.green(), sg);
3799 float a = mix_alpha_rgbafp(da, sa);
3800#undef OP
3801
3802 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
3803 }
3804}
3805
3806void QT_FASTCALL comp_func_solid_Exclusion_rgbafp(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
3807{
3808 if (const_alpha == 255)
3809 comp_func_solid_Exclusion_impl(dest, length, color, QFullCoverage());
3810 else
3811 comp_func_solid_Exclusion_impl(dest, length, color, QPartialCoverage(const_alpha));
3812}
3813#endif
3814
3815template <typename T>
3816static inline void comp_func_Exclusion_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
3817{
3818 for (int i = 0; i < length; ++i) {
3819 uint d = dest[i];
3820 uint s = src[i];
3821
3822 int da = qAlpha(d);
3823 int sa = qAlpha(s);
3824
3825#define OP(a, b) (a + b - ((a*b) >> 7))
3826 int r = OP( qRed(d), qRed(s));
3827 int b = OP( qBlue(d), qBlue(s));
3828 int g = OP(qGreen(d), qGreen(s));
3829 int a = mix_alpha(da, sa);
3830#undef OP
3831
3832 coverage.store(&dest[i], qRgba(r, g, b, a));
3833 }
3834}
3835
3836void QT_FASTCALL comp_func_Exclusion(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
3837{
3838 if (const_alpha == 255)
3839 comp_func_Exclusion_impl(dest, src, length, QFullCoverage());
3840 else
3841 comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha));
3842}
3843
3844#if QT_CONFIG(raster_64bit)
3845template <typename T>
3846static inline void comp_func_Exclusion_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage)
3847{
3848 for (int i = 0; i < length; ++i) {
3849 QRgba64 d = dest[i];
3850 QRgba64 s = src[i];
3851
3852 uint da = d.alpha();
3853 uint sa = s.alpha();
3854
3855#define OP(a, b) (a + b - ((qint64(a)*b) >> 15))
3856 uint r = OP( d.red(), s.red());
3857 uint b = OP( d.blue(), s.blue());
3858 uint g = OP(d.green(), s.green());
3859 uint a = mix_alpha_rgb64(da, sa);
3860#undef OP
3861
3862 coverage.store(&dest[i], qRgba64(r, g, b, a));
3863 }
3864}
3865
3866void QT_FASTCALL comp_func_Exclusion_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3867{
3868 if (const_alpha == 255)
3869 comp_func_Exclusion_impl(dest, src, length, QFullCoverage());
3870 else
3871 comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha));
3872}
3873#endif
3874
3875#if QT_CONFIG(raster_fp)
3876template <typename T>
3877static inline void comp_func_Exclusion_impl(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, const T &coverage)
3878{
3879 for (int i = 0; i < length; ++i) {
3880 QRgbaFloat32 d = dest[i];
3881 QRgbaFloat32 s = src[i];
3882
3883 float da = d.alpha();
3884 float sa = s.alpha();
3885
3886#define OP(a, b) (a + b - (2.0f * a * b))
3887 float r = OP( d.red(), s.red());
3888 float b = OP( d.blue(), s.blue());
3889 float g = OP(d.green(), s.green());
3890 float a = mix_alpha_rgbafp(da, sa);
3891#undef OP
3892
3893 coverage.store(&dest[i], qRgbaFloat32(r, g, b, a));
3894 }
3895}
3896
3897void QT_FASTCALL comp_func_Exclusion_rgbafp(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
3898{
3899 if (const_alpha == 255)
3900 comp_func_Exclusion_impl(dest, src, length, QFullCoverage());
3901 else
3902 comp_func_Exclusion_impl(dest, src, length, QPartialCoverage(const_alpha));
3903}
3904#endif
3905
3906void QT_FASTCALL rasterop_solid_SourceOrDestination(uint *dest,
3907 int length,
3908 uint color,
3909 uint const_alpha)
3910{
3911 Q_UNUSED(const_alpha);
3912 while (length--)
3913 *dest++ |= color;
3914}
3915
3916void QT_FASTCALL rasterop_SourceOrDestination(uint *Q_DECL_RESTRICT dest,
3917 const uint *Q_DECL_RESTRICT src,
3918 int length,
3919 uint const_alpha)
3920{
3921 Q_UNUSED(const_alpha);
3922 while (length--)
3923 *dest++ |= *src++;
3924}
3925
3926void QT_FASTCALL rasterop_solid_SourceAndDestination(uint *dest,
3927 int length,
3928 uint color,
3929 uint const_alpha)
3930{
3931 Q_UNUSED(const_alpha);
3932 color |= 0xff000000;
3933 while (length--)
3934 *dest++ &= color;
3935}
3936
3937void QT_FASTCALL rasterop_SourceAndDestination(uint *Q_DECL_RESTRICT dest,
3938 const uint *Q_DECL_RESTRICT src,
3939 int length,
3940 uint const_alpha)
3941{
3942 Q_UNUSED(const_alpha);
3943 while (length--) {
3944 *dest = (*src & *dest) | 0xff000000;
3945 ++dest; ++src;
3946 }
3947}
3948
3949void QT_FASTCALL rasterop_solid_SourceXorDestination(uint *dest,
3950 int length,
3951 uint color,
3952 uint const_alpha)
3953{
3954 Q_UNUSED(const_alpha);
3955 color &= 0x00ffffff;
3956 while (length--)
3957 *dest++ ^= color;
3958}
3959
3960void QT_FASTCALL rasterop_SourceXorDestination(uint *Q_DECL_RESTRICT dest,
3961 const uint *Q_DECL_RESTRICT src,
3962 int length,
3963 uint const_alpha)
3964{
3965 Q_UNUSED(const_alpha);
3966 while (length--) {
3967 *dest = (*src ^ *dest) | 0xff000000;
3968 ++dest; ++src;
3969 }
3970}
3971
3972void QT_FASTCALL rasterop_solid_NotSourceAndNotDestination(uint *dest,
3973 int length,
3974 uint color,
3975 uint const_alpha)
3976{
3977 Q_UNUSED(const_alpha);
3978 color = ~color;
3979 while (length--) {
3980 *dest = (color & ~(*dest)) | 0xff000000;
3981 ++dest;
3982 }
3983}
3984
3985void QT_FASTCALL rasterop_NotSourceAndNotDestination(uint *Q_DECL_RESTRICT dest,
3986 const uint *Q_DECL_RESTRICT src,
3987 int length,
3988 uint const_alpha)
3989{
3990 Q_UNUSED(const_alpha);
3991 while (length--) {
3992 *dest = (~(*src) & ~(*dest)) | 0xff000000;
3993 ++dest; ++src;
3994 }
3995}
3996
3997void QT_FASTCALL rasterop_solid_NotSourceOrNotDestination(uint *dest,
3998 int length,
3999 uint color,
4000 uint const_alpha)
4001{
4002 Q_UNUSED(const_alpha);
4003 color = ~color | 0xff000000;
4004 while (length--) {
4005 *dest = color | ~(*dest);
4006 ++dest;
4007 }
4008}
4009
4010void QT_FASTCALL rasterop_NotSourceOrNotDestination(uint *Q_DECL_RESTRICT dest,
4011 const uint *Q_DECL_RESTRICT src,
4012 int length,
4013 uint const_alpha)
4014{
4015 Q_UNUSED(const_alpha);
4016 while (length--) {
4017 *dest = ~(*src) | ~(*dest) | 0xff000000;
4018 ++dest; ++src;
4019 }
4020}
4021
4022void QT_FASTCALL rasterop_solid_NotSourceXorDestination(uint *dest,
4023 int length,
4024 uint color,
4025 uint const_alpha)
4026{
4027 Q_UNUSED(const_alpha);
4028 color = ~color & 0x00ffffff;
4029 while (length--) {
4030 *dest = color ^ (*dest);
4031 ++dest;
4032 }
4033}
4034
4035void QT_FASTCALL rasterop_NotSourceXorDestination(uint *Q_DECL_RESTRICT dest,
4036 const uint *Q_DECL_RESTRICT src,
4037 int length,
4038 uint const_alpha)
4039{
4040 Q_UNUSED(const_alpha);
4041 while (length--) {
4042 *dest = ((~(*src)) ^ (*dest)) | 0xff000000;
4043 ++dest; ++src;
4044 }
4045}
4046
4047void QT_FASTCALL rasterop_solid_NotSource(uint *dest, int length,
4048 uint color, uint const_alpha)
4049{
4050 Q_UNUSED(const_alpha);
4051 qt_memfill(dest, ~color | 0xff000000, length);
4052}
4053
4054void QT_FASTCALL rasterop_NotSource(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src,
4055 int length, uint const_alpha)
4056{
4057 Q_UNUSED(const_alpha);
4058 while (length--)
4059 *dest++ = ~(*src++) | 0xff000000;
4060}
4061
4062void QT_FASTCALL rasterop_solid_NotSourceAndDestination(uint *dest,
4063 int length,
4064 uint color,
4065 uint const_alpha)
4066{
4067 Q_UNUSED(const_alpha);
4068 color = ~color | 0xff000000;
4069 while (length--) {
4070 *dest = color & *dest;
4071 ++dest;
4072 }
4073}
4074
4075void QT_FASTCALL rasterop_NotSourceAndDestination(uint *Q_DECL_RESTRICT dest,
4076 const uint *Q_DECL_RESTRICT src,
4077 int length,
4078 uint const_alpha)
4079{
4080 Q_UNUSED(const_alpha);
4081 while (length--) {
4082 *dest = (~(*src) & *dest) | 0xff000000;
4083 ++dest; ++src;
4084 }
4085}
4086
4087void QT_FASTCALL rasterop_solid_SourceAndNotDestination(uint *dest,
4088 int length,
4089 uint color,
4090 uint const_alpha)
4091{
4092 Q_UNUSED(const_alpha);
4093 while (length--) {
4094 *dest = (color & ~(*dest)) | 0xff000000;
4095 ++dest;
4096 }
4097}
4098
4099void QT_FASTCALL rasterop_SourceAndNotDestination(uint *Q_DECL_RESTRICT dest,
4100 const uint *Q_DECL_RESTRICT src,
4101 int length,
4102 uint const_alpha)
4103{
4104 Q_UNUSED(const_alpha);
4105 while (length--) {
4106 *dest = (*src & ~(*dest)) | 0xff000000;
4107 ++dest; ++src;
4108 }
4109}
4110
4111void QT_FASTCALL rasterop_NotSourceOrDestination(uint *Q_DECL_RESTRICT dest,
4112 const uint *Q_DECL_RESTRICT src,
4113 int length,
4114 uint const_alpha)
4115{
4116 Q_UNUSED(const_alpha);
4117 while (length--) {
4118 *dest = (~(*src) | *dest) | 0xff000000;
4119 ++dest; ++src;
4120 }
4121}
4122
4123void QT_FASTCALL rasterop_solid_NotSourceOrDestination(uint *Q_DECL_RESTRICT dest,
4124 int length,
4125 uint color,
4126 uint const_alpha)
4127{
4128 Q_UNUSED(const_alpha);
4129 color = ~color | 0xff000000;
4130 while (length--)
4131 *dest++ |= color;
4132}
4133
4134void QT_FASTCALL rasterop_SourceOrNotDestination(uint *Q_DECL_RESTRICT dest,
4135 const uint *Q_DECL_RESTRICT src,
4136 int length,
4137 uint const_alpha)
4138{
4139 Q_UNUSED(const_alpha);
4140 while (length--) {
4141 *dest = (*src | ~(*dest)) | 0xff000000;
4142 ++dest; ++src;
4143 }
4144}
4145
4146void QT_FASTCALL rasterop_solid_SourceOrNotDestination(uint *Q_DECL_RESTRICT dest,
4147 int length,
4148 uint color,
4149 uint const_alpha)
4150{
4151 Q_UNUSED(const_alpha);
4152 while (length--) {
4153 *dest = (color | ~(*dest)) | 0xff000000;
4154 ++dest;
4155 }
4156}
4157
4158void QT_FASTCALL rasterop_ClearDestination(uint *Q_DECL_RESTRICT dest,
4159 const uint *Q_DECL_RESTRICT src,
4160 int length,
4161 uint const_alpha)
4162{
4163 Q_UNUSED(src);
4164 comp_func_solid_SourceOver (dest, length, 0xff000000, const_alpha);
4165}
4166
4167void QT_FASTCALL rasterop_solid_ClearDestination(uint *Q_DECL_RESTRICT dest,
4168 int length,
4169 uint color,
4170 uint const_alpha)
4171{
4172 Q_UNUSED(color);
4173 comp_func_solid_SourceOver (dest, length, 0xff000000, const_alpha);
4174}
4175
4176void QT_FASTCALL rasterop_SetDestination(uint *Q_DECL_RESTRICT dest,
4177 const uint *Q_DECL_RESTRICT src,
4178 int length,
4179 uint const_alpha)
4180{
4181 Q_UNUSED(src);
4182 comp_func_solid_SourceOver (dest, length, 0xffffffff, const_alpha);
4183}
4184
4185void QT_FASTCALL rasterop_solid_SetDestination(uint *Q_DECL_RESTRICT dest,
4186 int length,
4187 uint color,
4188 uint const_alpha)
4189{
4190 Q_UNUSED(color);
4191 comp_func_solid_SourceOver (dest, length, 0xffffffff, const_alpha);
4192}
4193
4194void QT_FASTCALL rasterop_NotDestination(uint *Q_DECL_RESTRICT dest,
4195 const uint *Q_DECL_RESTRICT src,
4196 int length,
4197 uint const_alpha)
4198{
4199 Q_UNUSED(src);
4200 rasterop_solid_SourceXorDestination (dest, length, 0x00ffffff, const_alpha);
4201}
4202
4203void QT_FASTCALL rasterop_solid_NotDestination(uint *Q_DECL_RESTRICT dest,
4204 int length,
4205 uint color,
4206 uint const_alpha)
4207{
4208 Q_UNUSED(color);
4209 rasterop_solid_SourceXorDestination (dest, length, 0x00ffffff, const_alpha);
4210}
4211
4213 comp_func_solid_SourceOver,
4214 comp_func_solid_DestinationOver,
4215 comp_func_solid_Clear,
4216 comp_func_solid_Source,
4217 comp_func_solid_Destination,
4218 comp_func_solid_SourceIn,
4219 comp_func_solid_DestinationIn,
4220 comp_func_solid_SourceOut,
4221 comp_func_solid_DestinationOut,
4222 comp_func_solid_SourceAtop,
4223 comp_func_solid_DestinationAtop,
4224 comp_func_solid_XOR,
4225 comp_func_solid_Plus,
4226 comp_func_solid_Multiply,
4227 comp_func_solid_Screen,
4228 comp_func_solid_Overlay,
4229 comp_func_solid_Darken,
4230 comp_func_solid_Lighten,
4231 comp_func_solid_ColorDodge,
4232 comp_func_solid_ColorBurn,
4233 comp_func_solid_HardLight,
4234 comp_func_solid_SoftLight,
4235 comp_func_solid_Difference,
4236 comp_func_solid_Exclusion,
4237 rasterop_solid_SourceOrDestination,
4238 rasterop_solid_SourceAndDestination,
4239 rasterop_solid_SourceXorDestination,
4240 rasterop_solid_NotSourceAndNotDestination,
4241 rasterop_solid_NotSourceOrNotDestination,
4242 rasterop_solid_NotSourceXorDestination,
4243 rasterop_solid_NotSource,
4244 rasterop_solid_NotSourceAndDestination,
4245 rasterop_solid_SourceAndNotDestination,
4246 rasterop_solid_NotSourceOrDestination,
4247 rasterop_solid_SourceOrNotDestination,
4248 rasterop_solid_ClearDestination,
4249 rasterop_solid_SetDestination,
4250 rasterop_solid_NotDestination
4251};
4252
4253static_assert(std::size(qt_functionForModeSolid_C) == QPainter::NCompositionModes);
4254
4256#if QT_CONFIG(raster_64bit)
4257 comp_func_solid_SourceOver_rgb64,
4258 comp_func_solid_DestinationOver_rgb64,
4259 comp_func_solid_Clear_rgb64,
4260 comp_func_solid_Source_rgb64,
4261 comp_func_solid_Destination_rgb64,
4262 comp_func_solid_SourceIn_rgb64,
4263 comp_func_solid_DestinationIn_rgb64,
4264 comp_func_solid_SourceOut_rgb64,
4265 comp_func_solid_DestinationOut_rgb64,
4266 comp_func_solid_SourceAtop_rgb64,
4267 comp_func_solid_DestinationAtop_rgb64,
4268 comp_func_solid_XOR_rgb64,
4269 comp_func_solid_Plus_rgb64,
4270 comp_func_solid_Multiply_rgb64,
4271 comp_func_solid_Screen_rgb64,
4272 comp_func_solid_Overlay_rgb64,
4273 comp_func_solid_Darken_rgb64,
4274 comp_func_solid_Lighten_rgb64,
4275 comp_func_solid_ColorDodge_rgb64,
4276 comp_func_solid_ColorBurn_rgb64,
4277 comp_func_solid_HardLight_rgb64,
4278 comp_func_solid_SoftLight_rgb64,
4279 comp_func_solid_Difference_rgb64,
4280 comp_func_solid_Exclusion_rgb64,
4281#else
4282 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4283 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4284 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4285#endif
4286 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4287 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
4288};
4289
4290static_assert(std::size(qt_functionForModeSolid64_C) == QPainter::NCompositionModes);
4291
4293#if QT_CONFIG(raster_fp)
4294 comp_func_solid_SourceOver_rgbafp,
4295 comp_func_solid_DestinationOver_rgbafp,
4296 comp_func_solid_Clear_rgbafp,
4297 comp_func_solid_Source_rgbafp,
4298 comp_func_solid_Destination_rgbafp,
4299 comp_func_solid_SourceIn_rgbafp,
4300 comp_func_solid_DestinationIn_rgbafp,
4301 comp_func_solid_SourceOut_rgbafp,
4302 comp_func_solid_DestinationOut_rgbafp,
4303 comp_func_solid_SourceAtop_rgbafp,
4304 comp_func_solid_DestinationAtop_rgbafp,
4305 comp_func_solid_XOR_rgbafp,
4306 comp_func_solid_Plus_rgbafp,
4307 comp_func_solid_Multiply_rgbafp,
4308 comp_func_solid_Screen_rgbafp,
4309 comp_func_solid_Overlay_rgbafp,
4310 comp_func_solid_Darken_rgbafp,
4311 comp_func_solid_Lighten_rgbafp,
4312 comp_func_solid_ColorDodge_rgbafp,
4313 comp_func_solid_ColorBurn_rgbafp,
4314 comp_func_solid_HardLight_rgbafp,
4315 comp_func_solid_SoftLight_rgbafp,
4316 comp_func_solid_Difference_rgbafp,
4317 comp_func_solid_Exclusion_rgbafp,
4318#else
4319 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4320 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4321#endif
4322 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4323 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
4324};
4325
4326static_assert(std::size(qt_functionForModeSolidFP_C) == QPainter::NCompositionModes);
4327
4329 comp_func_SourceOver,
4330 comp_func_DestinationOver,
4331 comp_func_Clear,
4332 comp_func_Source,
4333 comp_func_Destination,
4334 comp_func_SourceIn,
4335 comp_func_DestinationIn,
4336 comp_func_SourceOut,
4337 comp_func_DestinationOut,
4338 comp_func_SourceAtop,
4339 comp_func_DestinationAtop,
4340 comp_func_XOR,
4341 comp_func_Plus,
4342 comp_func_Multiply,
4343 comp_func_Screen,
4344 comp_func_Overlay,
4345 comp_func_Darken,
4346 comp_func_Lighten,
4347 comp_func_ColorDodge,
4348 comp_func_ColorBurn,
4349 comp_func_HardLight,
4350 comp_func_SoftLight,
4351 comp_func_Difference,
4352 comp_func_Exclusion,
4353 rasterop_SourceOrDestination,
4354 rasterop_SourceAndDestination,
4355 rasterop_SourceXorDestination,
4356 rasterop_NotSourceAndNotDestination,
4357 rasterop_NotSourceOrNotDestination,
4358 rasterop_NotSourceXorDestination,
4359 rasterop_NotSource,
4360 rasterop_NotSourceAndDestination,
4361 rasterop_SourceAndNotDestination,
4362 rasterop_NotSourceOrDestination,
4363 rasterop_SourceOrNotDestination,
4364 rasterop_ClearDestination,
4365 rasterop_SetDestination,
4366 rasterop_NotDestination
4367};
4368
4369static_assert(std::size(qt_functionForMode_C) == QPainter::NCompositionModes);
4370
4372#if QT_CONFIG(raster_64bit)
4373 comp_func_SourceOver_rgb64,
4374 comp_func_DestinationOver_rgb64,
4375 comp_func_Clear_rgb64,
4376 comp_func_Source_rgb64,
4377 comp_func_Destination_rgb64,
4378 comp_func_SourceIn_rgb64,
4379 comp_func_DestinationIn_rgb64,
4380 comp_func_SourceOut_rgb64,
4381 comp_func_DestinationOut_rgb64,
4382 comp_func_SourceAtop_rgb64,
4383 comp_func_DestinationAtop_rgb64,
4384 comp_func_XOR_rgb64,
4385 comp_func_Plus_rgb64,
4386 comp_func_Multiply_rgb64,
4387 comp_func_Screen_rgb64,
4388 comp_func_Overlay_rgb64,
4389 comp_func_Darken_rgb64,
4390 comp_func_Lighten_rgb64,
4391 comp_func_ColorDodge_rgb64,
4392 comp_func_ColorBurn_rgb64,
4393 comp_func_HardLight_rgb64,
4394 comp_func_SoftLight_rgb64,
4395 comp_func_Difference_rgb64,
4396 comp_func_Exclusion_rgb64,
4397#else
4398 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4399 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4400 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4401#endif
4402 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4403 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
4404};
4405
4406static_assert(std::size(qt_functionForMode64_C) == QPainter::NCompositionModes);
4407
4409#if QT_CONFIG(raster_fp)
4410 comp_func_SourceOver_rgbafp,
4411 comp_func_DestinationOver_rgbafp,
4412 comp_func_Clear_rgbafp,
4413 comp_func_Source_rgbafp,
4414 comp_func_Destination_rgbafp,
4415 comp_func_SourceIn_rgbafp,
4416 comp_func_DestinationIn_rgbafp,
4417 comp_func_SourceOut_rgbafp,
4418 comp_func_DestinationOut_rgbafp,
4419 comp_func_SourceAtop_rgbafp,
4420 comp_func_DestinationAtop_rgbafp,
4421 comp_func_XOR_rgbafp,
4422 comp_func_Plus_rgbafp,
4423 comp_func_Multiply_rgbafp,
4424 comp_func_Screen_rgbafp,
4425 comp_func_Overlay_rgbafp,
4426 comp_func_Darken_rgbafp,
4427 comp_func_Lighten_rgbafp,
4428 comp_func_ColorDodge_rgbafp,
4429 comp_func_ColorBurn_rgbafp,
4430 comp_func_HardLight_rgbafp,
4431 comp_func_SoftLight_rgbafp,
4432 comp_func_Difference_rgbafp,
4433 comp_func_Exclusion_rgbafp,
4434#else
4435 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4436 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4437#endif
4438 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
4439 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
4440};
4441
4442static_assert(std::size(qt_functionForModeFP_C) == QPainter::NCompositionModes);
4443
4444QT_END_NAMESPACE
static void comp_func_solid_ColorBurn_impl(uint *dest, int length, uint color, const T &coverage)
#define OP(a, b)
static void comp_func_solid_ColorDodge_impl(uint *dest, int length, uint color, const T &coverage)
CompositionFunctionFP qt_functionForModeFP_C[]
static void comp_func_solid_Darken_impl(uint *dest, int length, uint color, const T &coverage)
CompositionFunction qt_functionForMode_C[]
static void comp_func_solid_SourceOut_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
static void comp_func_solid_Screen_impl(uint *dest, int length, uint color, const T &coverage)
static void comp_func_solid_SoftLight_impl(uint *dest, int length, uint color, const T &coverage)
static void comp_func_Difference_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static void comp_func_Plus_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
static uint hardlight_op(int dst, int src, int da, int sa)
static void comp_func_solid_XOR_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
static void comp_func_Clear_template(typename Ops::Type *dest, int length, uint const_alpha)
static void comp_func_SourceAtop_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
static void comp_func_Multiply_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static void comp_func_DestinationIn_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
static void comp_func_solid_Source_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
static int color_dodge_op(int dst, int src, int da, int sa)
static void comp_func_solid_HardLight_impl(uint *dest, int length, uint color, const T &coverage)
static void comp_func_solid_Overlay_impl(uint *dest, int length, uint color, const T &coverage)
static int overlay_op(int dst, int src, int da, int sa)
static void comp_func_DestinationOver_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
static void comp_func_solid_SourceIn_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
static void comp_func_solid_Plus_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
static void comp_func_solid_SourceOver_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
Argb32OperationsC Argb32Operations
static void comp_func_solid_Difference_impl(uint *dest, int length, uint color, const T &coverage)
static int multiply_op(int dst, int src, int da, int sa)
static void comp_func_DestinationAtop_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
static int soft_light_op(int dst, int src, int da, int sa)
static void comp_func_ColorBurn_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static void comp_func_solid_DestinationOver_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
static void comp_func_Source_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
static void comp_func_HardLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static int mix_alpha(int da, int sa)
static void comp_func_solid_DestinationOut_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
static void comp_func_SourceOver_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
static int difference_op(int dst, int src, int da, int sa)
static void comp_func_solid_SourceAtop_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
static int color_burn_op(int dst, int src, int da, int sa)
static void comp_func_SourceOut_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
CompositionFunctionSolidFP qt_functionForModeSolidFP_C[]
static void comp_func_Overlay_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static void comp_func_Lighten_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static void comp_func_solid_DestinationIn_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
static void comp_func_Darken_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static int lighten_op(int dst, int src, int da, int sa)
static void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static void comp_func_solid_DestinationAtop_template(typename Ops::Type *dest, int length, typename Ops::Type color, uint const_alpha)
CompositionFunction64 qt_functionForMode64_C[]
CompositionFunctionSolid qt_functionForModeSolid_C[]
static void comp_func_ColorDodge_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static void comp_func_solid_Multiply_impl(uint *dest, int length, uint color, const T &coverage)
static void comp_func_DestinationOut_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
static void comp_func_Exclusion_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static void comp_func_SoftLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage)
static void comp_func_XOR_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
static void comp_func_solid_Lighten_impl(uint *dest, int length, uint color, const T &coverage)
static int darken_op(int dst, int src, int da, int sa)
CompositionFunctionSolid64 qt_functionForModeSolid64_C[]
static void comp_func_SourceIn_template(typename Ops::Type *Q_DECL_RESTRICT dest, const typename Ops::Type *Q_DECL_RESTRICT src, int length, uint const_alpha)
uint QT_FASTCALL fetch1Pixel< QPixelLayout::BPP1LSB >(const uchar *src, int index)
#define Q_DECL_RESTRICT
static constexpr int qt_div_255(int x)
static OptimalType add(OptimalType a, OptimalType b)
static OptimalType interpolate(OptimalType x, OptimalScalar a1, OptimalType y, OptimalScalar a2)
static Scalar scalarFrom8bit(uint8_t a)
static bool isTransparent(Type val)
static void memfill(Type *ptr, Type value, qsizetype len)
static void store(Type *ptr, OptimalType value)
static void memcpy(Type *Q_DECL_RESTRICT dest, const Type *Q_DECL_RESTRICT src, qsizetype len)
static OptimalScalar invAlpha(OptimalScalar c)
static OptimalType convert(const Type &val)
static OptimalType plus(OptimalType a, OptimalType b)
static OptimalType interpolate8bit(OptimalType x, uint8_t a1, OptimalType y, uint8_t a2)
static OptimalScalar scalar(Scalar v)
static OptimalType multiplyAlpha8bit(OptimalType val, uint8_t a)
static OptimalType load(const Type *ptr)
static OptimalType multiplyAlpha(OptimalType val, OptimalScalar a)
static OptimalScalar alpha(OptimalType val)
static bool isOpaque(Type val)
void store(uint *dest, const uint src) const
void store_template(typename Op::Type *dest, const typename Op::Type src) const
void store(uint *dest, const uint src) const
QPartialCoverage(uint const_alpha)
static bool isOpaque(Type val)
static void memcpy(Type *Q_DECL_RESTRICT dest, const Type *Q_DECL_RESTRICT src, qsizetype len)
static void memfill(Type *ptr, Type value, qsizetype len)
static Scalar scalarFrom8bit(uint8_t a)
static bool isTransparent(Type val)