Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qdrawhelper_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QDRAWHELPER_P_H
5#define QDRAWHELPER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtGui/private/qtguiglobal_p.h>
19#include "QtCore/qmath.h"
20#include "QtGui/qcolor.h"
21#include "QtGui/qpainter.h"
22#include "QtGui/qimage.h"
23#include "QtGui/qrgba64.h"
24#ifndef QT_FT_BEGIN_HEADER
25#define QT_FT_BEGIN_HEADER
26#define QT_FT_END_HEADER
27#endif
28#include "private/qpixellayout_p.h"
29#include "private/qrasterdefs_p.h"
30#include <private/qsimd_p.h>
31
32#include <memory>
33
35
36#if defined(Q_CC_GNU)
37# define Q_DECL_RESTRICT __restrict__
38# if defined(Q_PROCESSOR_X86_32) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
39# define Q_DECL_VECTORCALL __attribute__((sseregparm,regparm(3)))
40# else
41# define Q_DECL_VECTORCALL
42# endif
43#elif defined(Q_CC_MSVC)
44# define Q_DECL_RESTRICT __restrict
45# define Q_DECL_VECTORCALL __vectorcall
46#else
47# define Q_DECL_RESTRICT
48# define Q_DECL_VECTORCALL
49#endif
50
51static const uint AMASK = 0xff000000;
52static const uint RMASK = 0x00ff0000;
53static const uint GMASK = 0x0000ff00;
54static const uint BMASK = 0x000000ff;
55
56struct QSolidData;
57struct QTextureData;
58struct QGradientData;
62struct QSpanData;
63class QGradient;
64class QRasterBuffer;
65class QClipData;
67
68template<typename F> class QRgbaFloat;
70
72typedef void (*BitmapBlitFunc)(QRasterBuffer *rasterBuffer,
73 int x, int y, const QRgba64 &color,
74 const uchar *bitmap,
75 int mapWidth, int mapHeight, int mapStride);
76
77typedef void (*AlphamapBlitFunc)(QRasterBuffer *rasterBuffer,
78 int x, int y, const QRgba64 &color,
79 const uchar *bitmap,
80 int mapWidth, int mapHeight, int mapStride,
81 const QClipData *clip, bool useGammaCorrection);
82
83typedef void (*AlphaRGBBlitFunc)(QRasterBuffer *rasterBuffer,
84 int x, int y, const QRgba64 &color,
85 const uint *rgbmask,
86 int mapWidth, int mapHeight, int mapStride,
87 const QClipData *clip, bool useGammaCorrection);
88
89typedef void (*RectFillFunc)(QRasterBuffer *rasterBuffer,
90 int x, int y, int width, int height,
91 const QRgba64 &color);
92
93typedef void (*SrcOverBlendFunc)(uchar *destPixels, int dbpl,
94 const uchar *src, int spbl,
95 int w, int h,
96 int const_alpha);
97
98typedef void (*SrcOverScaleFunc)(uchar *destPixels, int dbpl,
99 const uchar *src, int spbl, int srch,
100 const QRectF &targetRect,
101 const QRectF &sourceRect,
102 const QRect &clipRect,
103 int const_alpha);
104
105typedef void (*SrcOverTransformFunc)(uchar *destPixels, int dbpl,
106 const uchar *src, int spbl,
107 const QRectF &targetRect,
108 const QRectF &sourceRect,
109 const QRect &clipRect,
110 const QTransform &targetRectTransform,
111 int const_alpha);
112
119};
120
124
126
127struct quint24 {
128 quint24() = default;
130 {
131 data[0] = uchar(value >> 16);
132 data[1] = uchar(value >> 8);
133 data[2] = uchar(value);
134 }
135 operator uint() const
136 {
137 return data[2] | (data[1] << 8) | (data[0] << 16);
138 }
139
141};
142
143void qBlendGradient(int count, const QT_FT_Span *spans, void *userData);
144void qBlendTexture(int count, const QT_FT_Span *spans, void *userData);
145#ifdef Q_PROCESSOR_X86
148#else
149extern void qt_memfill64(quint64 *dest, quint64 value, qsizetype count);
150extern void qt_memfill32(quint32 *dest, quint32 value, qsizetype count);
151#endif
152extern void qt_memfill24(quint24 *dest, quint24 value, qsizetype count);
153extern void qt_memfill16(quint16 *dest, quint16 value, qsizetype count);
154
158typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha);
161
163{
168};
169
171{
179};
180
181struct Operator;
182typedef uint* (QT_FASTCALL *DestFetchProc)(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length);
183typedef QRgba64* (QT_FASTCALL *DestFetchProc64)(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length);
185typedef void (QT_FASTCALL *DestStoreProc)(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length);
186typedef void (QT_FASTCALL *DestStoreProc64)(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length);
187typedef void (QT_FASTCALL *DestStoreProcFP)(QRasterBuffer *rasterBuffer, int x, int y, const QRgbaFloat32 *buffer, int length);
188typedef const uint* (QT_FASTCALL *SourceFetchProc)(uint *buffer, const Operator *o, const QSpanData *data, int y, int x, int length);
189typedef const QRgba64* (QT_FASTCALL *SourceFetchProc64)(QRgba64 *buffer, const Operator *o, const QSpanData *data, int y, int x, int length);
190typedef const QRgbaFloat32* (QT_FASTCALL *SourceFetchProcFP)(QRgbaFloat32 *buffer, const Operator *o, const QSpanData *data, int y, int x, int length);
191
193{
200
206
212
213 union {
216 };
217};
218
220
222{
223 struct {
227 struct {
228 qreal x;
229 qreal y;
231};
232
234{
235 struct {
240 struct {
241 qreal x;
242 qreal y;
245};
246
248{
249 struct {
254};
255
257{
259
260 union {
264 };
265
266#define GRADIENT_STOPTABLE_SIZE 1024
267#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
268
269#if QT_CONFIG(raster_64bit) || QT_CONFIG(raster_fp)
270 const QRgba64 *colorTable64; //[GRADIENT_STOPTABLE_SIZE];
271#endif
272 const QRgb *colorTable32; //[GRADIENT_STOPTABLE_SIZE];
273
275};
276
278{
280 const uchar *scanLine(int y) const { return imageData + y*bytesPerLine; }
281
282 int width;
284 // clip rect
285 int x1;
286 int y1;
287 int x2;
288 int y2;
293 enum Type {
296 Pattern
297 };
300};
301
303{
305 ~QSpanData() { delete tempImage; }
306
314 qreal m11, m12, m13, m21, m22, m23, m33, dx, dy; // inverse xform matrix
316 enum Type {
322 Texture
323 } type : 8;
324 signed int txop : 8;
329 union {
332 };
333 std::shared_ptr<const void> cachedGradient;
334
335
336 void init(QRasterBuffer *rb, const QRasterPaintEngine *pe);
337 void setup(const QBrush &brush, int alpha, QPainter::CompositionMode compositionMode, bool isCosmetic);
338 void setupMatrix(const QTransform &matrix, int bilinear);
339 void initTexture(const QImage *image, int alpha, QTextureData::Type = QTextureData::Plain, const QRect &sourceRect = QRect());
340 void adjustSpanMethods();
341};
342
343static inline uint qt_gradient_clamp(const QGradientData *data, int ipos)
344{
345 if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) {
346 if (data->spread == QGradient::RepeatSpread) {
347 ipos = ipos % GRADIENT_STOPTABLE_SIZE;
348 ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos;
349 } else if (data->spread == QGradient::ReflectSpread) {
350 const int limit = GRADIENT_STOPTABLE_SIZE * 2;
351 ipos = ipos % limit;
352 ipos = ipos < 0 ? limit + ipos : ipos;
353 ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - 1 - ipos : ipos;
354 } else {
355 if (ipos < 0)
356 ipos = 0;
357 else if (ipos >= GRADIENT_STOPTABLE_SIZE)
359 }
360 }
361
362 Q_ASSERT(ipos >= 0);
364
365 return ipos;
366}
367
369{
370 int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
371 return data->colorTable32[qt_gradient_clamp(data, ipos)];
372}
373
374#if QT_CONFIG(raster_64bit)
375static inline const QRgba64& qt_gradient_pixel64(const QGradientData *data, qreal pos)
376{
377 int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
378 return data->colorTable64[qt_gradient_clamp(data, ipos)];
379}
380#endif
381
383{
384 return (b * b) - (4 * a * c);
385}
386
387template <class RadialFetchFunc, typename BlendType> static
388const BlendType * QT_FASTCALL qt_fetch_radial_gradient_template(BlendType *buffer, const Operator *op,
389 const QSpanData *data, int y, int x, int length)
390{
391 // avoid division by zero
392 if (qFuzzyIsNull(op->radial.a)) {
393 RadialFetchFunc::memfill(buffer, RadialFetchFunc::null(), length);
394 return buffer;
395 }
396
397 const BlendType *b = buffer;
398 qreal rx = data->m21 * (y + qreal(0.5))
399 + data->dx + data->m11 * (x + qreal(0.5));
400 qreal ry = data->m22 * (y + qreal(0.5))
401 + data->dy + data->m12 * (x + qreal(0.5));
402 bool affine = !data->m13 && !data->m23;
403
404 BlendType *end = buffer + length;
405 if (affine) {
406 rx -= data->gradient.radial.focal.x;
407 ry -= data->gradient.radial.focal.y;
408
409 qreal inv_a = 1 / qreal(2 * op->radial.a);
410
411 const qreal delta_rx = data->m11;
412 const qreal delta_ry = data->m12;
413
414 qreal b = 2*(op->radial.dr*data->gradient.radial.focal.radius + rx * op->radial.dx + ry * op->radial.dy);
415 qreal delta_b = 2*(delta_rx * op->radial.dx + delta_ry * op->radial.dy);
416 const qreal b_delta_b = 2 * b * delta_b;
417 const qreal delta_b_delta_b = 2 * delta_b * delta_b;
418
419 const qreal bb = b * b;
420 const qreal delta_bb = delta_b * delta_b;
421
422 b *= inv_a;
423 delta_b *= inv_a;
424
425 const qreal rxrxryry = rx * rx + ry * ry;
426 const qreal delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry;
427 const qreal rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry);
428 const qreal delta_rx_plus_ry = 2 * delta_rxrxryry;
429
430 inv_a *= inv_a;
431
432 qreal det = (bb - 4 * op->radial.a * (op->radial.sqrfr - rxrxryry)) * inv_a;
433 qreal delta_det = (b_delta_b + delta_bb + 4 * op->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a;
434 const qreal delta_delta_det = (delta_b_delta_b + 4 * op->radial.a * delta_rx_plus_ry) * inv_a;
435
436 RadialFetchFunc::fetch(buffer, end, op, data, det, delta_det, delta_delta_det, b, delta_b);
437 } else {
438 qreal rw = data->m23 * (y + qreal(0.5))
439 + data->m33 + data->m13 * (x + qreal(0.5));
440
441 while (buffer < end) {
442 if (rw == 0) {
443 *buffer = RadialFetchFunc::null();
444 } else {
445 qreal invRw = 1 / rw;
446 qreal gx = rx * invRw - data->gradient.radial.focal.x;
447 qreal gy = ry * invRw - data->gradient.radial.focal.y;
448 qreal b = 2*(op->radial.dr*data->gradient.radial.focal.radius + gx*op->radial.dx + gy*op->radial.dy);
449 qreal det = qRadialDeterminant(op->radial.a, b, op->radial.sqrfr - (gx*gx + gy*gy));
450
451 BlendType result = RadialFetchFunc::null();
452 if (det >= 0) {
453 qreal detSqrt = qSqrt(det);
454
455 qreal s0 = (-b - detSqrt) * op->radial.inv2a;
456 qreal s1 = (-b + detSqrt) * op->radial.inv2a;
457
458 qreal s = qMax(s0, s1);
459
460 if (data->gradient.radial.focal.radius + op->radial.dr * s >= 0)
461 result = RadialFetchFunc::fetchSingle(data->gradient, s);
462 }
463
464 *buffer = result;
465 }
466
467 rx += data->m11;
468 ry += data->m12;
469 rw += data->m13;
470
471 ++buffer;
472 }
473 }
474
475 return b;
476}
477
478template <class Simd>
480{
481public:
482 static uint null() { return 0; }
483 static uint fetchSingle(const QGradientData& gradient, qreal v)
484 {
485 return qt_gradient_pixel(&gradient, v);
486 }
487 static void memfill(uint *buffer, uint fill, int length)
488 {
490 }
491 static void fetch(uint *buffer, uint *end, const Operator *op, const QSpanData *data, qreal det,
492 qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
493 {
494 typename Simd::Vect_buffer_f det_vec;
495 typename Simd::Vect_buffer_f delta_det4_vec;
496 typename Simd::Vect_buffer_f b_vec;
497
498 for (int i = 0; i < 4; ++i) {
499 det_vec.f[i] = det;
500 delta_det4_vec.f[i] = 4 * delta_det;
501 b_vec.f[i] = b;
502
503 det += delta_det;
504 delta_det += delta_delta_det;
505 b += delta_b;
506 }
507
508 const typename Simd::Float32x4 v_delta_delta_det16 = Simd::v_dup(16 * delta_delta_det);
509 const typename Simd::Float32x4 v_delta_delta_det6 = Simd::v_dup(6 * delta_delta_det);
510 const typename Simd::Float32x4 v_delta_b4 = Simd::v_dup(4 * delta_b);
511
512 const typename Simd::Float32x4 v_r0 = Simd::v_dup(data->gradient.radial.focal.radius);
513 const typename Simd::Float32x4 v_dr = Simd::v_dup(op->radial.dr);
514
515#if defined(__ARM_NEON__)
516 // NEON doesn't have SIMD sqrt, but uses rsqrt instead that can't be taken of 0.
517 const typename Simd::Float32x4 v_min = Simd::v_dup(std::numeric_limits<float>::epsilon());
518#else
519 const typename Simd::Float32x4 v_min = Simd::v_dup(0.0f);
520#endif
521 const typename Simd::Float32x4 v_max = Simd::v_dup(float(GRADIENT_STOPTABLE_SIZE-1));
522 const typename Simd::Float32x4 v_half = Simd::v_dup(0.5f);
523
524 const typename Simd::Int32x4 v_repeat_mask = Simd::v_dup(~(uint(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT));
525 const typename Simd::Int32x4 v_reflect_mask = Simd::v_dup(~(uint(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1)));
526
527 const typename Simd::Int32x4 v_reflect_limit = Simd::v_dup(2 * GRADIENT_STOPTABLE_SIZE - 1);
528
529 const int extended_mask = op->radial.extended ? 0x0 : ~0x0;
530
531#define FETCH_RADIAL_LOOP_PROLOGUE \
532 while (buffer < end) { \
533 typename Simd::Vect_buffer_i v_buffer_mask; \
534 v_buffer_mask.v = Simd::v_greaterOrEqual(det_vec.v, v_min); \
535 const typename Simd::Float32x4 v_index_local = Simd::v_sub(Simd::v_sqrt(Simd::v_max(v_min, det_vec.v)), b_vec.v); \
536 const typename Simd::Float32x4 v_index = Simd::v_add(Simd::v_mul(v_index_local, v_max), v_half); \
537 v_buffer_mask.v = Simd::v_and(v_buffer_mask.v, Simd::v_greaterOrEqual(Simd::v_add(v_r0, Simd::v_mul(v_dr, v_index_local)), v_min)); \
538 typename Simd::Vect_buffer_i index_vec;
539#define FETCH_RADIAL_LOOP_CLAMP_REPEAT \
540 index_vec.v = Simd::v_and(v_repeat_mask, Simd::v_toInt(v_index));
541#define FETCH_RADIAL_LOOP_CLAMP_REFLECT \
542 const typename Simd::Int32x4 v_index_i = Simd::v_and(v_reflect_mask, Simd::v_toInt(v_index)); \
543 const typename Simd::Int32x4 v_index_i_inv = Simd::v_sub(v_reflect_limit, v_index_i); \
544 index_vec.v = Simd::v_min_16(v_index_i, v_index_i_inv);
545#define FETCH_RADIAL_LOOP_CLAMP_PAD \
546 index_vec.v = Simd::v_toInt(Simd::v_min(v_max, Simd::v_max(v_min, v_index)));
547#define FETCH_RADIAL_LOOP_EPILOGUE \
548 det_vec.v = Simd::v_add(Simd::v_add(det_vec.v, delta_det4_vec.v), v_delta_delta_det6); \
549 delta_det4_vec.v = Simd::v_add(delta_det4_vec.v, v_delta_delta_det16); \
550 b_vec.v = Simd::v_add(b_vec.v, v_delta_b4); \
551 for (int i = 0; i < 4; ++i) \
552 *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable32[index_vec.i[i]]; \
553 }
554
555#define FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP) \
556 FETCH_RADIAL_LOOP_PROLOGUE \
557 FETCH_RADIAL_LOOP_CLAMP \
558 FETCH_RADIAL_LOOP_EPILOGUE
559
560 switch (data->gradient.spread) {
563 break;
566 break;
569 break;
570 default:
571 Q_UNREACHABLE();
572 }
573 }
574};
575
577 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
578 t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
579 t &= 0xff00ff;
580
581 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
582 x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
583 x &= 0xff00ff00;
584 x |= t;
585 return x;
586}
587
588#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit versions
589
590static inline uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
591 quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
592 t += (((quint64(y)) | ((quint64(y)) << 24)) & 0x00ff00ff00ff00ff) * b;
593 t >>= 8;
594 t &= 0x00ff00ff00ff00ff;
595 return (uint(t)) | (uint(t >> 24));
596}
597
598static inline uint BYTE_MUL(uint x, uint a) {
599 quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
600 t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8;
601 t &= 0x00ff00ff00ff00ff;
602 return (uint(t)) | (uint(t >> 24));
603}
604
605#else // 32-bit versions
606
608 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
609 t >>= 8;
610 t &= 0xff00ff;
611
612 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
613 x &= 0xff00ff00;
614 x |= t;
615 return x;
616}
617
618static inline uint BYTE_MUL(uint x, uint a) {
619 uint t = (x & 0xff00ff) * a;
620 t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
621 t &= 0xff00ff;
622
623 x = ((x >> 8) & 0xff00ff) * a;
624 x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
625 x &= 0xff00ff00;
626 x |= t;
627 return x;
628}
629#endif
630
631static inline void blend_pixel(quint32 &dst, const quint32 src)
632{
633 if (src >= 0xff000000)
634 dst = src;
635 else if (src != 0)
636 dst = src + BYTE_MUL(dst, qAlpha(~src));
637}
638
639static inline void blend_pixel(quint32 &dst, const quint32 src, const int const_alpha)
640{
641 if (const_alpha == 255)
642 return blend_pixel(dst, src);
643 if (src != 0) {
644 const quint32 s = BYTE_MUL(src, const_alpha);
645 dst = s + BYTE_MUL(dst, qAlpha(~s));
646 }
647}
648
649#if defined(__SSE2__)
650static inline uint Q_DECL_VECTORCALL interpolate_4_pixels_sse2(__m128i vt, __m128i vb, uint distx, uint disty)
651{
652 // First interpolate top and bottom pixels in parallel.
653 vt = _mm_unpacklo_epi8(vt, _mm_setzero_si128());
654 vb = _mm_unpacklo_epi8(vb, _mm_setzero_si128());
655 vt = _mm_mullo_epi16(vt, _mm_set1_epi16(256 - disty));
656 vb = _mm_mullo_epi16(vb, _mm_set1_epi16(disty));
657 __m128i vlr = _mm_add_epi16(vt, vb);
658 vlr = _mm_srli_epi16(vlr, 8);
659 // vlr now contains the result of the first two interpolate calls vlr = unpacked((xright << 64) | xleft)
660
661 // Now the last interpolate between left and right..
662 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(256 - distx), _MM_SHUFFLE(0, 0, 0, 0));
663 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
664 const __m128i vmulx = _mm_unpacklo_epi16(vidistx, vdistx);
665 vlr = _mm_unpacklo_epi16(vlr, _mm_srli_si128(vlr, 8));
666 // vlr now contains the colors of left and right interleaved { la, ra, lr, rr, lg, rg, lb, rb }
667 vlr = _mm_madd_epi16(vlr, vmulx); // Multiply and horizontal add.
668 vlr = _mm_srli_epi32(vlr, 8);
669 vlr = _mm_packs_epi32(vlr, vlr);
670 vlr = _mm_packus_epi16(vlr, vlr);
671 return _mm_cvtsi128_si32(vlr);
672}
673
674static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
675{
676 __m128i vt = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tl), _mm_cvtsi32_si128(tr));
677 __m128i vb = _mm_unpacklo_epi32(_mm_cvtsi32_si128(bl), _mm_cvtsi32_si128(br));
678 return interpolate_4_pixels_sse2(vt, vb, distx, disty);
679}
680
681static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint distx, uint disty)
682{
683 __m128i vt = _mm_loadl_epi64((const __m128i*)t);
684 __m128i vb = _mm_loadl_epi64((const __m128i*)b);
685 return interpolate_4_pixels_sse2(vt, vb, distx, disty);
686}
687
688static constexpr inline bool hasFastInterpolate4() { return true; }
689
690#elif defined(__ARM_NEON__)
691static inline uint interpolate_4_pixels_neon(uint32x2_t vt32, uint32x2_t vb32, uint distx, uint disty)
692{
693 uint16x8_t vt16 = vmovl_u8(vreinterpret_u8_u32(vt32));
694 uint16x8_t vb16 = vmovl_u8(vreinterpret_u8_u32(vb32));
695 vt16 = vmulq_n_u16(vt16, 256 - disty);
696 vt16 = vmlaq_n_u16(vt16, vb16, disty);
697 vt16 = vshrq_n_u16(vt16, 8);
698 uint16x4_t vl16 = vget_low_u16(vt16);
699 uint16x4_t vr16 = vget_high_u16(vt16);
700 vl16 = vmul_n_u16(vl16, 256 - distx);
701 vl16 = vmla_n_u16(vl16, vr16, distx);
702 vl16 = vshr_n_u16(vl16, 8);
703 uint8x8_t vr = vmovn_u16(vcombine_u16(vl16, vl16));
704 return vget_lane_u32(vreinterpret_u32_u8(vr), 0);
705}
706
707static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
708{
709 uint32x2_t vt32 = vmov_n_u32(tl);
710 uint32x2_t vb32 = vmov_n_u32(bl);
711 vt32 = vset_lane_u32(tr, vt32, 1);
712 vb32 = vset_lane_u32(br, vb32, 1);
713 return interpolate_4_pixels_neon(vt32, vb32, distx, disty);
714}
715
716static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint distx, uint disty)
717{
718 uint32x2_t vt32 = vld1_u32(t);
719 uint32x2_t vb32 = vld1_u32(b);
720 return interpolate_4_pixels_neon(vt32, vb32, distx, disty);
721}
722
723static constexpr inline bool hasFastInterpolate4() { return true; }
724
725#else
726static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
727{
728 uint idistx = 256 - distx;
729 uint idisty = 256 - disty;
730 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
731 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
732 return INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
733}
734
735static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint distx, uint disty)
736{
737 return interpolate_4_pixels(t[0], t[1], b[0], b[1], distx, disty);
738}
739
740static constexpr inline bool hasFastInterpolate4() { return false; }
741
742#endif
743
744static inline QRgba64 multiplyAlpha256(QRgba64 rgba64, uint alpha256)
745{
746 return QRgba64::fromRgba64((rgba64.red() * alpha256) >> 8,
747 (rgba64.green() * alpha256) >> 8,
748 (rgba64.blue() * alpha256) >> 8,
749 (rgba64.alpha() * alpha256) >> 8);
750}
751static inline QRgba64 interpolate256(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
752{
753 return QRgba64::fromRgba64(multiplyAlpha256(x, alpha1) + multiplyAlpha256(y, alpha2));
754}
755
756#ifdef __SSE2__
757static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
758{
759 __m128i vt = _mm_loadu_si128((const __m128i*)t);
760 if (disty) {
761 __m128i vb = _mm_loadu_si128((const __m128i*)b);
762 vt = _mm_mulhi_epu16(vt, _mm_set1_epi16(0x10000 - disty));
763 vb = _mm_mulhi_epu16(vb, _mm_set1_epi16(disty));
764 vt = _mm_add_epi16(vt, vb);
765 }
766 if (distx) {
767 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
768 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
769 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
770 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
771 }
772#ifdef Q_PROCESSOR_X86_64
773 return QRgba64::fromRgba64(_mm_cvtsi128_si64(vt));
774#else
775 QRgba64 out;
776 _mm_storel_epi64((__m128i*)&out, vt);
777 return out;
778#endif // Q_PROCESSOR_X86_64
779}
780#elif defined(__ARM_NEON__)
781static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
782{
783 uint64x1x2_t vt = vld2_u64(reinterpret_cast<const uint64_t *>(t));
784 if (disty) {
785 uint64x1x2_t vb = vld2_u64(reinterpret_cast<const uint64_t *>(b));
786 uint32x4_t vt0 = vmull_n_u16(vreinterpret_u16_u64(vt.val[0]), 0x10000 - disty);
787 uint32x4_t vt1 = vmull_n_u16(vreinterpret_u16_u64(vt.val[1]), 0x10000 - disty);
788 vt0 = vmlal_n_u16(vt0, vreinterpret_u16_u64(vb.val[0]), disty);
789 vt1 = vmlal_n_u16(vt1, vreinterpret_u16_u64(vb.val[1]), disty);
790 vt.val[0] = vreinterpret_u64_u16(vshrn_n_u32(vt0, 16));
791 vt.val[1] = vreinterpret_u64_u16(vshrn_n_u32(vt1, 16));
792 }
793 if (distx) {
794 uint32x4_t vt0 = vmull_n_u16(vreinterpret_u16_u64(vt.val[0]), 0x10000 - distx);
795 vt0 = vmlal_n_u16(vt0, vreinterpret_u16_u64(vt.val[1]), distx);
796 vt.val[0] = vreinterpret_u64_u16(vshrn_n_u32(vt0, 16));
797 }
798 QRgba64 out;
799 vst1_u64(reinterpret_cast<uint64_t *>(&out), vt.val[0]);
800 return out;
801}
802#else
803static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
804{
805 const uint dx = distx>>8;
806 const uint dy = disty>>8;
807 const uint idx = 256 - dx;
808 const uint idy = 256 - dy;
809 QRgba64 xtop = interpolate256(t[0], idx, t[1], dx);
810 QRgba64 xbot = interpolate256(b[0], idx, b[1], dx);
811 return interpolate256(xtop, idy, xbot, dy);
812}
813#endif // __SSE2__
814
815#if QT_CONFIG(raster_fp)
816static inline QRgbaFloat32 multiplyAlpha_rgba32f(QRgbaFloat32 c, float a)
817{
818 return QRgbaFloat32 { c.r * a, c.g * a, c.b * a, c.a * a };
819}
820
821static inline QRgbaFloat32 interpolate_rgba32f(QRgbaFloat32 x, float alpha1, QRgbaFloat32 y, float alpha2)
822{
823 x = multiplyAlpha_rgba32f(x, alpha1);
824 y = multiplyAlpha_rgba32f(y, alpha2);
825 return QRgbaFloat32 { x.r + y.r, x.g + y.g, x.b + y.b, x.a + y.a };
826}
827#ifdef __SSE2__
828static inline __m128 Q_DECL_VECTORCALL interpolate_rgba32f(__m128 x, __m128 alpha1, __m128 y, __m128 alpha2)
829{
830 return _mm_add_ps(_mm_mul_ps(x, alpha1), _mm_mul_ps(y, alpha2));
831}
832#endif
833
834static inline QRgbaFloat32 interpolate_4_pixels_rgba32f(const QRgbaFloat32 t[], const QRgbaFloat32 b[], uint distx, uint disty)
835{
836 constexpr float f = 1.0f / 65536.0f;
837 const float dx = distx * f;
838 const float dy = disty * f;
839 const float idx = 1.0f - dx;
840 const float idy = 1.0f - dy;
841#ifdef __SSE2__
842 const __m128 vtl = _mm_load_ps((const float *)&t[0]);
843 const __m128 vtr = _mm_load_ps((const float *)&t[1]);
844 const __m128 vbl = _mm_load_ps((const float *)&b[0]);
845 const __m128 vbr = _mm_load_ps((const float *)&b[1]);
846
847 const __m128 vdx = _mm_set1_ps(dx);
848 const __m128 vidx = _mm_set1_ps(idx);
849 __m128 vt = interpolate_rgba32f(vtl, vidx, vtr, vdx);
850 __m128 vb = interpolate_rgba32f(vbl, vidx, vbr, vdx);
851 const __m128 vdy = _mm_set1_ps(dy);
852 const __m128 vidy = _mm_set1_ps(idy);
853 vt = interpolate_rgba32f(vt, vidy, vb, vdy);
855 _mm_store_ps((float*)&res, vt);
856 return res;
857#else
858 QRgbaFloat32 xtop = interpolate_rgba32f(t[0], idx, t[1], dx);
859 QRgbaFloat32 xbot = interpolate_rgba32f(b[0], idx, b[1], dx);
860 xtop = interpolate_rgba32f(xtop, idy, xbot, dy);
861 return xtop;
862#endif
863}
864#endif // QT_CONFIG(raster_fp)
865
866static inline uint BYTE_MUL_RGB16(uint x, uint a) {
867 a += 1;
868 uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0;
869 t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f;
870 return t;
871}
872
874 uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0;
875 t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f;
876 return t;
877}
878
879// qt_div_255 is a fast rounded division by 255 using an approximation that is accurate for all positive 16-bit integers
880static constexpr inline int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
881static constexpr inline uint qt_div_257_floor(uint x) { return (x - (x >> 8)) >> 8; }
882static constexpr inline uint qt_div_257(uint x) { return qt_div_257_floor(x + 128); }
883static constexpr inline uint qt_div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
884
885template <class T> inline void qt_memfill_template(T *dest, T color, qsizetype count)
886{
887 if (!count)
888 return;
889
890 qsizetype n = (count + 7) / 8;
891 switch (count & 0x07)
892 {
893 case 0: do { *dest++ = color; Q_FALLTHROUGH();
894 case 7: *dest++ = color; Q_FALLTHROUGH();
895 case 6: *dest++ = color; Q_FALLTHROUGH();
896 case 5: *dest++ = color; Q_FALLTHROUGH();
897 case 4: *dest++ = color; Q_FALLTHROUGH();
898 case 3: *dest++ = color; Q_FALLTHROUGH();
899 case 2: *dest++ = color; Q_FALLTHROUGH();
900 case 1: *dest++ = color;
901 } while (--n > 0);
902 }
903}
904
905template <class T> inline void qt_memfill(T *dest, T value, qsizetype count)
906{
908}
909
910template<> inline void qt_memfill(quint64 *dest, quint64 color, qsizetype count)
911{
912 qt_memfill64(dest, color, count);
913}
914
915template<> inline void qt_memfill(quint32 *dest, quint32 color, qsizetype count)
916{
917 qt_memfill32(dest, color, count);
918}
919
920template<> inline void qt_memfill(quint24 *dest, quint24 color, qsizetype count)
921{
922 qt_memfill24(dest, color, count);
923}
924
925template<> inline void qt_memfill(quint16 *dest, quint16 color, qsizetype count)
926{
927 qt_memfill16(dest, color, count);
928}
929
930template<> inline void qt_memfill(quint8 *dest, quint8 color, qsizetype count)
931{
932 memset(dest, color, count);
933}
934
935template <class T> static
936inline void qt_rectfill(T *dest, T value,
937 int x, int y, int width, int height, qsizetype stride)
938{
939 char *d = reinterpret_cast<char*>(dest + x) + y * stride;
940 if (uint(stride) == (width * sizeof(T))) {
941 qt_memfill(reinterpret_cast<T*>(d), value, qsizetype(width) * height);
942 } else {
943 for (int j = 0; j < height; ++j) {
944 dest = reinterpret_cast<T*>(d);
945 qt_memfill(dest, value, width);
946 d += stride;
947 }
948 }
949}
950
952{
953 return (((c) >> 3) & 0x001f)
954 | (((c) >> 5) & 0x07e0)
955 | (((c) >> 8) & 0xf800);
956}
957
959{
960 return 0xff000000
961 | ((((c) << 3) & 0xf8) | (((c) >> 2) & 0x7))
962 | ((((c) << 5) & 0xfc00) | (((c) >> 1) & 0x300))
963 | ((((c) << 8) & 0xf80000) | (((c) << 3) & 0x70000));
964}
965
966const uint qt_bayer_matrix[16][16] = {
967 { 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc,
968 0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff},
969 { 0x80, 0x40, 0xb0, 0x70, 0x8c, 0x4c, 0xbc, 0x7c,
970 0x83, 0x43, 0xb3, 0x73, 0x8f, 0x4f, 0xbf, 0x7f},
971 { 0x20, 0xe0, 0x10, 0xd0, 0x2c, 0xec, 0x1c, 0xdc,
972 0x23, 0xe3, 0x13, 0xd3, 0x2f, 0xef, 0x1f, 0xdf},
973 { 0xa0, 0x60, 0x90, 0x50, 0xac, 0x6c, 0x9c, 0x5c,
974 0xa3, 0x63, 0x93, 0x53, 0xaf, 0x6f, 0x9f, 0x5f},
975 { 0x8, 0xc8, 0x38, 0xf8, 0x4, 0xc4, 0x34, 0xf4,
976 0xb, 0xcb, 0x3b, 0xfb, 0x7, 0xc7, 0x37, 0xf7},
977 { 0x88, 0x48, 0xb8, 0x78, 0x84, 0x44, 0xb4, 0x74,
978 0x8b, 0x4b, 0xbb, 0x7b, 0x87, 0x47, 0xb7, 0x77},
979 { 0x28, 0xe8, 0x18, 0xd8, 0x24, 0xe4, 0x14, 0xd4,
980 0x2b, 0xeb, 0x1b, 0xdb, 0x27, 0xe7, 0x17, 0xd7},
981 { 0xa8, 0x68, 0x98, 0x58, 0xa4, 0x64, 0x94, 0x54,
982 0xab, 0x6b, 0x9b, 0x5b, 0xa7, 0x67, 0x97, 0x57},
983 { 0x2, 0xc2, 0x32, 0xf2, 0xe, 0xce, 0x3e, 0xfe,
984 0x1, 0xc1, 0x31, 0xf1, 0xd, 0xcd, 0x3d, 0xfd},
985 { 0x82, 0x42, 0xb2, 0x72, 0x8e, 0x4e, 0xbe, 0x7e,
986 0x81, 0x41, 0xb1, 0x71, 0x8d, 0x4d, 0xbd, 0x7d},
987 { 0x22, 0xe2, 0x12, 0xd2, 0x2e, 0xee, 0x1e, 0xde,
988 0x21, 0xe1, 0x11, 0xd1, 0x2d, 0xed, 0x1d, 0xdd},
989 { 0xa2, 0x62, 0x92, 0x52, 0xae, 0x6e, 0x9e, 0x5e,
990 0xa1, 0x61, 0x91, 0x51, 0xad, 0x6d, 0x9d, 0x5d},
991 { 0xa, 0xca, 0x3a, 0xfa, 0x6, 0xc6, 0x36, 0xf6,
992 0x9, 0xc9, 0x39, 0xf9, 0x5, 0xc5, 0x35, 0xf5},
993 { 0x8a, 0x4a, 0xba, 0x7a, 0x86, 0x46, 0xb6, 0x76,
994 0x89, 0x49, 0xb9, 0x79, 0x85, 0x45, 0xb5, 0x75},
995 { 0x2a, 0xea, 0x1a, 0xda, 0x26, 0xe6, 0x16, 0xd6,
996 0x29, 0xe9, 0x19, 0xd9, 0x25, 0xe5, 0x15, 0xd5},
997 { 0xaa, 0x6a, 0x9a, 0x5a, 0xa6, 0x66, 0x96, 0x56,
998 0xa9, 0x69, 0x99, 0x59, 0xa5, 0x65, 0x95, 0x55}
999};
1000
1001#define ARGB_COMBINE_ALPHA(argb, alpha) \
1002 ((((argb >> 24) * alpha) >> 8) << 24) | (argb & 0x00ffffff)
1003
1004
1005#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit versions
1006#define AMIX(mask) (qMin(((quint64(s)&mask) + (quint64(d)&mask)), quint64(mask)))
1007#define MIX(mask) (qMin(((quint64(s)&mask) + (quint64(d)&mask)), quint64(mask)))
1008#else // 32 bits
1009// The mask for alpha can overflow over 32 bits
1010#define AMIX(mask) quint32(qMin(((quint64(s)&mask) + (quint64(d)&mask)), quint64(mask)))
1011#define MIX(mask) (qMin(((quint32(s)&mask) + (quint32(d)&mask)), quint32(mask)))
1012#endif
1013
1014inline uint comp_func_Plus_one_pixel_const_alpha(uint d, const uint s, const uint const_alpha, const uint one_minus_const_alpha)
1015{
1016 const uint result = uint(AMIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
1017 return INTERPOLATE_PIXEL_255(result, const_alpha, d, one_minus_const_alpha);
1018}
1019
1021{
1022 const uint result = uint(AMIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
1023 return result;
1024}
1025
1026#undef MIX
1027#undef AMIX
1028
1029// must be multiple of 4 for easier SIMD implementations
1030static constexpr int BufferSize = 2048;
1031
1032// A buffer of intermediate results used by simple bilinear scaling.
1034{
1035 // The idea is first to do the interpolation between the row s1 and the row s2
1036 // into this intermediate buffer, then later interpolate between two pixel of this buffer.
1037 //
1038 // buffer_rb is a buffer of red-blue component of the pixel, in the form 0x00RR00BB
1039 // buffer_ag is the alpha-green component of the pixel, in the form 0x00AA00GG
1040 // +1 for the last pixel to interpolate with, and +1 for rounding errors.
1043};
1044
1046
1047#endif // QDRAWHELPER_P_H
\inmodule QtGui
Definition qbrush.h:30
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtGui
Definition qbrush.h:135
Spread
Specifies how the area outside the gradient area should be filled.
Definition qbrush.h:146
@ ReflectSpread
Definition qbrush.h:148
@ RepeatSpread
Definition qbrush.h:149
@ PadSpread
Definition qbrush.h:147
\inmodule QtGui
Definition qimage.h:37
Format
The following image formats are available in Qt.
Definition qimage.h:41
@ NImageFormats
Definition qimage.h:79
Definition qlist.h:74
CompositionMode
Defines the modes supported for digital image compositing.
Definition qpainter.h:97
static void memfill(uint *buffer, uint fill, int length)
static void fetch(uint *buffer, uint *end, const Operator *op, const QSpanData *data, qreal det, qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
static uint fetchSingle(const QGradientData &gradient, qreal v)
static uint null()
The QRasterPaintEngine class enables hardware acceleration of painting operations in Qt for Embedded ...
\inmodule QtCore\reentrant
Definition qrect.h:483
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr quint16 red() const
Definition qrgba64.h:70
constexpr quint16 alpha() const
Definition qrgba64.h:73
constexpr quint16 green() const
Definition qrgba64.h:71
constexpr quint16 blue() const
Definition qrgba64.h:72
static constexpr QRgba64 fromRgba64(quint64 c)
Definition qrgba64.h:36
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
Combined button and popup list for selecting options.
Definition brush.cpp:5
Definition image.cpp:4
#define Q_FALLTHROUGH()
#define QT_FASTCALL
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
void qt_memfill24(quint24 *dest, quint24 value, qsizetype count)
void(QT_FASTCALL * CompositionFunction64)(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha)
static const uint BMASK
void(* RectFillFunc)(QRasterBuffer *rasterBuffer, int x, int y, int width, int height, const QRgba64 &color)
const QRgba64 *(QT_FASTCALL * SourceFetchProc64)(QRgba64 *buffer, const Operator *o, const QSpanData *data, int y, int x, int length)
DrawHelper qDrawHelper[QImage::NImageFormats]
static constexpr uint qt_div_65535(uint x)
void qt_memfill(T *dest, T value, qsizetype count)
uint comp_func_Plus_one_pixel_const_alpha(uint d, const uint s, const uint const_alpha, const uint one_minus_const_alpha)
#define FETCH_RADIAL_LOOP_CLAMP_PAD
void(QT_FASTCALL * CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha)
#define Q_DECL_RESTRICT
void(QT_FASTCALL * CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha)
#define FETCH_RADIAL_LOOP_CLAMP_REPEAT
const QRgbaFloat32 *(QT_FASTCALL * SourceFetchProcFP)(QRgbaFloat32 *buffer, const Operator *o, const QSpanData *data, int y, int x, int length)
static constexpr bool hasFastInterpolate4()
static constexpr int BufferSize
QRgba64 *(QT_FASTCALL * DestFetchProc64)(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
static void qt_rectfill(T *dest, T value, int x, int y, int width, int height, qsizetype stride)
const uint *(QT_FASTCALL * SourceFetchProc)(uint *buffer, const Operator *o, const QSpanData *data, int y, int x, int length)
void(* SrcOverBlendFunc)(uchar *destPixels, int dbpl, const uchar *src, int spbl, int w, int h, int const_alpha)
void(QT_FASTCALL * DestStoreProcFP)(QRasterBuffer *rasterBuffer, int x, int y, const QRgbaFloat32 *buffer, int length)
static constexpr uint qt_div_257(uint x)
static uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b)
void qt_memfill16(quint16 *dest, quint16 value, qsizetype count)
static qreal qRadialDeterminant(qreal a, qreal b, qreal c)
static constexpr uint qt_div_257_floor(uint x)
ushort qConvertRgb32To16(uint c)
static void blend_pixel(quint32 &dst, const quint32 src)
static constexpr int qt_div_255(int x)
static uint INTERPOLATE_PIXEL_255(uint x, uint a, uint y, uint b)
#define FETCH_RADIAL_LOOP_CLAMP_REFLECT
static uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
void(QT_FASTCALL * DestStoreProc)(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length)
SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats]
QT_FT_SpanFunc ProcessSpans
QRgbaFloat< float > QRgbaFloat32
void(* BitmapBlitFunc)(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *bitmap, int mapWidth, int mapHeight, int mapStride)
static QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
#define FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP)
static uint qt_gradient_pixel(const QGradientData *data, qreal pos)
static const uint RMASK
void qt_memfill32(quint32 *dest, quint32 value, qsizetype count)
SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats]
void(QT_FASTCALL * CompositionFunctionFP)(QRgbaFloat32 *Q_DECL_RESTRICT dest, const QRgbaFloat32 *Q_DECL_RESTRICT src, int length, uint const_alpha)
void(* AlphamapBlitFunc)(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *bitmap, int mapWidth, int mapHeight, int mapStride, const QClipData *clip, bool useGammaCorrection)
static uint BYTE_MUL(uint x, uint a)
void(QT_FASTCALL * CompositionFunctionSolid64)(QRgba64 *dest, int length, QRgba64 color, uint const_alpha)
static QRgba64 interpolate256(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
QRgbaFloat32 *(QT_FASTCALL * DestFetchProcFP)(QRgbaFloat32 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
static const BlendType *QT_FASTCALL qt_fetch_radial_gradient_template(BlendType *buffer, const Operator *op, const QSpanData *data, int y, int x, int length)
static QRgba64 multiplyAlpha256(QRgba64 rgba64, uint alpha256)
#define AMIX(mask)
uint comp_func_Plus_one_pixel(uint d, const uint s)
#define MIX(mask)
static const uint GMASK
#define GRADIENT_STOPTABLE_SIZE_SHIFT
static const uint AMASK
static uint BYTE_MUL_RGB16_32(uint x, uint a)
static uint qt_gradient_clamp(const QGradientData *data, int ipos)
uint *(QT_FASTCALL * DestFetchProc)(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length)
void(QT_FASTCALL * CompositionFunctionSolidFP)(QRgbaFloat32 *dest, int length, QRgbaFloat32 color, uint const_alpha)
void(* AlphaRGBBlitFunc)(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uint *rgbmask, int mapWidth, int mapHeight, int mapStride, const QClipData *clip, bool useGammaCorrection)
#define GRADIENT_STOPTABLE_SIZE
void qBlendGradient(int count, const QT_FT_Span *spans, void *userData)
void(QT_FASTCALL * DestStoreProc64)(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length)
const uint qt_bayer_matrix[16][16]
QRgb qConvertRgb16To32(uint c)
void(* SrcOverScaleFunc)(uchar *destPixels, int dbpl, const uchar *src, int spbl, int srch, const QRectF &targetRect, const QRectF &sourceRect, const QRect &clipRect, int const_alpha)
void qt_memfill_template(T *dest, T color, qsizetype count)
void qBlendTexture(int count, const QT_FT_Span *spans, void *userData)
SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats]
void qt_memfill64(quint64 *dest, quint64 value, qsizetype count)
void(* SrcOverTransformFunc)(uchar *destPixels, int dbpl, const uchar *src, int spbl, const QRectF &targetRect, const QRectF &sourceRect, const QRect &clipRect, const QTransform &targetRectTransform, int const_alpha)
static uint BYTE_MUL_RGB16(uint x, uint a)
#define Q_DECL_VECTORCALL
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
qfloat16 qSqrt(qfloat16 f)
Definition qfloat16.h:243
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint GLuint end
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLenum src
const void GLsizei GLsizei stride
GLenum GLuint buffer
GLint GLsizei width
GLenum GLenum dst
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat n
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
GLuint res
const GLubyte * c
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
GLint limit
GLuint GLenum matrix
GLdouble GLdouble t
Definition qopenglext.h:243
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat GLfloat alpha
Definition qopenglext.h:418
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
void(* QT_FT_SpanFunc)(int count, const QT_FT_Span *spans, void *worker)
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
Definition qrgb.h:13
constexpr int qAlpha(QRgb rgb)
Definition qrgb.h:27
#define tr(X)
unsigned int quint32
Definition qtypes.h:45
unsigned char uchar
Definition qtypes.h:27
unsigned short quint16
Definition qtypes.h:43
unsigned long long quint64
Definition qtypes.h:56
ptrdiff_t qsizetype
Definition qtypes.h:70
unsigned int uint
Definition qtypes.h:29
unsigned short ushort
Definition qtypes.h:28
double qreal
Definition qtypes.h:92
unsigned char quint8
Definition qtypes.h:41
QTextStream out(stdout)
[7]
QObject::connect nullptr
ba fill(true)
p ry()++
p rx()++
QPointer< QVBoxLayout > vbl
RectFillFunc fillRect
AlphaRGBBlitFunc alphaRGBBlit
ProcessSpans blendColor
AlphamapBlitFunc alphamapBlit
BitmapBlitFunc bitmapBlit
quint32 buffer_ag[BufferSize+2]
quint32 buffer_rb[BufferSize+2]
LinearGradientValues linear
CompositionFunction64 func64
DestStoreProcFP destStoreFP
CompositionFunctionSolidFP funcSolidFP
CompositionFunctionSolid funcSolid
DestStoreProc64 destStore64
SourceFetchProcFP srcFetchFP
DestStoreProc destStore
SourceFetchProc64 srcFetch64
QPainter::CompositionMode mode
CompositionFunction func
CompositionFunctionFP funcFP
DestFetchProcFP destFetchFP
DestFetchProc64 destFetch64
RadialGradientValues radial
SourceFetchProc srcFetch
CompositionFunctionSolid64 funcSolid64
DestFetchProc destFetch
struct QConicalGradientData::@218 center
QRadialGradientData radial
const QRgb * colorTable32
QLinearGradientData linear
QGradient::Spread spread
QConicalGradientData conical
struct QLinearGradientData::@214 origin
struct QLinearGradientData::@215 end
struct QRadialGradientData::@217 focal
struct QRadialGradientData::@216 center
AlphaRGBBlitFunc alphaRGBBlit
QRasterBuffer * rasterBuffer
void initTexture(const QImage *image, int alpha, QTextureData::Type=QTextureData::Plain, const QRect &sourceRect=QRect())
void setup(const QBrush &brush, int alpha, QPainter::CompositionMode compositionMode, bool isCosmetic)
BitmapBlitFunc bitmapBlit
std::shared_ptr< const void > cachedGradient
QImage * tempImage
enum QSpanData::Type type
QTextureData texture
signed int txop
RectFillFunc fillRect
ProcessSpans unclipped_blend
ProcessSpans blend
QColor solidColor
void init(QRasterBuffer *rb, const QRasterPaintEngine *pe)
QGradientData gradient
const QClipData * clip
AlphamapBlitFunc alphamapBlit
void setupMatrix(const QTransform &matrix, int bilinear)
QImage::Format format
const uchar * imageData
const uchar * scanLine(int y) const
const QList< QRgb > * colorTable
qsizetype bytesPerLine
Definition moc.h:24
quint24()=default
quint24(uint value)