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