Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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;
69typedef QRgbaFloat<float> QRgbaFloat32;
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
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
169
179
180struct Operator;
181typedef uint* (QT_FASTCALL *DestFetchProc)(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length);
182typedef QRgba64* (QT_FASTCALL *DestFetchProc64)(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length);
184typedef void (QT_FASTCALL *DestStoreProc)(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length);
185typedef void (QT_FASTCALL *DestStoreProc64)(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length);
186typedef void (QT_FASTCALL *DestStoreProcFP)(QRasterBuffer *rasterBuffer, int x, int y, const QRgbaFloat32 *buffer, int length);
187typedef const uint* (QT_FASTCALL *SourceFetchProc)(uint *buffer, const Operator *o, const QSpanData *data, int y, int x, int length);
188typedef const QRgba64* (QT_FASTCALL *SourceFetchProc64)(QRgba64 *buffer, const Operator *o, const QSpanData *data, int y, int x, int length);
189typedef const QRgbaFloat32* (QT_FASTCALL *SourceFetchProcFP)(QRgbaFloat32 *buffer, const Operator *o, const QSpanData *data, int y, int x, int length);
190
217
219
221{
222 struct {
226 struct {
227 qreal x;
228 qreal y;
230};
231
233{
234 struct {
239 struct {
240 qreal x;
241 qreal y;
244};
245
254
256{
258
259 union {
263 };
264
265#define GRADIENT_STOPTABLE_SIZE 1024
266#define GRADIENT_STOPTABLE_SIZE_SHIFT 10
267
268#if QT_CONFIG(raster_64bit) || QT_CONFIG(raster_fp)
269 const QRgba64 *colorTable64; //[GRADIENT_STOPTABLE_SIZE];
270#endif
271 const QRgb *colorTable32; //[GRADIENT_STOPTABLE_SIZE];
272
274};
275
277{
279 const uchar *scanLine(int y) const { return imageData + y*bytesPerLine; }
280
281 int width;
283 // clip rect
284 int x1;
285 int y1;
286 int x2;
287 int y2;
290 const QList<QRgb> *colorTable;
299};
300
341
342static inline uint qt_gradient_clamp(const QGradientData *data, int ipos)
343{
344 if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) {
345 if (data->spread == QGradient::RepeatSpread) {
346 ipos = ipos % GRADIENT_STOPTABLE_SIZE;
347 ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos;
348 } else if (data->spread == QGradient::ReflectSpread) {
349 const int limit = GRADIENT_STOPTABLE_SIZE * 2;
350 ipos = ipos % limit;
351 ipos = ipos < 0 ? limit + ipos : ipos;
352 ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - 1 - ipos : ipos;
353 } else {
354 if (ipos < 0)
355 ipos = 0;
356 else if (ipos >= GRADIENT_STOPTABLE_SIZE)
358 }
359 }
360
361 Q_ASSERT(ipos >= 0);
363
364 return ipos;
365}
366
368{
369 int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
370 return data->colorTable32[qt_gradient_clamp(data, ipos)];
371}
372
373#if QT_CONFIG(raster_64bit)
374static inline const QRgba64& qt_gradient_pixel64(const QGradientData *data, qreal pos)
375{
376 int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5));
377 return data->colorTable64[qt_gradient_clamp(data, ipos)];
378}
379#endif
380
382{
383 return (b * b) - (4 * a * c);
384}
385
386template <class RadialFetchFunc, typename BlendType> static
387const BlendType * QT_FASTCALL qt_fetch_radial_gradient_template(BlendType *buffer, const Operator *op,
388 const QSpanData *data, int y, int x, int length)
389{
390 // avoid division by zero
391 if (qFuzzyIsNull(op->radial.a)) {
392 RadialFetchFunc::memfill(buffer, RadialFetchFunc::null(), length);
393 return buffer;
394 }
395
396 const BlendType *b = buffer;
397 qreal rx = data->m21 * (y + qreal(0.5))
398 + data->dx + data->m11 * (x + qreal(0.5));
399 qreal ry = data->m22 * (y + qreal(0.5))
400 + data->dy + data->m12 * (x + qreal(0.5));
401 bool affine = !data->m13 && !data->m23;
402
403 BlendType *end = buffer + length;
404 qreal inv_a = 1 / qreal(2 * op->radial.a);
405
406 if (affine) {
407 rx -= data->gradient.radial.focal.x;
408 ry -= data->gradient.radial.focal.y;
409
410 const qreal delta_rx = data->m11;
411 const qreal delta_ry = data->m12;
412
413 qreal b = 2*(op->radial.dr*data->gradient.radial.focal.radius + rx * op->radial.dx + ry * op->radial.dy);
414 qreal delta_b = 2*(delta_rx * op->radial.dx + delta_ry * op->radial.dy);
415 const qreal b_delta_b = 2 * b * delta_b;
416 const qreal delta_b_delta_b = 2 * delta_b * delta_b;
417
418 const qreal bb = b * b;
419 const qreal delta_bb = delta_b * delta_b;
420
421 b *= inv_a;
422 delta_b *= inv_a;
423
424 const qreal rxrxryry = rx * rx + ry * ry;
425 const qreal delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry;
426 const qreal rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry);
427 const qreal delta_rx_plus_ry = 2 * delta_rxrxryry;
428
429 inv_a *= inv_a;
430
431 qreal det = (bb - 4 * op->radial.a * (op->radial.sqrfr - rxrxryry)) * inv_a;
432 qreal delta_det = (b_delta_b + delta_bb + 4 * op->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a;
433 const qreal delta_delta_det = (delta_b_delta_b + 4 * op->radial.a * delta_rx_plus_ry) * inv_a;
434
435 RadialFetchFunc::fetch(buffer, end, op, data, det, delta_det, delta_delta_det, b, delta_b);
436 } else {
437 qreal rw = data->m23 * (y + qreal(0.5))
438 + data->m33 + data->m13 * (x + qreal(0.5));
439
440 while (buffer < end) {
441 if (rw == 0) {
442 *buffer = RadialFetchFunc::null();
443 } else {
444 qreal invRw = 1 / rw;
445 qreal gx = rx * invRw - data->gradient.radial.focal.x;
446 qreal gy = ry * invRw - data->gradient.radial.focal.y;
447 qreal b = 2*(op->radial.dr*data->gradient.radial.focal.radius + gx*op->radial.dx + gy*op->radial.dy);
448 qreal det = qRadialDeterminant(op->radial.a, b, op->radial.sqrfr - (gx*gx + gy*gy));
449
450 BlendType result = RadialFetchFunc::null();
451 if (det >= 0) {
452 qreal detSqrt = qSqrt(det);
453
454 qreal s0 = (-b - detSqrt) * inv_a;
455 qreal s1 = (-b + detSqrt) * inv_a;
456
457 qreal s = qMax(s0, s1);
458
459 if (data->gradient.radial.focal.radius + op->radial.dr * s >= 0)
460 result = RadialFetchFunc::fetchSingle(data->gradient, s);
461 }
462
463 *buffer = result;
464 }
465
466 rx += data->m11;
467 ry += data->m12;
468 rw += data->m13;
469
470 ++buffer;
471 }
472 }
473
474 return b;
475}
476
477template <class Simd>
479{
480public:
481 static uint null() { return 0; }
482 static uint fetchSingle(const QGradientData& gradient, qreal v)
483 {
484 return qt_gradient_pixel(&gradient, v);
485 }
486 static void memfill(uint *buffer, uint fill, int length)
487 {
489 }
490 static void fetch(uint *buffer, uint *end, const Operator *op, const QSpanData *data, qreal det,
491 qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b)
492 {
493 typename Simd::Vect_buffer_f det_vec;
494 typename Simd::Vect_buffer_f delta_det4_vec;
495 typename Simd::Vect_buffer_f b_vec;
496
497 for (int i = 0; i < 4; ++i) {
498 det_vec.f[i] = det;
499 delta_det4_vec.f[i] = 4 * delta_det;
500 b_vec.f[i] = b;
501
502 det += delta_det;
503 delta_det += delta_delta_det;
504 b += delta_b;
505 }
506
507 const typename Simd::Float32x4 v_delta_delta_det16 = Simd::v_dup(16 * delta_delta_det);
508 const typename Simd::Float32x4 v_delta_delta_det6 = Simd::v_dup(6 * delta_delta_det);
509 const typename Simd::Float32x4 v_delta_b4 = Simd::v_dup(4 * delta_b);
510
511 const typename Simd::Float32x4 v_r0 = Simd::v_dup(data->gradient.radial.focal.radius);
512 const typename Simd::Float32x4 v_dr = Simd::v_dup(op->radial.dr);
513
514#if defined(__ARM_NEON__)
515 // NEON doesn't have SIMD sqrt, but uses rsqrt instead that can't be taken of 0.
516 const typename Simd::Float32x4 v_min = Simd::v_dup(std::numeric_limits<float>::epsilon());
517#else
518 const typename Simd::Float32x4 v_min = Simd::v_dup(0.0f);
519#endif
520 const typename Simd::Float32x4 v_max = Simd::v_dup(float(GRADIENT_STOPTABLE_SIZE-1));
521 const typename Simd::Float32x4 v_half = Simd::v_dup(0.5f);
522
523 const typename Simd::Int32x4 v_repeat_mask = Simd::v_dup(~(uint(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT));
524 const typename Simd::Int32x4 v_reflect_mask = Simd::v_dup(~(uint(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1)));
525
526 const typename Simd::Int32x4 v_reflect_limit = Simd::v_dup(2 * GRADIENT_STOPTABLE_SIZE - 1);
527
528 const int extended_mask = op->radial.extended ? 0x0 : ~0x0;
529
530#define FETCH_RADIAL_LOOP_PROLOGUE \
531 while (buffer < end) { \
532 typename Simd::Vect_buffer_i v_buffer_mask; \
533 v_buffer_mask.v = Simd::v_greaterOrEqual(det_vec.v, v_min); \
534 const typename Simd::Float32x4 v_index_local = Simd::v_sub(Simd::v_sqrt(Simd::v_max(v_min, det_vec.v)), b_vec.v); \
535 const typename Simd::Float32x4 v_index = Simd::v_add(Simd::v_mul(v_index_local, v_max), v_half); \
536 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)); \
537 typename Simd::Vect_buffer_i index_vec;
538#define FETCH_RADIAL_LOOP_CLAMP_REPEAT \
539 index_vec.v = Simd::v_and(v_repeat_mask, Simd::v_toInt(v_index));
540#define FETCH_RADIAL_LOOP_CLAMP_REFLECT \
541 const typename Simd::Int32x4 v_index_i = Simd::v_and(v_reflect_mask, Simd::v_toInt(v_index)); \
542 const typename Simd::Int32x4 v_index_i_inv = Simd::v_sub(v_reflect_limit, v_index_i); \
543 index_vec.v = Simd::v_min_16(v_index_i, v_index_i_inv);
544#define FETCH_RADIAL_LOOP_CLAMP_PAD \
545 index_vec.v = Simd::v_toInt(Simd::v_min(v_max, Simd::v_max(v_min, v_index)));
546#define FETCH_RADIAL_LOOP_EPILOGUE \
547 det_vec.v = Simd::v_add(Simd::v_add(det_vec.v, delta_det4_vec.v), v_delta_delta_det6); \
548 delta_det4_vec.v = Simd::v_add(delta_det4_vec.v, v_delta_delta_det16); \
549 b_vec.v = Simd::v_add(b_vec.v, v_delta_b4); \
550 for (int i = 0; i < 4; ++i) \
551 *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable32[index_vec.i[i]]; \
552 }
553
554#define FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP) \
555 FETCH_RADIAL_LOOP_PROLOGUE \
556 FETCH_RADIAL_LOOP_CLAMP \
557 FETCH_RADIAL_LOOP_EPILOGUE
558
559 switch (data->gradient.spread) {
562 break;
565 break;
568 break;
569 default:
570 Q_UNREACHABLE();
571 }
572 }
573};
574
576 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
577 t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
578 t &= 0xff00ff;
579
580 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
581 x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
582 x &= 0xff00ff00;
583 x |= t;
584 return x;
585}
586
587#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit versions
588
589static inline uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
590 quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
591 t += (((quint64(y)) | ((quint64(y)) << 24)) & 0x00ff00ff00ff00ff) * b;
592 t >>= 8;
593 t &= 0x00ff00ff00ff00ff;
594 return (uint(t)) | (uint(t >> 24));
595}
596
597static inline uint BYTE_MUL(uint x, uint a) {
598 quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
599 t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8;
600 t &= 0x00ff00ff00ff00ff;
601 return (uint(t)) | (uint(t >> 24));
602}
603
604#else // 32-bit versions
605
607 uint t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
608 t >>= 8;
609 t &= 0xff00ff;
610
611 x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
612 x &= 0xff00ff00;
613 x |= t;
614 return x;
615}
616
617static inline uint BYTE_MUL(uint x, uint a) {
618 uint t = (x & 0xff00ff) * a;
619 t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
620 t &= 0xff00ff;
621
622 x = ((x >> 8) & 0xff00ff) * a;
623 x = (x + ((x >> 8) & 0xff00ff) + 0x800080);
624 x &= 0xff00ff00;
625 x |= t;
626 return x;
627}
628#endif
629
630static inline void blend_pixel(quint32 &dst, const quint32 src)
631{
632 if (src >= 0xff000000)
633 dst = src;
634 else if (src != 0)
635 dst = src + BYTE_MUL(dst, qAlpha(~src));
636}
637
638static inline void blend_pixel(quint32 &dst, const quint32 src, const int const_alpha)
639{
640 if (const_alpha == 255)
641 return blend_pixel(dst, src);
642 if (src != 0) {
643 const quint32 s = BYTE_MUL(src, const_alpha);
644 dst = s + BYTE_MUL(dst, qAlpha(~s));
645 }
646}
647
648#if defined(__SSE2__)
649static inline uint Q_DECL_VECTORCALL interpolate_4_pixels_sse2(__m128i vt, __m128i vb, uint distx, uint disty)
650{
651 // First interpolate top and bottom pixels in parallel.
652 vt = _mm_unpacklo_epi8(vt, _mm_setzero_si128());
653 vb = _mm_unpacklo_epi8(vb, _mm_setzero_si128());
654 vt = _mm_mullo_epi16(vt, _mm_set1_epi16(256 - disty));
655 vb = _mm_mullo_epi16(vb, _mm_set1_epi16(disty));
656 __m128i vlr = _mm_add_epi16(vt, vb);
657 vlr = _mm_srli_epi16(vlr, 8);
658 // vlr now contains the result of the first two interpolate calls vlr = unpacked((xright << 64) | xleft)
659
660 // Now the last interpolate between left and right..
661 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(256 - distx), _MM_SHUFFLE(0, 0, 0, 0));
662 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
663 const __m128i vmulx = _mm_unpacklo_epi16(vidistx, vdistx);
664 vlr = _mm_unpacklo_epi16(vlr, _mm_srli_si128(vlr, 8));
665 // vlr now contains the colors of left and right interleaved { la, ra, lr, rr, lg, rg, lb, rb }
666 vlr = _mm_madd_epi16(vlr, vmulx); // Multiply and horizontal add.
667 vlr = _mm_srli_epi32(vlr, 8);
668 vlr = _mm_packs_epi32(vlr, vlr);
669 vlr = _mm_packus_epi16(vlr, vlr);
670 return _mm_cvtsi128_si32(vlr);
671}
672
673static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
674{
675 __m128i vt = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tl), _mm_cvtsi32_si128(tr));
676 __m128i vb = _mm_unpacklo_epi32(_mm_cvtsi32_si128(bl), _mm_cvtsi32_si128(br));
677 return interpolate_4_pixels_sse2(vt, vb, distx, disty);
678}
679
680static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint distx, uint disty)
681{
682 __m128i vt = _mm_loadl_epi64((const __m128i*)t);
683 __m128i vb = _mm_loadl_epi64((const __m128i*)b);
684 return interpolate_4_pixels_sse2(vt, vb, distx, disty);
685}
686
687static constexpr inline bool hasFastInterpolate4() { return true; }
688
689#elif defined(__ARM_NEON__)
690static inline uint interpolate_4_pixels_neon(uint32x2_t vt32, uint32x2_t vb32, uint distx, uint disty)
691{
692 uint16x8_t vt16 = vmovl_u8(vreinterpret_u8_u32(vt32));
693 uint16x8_t vb16 = vmovl_u8(vreinterpret_u8_u32(vb32));
694 vt16 = vmulq_n_u16(vt16, 256 - disty);
695 vt16 = vmlaq_n_u16(vt16, vb16, disty);
696 vt16 = vshrq_n_u16(vt16, 8);
697 uint16x4_t vl16 = vget_low_u16(vt16);
698 uint16x4_t vr16 = vget_high_u16(vt16);
699 vl16 = vmul_n_u16(vl16, 256 - distx);
700 vl16 = vmla_n_u16(vl16, vr16, distx);
701 vl16 = vshr_n_u16(vl16, 8);
702 uint8x8_t vr = vmovn_u16(vcombine_u16(vl16, vl16));
703 return vget_lane_u32(vreinterpret_u32_u8(vr), 0);
704}
705
706static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
707{
708 uint32x2_t vt32 = vmov_n_u32(tl);
709 uint32x2_t vb32 = vmov_n_u32(bl);
710 vt32 = vset_lane_u32(tr, vt32, 1);
711 vb32 = vset_lane_u32(br, vb32, 1);
712 return interpolate_4_pixels_neon(vt32, vb32, distx, disty);
713}
714
715static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint distx, uint disty)
716{
717 uint32x2_t vt32 = vld1_u32(t);
718 uint32x2_t vb32 = vld1_u32(b);
719 return interpolate_4_pixels_neon(vt32, vb32, distx, disty);
720}
721
722static constexpr inline bool hasFastInterpolate4() { return true; }
723
724#else
725static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
726{
727 uint idistx = 256 - distx;
728 uint idisty = 256 - disty;
729 uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
730 uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
731 return INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
732}
733
734static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint distx, uint disty)
735{
736 return interpolate_4_pixels(t[0], t[1], b[0], b[1], distx, disty);
737}
738
739static constexpr inline bool hasFastInterpolate4() { return false; }
740
741#endif
742
743static inline QRgba64 multiplyAlpha256(QRgba64 rgba64, uint alpha256)
744{
745 return QRgba64::fromRgba64((rgba64.red() * alpha256) >> 8,
746 (rgba64.green() * alpha256) >> 8,
747 (rgba64.blue() * alpha256) >> 8,
748 (rgba64.alpha() * alpha256) >> 8);
749}
750static inline QRgba64 interpolate256(QRgba64 x, uint alpha1, QRgba64 y, uint alpha2)
751{
752 return QRgba64::fromRgba64(multiplyAlpha256(x, alpha1) + multiplyAlpha256(y, alpha2));
753}
754
755#ifdef __SSE2__
756static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
757{
758 __m128i vt = _mm_loadu_si128((const __m128i*)t);
759 if (disty) {
760 __m128i vb = _mm_loadu_si128((const __m128i*)b);
761 vt = _mm_mulhi_epu16(vt, _mm_set1_epi16(0x10000 - disty));
762 vb = _mm_mulhi_epu16(vb, _mm_set1_epi16(disty));
763 vt = _mm_add_epi16(vt, vb);
764 }
765 if (distx) {
766 const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0));
767 const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0));
768 vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx));
769 vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8));
770 }
771#ifdef Q_PROCESSOR_X86_64
772 return QRgba64::fromRgba64(_mm_cvtsi128_si64(vt));
773#else
774 QRgba64 out;
775 _mm_storel_epi64((__m128i*)&out, vt);
776 return out;
777#endif // Q_PROCESSOR_X86_64
778}
779#elif defined(__ARM_NEON__)
780static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
781{
782 uint64x1x2_t vt = vld2_u64(reinterpret_cast<const uint64_t *>(t));
783 if (disty) {
784 uint64x1x2_t vb = vld2_u64(reinterpret_cast<const uint64_t *>(b));
785 uint32x4_t vt0 = vmull_n_u16(vreinterpret_u16_u64(vt.val[0]), 0x10000 - disty);
786 uint32x4_t vt1 = vmull_n_u16(vreinterpret_u16_u64(vt.val[1]), 0x10000 - disty);
787 vt0 = vmlal_n_u16(vt0, vreinterpret_u16_u64(vb.val[0]), disty);
788 vt1 = vmlal_n_u16(vt1, vreinterpret_u16_u64(vb.val[1]), disty);
789 vt.val[0] = vreinterpret_u64_u16(vshrn_n_u32(vt0, 16));
790 vt.val[1] = vreinterpret_u64_u16(vshrn_n_u32(vt1, 16));
791 }
792 if (distx) {
793 uint32x4_t vt0 = vmull_n_u16(vreinterpret_u16_u64(vt.val[0]), 0x10000 - distx);
794 vt0 = vmlal_n_u16(vt0, vreinterpret_u16_u64(vt.val[1]), distx);
795 vt.val[0] = vreinterpret_u64_u16(vshrn_n_u32(vt0, 16));
796 }
797 QRgba64 out;
798 vst1_u64(reinterpret_cast<uint64_t *>(&out), vt.val[0]);
799 return out;
800}
801#else
802static inline QRgba64 interpolate_4_pixels_rgb64(const QRgba64 t[], const QRgba64 b[], uint distx, uint disty)
803{
804 const uint dx = distx>>8;
805 const uint dy = disty>>8;
806 const uint idx = 256 - dx;
807 const uint idy = 256 - dy;
808 QRgba64 xtop = interpolate256(t[0], idx, t[1], dx);
809 QRgba64 xbot = interpolate256(b[0], idx, b[1], dx);
810 return interpolate256(xtop, idy, xbot, dy);
811}
812#endif // __SSE2__
813
814#if QT_CONFIG(raster_fp)
815static inline QRgbaFloat32 multiplyAlpha_rgba32f(QRgbaFloat32 c, float a)
816{
817 return QRgbaFloat32 { c.r * a, c.g * a, c.b * a, c.a * a };
818}
819
820static inline QRgbaFloat32 interpolate_rgba32f(QRgbaFloat32 x, float alpha1, QRgbaFloat32 y, float alpha2)
821{
822 x = multiplyAlpha_rgba32f(x, alpha1);
823 y = multiplyAlpha_rgba32f(y, alpha2);
824 return QRgbaFloat32 { x.r + y.r, x.g + y.g, x.b + y.b, x.a + y.a };
825}
826#ifdef __SSE2__
827static inline __m128 Q_DECL_VECTORCALL interpolate_rgba32f(__m128 x, __m128 alpha1, __m128 y, __m128 alpha2)
828{
829 return _mm_add_ps(_mm_mul_ps(x, alpha1), _mm_mul_ps(y, alpha2));
830}
831#endif
832
833static inline QRgbaFloat32 interpolate_4_pixels_rgba32f(const QRgbaFloat32 t[], const QRgbaFloat32 b[], uint distx, uint disty)
834{
835 constexpr float f = 1.0f / 65536.0f;
836 const float dx = distx * f;
837 const float dy = disty * f;
838 const float idx = 1.0f - dx;
839 const float idy = 1.0f - dy;
840#ifdef __SSE2__
841 const __m128 vtl = _mm_load_ps((const float *)&t[0]);
842 const __m128 vtr = _mm_load_ps((const float *)&t[1]);
843 const __m128 vbl = _mm_load_ps((const float *)&b[0]);
844 const __m128 vbr = _mm_load_ps((const float *)&b[1]);
845
846 const __m128 vdx = _mm_set1_ps(dx);
847 const __m128 vidx = _mm_set1_ps(idx);
848 __m128 vt = interpolate_rgba32f(vtl, vidx, vtr, vdx);
849 __m128 vb = interpolate_rgba32f(vbl, vidx, vbr, vdx);
850 const __m128 vdy = _mm_set1_ps(dy);
851 const __m128 vidy = _mm_set1_ps(idy);
852 vt = interpolate_rgba32f(vt, vidy, vb, vdy);
854 _mm_store_ps((float*)&res, vt);
855 return res;
856#else
857 QRgbaFloat32 xtop = interpolate_rgba32f(t[0], idx, t[1], dx);
858 QRgbaFloat32 xbot = interpolate_rgba32f(b[0], idx, b[1], dx);
859 xtop = interpolate_rgba32f(xtop, idy, xbot, dy);
860 return xtop;
861#endif
862}
863#endif // QT_CONFIG(raster_fp)
864
865static inline uint BYTE_MUL_RGB16(uint x, uint a) {
866 a += 1;
867 uint t = (((x & 0x07e0)*a) >> 8) & 0x07e0;
868 t |= (((x & 0xf81f)*(a>>2)) >> 6) & 0xf81f;
869 return t;
870}
871
873 uint t = (((x & 0xf81f07e0) >> 5)*a) & 0xf81f07e0;
874 t |= (((x & 0x07e0f81f)*a) >> 5) & 0x07e0f81f;
875 return t;
876}
877
878// qt_div_255 is a fast rounded division by 255 using an approximation that is accurate for all positive 16-bit integers
879static constexpr inline int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; }
880static constexpr inline uint qt_div_257_floor(uint x) { return (x - (x >> 8)) >> 8; }
881static constexpr inline uint qt_div_257(uint x) { return qt_div_257_floor(x + 128); }
882static constexpr inline uint qt_div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; }
883
884template <class T> inline void qt_memfill_template(T *dest, T color, qsizetype count)
885{
886 if (!count)
887 return;
888
889 qsizetype n = (count + 7) / 8;
890 switch (count & 0x07)
891 {
892 case 0: do { *dest++ = color; Q_FALLTHROUGH();
893 case 7: *dest++ = color; Q_FALLTHROUGH();
894 case 6: *dest++ = color; Q_FALLTHROUGH();
895 case 5: *dest++ = color; Q_FALLTHROUGH();
896 case 4: *dest++ = color; Q_FALLTHROUGH();
897 case 3: *dest++ = color; Q_FALLTHROUGH();
898 case 2: *dest++ = color; Q_FALLTHROUGH();
899 case 1: *dest++ = color;
900 } while (--n > 0);
901 }
902}
903
904template <class T> inline void qt_memfill(T *dest, T value, qsizetype count)
905{
907}
908
909template<> inline void qt_memfill(quint64 *dest, quint64 color, qsizetype count)
910{
911 qt_memfill64(dest, color, count);
912}
913
914template<> inline void qt_memfill(quint32 *dest, quint32 color, qsizetype count)
915{
916 qt_memfill32(dest, color, count);
917}
918
919template<> inline void qt_memfill(quint24 *dest, quint24 color, qsizetype count)
920{
921 qt_memfill24(dest, color, count);
922}
923
924template<> inline void qt_memfill(quint16 *dest, quint16 color, qsizetype count)
925{
926 qt_memfill16(dest, color, count);
927}
928
929template<> inline void qt_memfill(quint8 *dest, quint8 color, qsizetype count)
930{
931 memset(dest, color, count);
932}
933
934template <class T> static
935inline void qt_rectfill(T *dest, T value,
936 int x, int y, int width, int height, qsizetype stride)
937{
938 char *d = reinterpret_cast<char*>(dest + x) + y * stride;
939 if (uint(stride) == (width * sizeof(T))) {
940 qt_memfill(reinterpret_cast<T*>(d), value, qsizetype(width) * height);
941 } else {
942 for (int j = 0; j < height; ++j) {
943 dest = reinterpret_cast<T*>(d);
944 qt_memfill(dest, value, width);
945 d += stride;
946 }
947 }
948}
949
951{
952 return (((c) >> 3) & 0x001f)
953 | (((c) >> 5) & 0x07e0)
954 | (((c) >> 8) & 0xf800);
955}
956
958{
959 return 0xff000000
960 | ((((c) << 3) & 0xf8) | (((c) >> 2) & 0x7))
961 | ((((c) << 5) & 0xfc00) | (((c) >> 1) & 0x300))
962 | ((((c) << 8) & 0xf80000) | (((c) << 3) & 0x70000));
963}
964
965const uint qt_bayer_matrix[16][16] = {
966 { 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc,
967 0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff},
968 { 0x80, 0x40, 0xb0, 0x70, 0x8c, 0x4c, 0xbc, 0x7c,
969 0x83, 0x43, 0xb3, 0x73, 0x8f, 0x4f, 0xbf, 0x7f},
970 { 0x20, 0xe0, 0x10, 0xd0, 0x2c, 0xec, 0x1c, 0xdc,
971 0x23, 0xe3, 0x13, 0xd3, 0x2f, 0xef, 0x1f, 0xdf},
972 { 0xa0, 0x60, 0x90, 0x50, 0xac, 0x6c, 0x9c, 0x5c,
973 0xa3, 0x63, 0x93, 0x53, 0xaf, 0x6f, 0x9f, 0x5f},
974 { 0x8, 0xc8, 0x38, 0xf8, 0x4, 0xc4, 0x34, 0xf4,
975 0xb, 0xcb, 0x3b, 0xfb, 0x7, 0xc7, 0x37, 0xf7},
976 { 0x88, 0x48, 0xb8, 0x78, 0x84, 0x44, 0xb4, 0x74,
977 0x8b, 0x4b, 0xbb, 0x7b, 0x87, 0x47, 0xb7, 0x77},
978 { 0x28, 0xe8, 0x18, 0xd8, 0x24, 0xe4, 0x14, 0xd4,
979 0x2b, 0xeb, 0x1b, 0xdb, 0x27, 0xe7, 0x17, 0xd7},
980 { 0xa8, 0x68, 0x98, 0x58, 0xa4, 0x64, 0x94, 0x54,
981 0xab, 0x6b, 0x9b, 0x5b, 0xa7, 0x67, 0x97, 0x57},
982 { 0x2, 0xc2, 0x32, 0xf2, 0xe, 0xce, 0x3e, 0xfe,
983 0x1, 0xc1, 0x31, 0xf1, 0xd, 0xcd, 0x3d, 0xfd},
984 { 0x82, 0x42, 0xb2, 0x72, 0x8e, 0x4e, 0xbe, 0x7e,
985 0x81, 0x41, 0xb1, 0x71, 0x8d, 0x4d, 0xbd, 0x7d},
986 { 0x22, 0xe2, 0x12, 0xd2, 0x2e, 0xee, 0x1e, 0xde,
987 0x21, 0xe1, 0x11, 0xd1, 0x2d, 0xed, 0x1d, 0xdd},
988 { 0xa2, 0x62, 0x92, 0x52, 0xae, 0x6e, 0x9e, 0x5e,
989 0xa1, 0x61, 0x91, 0x51, 0xad, 0x6d, 0x9d, 0x5d},
990 { 0xa, 0xca, 0x3a, 0xfa, 0x6, 0xc6, 0x36, 0xf6,
991 0x9, 0xc9, 0x39, 0xf9, 0x5, 0xc5, 0x35, 0xf5},
992 { 0x8a, 0x4a, 0xba, 0x7a, 0x86, 0x46, 0xb6, 0x76,
993 0x89, 0x49, 0xb9, 0x79, 0x85, 0x45, 0xb5, 0x75},
994 { 0x2a, 0xea, 0x1a, 0xda, 0x26, 0xe6, 0x16, 0xd6,
995 0x29, 0xe9, 0x19, 0xd9, 0x25, 0xe5, 0x15, 0xd5},
996 { 0xaa, 0x6a, 0x9a, 0x5a, 0xa6, 0x66, 0x96, 0x56,
997 0xa9, 0x69, 0x99, 0x59, 0xa5, 0x65, 0x95, 0x55}
998};
999
1000#define ARGB_COMBINE_ALPHA(argb, alpha) \
1001 ((((argb >> 24) * alpha) >> 8) << 24) | (argb & 0x00ffffff)
1002
1003
1004#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit versions
1005#define AMIX(mask) (qMin(((quint64(s)&mask) + (quint64(d)&mask)), quint64(mask)))
1006#define MIX(mask) (qMin(((quint64(s)&mask) + (quint64(d)&mask)), quint64(mask)))
1007#else // 32 bits
1008// The mask for alpha can overflow over 32 bits
1009#define AMIX(mask) quint32(qMin(((quint64(s)&mask) + (quint64(d)&mask)), quint64(mask)))
1010#define MIX(mask) (qMin(((quint32(s)&mask) + (quint32(d)&mask)), quint32(mask)))
1011#endif
1012
1013inline uint comp_func_Plus_one_pixel_const_alpha(uint d, const uint s, const uint const_alpha, const uint one_minus_const_alpha)
1014{
1015 const uint result = uint(AMIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
1016 return INTERPOLATE_PIXEL_255(result, const_alpha, d, one_minus_const_alpha);
1017}
1018
1020{
1021 const uint result = uint(AMIX(AMASK) | MIX(RMASK) | MIX(GMASK) | MIX(BMASK));
1022 return result;
1023}
1024
1025#undef MIX
1026#undef AMIX
1027
1028// must be multiple of 4 for easier SIMD implementations
1029static constexpr int BufferSize = 2048;
1030
1031// A buffer of intermediate results used by simple bilinear scaling.
1033{
1034 // The idea is first to do the interpolation between the row s1 and the row s2
1035 // into this intermediate buffer, then later interpolate between two pixel of this buffer.
1036 //
1037 // buffer_rb is a buffer of red-blue component of the pixel, in the form 0x00RR00BB
1038 // buffer_ag is the alpha-green component of the pixel, in the form 0x00AA00GG
1039 // +1 for the last pixel to interpolate with, and +1 for rounding errors.
1042};
1043
1045
1046#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:80
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:484
\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:349
qfloat16 qSqrt(qfloat16 f)
Definition qfloat16.h:289
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
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLenum src
const void GLsizei GLsizei stride
GLenum GLuint buffer
GLint GLsizei width
GLuint color
[2]
GLenum GLenum dst
GLfloat n
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
GLdouble s
[6]
Definition qopenglext.h:235
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]
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:50
unsigned char uchar
Definition qtypes.h:32
unsigned short quint16
Definition qtypes.h:48
unsigned long long quint64
Definition qtypes.h:61
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
unsigned short ushort
Definition qtypes.h:33
double qreal
Definition qtypes.h:187
unsigned char quint8
Definition qtypes.h:46
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::@215 center
QRadialGradientData radial
const QRgb * colorTable32
QLinearGradientData linear
QGradient::Spread spread
QConicalGradientData conical
struct QLinearGradientData::@212 end
struct QLinearGradientData::@211 origin
struct QRadialGradientData::@213 center
struct QRadialGradientData::@214 focal
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:23
quint24()=default
quint24(uint value)