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
qbrush.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qbrush.h"
6#include "qpixmap.h"
7#include "qbitmap.h"
8#include "qpixmapcache.h"
9#include <qpa/qplatformpixmap.h>
10#include "qdatastream.h"
11#include "qvariant.h"
12#include "qline.h"
13#include "qdebug.h"
14#include <QtCore/qjsondocument.h>
15#include <QtCore/qjsonarray.h>
16#include <QtCore/qcoreapplication.h>
17#include "private/qhexstring_p.h"
18#include <QtCore/qnumeric.h>
19#include <QtCore/qfile.h>
20#include <QtCore/qmutex.h>
21#include <QtCore/private/qoffsetstringarray_p.h>
22
24
25using namespace Qt::StringLiterals;
26
27#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
28// Avoid an ABI break due to the QScopedPointer->std::unique_ptr change
29static_assert(sizeof(QBrush::DataPtr) == sizeof(QScopedPointer<QBrushData, QBrushDataPointerDeleter>));
30#endif
31
32const uchar *qt_patternForBrush(int brushStyle, bool invert)
33{
34 Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
35 static const uchar pat_tbl[][2][8] = {
36 {
37 /* dense1 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
38 /*~dense1 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
39 }, {
40 /* dense2 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
41 /*~dense2 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
42 }, {
43 /* dense3 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
44 /*~dense3 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
45 }, {
46 /* dense4 */ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
47 /*~dense4 */ { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 },
48 }, {
49 /* dense5 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
50 /*~dense5 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
51 }, {
52 /* dense6 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
53 /*~dense6 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
54 }, {
55 /* dense7 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
56 /*~dense7 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
57 }, {
58 /* hor */ { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff },
59 /*~hor */ { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 },
60 }, {
61 /* ver */ { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef },
62 /*~ver */ { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
63 }, {
64 /* cross */ { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef },
65 /*~cross */ { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 },
66 }, {
67 /* bdiag */ { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe },
68 /*~bdiag */ { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 },
69 }, {
70 /* fdiag */ { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f },
71 /*~fdiag */ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
72 }, {
73 /* dcross */ { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e },
74 /*~dcross */ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 },
75 },
76 };
77 return pat_tbl[brushStyle - Qt::Dense1Pattern][invert];
78}
79
80Q_GUI_EXPORT QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
81{
82
83 QPixmap pm;
84 QString key = "$qt-brush$"_L1
85 % HexString<uint>(brushStyle)
86 % QLatin1Char(invert ? '1' : '0');
87 if (!QPixmapCache::find(key, &pm)) {
88 pm = QBitmap::fromData(QSize(8, 8), qt_patternForBrush(brushStyle, invert),
91 }
92
93 return pm;
94}
95
98{
99public:
101 : m_initialized(false)
102 {
103 init();
104 }
105
106 void init()
107 {
109 for (int style = Qt::Dense1Pattern; style <= Qt::DiagCrossPattern; ++style) {
110 int i = style - Qt::Dense1Pattern;
111 m_images[i][0] = QImage(qt_patternForBrush(style, 0), 8, 8, 1, QImage::Format_MonoLSB);
112 m_images[i][1] = QImage(qt_patternForBrush(style, 1), 8, 8, 1, QImage::Format_MonoLSB);
113 }
114 m_initialized = true;
115 }
116
117 QImage getImage(int brushStyle, bool invert) const
118 {
119 Q_ASSERT(brushStyle >= Qt::Dense1Pattern && brushStyle <= Qt::DiagCrossPattern);
120 if (!m_initialized)
121 const_cast<QBrushPatternImageCache*>(this)->init();
122 return m_images[brushStyle - Qt::Dense1Pattern][invert];
123 }
124
125 void cleanup() {
126 for (int style = Qt::Dense1Pattern; style <= Qt::DiagCrossPattern; ++style) {
127 int i = style - Qt::Dense1Pattern;
128 m_images[i][0] = QImage();
129 m_images[i][1] = QImage();
130 }
131 m_initialized = false;
132 }
133
134private:
136 bool m_initialized;
137};
138
139Q_GLOBAL_STATIC(QBrushPatternImageCache, qt_brushPatternImageCache)
140
142{
143 qt_brushPatternImageCache()->cleanup();
144}
145
146Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert)
147{
148 return qt_brushPatternImageCache()->getImage(brushStyle, invert);
149}
150
152{
154 m_has_pixmap_texture = false;
155 m_pixmap = nullptr;
156 }
158 delete m_pixmap;
159 }
160
161 void setPixmap(const QPixmap &pm) {
162 delete m_pixmap;
163
164 if (pm.isNull()) {
165 m_pixmap = nullptr;
166 m_has_pixmap_texture = false;
167 } else {
168 m_pixmap = new QPixmap(pm);
170 }
171
172 m_image = QImage();
173 }
174
175 void setImage(const QImage &image) {
176 m_image = image;
177 delete m_pixmap;
178 m_pixmap = nullptr;
179 m_has_pixmap_texture = false;
180 }
181
183 if (!m_pixmap) {
185 }
186 return *m_pixmap;
187 }
188
190 if (m_image.isNull() && m_pixmap)
192 return m_image;
193 }
194
198};
199
200// returns true if the brush has a pixmap (or bitmap) set as the
201// brush texture, false otherwise
202bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush& brush)
203{
204 if (brush.style() != Qt::TexturePattern)
205 return false;
206 QTexturedBrushData *tx_data = static_cast<QTexturedBrushData *>(brush.d.get());
207 return tx_data->m_has_pixmap_texture;
208}
209
214
216{
217 switch (d->style) {
219 delete static_cast<QTexturedBrushData*>(d);
220 break;
224 delete static_cast<QGradientBrushData*>(d);
225 break;
226 default:
227 delete d;
228 }
229}
230
232{
233 if (d && !d->ref.deref())
234 deleteData(d);
235}
236
319{
320public:
323 {
324 brush->ref.storeRelaxed(1);
325 brush->style = Qt::BrushStyle(0);
326 brush->color = Qt::black;
327 }
329 {
330 if (!brush->ref.deref())
331 delete brush;
332 brush = nullptr;
333 }
334};
335
336Q_GLOBAL_STATIC(QNullBrushData, nullBrushInstance_holder)
338{
339 return nullBrushInstance_holder()->brush;
340}
341
343 switch (style) {
345 qWarning("QBrush: Incorrect use of TexturePattern");
346 break;
350 qWarning("QBrush: Wrong use of a gradient pattern");
351 break;
352 default:
353 return true;
354 }
355 return false;
356}
357
363void QBrush::init(const QColor &color, Qt::BrushStyle style)
364{
365 switch(style) {
366 case Qt::NoBrush:
367 d.reset(nullBrushInstance());
368 d->ref.ref();
369 if (d->color != color) setColor(color);
370 return;
372 d.reset(new QTexturedBrushData);
373 break;
377 d.reset(new QGradientBrushData);
378 break;
379 default:
380 d.reset(new QBrushData);
381 break;
382 }
383 d->ref.storeRelaxed(1);
384 d->style = style;
385 d->color = color;
386}
387
395{
396 Q_ASSERT(d);
397 d->ref.ref();
398}
399
412
413
426
434 : QBrush(QColor(Qt::black), style)
435{
436}
437
445{
447 init(color, style);
448 else {
449 d.reset(nullBrushInstance());
450 d->ref.ref();
451 }
452}
453
465
481
497
503 : d(other.d.get())
504{
505 d->ref.ref();
506}
507
515QBrush::QBrush(const QGradient &gradient)
516{
518 d.reset(nullBrushInstance());
519 d->ref.ref();
520 return;
521 }
522
523 const Qt::BrushStyle enum_table[] = {
527 };
528
529 init(QColor(), enum_table[gradient.type()]);
530 QGradientBrushData *grad = static_cast<QGradientBrushData *>(d.get());
531 grad->gradient = gradient;
532}
533
539{
540}
541
542static constexpr inline bool use_same_brushdata(Qt::BrushStyle lhs, Qt::BrushStyle rhs)
543{
544 return lhs == rhs // includes Qt::TexturePattern
545 || (lhs >= Qt::NoBrush && lhs <= Qt::DiagCrossPattern && rhs >= Qt::NoBrush && rhs <= Qt::DiagCrossPattern)
546 || (lhs >= Qt::LinearGradientPattern && lhs <= Qt::ConicalGradientPattern && rhs >= Qt::LinearGradientPattern && rhs <= Qt::ConicalGradientPattern)
547 ;
548}
549
550void QBrush::detach(Qt::BrushStyle newStyle)
551{
552 if (use_same_brushdata(newStyle, d->style) && d->ref.loadRelaxed() == 1) {
553 d->style = newStyle;
554 return;
555 }
556
557 DataPtr x;
558 switch(newStyle) {
559 case Qt::TexturePattern: {
561 if (d->style == Qt::TexturePattern) {
562 QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.get());
563 if (data->m_has_pixmap_texture)
564 tbd->setPixmap(data->pixmap());
565 else
566 tbd->setImage(data->image());
567 }
568 x.reset(tbd);
569 break;
570 }
575 switch (d->style) {
579 gbd->gradient =
580 static_cast<QGradientBrushData *>(d.get())->gradient;
581 break;
582 default:
583 break;
584 }
585 x.reset(gbd);
586 break;
587 }
588 default:
589 x.reset(new QBrushData);
590 break;
591 }
592 x->ref.storeRelaxed(1); // must be first lest the QBrushDataPointerDeleter turns into a no-op
593 x->style = newStyle;
594 x->color = d->color;
595 x->transform = d->transform;
596 d.swap(x);
597}
598
599
608{
609 if (d == b.d)
610 return *this;
611
612 b.d->ref.ref();
613 d.reset(b.d.get());
614 return *this;
615}
616
636QBrush::operator QVariant() const
637{
638 return QVariant::fromValue(*this);
639}
640
656{
657 if (d->style == style)
658 return;
659
661 detach(style);
662 d->style = style;
663 }
664}
665
666
688{
689 if (d->color == c)
690 return;
691
692 detach(d->style);
693 d->color = c;
694}
695
712{
713 return d->style == Qt::TexturePattern
714 ? (static_cast<QTexturedBrushData *>(d.get()))->pixmap()
715 : QPixmap();
716}
717
729{
730 if (!pixmap.isNull()) {
731 detach(Qt::TexturePattern);
732 QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.get());
734 } else {
735 detach(Qt::NoBrush);
736 }
737}
738
739
753{
754 return d->style == Qt::TexturePattern
755 ? (static_cast<QTexturedBrushData *>(d.get()))->image()
756 : QImage();
757}
758
759
777{
778 if (!image.isNull()) {
779 detach(Qt::TexturePattern);
780 QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.get());
782 } else {
783 detach(Qt::NoBrush);
784 }
785}
786
787
792{
793 if (d->style == Qt::LinearGradientPattern
794 || d->style == Qt::RadialGradientPattern
795 || d->style == Qt::ConicalGradientPattern) {
796 return &static_cast<const QGradientBrushData *>(d.get())->gradient;
797 }
798 return nullptr;
799}
800
801Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush)
802{
803 if (brush.style() == Qt::RadialGradientPattern) {
804 const QGradient *g = brush.gradient();
805 const QRadialGradient *rg = static_cast<const QRadialGradient *>(g);
806
807 if (!qFuzzyIsNull(rg->focalRadius()))
808 return true;
809
810 QPointF delta = rg->focalPoint() - rg->center();
811 if (delta.x() * delta.x() + delta.y() * delta.y() > rg->radius() * rg->radius())
812 return true;
813 }
814
815 return false;
816}
817
831{
832 bool opaqueColor = d->color.alphaF() >= 1.0f;
833
834 // Test awfully simple case first
835 if (d->style == Qt::SolidPattern)
836 return opaqueColor;
837
839 return false;
840
841 if (d->style == Qt::LinearGradientPattern
842 || d->style == Qt::RadialGradientPattern
843 || d->style == Qt::ConicalGradientPattern) {
844 QGradientStops stops = gradient()->stops();
845 for (int i=0; i<stops.size(); ++i)
846 if (stops.at(i).second.alphaF() < 1.0f)
847 return false;
848 return true;
849 } else if (d->style == Qt::TexturePattern) {
850 return qHasPixmapTexture(*this)
853 }
854
855 return false;
856}
857
868{
869 detach(d->style);
870 d->transform = matrix;
871}
872
873
898bool QBrush::operator==(const QBrush &b) const
899{
900 if (b.d == d)
901 return true;
902 if (b.d->style != d->style || b.d->color != d->color || b.d->transform != d->transform)
903 return false;
904 switch (d->style) {
906 {
907 // Note this produces false negatives if the textures have identical data,
908 // but does not share the same data in memory. Since equality is likely to
909 // be used to avoid iterating over the data for a texture update, this should
910 // still be better than doing an accurate comparison.
911 const QPixmap *us = nullptr, *them = nullptr;
912 qint64 cacheKey1, cacheKey2;
913 if (qHasPixmapTexture(*this)) {
914 us = (static_cast<QTexturedBrushData *>(d.get()))->m_pixmap;
915 cacheKey1 = us->cacheKey();
916 } else
917 cacheKey1 = (static_cast<QTexturedBrushData *>(d.get()))->image().cacheKey();
918
919 if (qHasPixmapTexture(b)) {
920 them = (static_cast<QTexturedBrushData *>(b.d.get()))->m_pixmap;
921 cacheKey2 = them->cacheKey();
922 } else
923 cacheKey2 = (static_cast<QTexturedBrushData *>(b.d.get()))->image().cacheKey();
924
925 if (cacheKey1 != cacheKey2)
926 return false;
927 if (!us == !them) // both images or both pixmaps
928 return true;
929 // Only raster QPixmaps use the same cachekeys as QImages.
930 if (us && us->handle()->classId() == QPlatformPixmap::RasterClass)
931 return true;
932 if (them && them->handle()->classId() == QPlatformPixmap::RasterClass)
933 return true;
934 return false;
935 }
939 {
940 const QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d.get());
941 const QGradientBrushData *d2 = static_cast<QGradientBrushData *>(b.d.get());
942 return d1->gradient == d2->gradient;
943 }
944 default:
945 return true;
946 }
947}
948
949#ifndef QT_NO_DEBUG_STREAM
954{
955 static constexpr auto BRUSH_STYLES = qOffsetStringArray(
956 "NoBrush",
957 "SolidPattern",
958 "Dense1Pattern",
959 "Dense2Pattern",
960 "Dense3Pattern",
961 "Dense4Pattern",
962 "Dense5Pattern",
963 "Dense6Pattern",
964 "Dense7Pattern",
965 "HorPattern",
966 "VerPattern",
967 "CrossPattern",
968 "BDiagPattern",
969 "FDiagPattern",
970 "DiagCrossPattern",
971 "LinearGradientPattern",
972 "RadialGradientPattern",
973 "ConicalGradientPattern",
974 "", "", "", "", "", "",
975 "TexturePattern" // 24
976 );
977
978 QDebugStateSaver saver(dbg);
979 dbg.nospace() << "QBrush(" << b.color() << ',' << BRUSH_STYLES[b.style()] << ')';
980 return dbg;
981}
982#endif
983
984/*****************************************************************************
985 QBrush stream functions
986 *****************************************************************************/
987#ifndef QT_NO_DATASTREAM
999{
1000 quint8 style = (quint8) b.style();
1001 bool gradient_style = false;
1002
1004 || style == Qt::ConicalGradientPattern)
1005 gradient_style = true;
1006
1007 if (s.version() < QDataStream::Qt_4_0 && gradient_style)
1008 style = Qt::NoBrush;
1009
1010 s << style << b.color();
1011 if (b.style() == Qt::TexturePattern) {
1012 if (s.version() >= QDataStream::Qt_5_5)
1013 s << b.textureImage();
1014 else
1015 s << b.texture();
1016 } else if (s.version() >= QDataStream::Qt_4_0 && gradient_style) {
1017 const QGradient *gradient = b.gradient();
1018 int type_as_int = int(gradient->type());
1019 s << type_as_int;
1020 if (s.version() >= QDataStream::Qt_4_3) {
1021 s << int(gradient->spread());
1022 QGradient::CoordinateMode co_mode = gradient->coordinateMode();
1023 if (s.version() < QDataStream::Qt_5_12 && co_mode == QGradient::ObjectMode)
1025 s << int(co_mode);
1026 }
1027
1028 if (s.version() >= QDataStream::Qt_4_5)
1029 s << int(gradient->interpolationMode());
1030
1031 if (sizeof(qreal) == sizeof(double)) {
1032 s << gradient->stops();
1033 } else {
1034 // ensure that we write doubles here instead of streaming the stops
1035 // directly; otherwise, platforms that redefine qreal might generate
1036 // data that cannot be read on other platforms.
1037 QList<QGradientStop> stops = gradient->stops();
1038 s << quint32(stops.size());
1039 for (int i = 0; i < stops.size(); ++i) {
1040 const QGradientStop &stop = stops.at(i);
1041 s << QPair<double, QColor>(double(stop.first), stop.second);
1042 }
1043 }
1044
1045 if (gradient->type() == QGradient::LinearGradient) {
1046 s << static_cast<const QLinearGradient *>(gradient)->start();
1047 s << static_cast<const QLinearGradient *>(gradient)->finalStop();
1048 } else if (gradient->type() == QGradient::RadialGradient) {
1049 s << static_cast<const QRadialGradient *>(gradient)->center();
1050 s << static_cast<const QRadialGradient *>(gradient)->focalPoint();
1051 s << (double) static_cast<const QRadialGradient *>(gradient)->radius();
1052 if (s.version() >= QDataStream::Qt_6_0)
1053 s << (double) static_cast<const QRadialGradient *>(gradient)->focalRadius();
1054 } else { // type == Conical
1055 s << static_cast<const QConicalGradient *>(gradient)->center();
1056 s << (double) static_cast<const QConicalGradient *>(gradient)->angle();
1057 }
1058 }
1059 if (s.version() >= QDataStream::Qt_4_3)
1060 s << b.transform();
1061 return s;
1062}
1063
1075{
1076 quint8 style;
1077 QColor color;
1078 s >> style;
1079 s >> color;
1080 b = QBrush(color);
1081 if (style == Qt::TexturePattern) {
1082 if (s.version() >= QDataStream::Qt_5_5) {
1083 QImage img;
1084 s >> img;
1085 b.setTextureImage(std::move(img));
1086 } else {
1087 QPixmap pm;
1088 s >> pm;
1089 b.setTexture(std::move(pm));
1090 }
1091 } else if (style == Qt::LinearGradientPattern
1092 || style == Qt::RadialGradientPattern
1093 || style == Qt::ConicalGradientPattern) {
1094
1095 int type_as_int;
1097 QGradientStops stops;
1101
1102 s >> type_as_int;
1103 type = QGradient::Type(type_as_int);
1104 if (s.version() >= QDataStream::Qt_4_3) {
1105 s >> type_as_int;
1106 spread = QGradient::Spread(type_as_int);
1107 s >> type_as_int;
1108 cmode = QGradient::CoordinateMode(type_as_int);
1109 }
1110
1111 if (s.version() >= QDataStream::Qt_4_5) {
1112 s >> type_as_int;
1113 imode = QGradient::InterpolationMode(type_as_int);
1114 }
1115
1116 if (sizeof(qreal) == sizeof(double)) {
1117 s >> stops;
1118 } else {
1119 quint32 numStops;
1120 double n;
1121 QColor c;
1122
1123 s >> numStops;
1124 stops.reserve(numStops);
1125 for (quint32 i = 0; i < numStops; ++i) {
1126 s >> n >> c;
1127 stops << QPair<qreal, QColor>(n, c);
1128 }
1129 }
1130
1132 QPointF p1, p2;
1133 s >> p1;
1134 s >> p2;
1135 QLinearGradient lg(p1, p2);
1136 lg.setStops(stops);
1137 lg.setSpread(spread);
1138 lg.setCoordinateMode(cmode);
1139 lg.setInterpolationMode(imode);
1140 b = QBrush(lg);
1141 } else if (type == QGradient::RadialGradient) {
1142 QPointF center, focal;
1143 double radius;
1144 double focalRadius = 0;
1145 s >> center;
1146 s >> focal;
1147 s >> radius;
1148 QRadialGradient rg(center, radius, focal);
1149 rg.setStops(stops);
1150 rg.setSpread(spread);
1151 rg.setCoordinateMode(cmode);
1152 rg.setInterpolationMode(imode);
1153 if (s.version() >= QDataStream::Qt_6_0)
1154 s >> focalRadius;
1155 rg.setFocalRadius(focalRadius);
1156 b = QBrush(rg);
1157 } else { // type == QGradient::ConicalGradient
1158 QPointF center;
1159 double angle;
1160 s >> center;
1161 s >> angle;
1162 QConicalGradient cg(center, angle);
1163 cg.setStops(stops);
1164 cg.setSpread(spread);
1165 cg.setCoordinateMode(cmode);
1166 cg.setInterpolationMode(imode);
1167 b = QBrush(cg);
1168 }
1169 } else {
1170 b = QBrush(color, (Qt::BrushStyle)style);
1171 }
1172 if (s.version() >= QDataStream::Qt_4_3) {
1174 s >> transform;
1175 b.setTransform(transform);
1176 }
1177 return s;
1178}
1179#endif // QT_NO_DATASTREAM
1180
1181/*******************************************************************************
1182 * QGradient implementations
1183 */
1184
1185
1284 : m_type(NoGradient)
1285{
1286}
1287
1465#include "webgradients.cpp"
1466
1478 : m_type(LinearGradient)
1479 , m_stops(qt_preset_gradient_stops(preset))
1480 , m_data(qt_preset_gradient_data[preset - 1])
1481 , m_coordinateMode(ObjectMode)
1482{
1483}
1484
1491
1564{
1565 if ((pos > 1 || pos < 0) && !qIsNaN(pos)) {
1566 qWarning("QGradient::setColorAt: Color position must be specified in the range 0 to 1");
1567 return;
1568 }
1569
1570 int index = 0;
1571 if (!qIsNaN(pos))
1572 while (index < m_stops.size() && m_stops.at(index).first < pos) ++index;
1573
1574 if (index < m_stops.size() && m_stops.at(index).first == pos)
1575 m_stops[index].second = color;
1576 else
1577 m_stops.insert(index, QGradientStop(pos, color));
1578}
1579
1580static inline bool ok(QGradientStop stop)
1581{
1582 return stop.first >= 0 && stop.first <= 1; // rejects NaNs
1583}
1584
1585static inline bool ok(const QGradientStops &stops)
1586{
1587 qreal lastPos = -1;
1588 for (const QGradientStop &stop : stops) {
1589 if (Q_UNLIKELY(!ok(stop)))
1590 return false;
1591 const bool sorted = stop.first > lastPos; // rejects duplicates
1592 if (Q_UNLIKELY(!sorted))
1593 return false;
1594 lastPos = stop.first;
1595 }
1596 return true;
1597}
1598
1609{
1610 if (Q_LIKELY(ok(stops))) {
1611 // fast path for the common case: if everything is ok with the stops, just copy them
1612 m_stops = stops;
1613 return;
1614 }
1615 // otherwise, to keep the pre-5.9 behavior, add them one after another,
1616 // so each stop is checked, invalid ones are skipped, they are added in-order (which may be O(N^2)).
1617 m_stops.clear();
1618 for (int i=0; i<stops.size(); ++i)
1619 setColorAt(stops.at(i).first, stops.at(i).second);
1620}
1621
1622
1632{
1633 if (m_stops.isEmpty()) {
1634 static constexpr QGradientStop blackAndWhite[] = {
1636 };
1637 return QGradientStops::fromReadOnlyData(blackAndWhite);
1638 }
1639 return m_stops;
1640}
1641
1673{
1674 return m_coordinateMode;
1675}
1676
1684{
1685 m_coordinateMode = mode;
1686}
1687
1707{
1708 return m_interpolationMode;
1709}
1710
1719{
1720 m_interpolationMode = mode;
1721}
1722
1739bool QGradient::operator==(const QGradient &gradient) const
1740{
1741 if (gradient.m_type != m_type
1742 || gradient.m_spread != m_spread
1743 || gradient.m_coordinateMode != m_coordinateMode
1744 || gradient.m_interpolationMode != m_interpolationMode) return false;
1745
1746 if (m_type == LinearGradient) {
1747 if (m_data.linear.x1 != gradient.m_data.linear.x1
1748 || m_data.linear.y1 != gradient.m_data.linear.y1
1749 || m_data.linear.x2 != gradient.m_data.linear.x2
1750 || m_data.linear.y2 != gradient.m_data.linear.y2)
1751 return false;
1752 } else if (m_type == RadialGradient) {
1753 if (m_data.radial.cx != gradient.m_data.radial.cx
1754 || m_data.radial.cy != gradient.m_data.radial.cy
1755 || m_data.radial.fx != gradient.m_data.radial.fx
1756 || m_data.radial.fy != gradient.m_data.radial.fy
1757 || m_data.radial.cradius != gradient.m_data.radial.cradius
1758 || m_data.radial.fradius != gradient.m_data.radial.fradius)
1759 return false;
1760 } else { // m_type == ConicalGradient
1761 if (m_data.conical.cx != gradient.m_data.conical.cx
1762 || m_data.conical.cy != gradient.m_data.conical.cy
1763 || m_data.conical.angle != gradient.m_data.conical.angle)
1764 return false;
1765 }
1766
1767 return stops() == gradient.stops();
1768}
1769
1820{
1821 m_type = LinearGradient;
1822 m_spread = PadSpread;
1823 m_data.linear.x1 = 0;
1824 m_data.linear.y1 = 0;
1825 m_data.linear.x2 = 1;
1826 m_data.linear.y2 = 1;
1827}
1828
1829
1839{
1840 m_type = LinearGradient;
1841 m_spread = PadSpread;
1842 m_data.linear.x1 = start.x();
1843 m_data.linear.y1 = start.y();
1844 m_data.linear.x2 = finalStop.x();
1845 m_data.linear.y2 = finalStop.y();
1846}
1847
1858QLinearGradient::QLinearGradient(qreal xStart, qreal yStart, qreal xFinalStop, qreal yFinalStop)
1859 : QLinearGradient(QPointF(xStart, yStart), QPointF(xFinalStop, yFinalStop))
1860{
1861}
1862
1869
1877{
1878 Q_ASSERT(m_type == LinearGradient);
1879 return QPointF(m_data.linear.x1, m_data.linear.y1);
1880}
1881
1903{
1904 Q_ASSERT(m_type == LinearGradient);
1905 m_data.linear.x1 = start.x();
1906 m_data.linear.y1 = start.y();
1907}
1908
1909
1928{
1929 Q_ASSERT(m_type == LinearGradient);
1930 return QPointF(m_data.linear.x2, m_data.linear.y2);
1931}
1932
1933
1944{
1945 Q_ASSERT(m_type == LinearGradient);
1946 m_data.linear.x2 = stop.x();
1947 m_data.linear.y2 = stop.y();
1948}
1949
1950
2000 qreal radius,
2001 const QPointF &focalPoint)
2002{
2003 // We have a one pixel buffer zone to avoid numerical instability on the
2004 // circle border
2005 //### this is hacky because technically we should adjust based on current matrix
2006 const qreal compensated_radius = radius - radius * qreal(0.001);
2007 QLineF line(center, focalPoint);
2008 if (line.length() > (compensated_radius))
2009 line.setLength(compensated_radius);
2010 return line.p2();
2011}
2012
2026{
2027 m_type = RadialGradient;
2028 m_spread = PadSpread;
2029 m_data.radial.cx = center.x();
2030 m_data.radial.cy = center.y();
2031 m_data.radial.cradius = radius;
2032 m_data.radial.fradius = 0;
2033
2035 m_data.radial.fx = adapted_focal.x();
2036 m_data.radial.fy = adapted_focal.y();
2037}
2038
2046{
2047 m_type = RadialGradient;
2048 m_spread = PadSpread;
2049 m_data.radial.cx = center.x();
2050 m_data.radial.cy = center.y();
2051 m_data.radial.cradius = radius;
2052 m_data.radial.fradius = 0;
2053 m_data.radial.fx = center.x();
2054 m_data.radial.fy = center.y();
2055}
2056
2057
2071 : QRadialGradient(QPointF(cx, cy), radius, QPointF(fx, fy))
2072{
2073}
2074
2082 : QRadialGradient(QPointF(cx, cy), radius)
2083{
2084}
2085
2086
2092{
2093 m_type = RadialGradient;
2094 m_spread = PadSpread;
2095 m_data.radial.cx = 0;
2096 m_data.radial.cy = 0;
2097 m_data.radial.cradius = 1;
2098 m_data.radial.fradius = 0;
2099 m_data.radial.fx = 0;
2100 m_data.radial.fy = 0;
2101}
2102
2109QRadialGradient::QRadialGradient(const QPointF &center, qreal centerRadius, const QPointF &focalPoint, qreal focalRadius)
2110{
2111 m_type = RadialGradient;
2112 m_spread = PadSpread;
2113 m_data.radial.cx = center.x();
2114 m_data.radial.cy = center.y();
2115 m_data.radial.cradius = centerRadius;
2116 m_data.radial.fradius = 0;
2117
2118 m_data.radial.fx = focalPoint.x();
2119 m_data.radial.fy = focalPoint.y();
2121}
2122
2130QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius)
2131{
2132 m_type = RadialGradient;
2133 m_spread = PadSpread;
2134 m_data.radial.cx = cx;
2135 m_data.radial.cy = cy;
2136 m_data.radial.cradius = centerRadius;
2137 m_data.radial.fradius = 0;
2138
2139 m_data.radial.fx = fx;
2140 m_data.radial.fy = fy;
2142}
2143
2150
2158{
2159 Q_ASSERT(m_type == RadialGradient);
2160 return QPointF(m_data.radial.cx, m_data.radial.cy);
2161}
2162
2184{
2185 Q_ASSERT(m_type == RadialGradient);
2186 m_data.radial.cx = center.x();
2187 m_data.radial.cy = center.y();
2188}
2189
2190
2200{
2201 Q_ASSERT(m_type == RadialGradient);
2202 return m_data.radial.cradius;
2203}
2204
2205
2215{
2216 Q_ASSERT(m_type == RadialGradient);
2217 m_data.radial.cradius = radius;
2218}
2219
2229{
2230 Q_ASSERT(m_type == RadialGradient);
2231 return m_data.radial.cradius;
2232}
2233
2241{
2242 Q_ASSERT(m_type == RadialGradient);
2243 m_data.radial.cradius = radius;
2244}
2245
2255{
2256 Q_ASSERT(m_type == RadialGradient);
2257 return m_data.radial.fradius;
2258}
2259
2267{
2268 Q_ASSERT(m_type == RadialGradient);
2269 m_data.radial.fradius = radius;
2270}
2271
2280{
2281 Q_ASSERT(m_type == RadialGradient);
2282 return QPointF(m_data.radial.fx, m_data.radial.fy);
2283}
2284
2306{
2307 Q_ASSERT(m_type == RadialGradient);
2308 m_data.radial.fx = focalPoint.x();
2309 m_data.radial.fy = focalPoint.y();
2310}
2311
2312
2313
2360{
2361 m_type = ConicalGradient;
2362 m_spread = PadSpread;
2363 m_data.conical.cx = center.x();
2364 m_data.conical.cy = center.y();
2365 m_data.conical.angle = angle;
2366}
2367
2368
2381
2388
2389
2398{
2399 m_type = ConicalGradient;
2400 m_spread = PadSpread;
2401 m_data.conical.cx = 0;
2402 m_data.conical.cy = 0;
2403 m_data.conical.angle = 0;
2404}
2405
2406
2415{
2416 Q_ASSERT(m_type == ConicalGradient);
2417 return QPointF(m_data.conical.cx, m_data.conical.cy);
2418}
2419
2420
2440{
2441 Q_ASSERT(m_type == ConicalGradient);
2442 m_data.conical.cx = center.x();
2443 m_data.conical.cy = center.y();
2444}
2445
2454{
2455 Q_ASSERT(m_type == ConicalGradient);
2456 return m_data.conical.angle;
2457}
2458
2459
2470{
2471 Q_ASSERT(m_type == ConicalGradient);
2472 m_data.conical.angle = angle;
2473}
2474
2515
2516#include "moc_qbrush.cpp"
NSData * m_data
static QBitmap fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat=QImage::Format_MonoLSB)
Constructs a bitmap with the given size, and sets the contents to the bits supplied.
Definition qbitmap.cpp:207
QImage getImage(int brushStyle, bool invert) const
Definition qbrush.cpp:117
\inmodule QtGui
Definition qbrush.h:30
void setColor(const QColor &color)
Sets the brush color to the given color.
Definition qbrush.cpp:687
void setStyle(Qt::BrushStyle)
Sets the brush style to style.
Definition qbrush.cpp:655
void setTransform(const QTransform &)
Definition qbrush.cpp:867
QBrush & operator=(const QBrush &brush)
Assigns the given brush to this brush and returns a reference to this brush.
Definition qbrush.cpp:607
std::unique_ptr< QBrushData, QBrushDataPointerDeleter > DataPtr
Definition qbrush.h:77
void setTextureImage(const QImage &image)
Definition qbrush.cpp:776
bool operator==(const QBrush &b) const
Returns true if the brush is equal to the given brush; otherwise returns false.
Definition qbrush.cpp:898
friend bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush &brush)
Definition qbrush.cpp:202
bool isOpaque() const
Returns true if the brush is fully opaque otherwise false.
Definition qbrush.cpp:830
const QGradient * gradient() const
Returns the gradient describing this brush.
Definition qbrush.cpp:791
QBrush()
Constructs a default black brush with the style Qt::NoBrush (i.e.
Definition qbrush.cpp:393
void setTexture(const QPixmap &pixmap)
Sets the brush pixmap to pixmap.
Definition qbrush.cpp:728
~QBrush()
Destroys the brush.
Definition qbrush.cpp:538
QImage textureImage() const
Definition qbrush.cpp:752
QPixmap texture() const
Returns the custom brush pattern, or a null pixmap if no custom brush pattern has been set.
Definition qbrush.cpp:711
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
Qt::BrushStyle style() const
Returns the brush style.
Definition qbrush.h:120
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtGui
Definition qbrush.h:446
void setCenter(const QPointF &center)
Sets the center of this conical gradient in logical coordinates to center.
Definition qbrush.cpp:2439
qreal angle() const
Returns the start angle of the conical gradient in logical coordinates.
Definition qbrush.cpp:2453
QConicalGradient()
Constructs a conical with center at (0, 0) starting the interpolation at angle 0.
Definition qbrush.cpp:2397
void setAngle(qreal angle)
Definition qbrush.cpp:2469
QPointF center() const
Returns the center of the conical gradient in logical coordinates.
Definition qbrush.cpp:2414
\inmodule QtCore\reentrant
Definition qdatastream.h:46
\inmodule QtCore
\inmodule QtCore
\inmodule QtGui
Definition qbrush.h:135
QGradientStop
Typedef for QPair<\l qreal, QColor>.
Definition qbrush.h:131
void setSpread(Spread spread)
Specifies the spread method that should be used for this gradient.
Definition qbrush.h:390
void setCoordinateMode(CoordinateMode mode)
Definition qbrush.cpp:1683
Spread spread() const
Returns the spread method use by this gradient.
Definition qbrush.h:347
InterpolationMode
Definition qbrush.h:161
@ ColorInterpolation
Definition qbrush.h:162
CoordinateMode coordinateMode() const
Definition qbrush.cpp:1672
void setStops(const QGradientStops &stops)
Replaces the current set of stop points with the given stopPoints.
Definition qbrush.cpp:1608
CoordinateMode
Definition qbrush.h:153
@ ObjectBoundingMode
Definition qbrush.h:156
@ LogicalMode
Definition qbrush.h:154
@ ObjectMode
Definition qbrush.h:157
void setColorAt(qreal pos, const QColor &color)
Creates a stop point at the given position with the given color.
Definition qbrush.cpp:1563
InterpolationMode interpolationMode() const
Definition qbrush.cpp:1706
Spread
Specifies how the area outside the gradient area should be filled.
Definition qbrush.h:146
@ PadSpread
Definition qbrush.h:147
Type type() const
Returns the type of gradient.
Definition qbrush.h:344
void setInterpolationMode(InterpolationMode mode)
Definition qbrush.cpp:1718
QGradientStops stops() const
Returns the stop points for this gradient.
Definition qbrush.cpp:1631
bool operator==(const QGradient &gradient) const
Returns true if the gradient is the same as the other gradient specified; otherwise returns false.
Definition qbrush.cpp:1739
Type
Specifies the type of gradient.
Definition qbrush.h:138
@ LinearGradient
Definition qbrush.h:139
@ NoGradient
Definition qbrush.h:142
@ ConicalGradient
Definition qbrush.h:141
@ RadialGradient
Definition qbrush.h:140
\inmodule QtGui
Definition qimage.h:37
bool hasAlphaChannel() const
Returns true if the image has a format that respects the alpha channel, otherwise returns false.
Definition qimage.cpp:4589
bool isNull() const
Returns true if it is a null image, otherwise returns false.
Definition qimage.cpp:1222
@ Format_MonoLSB
Definition qimage.h:44
\inmodule QtCore\compares equality \compareswith equality QLine \endcompareswith
Definition qline.h:192
\inmodule QtGui
Definition qbrush.h:394
QPointF start() const
Returns the start point of this linear gradient in logical coordinates.
Definition qbrush.cpp:1876
QPointF finalStop() const
Returns the final stop point of this linear gradient in logical coordinates.
Definition qbrush.cpp:1927
QLinearGradient()
Constructs a default linear gradient with interpolation area between (0, 0) and (1,...
Definition qbrush.cpp:1819
void setFinalStop(const QPointF &stop)
Definition qbrush.cpp:1943
void setStart(const QPointF &start)
Definition qbrush.cpp:1902
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
iterator insert(qsizetype i, parameter_type t)
Definition qlist.h:488
static QList< QGradientStop > fromReadOnlyData(const QGradientStop(&t)[N]) noexcept
Definition qlist.h:729
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
void reserve(qsizetype size)
Definition qlist.h:753
void clear()
Definition qlist.h:434
QBrushData * brush
Definition qbrush.cpp:321
static bool find(const QString &key, QPixmap *pixmap)
Looks for a cached pixmap associated with the given key in the cache.
static bool insert(const QString &key, const QPixmap &pixmap)
Inserts a copy of the pixmap pixmap associated with the key into the cache.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
QImage toImage() const
Converts the pixmap to a QImage.
Definition qpixmap.cpp:408
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
Definition qpixmap.cpp:456
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Converts the given image to a pixmap using the specified flags to control the conversion.
Definition qpixmap.cpp:1437
qint64 cacheKey() const
Returns a number that identifies this QPixmap.
Definition qpixmap.cpp:884
bool hasAlphaChannel() const
bool isQBitmap() const
Returns true if this is a QBitmap; otherwise returns false.
Definition qpixmap.cpp:443
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
\inmodule QtGui
Definition qbrush.h:412
void setCenter(const QPointF &center)
Definition qbrush.cpp:2183
QPointF center() const
Returns the center of this radial gradient in logical coordinates.
Definition qbrush.cpp:2157
qreal focalRadius() const
Definition qbrush.cpp:2254
void setFocalPoint(const QPointF &focalPoint)
Definition qbrush.cpp:2305
QRadialGradient()
Constructs a simple radial gradient with the center and focal point at (0, 0) with a radius of 1.
Definition qbrush.cpp:2091
void setCenterRadius(qreal radius)
Definition qbrush.cpp:2240
QPointF focalPoint() const
Returns the focal point of this radial gradient in logical coordinates.
Definition qbrush.cpp:2279
qreal centerRadius() const
Definition qbrush.cpp:2228
void setFocalRadius(qreal radius)
Definition qbrush.cpp:2266
qreal radius() const
Returns the radius of this radial gradient in logical coordinates.
Definition qbrush.cpp:2199
void setRadius(qreal radius)
Definition qbrush.cpp:2214
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
qsizetype length() const noexcept
Returns the number of characters in this string.
Definition qstring.h:191
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
\inmodule QtCore
Definition qvariant.h:65
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
QPixmap p2
QPixmap p1
[0]
constexpr QColor White
Definition qcolor.h:294
constexpr QColor Black
Definition qcolor.h:293
Combined button and popup list for selecting options.
Definition qcompare.h:63
GlobalColor
Definition qnamespace.h:27
@ black
Definition qnamespace.h:30
BrushStyle
@ DiagCrossPattern
@ SolidPattern
@ RadialGradientPattern
@ Dense1Pattern
@ TexturePattern
@ LinearGradientPattern
@ NoBrush
@ ConicalGradientPattern
Definition brush.cpp:5
Definition image.cpp:4
Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert)
Definition qbrush.cpp:146
static bool qbrush_check_type(Qt::BrushStyle style)
Definition qbrush.cpp:342
Q_GUI_EXPORT QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
Definition qbrush.cpp:80
static constexpr bool use_same_brushdata(Qt::BrushStyle lhs, Qt::BrushStyle rhs)
Definition qbrush.cpp:542
QDebug operator<<(QDebug dbg, const QBrush &b)
Definition qbrush.cpp:953
bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush &brush)
Definition qbrush.cpp:202
static void qt_cleanup_brush_pattern_image_cache()
Definition qbrush.cpp:141
static QPointF qt_radial_gradient_adapt_focal_point(const QPointF &center, qreal radius, const QPointF &focalPoint)
Definition qbrush.cpp:1999
static void deleteData(QBrushData *d)
Definition qbrush.cpp:215
static QBrushData * nullBrushInstance()
Definition qbrush.cpp:337
const uchar * qt_patternForBrush(int brushStyle, bool invert)
Definition qbrush.cpp:32
QDataStream & operator>>(QDataStream &s, QBrush &b)
Definition qbrush.cpp:1074
Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush)
Definition qbrush.cpp:801
QPair< qreal, QColor > QGradientStop
Definition qbrush.h:131
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
void qAddPostRoutine(QtCleanUpFunction p)
static QDBusError::ErrorType get(const char *name)
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:349
bool qIsNaN(qfloat16 f) noexcept
Definition qfloat16.h:284
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
constexpr auto qOffsetStringArray(const char(&...strings)[Nx]) noexcept
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLuint64 key
GLuint index
[2]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint GLuint focalPoint
GLuint color
[2]
GLenum type
GLfloat angle
GLuint start
GLboolean GLboolean g
GLfloat n
GLuint GLenum GLenum transform
GLdouble s
[6]
Definition qopenglext.h:235
const GLubyte * c
GLint void * img
Definition qopenglext.h:233
GLuint GLenum matrix
GLboolean invert
Definition qopenglext.h:226
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int quint32
Definition qtypes.h:50
unsigned char uchar
Definition qtypes.h:32
long long qint64
Definition qtypes.h:60
double qreal
Definition qtypes.h:187
unsigned char quint8
Definition qtypes.h:46
QDate d1(1995, 5, 17)
[0]
QDate d2(1995, 5, 20)
QSharedPointer< T > other(t)
[5]
widget render & pixmap
QGraphicsSvgItem * black
void operator()(QBrushData *d) const noexcept
Definition qbrush.cpp:231
QGradient gradient
Definition qbrush.cpp:212
\inmodule QtCore \reentrant
Definition qchar.h:18
void setImage(const QImage &image)
Definition qbrush.cpp:175
QPixmap & pixmap()
Definition qbrush.cpp:182
QPixmap * m_pixmap
Definition qbrush.cpp:195
void setPixmap(const QPixmap &pm)
Definition qbrush.cpp:161
QImage & image()
Definition qbrush.cpp:189
bool m_has_pixmap_texture
Definition qbrush.cpp:197
struct QGradient::QGradientData::@202 conical
struct QGradient::QGradientData::@200 linear
struct QGradient::QGradientData::@201 radial
static QList< QGradientStop > qt_preset_gradient_stops(QGradient::Preset preset)
static constexpr QGradient::QGradientData qt_preset_gradient_data[]