34 Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
35 static const uchar pat_tbl[][2][8] = {
37 { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
38 { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
40 { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
41 { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
43 { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
44 { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
46 { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
47 { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 },
49 { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
50 { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
52 { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
53 { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
55 { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
56 { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
58 { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff },
59 { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 },
61 { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef },
62 { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
64 { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef },
65 { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 },
67 { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe },
68 { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 },
70 { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f },
71 { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
73 { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e },
74 { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 },
77 return pat_tbl[brushStyle - Qt::Dense1Pattern][invert];
80Q_GUI_EXPORT
QPixmap qt_pixmapForBrush(
int brushStyle,
bool invert)
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),
89 QImage::Format_MonoLSB);
90 QPixmapCache::insert(key, pm);
101 : m_initialized(
false)
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);
114 m_initialized =
true;
119 Q_ASSERT(brushStyle >= Qt::Dense1Pattern && brushStyle <= Qt::DiagCrossPattern);
122 return m_images[brushStyle - Qt::Dense1Pattern][invert];
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();
131 m_initialized =
false;
135 QImage m_images[Qt::DiagCrossPattern - Qt::Dense1Pattern + 1][2];
143 qt_brushPatternImageCache()->cleanup();
146Q_GUI_EXPORT
QImage qt_imageForBrush(
int brushStyle,
bool invert)
148 return qt_brushPatternImageCache()->getImage(brushStyle, invert);
172 m_pixmap =
new QPixmap(pm);
188 m_pixmap =
new QPixmap(QPixmap::fromImage(m_image));
194 if (m_image.isNull() && m_pixmap)
195 m_image = m_pixmap->toImage();
208 if (brush.style() != Qt::TexturePattern)
210 QTexturedBrushData *tx_data =
static_cast<QTexturedBrushData *>(brush.d.get());
211 return tx_data->m_has_pixmap_texture;
222 case Qt::TexturePattern:
225 case Qt::LinearGradientPattern:
226 case Qt::RadialGradientPattern:
227 case Qt::ConicalGradientPattern:
231 case Qt::SolidPattern:
232 case Qt::Dense1Pattern:
233 case Qt::Dense2Pattern:
234 case Qt::Dense3Pattern:
235 case Qt::Dense4Pattern:
236 case Qt::Dense5Pattern:
237 case Qt::Dense6Pattern:
238 case Qt::Dense7Pattern:
241 case Qt::CrossPattern:
242 case Qt::BDiagPattern:
243 case Qt::FDiagPattern:
244 case Qt::DiagCrossPattern:
252 if (d && !d->ref.deref())
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
343 brush->ref.storeRelaxed(1);
344 brush->style = Qt::BrushStyle(0);
345 brush->color = Qt::black;
349 if (!
brush->ref.deref())
358 return nullBrushInstance_holder()->brush;
363 case Qt::TexturePattern:
364 qWarning(
"QBrush: Incorrect use of TexturePattern");
366 case Qt::LinearGradientPattern:
367 case Qt::RadialGradientPattern:
368 case Qt::ConicalGradientPattern:
369 qWarning(
"QBrush: Wrong use of a gradient pattern");
378
379
380
382void QBrush::init(
const QColor &color, Qt::BrushStyle style)
386 d.reset(nullBrushInstance());
388 if (d->color != color) setColor(color);
390 case Qt::TexturePattern:
391 d.reset(
new QTexturedBrushData);
393 case Qt::LinearGradientPattern:
394 case Qt::RadialGradientPattern:
395 case Qt::ConicalGradientPattern:
396 d.reset(
new QGradientBrushData);
398 case Qt::SolidPattern:
399 case Qt::Dense1Pattern:
400 case Qt::Dense2Pattern:
401 case Qt::Dense3Pattern:
402 case Qt::Dense4Pattern:
403 case Qt::Dense5Pattern:
404 case Qt::Dense6Pattern:
405 case Qt::Dense7Pattern:
408 case Qt::CrossPattern:
409 case Qt::BDiagPattern:
410 case Qt::FDiagPattern:
411 case Qt::DiagCrossPattern:
412 d.reset(
new QBasicBrushData);
415 d->ref.storeRelaxed(1);
421
422
423
426 : d(nullBrushInstance())
433
434
435
436
437
439QBrush::QBrush(
const QPixmap &pixmap)
441 init(Qt::black, Qt::TexturePattern);
447
448
449
450
451
453QBrush::QBrush(
const QImage &image)
455 init(Qt::black, Qt::TexturePattern);
456 setTextureImage(image);
460
461
462
463
465QBrush::QBrush(Qt::BrushStyle style)
466 : QBrush(QColor(Qt::black), style)
471
472
473
474
476QBrush::QBrush(
const QColor &color, Qt::BrushStyle style)
478 if (qbrush_check_type(style))
481 d.reset(nullBrushInstance());
487
488
489
490
491
492
493QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style)
494 : QBrush(QColor(color), style)
499
500
501
502
503
504
505
506
508QBrush::QBrush(
const QColor &color,
const QPixmap &pixmap)
510 init(color, Qt::TexturePattern);
515
516
517
518
519
520
521
522
523
524QBrush::QBrush(Qt::GlobalColor color,
const QPixmap &pixmap)
526 init(color, Qt::TexturePattern);
531
532
534QBrush::QBrush(
const QBrush &other)
541
542
543
544
545
546
547QBrush::QBrush(
const QGradient &gradient)
549 if (Q_UNLIKELY(gradient.type() == QGradient::NoGradient)) {
550 d.reset(nullBrushInstance());
555 const Qt::BrushStyle enum_table[] = {
556 Qt::LinearGradientPattern,
557 Qt::RadialGradientPattern,
558 Qt::ConicalGradientPattern
561 init(QColor(), enum_table[gradient.type()]);
562 QGradientBrushData *grad =
static_cast<QGradientBrushData *>(d.get());
563 grad->gradient = gradient;
567
568
577 || (lhs >= Qt::NoBrush && lhs <= Qt::DiagCrossPattern && rhs >= Qt::NoBrush && rhs <= Qt::DiagCrossPattern)
578 || (lhs >= Qt::LinearGradientPattern && lhs <= Qt::ConicalGradientPattern && rhs >= Qt::LinearGradientPattern && rhs <= Qt::ConicalGradientPattern)
582void QBrush::detach(Qt::BrushStyle newStyle)
584 if (use_same_brushdata(newStyle, d->style) && d->ref.loadRelaxed() == 1) {
591 case Qt::TexturePattern: {
592 QTexturedBrushData *tbd =
new QTexturedBrushData;
593 if (d->style == Qt::TexturePattern) {
594 QTexturedBrushData *data =
static_cast<QTexturedBrushData *>(d.get());
595 if (data->m_has_pixmap_texture)
596 tbd->setPixmap(data->pixmap());
598 tbd->setImage(data->image());
603 case Qt::LinearGradientPattern:
604 case Qt::RadialGradientPattern:
605 case Qt::ConicalGradientPattern: {
606 QGradientBrushData *gbd =
new QGradientBrushData;
608 case Qt::LinearGradientPattern:
609 case Qt::RadialGradientPattern:
610 case Qt::ConicalGradientPattern:
612 static_cast<QGradientBrushData *>(d.get())->gradient;
621 case Qt::SolidPattern:
622 case Qt::Dense1Pattern:
623 case Qt::Dense2Pattern:
624 case Qt::Dense3Pattern:
625 case Qt::Dense4Pattern:
626 case Qt::Dense5Pattern:
627 case Qt::Dense6Pattern:
628 case Qt::Dense7Pattern:
631 case Qt::CrossPattern:
632 case Qt::BDiagPattern:
633 case Qt::FDiagPattern:
634 case Qt::DiagCrossPattern:
635 x.reset(
new QBasicBrushData);
638 x->ref.storeRelaxed(1);
641 x->transform = d->transform;
647
648
649
651QBrush &QBrush::operator=(
const QBrush &brush)
657 d.reset(brush.d.get());
662
663
664
665
666
667
668
669
670QBrush &QBrush::operator=(QColor color)
672 detach(Qt::SolidPattern);
679
680
681
682
683
684
685QBrush &QBrush::operator=(Qt::BrushStyle style)
688 d->color = Qt::black;
694
695
696
697
698
699
702
703
704
705
708
709
710QBrush::operator QVariant()
const
712 return QVariant::fromValue(*
this);
716
717
718
719
720
721
724
725
726
727
729void QBrush::setStyle(Qt::BrushStyle style)
731 if (d->style == style)
734 if (qbrush_check_type(style)) {
742
743
744
745
746
747
750
751
752
753
754
755
756
757
758
759
761void QBrush::setColor(
const QColor &c)
771
772
773
774
775
778
779
780
781
782
783
784
785QPixmap QBrush::texture()
const
787 return d->style == Qt::TexturePattern
788 ? (
static_cast<QTexturedBrushData *>(d.get()))->pixmap()
793
794
795
796
797
798
799
800
802void QBrush::setTexture(
const QPixmap &pixmap)
804 if (!pixmap.isNull()) {
805 detach(Qt::TexturePattern);
806 QTexturedBrushData *data =
static_cast<QTexturedBrushData *>(d.get());
807 data->setPixmap(pixmap);
815
816
817
818
819
820
821
822
823
824
826QImage QBrush::textureImage()
const
828 return d->style == Qt::TexturePattern
829 ? (
static_cast<QTexturedBrushData *>(d.get()))->image()
835
836
837
838
839
840
841
842
843
844
845
846
847
848
850void QBrush::setTextureImage(
const QImage &image)
852 if (!image.isNull()) {
853 detach(Qt::TexturePattern);
854 QTexturedBrushData *data =
static_cast<QTexturedBrushData *>(d.get());
855 data->setImage(image);
863
864
865const QGradient *QBrush::gradient()
const
867 if (d->style == Qt::LinearGradientPattern
868 || d->style == Qt::RadialGradientPattern
869 || d->style == Qt::ConicalGradientPattern) {
870 return &
static_cast<
const QGradientBrushData *>(d.get())->gradient;
877 if (brush.style() == Qt::RadialGradientPattern) {
878 const QGradient *g = brush.gradient();
879 const QRadialGradient *rg =
static_cast<
const QRadialGradient *>(g);
881 if (!qFuzzyIsNull(rg->focalRadius()))
884 QPointF delta = rg->focalPoint() - rg->center();
885 if (delta.x() * delta.x() + delta.y() * delta.y() > rg->radius() * rg->radius())
893
894
895
896
897
898
899
900
901
902
904bool QBrush::isOpaque()
const
906 bool opaqueColor = d->color.alphaF() >= 1.0f;
909 if (d->style == Qt::SolidPattern)
912 if (qt_isExtendedRadialGradient(*
this))
915 if (d->style == Qt::LinearGradientPattern
916 || d->style == Qt::RadialGradientPattern
917 || d->style == Qt::ConicalGradientPattern) {
918 QGradientStops stops = gradient()->stops();
919 for (
int i=0; i<stops.size(); ++i)
920 if (stops.at(i).second.alphaF() < 1.0f)
923 }
else if (d->style == Qt::TexturePattern) {
924 return qHasPixmapTexture(*
this)
925 ? !texture().hasAlphaChannel() && !texture().isQBitmap()
926 : !textureImage().hasAlphaChannel();
933
934
935
936
937
938
939
940
941void QBrush::setTransform(
const QTransform &matrix)
944 d->transform = matrix;
949
950
951
952
953
954
955
956
957
958
961
962
963
964
965
966
967
968
969
970
972bool QBrush::operator==(
const QBrush &b)
const
976 if (b.d->style != d->style || b.d->color != d->color || b.d->transform != d->transform)
979 case Qt::TexturePattern:
985 const QPixmap *us =
nullptr, *them =
nullptr;
986 qint64 cacheKey1, cacheKey2;
987 if (qHasPixmapTexture(*
this)) {
988 us = (
static_cast<QTexturedBrushData *>(d.get()))->m_pixmap;
989 cacheKey1 = us->cacheKey();
991 cacheKey1 = (
static_cast<QTexturedBrushData *>(d.get()))->image().cacheKey();
993 if (qHasPixmapTexture(b)) {
994 them = (
static_cast<QTexturedBrushData *>(b.d.get()))->m_pixmap;
995 cacheKey2 = them->cacheKey();
997 cacheKey2 = (
static_cast<QTexturedBrushData *>(b.d.get()))->image().cacheKey();
999 if (cacheKey1 != cacheKey2)
1004 if (us && us->handle()->classId() == QPlatformPixmap::RasterClass)
1006 if (them && them->handle()->classId() == QPlatformPixmap::RasterClass)
1010 case Qt::LinearGradientPattern:
1011 case Qt::RadialGradientPattern:
1012 case Qt::ConicalGradientPattern:
1014 const QGradientBrushData *d1 =
static_cast<QGradientBrushData *>(d.get());
1015 const QGradientBrushData *d2 =
static_cast<QGradientBrushData *>(b.d.get());
1016 return d1->gradient == d2->gradient;
1024
1025
1026bool QBrush::doCompareEqualColor(QColor rhs)
const noexcept
1028 return style() == Qt::SolidPattern && color() == rhs && d->transform.isIdentity();
1032
1033
1034bool QBrush::doCompareEqualStyle(Qt::BrushStyle rhs)
const noexcept
1038 case Qt::TexturePattern:
1039 case Qt::LinearGradientPattern:
1040 case Qt::RadialGradientPattern:
1041 case Qt::ConicalGradientPattern:
1044 return style() == Qt::NoBrush;
1046 return style() == rhs && color() == QColor(0, 0, 0);
1050#ifndef QT_NO_DEBUG_STREAM
1052
1053
1056 static constexpr auto BRUSH_STYLES = qOffsetStringArray(
1072 "LinearGradientPattern",
1073 "RadialGradientPattern",
1074 "ConicalGradientPattern",
1075 "",
"",
"",
"",
"",
"",
1079 QDebugStateSaver saver(dbg);
1080 dbg.nospace() <<
"QBrush(" << b.color() <<
',' << BRUSH_STYLES[b.style()] <<
')';
1086
1087
1088#ifndef QT_NO_DATASTREAM
1090
1091
1092
1093
1094
1095
1096
1097
1099QDataStream &operator<<(QDataStream &s,
const QBrush &b)
1101 quint8 style = (quint8) b.style();
1102 bool gradient_style =
false;
1104 if (style == Qt::LinearGradientPattern || style == Qt::RadialGradientPattern
1105 || style == Qt::ConicalGradientPattern)
1106 gradient_style =
true;
1108 if (s.version() < QDataStream::Qt_4_0 && gradient_style)
1109 style = Qt::NoBrush;
1111 s << style << b.color();
1112 if (b.style() == Qt::TexturePattern) {
1113 if (s.version() >= QDataStream::Qt_5_5)
1114 s << b.textureImage();
1117 }
else if (s.version() >= QDataStream::Qt_4_0 && gradient_style) {
1118 const QGradient *gradient = b.gradient();
1119 int type_as_int =
int(gradient->type());
1121 if (s.version() >= QDataStream::Qt_4_3) {
1122 s <<
int(gradient->spread());
1123 QGradient::CoordinateMode co_mode = gradient->coordinateMode();
1124 if (s.version() < QDataStream::Qt_5_12 && co_mode == QGradient::ObjectMode)
1125 co_mode = QGradient::ObjectBoundingMode;
1129 if (s.version() >= QDataStream::Qt_4_5)
1130 s <<
int(gradient->interpolationMode());
1132 if (
sizeof(qreal) ==
sizeof(
double)) {
1133 s << gradient->stops();
1138 QList<QGradientStop> stops = gradient->stops();
1139 s << quint32(stops.size());
1140 for (
int i = 0; i < stops.size(); ++i) {
1142 s <<
std::pair<
double, QColor>(
double(stop.first), stop.second);
1146 if (gradient->type() == QGradient::LinearGradient) {
1147 s <<
static_cast<
const QLinearGradient *>(gradient)->start();
1148 s <<
static_cast<
const QLinearGradient *>(gradient)->finalStop();
1149 }
else if (gradient->type() == QGradient::RadialGradient) {
1150 s <<
static_cast<
const QRadialGradient *>(gradient)->center();
1151 s <<
static_cast<
const QRadialGradient *>(gradient)->focalPoint();
1152 s << (
double)
static_cast<
const QRadialGradient *>(gradient)->radius();
1153 if (s.version() >= QDataStream::Qt_6_0)
1154 s << (
double)
static_cast<
const QRadialGradient *>(gradient)->focalRadius();
1156 s <<
static_cast<
const QConicalGradient *>(gradient)->center();
1157 s << (
double)
static_cast<
const QConicalGradient *>(gradient)->angle();
1160 if (s.version() >= QDataStream::Qt_4_3)
1166
1167
1168
1169
1170
1171
1172
1173
1182 if (style == Qt::TexturePattern) {
1183 if (s.version() >= QDataStream::Qt_5_5) {
1186 b.setTextureImage(std::move(img));
1190 b.setTexture(
std::move(pm));
1192 }
else if (style == Qt::LinearGradientPattern
1193 || style == Qt::RadialGradientPattern
1194 || style == Qt::ConicalGradientPattern) {
1197 QGradient::Type type;
1199 QGradient::CoordinateMode cmode = QGradient::LogicalMode;
1200 QGradient::Spread spread = QGradient::PadSpread;
1201 QGradient::InterpolationMode imode = QGradient::ColorInterpolation;
1204 type = QGradient::Type(type_as_int);
1205 if (s.version() >= QDataStream::Qt_4_3) {
1207 spread = QGradient::Spread(type_as_int);
1209 cmode = QGradient::CoordinateMode(type_as_int);
1212 if (s.version() >= QDataStream::Qt_4_5) {
1214 imode = QGradient::InterpolationMode(type_as_int);
1217 if (
sizeof(qreal) ==
sizeof(
double)) {
1225 stops.reserve(numStops);
1226 for (quint32 i = 0; i < numStops; ++i) {
1228 stops << std::pair<qreal, QColor>(n, c);
1232 if (type == QGradient::LinearGradient) {
1238 lg.setSpread(spread);
1239 lg.setCoordinateMode(cmode);
1240 lg.setInterpolationMode(imode);
1242 }
else if (type == QGradient::RadialGradient) {
1245 double focalRadius = 0;
1251 rg.setSpread(spread);
1252 rg.setCoordinateMode(cmode);
1253 rg.setInterpolationMode(imode);
1254 if (s.version() >= QDataStream::Qt_6_0)
1256 rg.setFocalRadius(focalRadius);
1265 cg.setSpread(spread);
1266 cg.setCoordinateMode(cmode);
1267 cg.setInterpolationMode(imode);
1271 b = QBrush(color, (Qt::BrushStyle)style);
1273 if (s.version() >= QDataStream::Qt_4_3) {
1274 QTransform transform;
1276 b.setTransform(transform);
1283
1284
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1382
1383
1384QGradient::QGradient()
1385 : m_type(NoGradient)
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578QGradient::QGradient(Preset preset)
1579 : m_type(LinearGradient)
1580 , m_stops(qt_preset_gradient_stops(preset))
1581 , m_data(qt_preset_gradient_data[preset - 1])
1582 , m_coordinateMode(ObjectMode)
1587
1588
1589QGradient::~QGradient()
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1641
1642
1643
1644
1645
1646
1647
1650
1651
1652
1653
1656
1657
1658
1659
1660
1661
1662
1664void QGradient::setColorAt(qreal pos,
const QColor &color)
1666 if ((pos > 1 || pos < 0) && !qIsNaN(pos)) {
1667 qWarning(
"QGradient::setColorAt: Color position must be specified in the range 0 to 1");
1673 while (index < m_stops.size() && m_stops.at(index).first < pos) ++index;
1675 if (index < m_stops.size() && m_stops.at(index).first == pos)
1676 m_stops[index].second = color;
1678 m_stops.insert(index, QGradientStop(pos, color));
1683 return stop.first >= 0 && stop.first <= 1;
1689 for (
const QGradientStop &stop : stops) {
1690 if (Q_UNLIKELY(!ok(stop)))
1692 const bool sorted = stop.first > lastPos;
1693 if (Q_UNLIKELY(!sorted))
1695 lastPos = stop.first;
1701
1702
1703
1704
1705
1706
1707
1708
1709void QGradient::setStops(
const QGradientStops &stops)
1711 if (Q_LIKELY(ok(stops))) {
1719 for (
int i=0; i<stops.size(); ++i)
1720 setColorAt(stops.at(i).first, stops.at(i).second);
1725
1726
1727
1728
1729
1730
1731
1732QGradientStops QGradient::stops()
const
1734 if (m_stops.isEmpty()) {
1735 static constexpr QGradientStop blackAndWhite[] = {
1736 {0, QColorConstants::Black}, {1, QColorConstants::White},
1738 return QGradientStops::fromReadOnlyData(blackAndWhite);
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1768
1769
1770
1771
1772
1773QGradient::CoordinateMode QGradient::coordinateMode()
const
1775 return m_coordinateMode;
1779
1780
1781
1782
1783
1784void QGradient::setCoordinateMode(CoordinateMode mode)
1786 m_coordinateMode = mode;
1790
1791
1792
1793
1794
1795
1796
1797
1798
1801
1802
1803
1804
1805
1806
1807QGradient::InterpolationMode QGradient::interpolationMode()
const
1809 return m_interpolationMode;
1813
1814
1815
1816
1817
1818
1819void QGradient::setInterpolationMode(InterpolationMode mode)
1821 m_interpolationMode = mode;
1825
1826
1827
1828
1829
1830
1831
1832
1835
1836
1837
1838
1839
1840bool QGradient::operator==(
const QGradient &gradient)
const
1842 if (gradient.m_type != m_type
1843 || gradient.m_spread != m_spread
1844 || gradient.m_coordinateMode != m_coordinateMode
1845 || gradient.m_interpolationMode != m_interpolationMode)
return false;
1847 if (m_type == LinearGradient) {
1848 if (m_data.linear.x1 != gradient.m_data.linear.x1
1849 || m_data.linear.y1 != gradient.m_data.linear.y1
1850 || m_data.linear.x2 != gradient.m_data.linear.x2
1851 || m_data.linear.y2 != gradient.m_data.linear.y2)
1853 }
else if (m_type == RadialGradient) {
1854 if (m_data.radial.cx != gradient.m_data.radial.cx
1855 || m_data.radial.cy != gradient.m_data.radial.cy
1856 || m_data.radial.fx != gradient.m_data.radial.fx
1857 || m_data.radial.fy != gradient.m_data.radial.fy
1858 || m_data.radial.cradius != gradient.m_data.radial.cradius
1859 || m_data.radial.fradius != gradient.m_data.radial.fradius)
1862 if (m_data.conical.cx != gradient.m_data.conical.cx
1863 || m_data.conical.cy != gradient.m_data.conical.cy
1864 || m_data.conical.angle != gradient.m_data.conical.angle)
1868 return stops() == gradient.stops();
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1914
1915
1916
1917
1918
1920QLinearGradient::QLinearGradient()
1922 m_type = LinearGradient;
1923 m_spread = PadSpread;
1924 m_data.linear.x1 = 0;
1925 m_data.linear.y1 = 0;
1926 m_data.linear.x2 = 1;
1927 m_data.linear.y2 = 1;
1932
1933
1934
1935
1936
1937
1938
1939QLinearGradient::QLinearGradient(
const QPointF &start,
const QPointF &finalStop)
1941 m_type = LinearGradient;
1942 m_spread = PadSpread;
1943 m_data.linear.x1 = start.x();
1944 m_data.linear.y1 = start.y();
1945 m_data.linear.x2 = finalStop.x();
1946 m_data.linear.y2 = finalStop.y();
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959QLinearGradient::QLinearGradient(qreal xStart, qreal yStart, qreal xFinalStop, qreal yFinalStop)
1960 : QLinearGradient(QPointF(xStart, yStart), QPointF(xFinalStop, yFinalStop))
1965
1966
1967QLinearGradient::~QLinearGradient()
1972
1973
1974
1975
1977QPointF QLinearGradient::start()
const
1979 Q_ASSERT(m_type == LinearGradient);
1980 return QPointF(m_data.linear.x1, m_data.linear.y1);
1984
1985
1986
1987
1988
1989
1990
1991
1992
1995
1996
1997
1998
1999
2000
2001
2003void QLinearGradient::setStart(
const QPointF &start)
2005 Q_ASSERT(m_type == LinearGradient);
2006 m_data.linear.x1 = start.x();
2007 m_data.linear.y1 = start.y();
2012
2013
2014
2015
2016
2017
2018
2019
2020
2023
2024
2025
2026
2028QPointF QLinearGradient::finalStop()
const
2030 Q_ASSERT(m_type == LinearGradient);
2031 return QPointF(m_data.linear.x2, m_data.linear.y2);
2036
2037
2038
2039
2040
2041
2042
2044void QLinearGradient::setFinalStop(
const QPointF &stop)
2046 Q_ASSERT(m_type == LinearGradient);
2047 m_data.linear.x2 = stop.x();
2048 m_data.linear.y2 = stop.y();
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2107 const qreal compensated_radius = radius - radius * qreal(0.001);
2108 QLineF line(center, focalPoint);
2109 if (line.length() > (compensated_radius))
2110 line.setLength(compensated_radius);
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2126QRadialGradient::QRadialGradient(
const QPointF ¢er, qreal radius,
const QPointF &focalPoint)
2128 m_type = RadialGradient;
2129 m_spread = PadSpread;
2130 m_data.radial.cx = center.x();
2131 m_data.radial.cy = center.y();
2132 m_data.radial.cradius = radius;
2133 m_data.radial.fradius = 0;
2135 QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(center, radius, focalPoint);
2136 m_data.radial.fx = adapted_focal.x();
2137 m_data.radial.fy = adapted_focal.y();
2141
2142
2143
2144
2145
2146QRadialGradient::QRadialGradient(
const QPointF ¢er, qreal radius)
2148 m_type = RadialGradient;
2149 m_spread = PadSpread;
2150 m_data.radial.cx = center.x();
2151 m_data.radial.cy = center.y();
2152 m_data.radial.cradius = radius;
2153 m_data.radial.fradius = 0;
2154 m_data.radial.fx = center.x();
2155 m_data.radial.fy = center.y();
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2171QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius, qreal fx, qreal fy)
2172 : QRadialGradient(QPointF(cx, cy), radius, QPointF(fx, fy))
2177
2178
2179
2180
2181
2182QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius)
2183 : QRadialGradient(QPointF(cx, cy), radius)
2189
2190
2191
2192QRadialGradient::QRadialGradient()
2194 m_type = RadialGradient;
2195 m_spread = PadSpread;
2196 m_data.radial.cx = 0;
2197 m_data.radial.cy = 0;
2198 m_data.radial.cradius = 1;
2199 m_data.radial.fradius = 0;
2200 m_data.radial.fx = 0;
2201 m_data.radial.fy = 0;
2205
2206
2207
2208
2209
2210QRadialGradient::QRadialGradient(
const QPointF ¢er, qreal centerRadius,
const QPointF &focalPoint, qreal focalRadius)
2212 m_type = RadialGradient;
2213 m_spread = PadSpread;
2214 m_data.radial.cx = center.x();
2215 m_data.radial.cy = center.y();
2216 m_data.radial.cradius = centerRadius;
2217 m_data.radial.fradius = focalRadius;
2219 m_data.radial.fx = focalPoint.x();
2220 m_data.radial.fy = focalPoint.y();
2224
2225
2226
2227
2228
2229
2230QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius)
2232 m_type = RadialGradient;
2233 m_spread = PadSpread;
2234 m_data.radial.cx = cx;
2235 m_data.radial.cy = cy;
2236 m_data.radial.cradius = centerRadius;
2237 m_data.radial.fradius = focalRadius;
2239 m_data.radial.fx = fx;
2240 m_data.radial.fy = fy;
2244
2245
2246QRadialGradient::~QRadialGradient()
2251
2252
2253
2254
2256QPointF QRadialGradient::center()
const
2258 Q_ASSERT(m_type == RadialGradient);
2259 return QPointF(m_data.radial.cx, m_data.radial.cy);
2263
2264
2265
2266
2267
2268
2269
2270
2271
2274
2275
2276
2277
2278
2279
2280
2282void QRadialGradient::setCenter(
const QPointF ¢er)
2284 Q_ASSERT(m_type == RadialGradient);
2285 m_data.radial.cx = center.x();
2286 m_data.radial.cy = center.y();
2291
2292
2293
2294
2295
2296
2298qreal QRadialGradient::radius()
const
2300 Q_ASSERT(m_type == RadialGradient);
2301 return m_data.radial.cradius;
2306
2307
2308
2309
2310
2311
2312
2313void QRadialGradient::setRadius(qreal radius)
2315 Q_ASSERT(m_type == RadialGradient);
2316 m_data.radial.cradius = radius;
2320
2321
2322
2323
2324
2325
2326
2327qreal QRadialGradient::centerRadius()
const
2329 Q_ASSERT(m_type == RadialGradient);
2330 return m_data.radial.cradius;
2334
2335
2336
2337
2338
2339void QRadialGradient::setCenterRadius(qreal radius)
2341 Q_ASSERT(m_type == RadialGradient);
2342 m_data.radial.cradius = radius;
2346
2347
2348
2349
2350
2351
2352
2353qreal QRadialGradient::focalRadius()
const
2355 Q_ASSERT(m_type == RadialGradient);
2356 return m_data.radial.fradius;
2360
2361
2362
2363
2364
2365void QRadialGradient::setFocalRadius(qreal radius)
2367 Q_ASSERT(m_type == RadialGradient);
2368 m_data.radial.fradius = radius;
2372
2373
2374
2375
2376
2378QPointF QRadialGradient::focalPoint()
const
2380 Q_ASSERT(m_type == RadialGradient);
2381 return QPointF(m_data.radial.fx, m_data.radial.fy);
2385
2386
2387
2388
2389
2390
2391
2392
2393
2396
2397
2398
2399
2400
2401
2402
2404void QRadialGradient::setFocalPoint(
const QPointF &focalPoint)
2406 Q_ASSERT(m_type == RadialGradient);
2407 m_data.radial.fx = focalPoint.x();
2408 m_data.radial.fy = focalPoint.y();
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2452
2453
2454
2455
2456
2457
2459QConicalGradient::QConicalGradient(
const QPointF ¢er, qreal angle)
2461 m_type = ConicalGradient;
2462 m_spread = PadSpread;
2463 m_data.conical.cx = center.x();
2464 m_data.conical.cy = center.y();
2465 m_data.conical.angle = angle;
2470
2471
2472
2473
2474
2475
2477QConicalGradient::QConicalGradient(qreal cx, qreal cy, qreal angle)
2478 : QConicalGradient(QPointF(cx, cy), angle)
2483
2484
2485QConicalGradient::~QConicalGradient()
2491
2492
2493
2494
2495
2497QConicalGradient::QConicalGradient()
2499 m_type = ConicalGradient;
2500 m_spread = PadSpread;
2501 m_data.conical.cx = 0;
2502 m_data.conical.cy = 0;
2503 m_data.conical.angle = 0;
2508
2509
2510
2511
2512
2514QPointF QConicalGradient::center()
const
2516 Q_ASSERT(m_type == ConicalGradient);
2517 return QPointF(m_data.conical.cx, m_data.conical.cy);
2522
2523
2524
2525
2526
2527
2528
2529
2530
2533
2534
2535
2536
2537
2539void QConicalGradient::setCenter(
const QPointF ¢er)
2541 Q_ASSERT(m_type == ConicalGradient);
2542 m_data.conical.cx = center.x();
2543 m_data.conical.cy = center.y();
2547
2548
2549
2550
2551
2553qreal QConicalGradient::angle()
const
2555 Q_ASSERT(m_type == ConicalGradient);
2556 return m_data.conical.angle;
2561
2562
2563
2564
2565
2566
2567
2569void QConicalGradient::setAngle(qreal angle)
2571 Q_ASSERT(m_type == ConicalGradient);
2572 m_data.conical.angle = angle;
2576
2577
2578
2579
2580
2583
2584
2585
2586
2587
2590
2591
2592
2595
2596
2597
2601
2602
2603
2606
2607
2608
2609
2610
2611
2612
2616#include "moc_qbrush.cpp"