QtBase  v6.3.1
qbrush.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 #include "qbrush.h"
42 #include "qpixmap.h"
43 #include "qbitmap.h"
44 #include "qpixmapcache.h"
45 #include <qpa/qplatformpixmap.h>
46 #include "qdatastream.h"
47 #include "qvariant.h"
48 #include "qline.h"
49 #include "qdebug.h"
50 #include <QtCore/qjsondocument.h>
51 #include <QtCore/qjsonarray.h>
52 #include <QtCore/qcoreapplication.h>
53 #include "private/qhexstring_p.h"
54 #include <QtCore/qnumeric.h>
55 #include <QtCore/qfile.h>
56 #include <QtCore/qmutex.h>
57 
59 
60 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
61 // Avoid an ABI break due to the QScopedPointer->std::unique_ptr change
63 #endif
64 
65 const uchar *qt_patternForBrush(int brushStyle, bool invert)
66 {
67  Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
68  static const uchar pat_tbl[][2][8] = {
69  {
70  /* dense1 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
71  /*~dense1 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
72  }, {
73  /* dense2 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
74  /*~dense2 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
75  }, {
76  /* dense3 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
77  /*~dense3 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
78  }, {
79  /* dense4 */ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
80  /*~dense4 */ { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 },
81  }, {
82  /* dense5 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
83  /*~dense5 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
84  }, {
85  /* dense6 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
86  /*~dense6 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
87  }, {
88  /* dense7 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
89  /*~dense7 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
90  }, {
91  /* hor */ { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff },
92  /*~hor */ { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 },
93  }, {
94  /* ver */ { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef },
95  /*~ver */ { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
96  }, {
97  /* cross */ { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef },
98  /*~cross */ { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 },
99  }, {
100  /* bdiag */ { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe },
101  /*~bdiag */ { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 },
102  }, {
103  /* fdiag */ { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f },
104  /*~fdiag */ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
105  }, {
106  /* dcross */ { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e },
107  /*~dcross */ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 },
108  },
109  };
110  return pat_tbl[brushStyle - Qt::Dense1Pattern][invert];
111 }
112 
113 Q_GUI_EXPORT QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
114 {
115 
116  QPixmap pm;
117  QString key = QLatin1String("$qt-brush$")
118  % HexString<uint>(brushStyle)
119  % QLatin1Char(invert ? '1' : '0');
120  if (!QPixmapCache::find(key, &pm)) {
121  pm = QBitmap::fromData(QSize(8, 8), qt_patternForBrush(brushStyle, invert),
124  }
125 
126  return pm;
127 }
128 
129 static void qt_cleanup_brush_pattern_image_cache();
131 {
132 public:
134  : m_initialized(false)
135  {
136  init();
137  }
138 
139  void init()
140  {
141  qAddPostRoutine(qt_cleanup_brush_pattern_image_cache);
143  int i = style - Qt::Dense1Pattern;
144  m_images[i][0] = QImage(qt_patternForBrush(style, 0), 8, 8, 1, QImage::Format_MonoLSB);
145  m_images[i][1] = QImage(qt_patternForBrush(style, 1), 8, 8, 1, QImage::Format_MonoLSB);
146  }
147  m_initialized = true;
148  }
149 
150  QImage getImage(int brushStyle, bool invert) const
151  {
152  Q_ASSERT(brushStyle >= Qt::Dense1Pattern && brushStyle <= Qt::DiagCrossPattern);
153  if (!m_initialized)
154  const_cast<QBrushPatternImageCache*>(this)->init();
155  return m_images[brushStyle - Qt::Dense1Pattern][invert];
156  }
157 
158  void cleanup() {
160  int i = style - Qt::Dense1Pattern;
161  m_images[i][0] = QImage();
162  m_images[i][1] = QImage();
163  }
164  m_initialized = false;
165  }
166 
167 private:
168  QImage m_images[Qt::DiagCrossPattern - Qt::Dense1Pattern + 1][2];
169  bool m_initialized;
170 };
171 
172 Q_GLOBAL_STATIC(QBrushPatternImageCache, qt_brushPatternImageCache)
173 
174 static void qt_cleanup_brush_pattern_image_cache()
175 {
176  qt_brushPatternImageCache()->cleanup();
177 }
178 
179 Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert)
180 {
181  return qt_brushPatternImageCache()->getImage(brushStyle, invert);
182 }
183 
185 {
187  m_has_pixmap_texture = false;
188  m_pixmap = nullptr;
189  }
191  delete m_pixmap;
192  }
193 
194  void setPixmap(const QPixmap &pm) {
195  delete m_pixmap;
196 
197  if (pm.isNull()) {
198  m_pixmap = nullptr;
199  m_has_pixmap_texture = false;
200  } else {
201  m_pixmap = new QPixmap(pm);
202  m_has_pixmap_texture = true;
203  }
204 
205  m_image = QImage();
206  }
207 
208  void setImage(const QImage &image) {
209  m_image = image;
210  delete m_pixmap;
211  m_pixmap = nullptr;
212  m_has_pixmap_texture = false;
213  }
214 
216  if (!m_pixmap) {
218  }
219  return *m_pixmap;
220  }
221 
223  if (m_image.isNull() && m_pixmap)
224  m_image = m_pixmap->toImage();
225  return m_image;
226  }
227 
231 };
232 
233 // returns true if the brush has a pixmap (or bitmap) set as the
234 // brush texture, false otherwise
235 bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush& brush)
236 {
237  if (brush.style() != Qt::TexturePattern)
238  return false;
239  QTexturedBrushData *tx_data = static_cast<QTexturedBrushData *>(brush.d.get());
240  return tx_data->m_has_pixmap_texture;
241 }
242 
244 {
246 };
247 
248 static void deleteData(QBrushData *d)
249 {
250  switch (d->style) {
251  case Qt::TexturePattern:
252  delete static_cast<QTexturedBrushData*>(d);
253  break;
257  delete static_cast<QGradientBrushData*>(d);
258  break;
259  default:
260  delete d;
261  }
262 }
263 
265 {
266  if (d && !d->ref.deref())
267  deleteData(d);
268 }
269 
352 {
353 public:
356  {
357  brush->ref.storeRelaxed(1);
358  brush->style = Qt::BrushStyle(0);
359  brush->color = Qt::black;
360  }
362  {
363  if (!brush->ref.deref())
364  delete brush;
365  brush = nullptr;
366  }
367 };
368 
369 Q_GLOBAL_STATIC(QNullBrushData, nullBrushInstance_holder)
370 static QBrushData *nullBrushInstance()
371 {
372  return nullBrushInstance_holder()->brush;
373 }
374 
375 static bool qbrush_check_type(Qt::BrushStyle style) {
376  switch (style) {
377  case Qt::TexturePattern:
378  qWarning("QBrush: Incorrect use of TexturePattern");
379  break;
383  qWarning("QBrush: Wrong use of a gradient pattern");
384  break;
385  default:
386  return true;
387  }
388  return false;
389 }
390 
396 void QBrush::init(const QColor &color, Qt::BrushStyle style)
397 {
398  switch(style) {
399  case Qt::NoBrush:
400  d.reset(nullBrushInstance());
401  d->ref.ref();
402  if (d->color != color) setColor(color);
403  return;
404  case Qt::TexturePattern:
405  d.reset(new QTexturedBrushData);
406  break;
410  d.reset(new QGradientBrushData);
411  break;
412  default:
413  d.reset(new QBrushData);
414  break;
415  }
416  d->ref.storeRelaxed(1);
417  d->style = style;
418  d->color = color;
419 }
420 
427  : d(nullBrushInstance())
428 {
429  Q_ASSERT(d);
430  d->ref.ref();
431 }
432 
441 {
444 }
445 
446 
455 {
458 }
459 
467  : QBrush(QColor(Qt::black), style)
468 {
469 }
470 
478 {
479  if (qbrush_check_type(style))
480  init(color, style);
481  else {
482  d.reset(nullBrushInstance());
483  d->ref.ref();
484  }
485 }
486 
495  : QBrush(QColor(color), style)
496 {
497 }
498 
510 {
511  init(color, Qt::TexturePattern);
513 }
514 
526 {
527  init(color, Qt::TexturePattern);
529 }
530 
536  : d(other.d.get())
537 {
538  d->ref.ref();
539 }
540 
548 QBrush::QBrush(const QGradient &gradient)
549 {
551  d.reset(nullBrushInstance());
552  d->ref.ref();
553  return;
554  }
555 
556  const Qt::BrushStyle enum_table[] = {
560  };
561 
562  init(QColor(), enum_table[gradient.type()]);
563  QGradientBrushData *grad = static_cast<QGradientBrushData *>(d.get());
564  grad->gradient = gradient;
565 }
566 
572 {
573 }
574 
575 static constexpr inline bool use_same_brushdata(Qt::BrushStyle lhs, Qt::BrushStyle rhs)
576 {
577  return lhs == rhs // includes Qt::TexturePattern
578  || (lhs >= Qt::NoBrush && lhs <= Qt::DiagCrossPattern && rhs >= Qt::NoBrush && rhs <= Qt::DiagCrossPattern)
579  || (lhs >= Qt::LinearGradientPattern && lhs <= Qt::ConicalGradientPattern && rhs >= Qt::LinearGradientPattern && rhs <= Qt::ConicalGradientPattern)
580  ;
581 }
582 
583 void QBrush::detach(Qt::BrushStyle newStyle)
584 {
585  if (use_same_brushdata(newStyle, d->style) && d->ref.loadRelaxed() == 1) {
586  d->style = newStyle;
587  return;
588  }
589 
590  DataPtr x;
591  switch(newStyle) {
592  case Qt::TexturePattern: {
594  if (d->style == Qt::TexturePattern) {
595  QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.get());
596  if (data->m_has_pixmap_texture)
597  tbd->setPixmap(data->pixmap());
598  else
599  tbd->setImage(data->image());
600  }
601  x.reset(tbd);
602  break;
603  }
608  switch (d->style) {
612  gbd->gradient =
613  static_cast<QGradientBrushData *>(d.get())->gradient;
614  break;
615  default:
616  break;
617  }
618  x.reset(gbd);
619  break;
620  }
621  default:
622  x.reset(new QBrushData);
623  break;
624  }
625  x->ref.storeRelaxed(1); // must be first lest the QBrushDataPointerDeleter turns into a no-op
626  x->style = newStyle;
627  x->color = d->color;
628  x->transform = d->transform;
629  d.swap(x);
630 }
631 
632 
641 {
642  if (d == b.d)
643  return *this;
644 
645  b.d->ref.ref();
646  d.reset(b.d.get());
647  return *this;
648 }
649 
669 QBrush::operator QVariant() const
670 {
671  return QVariant::fromValue(*this);
672 }
673 
689 {
690  if (d->style == style)
691  return;
692 
693  if (qbrush_check_type(style)) {
694  detach(style);
695  d->style = style;
696  }
697 }
698 
699 
721 {
722  if (d->color == c)
723  return;
724 
725  detach(d->style);
726  d->color = c;
727 }
728 
745 {
746  return d->style == Qt::TexturePattern
747  ? (static_cast<QTexturedBrushData *>(d.get()))->pixmap()
748  : QPixmap();
749 }
750 
762 {
763  if (!pixmap.isNull()) {
764  detach(Qt::TexturePattern);
765  QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.get());
767  } else {
768  detach(Qt::NoBrush);
769  }
770 }
771 
772 
786 {
787  return d->style == Qt::TexturePattern
788  ? (static_cast<QTexturedBrushData *>(d.get()))->image()
789  : QImage();
790 }
791 
792 
810 {
811  if (!image.isNull()) {
812  detach(Qt::TexturePattern);
813  QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.get());
814  data->setImage(image);
815  } else {
816  detach(Qt::NoBrush);
817  }
818 }
819 
820 
825 {
826  if (d->style == Qt::LinearGradientPattern
827  || d->style == Qt::RadialGradientPattern
828  || d->style == Qt::ConicalGradientPattern) {
829  return &static_cast<const QGradientBrushData *>(d.get())->gradient;
830  }
831  return nullptr;
832 }
833 
834 Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush)
835 {
836  if (brush.style() == Qt::RadialGradientPattern) {
837  const QGradient *g = brush.gradient();
838  const QRadialGradient *rg = static_cast<const QRadialGradient *>(g);
839 
840  if (!qFuzzyIsNull(rg->focalRadius()))
841  return true;
842 
843  QPointF delta = rg->focalPoint() - rg->center();
844  if (delta.x() * delta.x() + delta.y() * delta.y() > rg->radius() * rg->radius())
845  return true;
846  }
847 
848  return false;
849 }
850 
863 bool QBrush::isOpaque() const
864 {
865  bool opaqueColor = d->color.alpha() == 255;
866 
867  // Test awfully simple case first
868  if (d->style == Qt::SolidPattern)
869  return opaqueColor;
870 
871  if (qt_isExtendedRadialGradient(*this))
872  return false;
873 
874  if (d->style == Qt::LinearGradientPattern
875  || d->style == Qt::RadialGradientPattern
876  || d->style == Qt::ConicalGradientPattern) {
877  QGradientStops stops = gradient()->stops();
878  for (int i=0; i<stops.size(); ++i)
879  if (stops.at(i).second.alpha() != 255)
880  return false;
881  return true;
882  } else if (d->style == Qt::TexturePattern) {
883  return qHasPixmapTexture(*this)
886  }
887 
888  return false;
889 }
890 
901 {
902  detach(d->style);
903  d->transform = matrix;
904 }
905 
906 
931 bool QBrush::operator==(const QBrush &b) const
932 {
933  if (b.d == d)
934  return true;
935  if (b.d->style != d->style || b.d->color != d->color || b.d->transform != d->transform)
936  return false;
937  switch (d->style) {
938  case Qt::TexturePattern:
939  {
940  // Note this produces false negatives if the textures have identical data,
941  // but does not share the same data in memory. Since equality is likely to
942  // be used to avoid iterating over the data for a texture update, this should
943  // still be better than doing an accurate comparison.
944  const QPixmap *us = nullptr, *them = nullptr;
945  qint64 cacheKey1, cacheKey2;
946  if (qHasPixmapTexture(*this)) {
947  us = (static_cast<QTexturedBrushData *>(d.get()))->m_pixmap;
948  cacheKey1 = us->cacheKey();
949  } else
950  cacheKey1 = (static_cast<QTexturedBrushData *>(d.get()))->image().cacheKey();
951 
952  if (qHasPixmapTexture(b)) {
953  them = (static_cast<QTexturedBrushData *>(b.d.get()))->m_pixmap;
954  cacheKey2 = them->cacheKey();
955  } else
956  cacheKey2 = (static_cast<QTexturedBrushData *>(b.d.get()))->image().cacheKey();
957 
958  if (cacheKey1 != cacheKey2)
959  return false;
960  if (!us == !them) // both images or both pixmaps
961  return true;
962  // Only raster QPixmaps use the same cachekeys as QImages.
963  if (us && us->handle()->classId() == QPlatformPixmap::RasterClass)
964  return true;
965  if (them && them->handle()->classId() == QPlatformPixmap::RasterClass)
966  return true;
967  return false;
968  }
972  {
973  const QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d.get());
974  const QGradientBrushData *d2 = static_cast<QGradientBrushData *>(b.d.get());
975  return d1->gradient == d2->gradient;
976  }
977  default:
978  return true;
979  }
980 }
981 
982 #ifndef QT_NO_DEBUG_STREAM
987 {
988  static const char BRUSH_STYLES[][24] = {
989  "NoBrush",
990  "SolidPattern",
991  "Dense1Pattern",
992  "Dense2Pattern",
993  "Dense3Pattern",
994  "Dense4Pattern",
995  "Dense5Pattern",
996  "Dense6Pattern",
997  "Dense7Pattern",
998  "HorPattern",
999  "VerPattern",
1000  "CrossPattern",
1001  "BDiagPattern",
1002  "FDiagPattern",
1003  "DiagCrossPattern",
1004  "LinearGradientPattern",
1005  "RadialGradientPattern",
1006  "ConicalGradientPattern",
1007  "", "", "", "", "", "",
1008  "TexturePattern" // 24
1009  };
1010 
1011  QDebugStateSaver saver(dbg);
1012  dbg.nospace() << "QBrush(" << b.color() << ',' << BRUSH_STYLES[b.style()] << ')';
1013  return dbg;
1014 }
1015 #endif
1016 
1017 /*****************************************************************************
1018  QBrush stream functions
1019  *****************************************************************************/
1020 #ifndef QT_NO_DATASTREAM
1032 {
1033  quint8 style = (quint8) b.style();
1034  bool gradient_style = false;
1035 
1038  gradient_style = true;
1039 
1040  if (s.version() < QDataStream::Qt_4_0 && gradient_style)
1041  style = Qt::NoBrush;
1042 
1043  s << style << b.color();
1044  if (b.style() == Qt::TexturePattern) {
1045  if (s.version() >= QDataStream::Qt_5_5)
1046  s << b.textureImage();
1047  else
1048  s << b.texture();
1049  } else if (s.version() >= QDataStream::Qt_4_0 && gradient_style) {
1050  const QGradient *gradient = b.gradient();
1051  int type_as_int = int(gradient->type());
1052  s << type_as_int;
1053  if (s.version() >= QDataStream::Qt_4_3) {
1054  s << int(gradient->spread());
1055  QGradient::CoordinateMode co_mode = gradient->coordinateMode();
1056  if (s.version() < QDataStream::Qt_5_12 && co_mode == QGradient::ObjectMode)
1058  s << int(co_mode);
1059  }
1060 
1061  if (s.version() >= QDataStream::Qt_4_5)
1062  s << int(gradient->interpolationMode());
1063 
1064  if (sizeof(qreal) == sizeof(double)) {
1065  s << gradient->stops();
1066  } else {
1067  // ensure that we write doubles here instead of streaming the stops
1068  // directly; otherwise, platforms that redefine qreal might generate
1069  // data that cannot be read on other platforms.
1070  QList<QGradientStop> stops = gradient->stops();
1071  s << quint32(stops.size());
1072  for (int i = 0; i < stops.size(); ++i) {
1073  const QGradientStop &stop = stops.at(i);
1074  s << QPair<double, QColor>(double(stop.first), stop.second);
1075  }
1076  }
1077 
1078  if (gradient->type() == QGradient::LinearGradient) {
1079  s << static_cast<const QLinearGradient *>(gradient)->start();
1080  s << static_cast<const QLinearGradient *>(gradient)->finalStop();
1081  } else if (gradient->type() == QGradient::RadialGradient) {
1082  s << static_cast<const QRadialGradient *>(gradient)->center();
1083  s << static_cast<const QRadialGradient *>(gradient)->focalPoint();
1085  if (s.version() >= QDataStream::Qt_6_0)
1086  s << (double) static_cast<const QRadialGradient *>(gradient)->focalRadius();
1087  } else { // type == Conical
1088  s << static_cast<const QConicalGradient *>(gradient)->center();
1090  }
1091  }
1092  if (s.version() >= QDataStream::Qt_4_3)
1093  s << b.transform();
1094  return s;
1095 }
1096 
1108 {
1109  quint8 style;
1110  QColor color;
1111  s >> style;
1112  s >> color;
1113  b = QBrush(color);
1114  if (style == Qt::TexturePattern) {
1115  if (s.version() >= QDataStream::Qt_5_5) {
1116  QImage img;
1117  s >> img;
1118  b.setTextureImage(std::move(img));
1119  } else {
1120  QPixmap pm;
1121  s >> pm;
1122  b.setTexture(std::move(pm));
1123  }
1124  } else if (style == Qt::LinearGradientPattern
1127 
1128  int type_as_int;
1130  QGradientStops stops;
1134 
1135  s >> type_as_int;
1136  type = QGradient::Type(type_as_int);
1137  if (s.version() >= QDataStream::Qt_4_3) {
1138  s >> type_as_int;
1139  spread = QGradient::Spread(type_as_int);
1140  s >> type_as_int;
1141  cmode = QGradient::CoordinateMode(type_as_int);
1142  }
1143 
1144  if (s.version() >= QDataStream::Qt_4_5) {
1145  s >> type_as_int;
1146  imode = QGradient::InterpolationMode(type_as_int);
1147  }
1148 
1149  if (sizeof(qreal) == sizeof(double)) {
1150  s >> stops;
1151  } else {
1152  quint32 numStops;
1153  double n;
1154  QColor c;
1155 
1156  s >> numStops;
1157  stops.reserve(numStops);
1158  for (quint32 i = 0; i < numStops; ++i) {
1159  s >> n >> c;
1160  stops << QPair<qreal, QColor>(n, c);
1161  }
1162  }
1163 
1165  QPointF p1, p2;
1166  s >> p1;
1167  s >> p2;
1168  QLinearGradient lg(p1, p2);
1169  lg.setStops(stops);
1170  lg.setSpread(spread);
1171  lg.setCoordinateMode(cmode);
1172  lg.setInterpolationMode(imode);
1173  b = QBrush(lg);
1174  } else if (type == QGradient::RadialGradient) {
1175  QPointF center, focal;
1176  double radius;
1177  double focalRadius = 0;
1178  s >> center;
1179  s >> focal;
1180  s >> radius;
1181  QRadialGradient rg(center, radius, focal);
1182  rg.setStops(stops);
1183  rg.setSpread(spread);
1184  rg.setCoordinateMode(cmode);
1185  rg.setInterpolationMode(imode);
1186  if (s.version() >= QDataStream::Qt_6_0)
1187  s >> focalRadius;
1188  rg.setFocalRadius(focalRadius);
1189  b = QBrush(rg);
1190  } else { // type == QGradient::ConicalGradient
1191  QPointF center;
1192  double angle;
1193  s >> center;
1194  s >> angle;
1196  cg.setStops(stops);
1197  cg.setSpread(spread);
1198  cg.setCoordinateMode(cmode);
1199  cg.setInterpolationMode(imode);
1200  b = QBrush(cg);
1201  }
1202  } else {
1204  }
1205  if (s.version() >= QDataStream::Qt_4_3) {
1207  s >> transform;
1208  b.setTransform(transform);
1209  }
1210  return s;
1211 }
1212 #endif // QT_NO_DATASTREAM
1213 
1214 /*******************************************************************************
1215  * QGradient implementations
1216  */
1217 
1218 
1317  : m_type(NoGradient)
1318 {
1319 }
1320 
1498 #include "webgradients.cpp"
1499 
1511  : m_type(LinearGradient)
1512  , m_stops(qt_preset_gradient_stops(preset))
1513  , m_data(qt_preset_gradient_data[preset - 1])
1514  , m_coordinateMode(ObjectMode)
1515 {
1516 }
1517 
1522 {
1523 }
1524 
1597 {
1598  if ((pos > 1 || pos < 0) && !qIsNaN(pos)) {
1599  qWarning("QGradient::setColorAt: Color position must be specified in the range 0 to 1");
1600  return;
1601  }
1602 
1603  int index = 0;
1604  if (!qIsNaN(pos))
1605  while (index < m_stops.size() && m_stops.at(index).first < pos) ++index;
1606 
1607  if (index < m_stops.size() && m_stops.at(index).first == pos)
1608  m_stops[index].second = color;
1609  else
1610  m_stops.insert(index, QGradientStop(pos, color));
1611 }
1612 
1613 static inline bool ok(QGradientStop stop)
1614 {
1615  return stop.first >= 0 && stop.first <= 1; // rejects NaNs
1616 }
1617 
1618 static inline bool ok(const QGradientStops &stops)
1619 {
1620  qreal lastPos = -1;
1621  for (const QGradientStop &stop : stops) {
1622  if (Q_UNLIKELY(!ok(stop)))
1623  return false;
1624  const bool sorted = stop.first > lastPos; // rejects duplicates
1625  if (Q_UNLIKELY(!sorted))
1626  return false;
1627  lastPos = stop.first;
1628  }
1629  return true;
1630 }
1631 
1642 {
1643  if (Q_LIKELY(ok(stops))) {
1644  // fast path for the common case: if everything is ok with the stops, just copy them
1645  m_stops = stops;
1646  return;
1647  }
1648  // otherwise, to keep the pre-5.9 behavior, add them one after another,
1649  // so each stop is checked, invalid ones are skipped, they are added in-order (which may be O(N^2)).
1650  m_stops.clear();
1651  for (int i=0; i<stops.size(); ++i)
1652  setColorAt(stops.at(i).first, stops.at(i).second);
1653 }
1654 
1655 
1665 {
1666  if (m_stops.isEmpty()) {
1667  static constexpr QGradientStop blackAndWhite[] = {
1669  };
1670  return QGradientStops::fromReadOnlyData(blackAndWhite);
1671  }
1672  return m_stops;
1673 }
1674 
1706 {
1707  return m_coordinateMode;
1708 }
1709 
1717 {
1718  m_coordinateMode = mode;
1719 }
1720 
1740 {
1741  return m_interpolationMode;
1742 }
1743 
1752 {
1753  m_interpolationMode = mode;
1754 }
1755 
1772 bool QGradient::operator==(const QGradient &gradient) const
1773 {
1774  if (gradient.m_type != m_type
1775  || gradient.m_spread != m_spread
1776  || gradient.m_coordinateMode != m_coordinateMode
1777  || gradient.m_interpolationMode != m_interpolationMode) return false;
1778 
1779  if (m_type == LinearGradient) {
1780  if (m_data.linear.x1 != gradient.m_data.linear.x1
1781  || m_data.linear.y1 != gradient.m_data.linear.y1
1782  || m_data.linear.x2 != gradient.m_data.linear.x2
1783  || m_data.linear.y2 != gradient.m_data.linear.y2)
1784  return false;
1785  } else if (m_type == RadialGradient) {
1786  if (m_data.radial.cx != gradient.m_data.radial.cx
1787  || m_data.radial.cy != gradient.m_data.radial.cy
1788  || m_data.radial.fx != gradient.m_data.radial.fx
1789  || m_data.radial.fy != gradient.m_data.radial.fy
1790  || m_data.radial.cradius != gradient.m_data.radial.cradius
1791  || m_data.radial.fradius != gradient.m_data.radial.fradius)
1792  return false;
1793  } else { // m_type == ConicalGradient
1794  if (m_data.conical.cx != gradient.m_data.conical.cx
1795  || m_data.conical.cy != gradient.m_data.conical.cy
1796  || m_data.conical.angle != gradient.m_data.conical.angle)
1797  return false;
1798  }
1799 
1800  return stops() == gradient.stops();
1801 }
1802 
1853 {
1854  m_type = LinearGradient;
1855  m_spread = PadSpread;
1856  m_data.linear.x1 = 0;
1857  m_data.linear.y1 = 0;
1858  m_data.linear.x2 = 1;
1859  m_data.linear.y2 = 1;
1860 }
1861 
1862 
1872 {
1873  m_type = LinearGradient;
1874  m_spread = PadSpread;
1875  m_data.linear.x1 = start.x();
1876  m_data.linear.y1 = start.y();
1877  m_data.linear.x2 = finalStop.x();
1878  m_data.linear.y2 = finalStop.y();
1879 }
1880 
1891 QLinearGradient::QLinearGradient(qreal xStart, qreal yStart, qreal xFinalStop, qreal yFinalStop)
1892  : QLinearGradient(QPointF(xStart, yStart), QPointF(xFinalStop, yFinalStop))
1893 {
1894 }
1895 
1900 {
1901 }
1902 
1910 {
1911  Q_ASSERT(m_type == LinearGradient);
1912  return QPointF(m_data.linear.x1, m_data.linear.y1);
1913 }
1914 
1936 {
1937  Q_ASSERT(m_type == LinearGradient);
1938  m_data.linear.x1 = start.x();
1939  m_data.linear.y1 = start.y();
1940 }
1941 
1942 
1961 {
1962  Q_ASSERT(m_type == LinearGradient);
1963  return QPointF(m_data.linear.x2, m_data.linear.y2);
1964 }
1965 
1966 
1977 {
1978  Q_ASSERT(m_type == LinearGradient);
1979  m_data.linear.x2 = stop.x();
1980  m_data.linear.y2 = stop.y();
1981 }
1982 
1983 
2032 static QPointF qt_radial_gradient_adapt_focal_point(const QPointF &center,
2033  qreal radius,
2034  const QPointF &focalPoint)
2035 {
2036  // We have a one pixel buffer zone to avoid numerical instability on the
2037  // circle border
2038  //### this is hacky because technically we should adjust based on current matrix
2039  const qreal compensated_radius = radius - radius * qreal(0.001);
2041  if (line.length() > (compensated_radius))
2042  line.setLength(compensated_radius);
2043  return line.p2();
2044 }
2045 
2059 {
2060  m_type = RadialGradient;
2061  m_spread = PadSpread;
2062  m_data.radial.cx = center.x();
2063  m_data.radial.cy = center.y();
2064  m_data.radial.cradius = radius;
2065  m_data.radial.fradius = 0;
2066 
2067  QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(center, radius, focalPoint);
2068  m_data.radial.fx = adapted_focal.x();
2069  m_data.radial.fy = adapted_focal.y();
2070 }
2071 
2079 {
2080  m_type = RadialGradient;
2081  m_spread = PadSpread;
2082  m_data.radial.cx = center.x();
2083  m_data.radial.cy = center.y();
2084  m_data.radial.cradius = radius;
2085  m_data.radial.fradius = 0;
2086  m_data.radial.fx = center.x();
2087  m_data.radial.fy = center.y();
2088 }
2089 
2090 
2104  : QRadialGradient(QPointF(cx, cy), radius, QPointF(fx, fy))
2105 {
2106 }
2107 
2115  : QRadialGradient(QPointF(cx, cy), radius)
2116 {
2117 }
2118 
2119 
2125 {
2126  m_type = RadialGradient;
2127  m_spread = PadSpread;
2128  m_data.radial.cx = 0;
2129  m_data.radial.cy = 0;
2130  m_data.radial.cradius = 1;
2131  m_data.radial.fradius = 0;
2132  m_data.radial.fx = 0;
2133  m_data.radial.fy = 0;
2134 }
2135 
2143 {
2144  m_type = RadialGradient;
2145  m_spread = PadSpread;
2146  m_data.radial.cx = center.x();
2147  m_data.radial.cy = center.y();
2148  m_data.radial.cradius = centerRadius;
2149  m_data.radial.fradius = 0;
2150 
2151  m_data.radial.fx = focalPoint.x();
2152  m_data.radial.fy = focalPoint.y();
2154 }
2155 
2163 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius)
2164 {
2165  m_type = RadialGradient;
2166  m_spread = PadSpread;
2167  m_data.radial.cx = cx;
2168  m_data.radial.cy = cy;
2169  m_data.radial.cradius = centerRadius;
2170  m_data.radial.fradius = 0;
2171 
2172  m_data.radial.fx = fx;
2173  m_data.radial.fy = fy;
2175 }
2176 
2181 {
2182 }
2183 
2191 {
2192  Q_ASSERT(m_type == RadialGradient);
2193  return QPointF(m_data.radial.cx, m_data.radial.cy);
2194 }
2195 
2217 {
2218  Q_ASSERT(m_type == RadialGradient);
2219  m_data.radial.cx = center.x();
2220  m_data.radial.cy = center.y();
2221 }
2222 
2223 
2233 {
2234  Q_ASSERT(m_type == RadialGradient);
2235  return m_data.radial.cradius;
2236 }
2237 
2238 
2248 {
2249  Q_ASSERT(m_type == RadialGradient);
2250  m_data.radial.cradius = radius;
2251 }
2252 
2262 {
2263  Q_ASSERT(m_type == RadialGradient);
2264  return m_data.radial.cradius;
2265 }
2266 
2274 {
2275  Q_ASSERT(m_type == RadialGradient);
2276  m_data.radial.cradius = radius;
2277 }
2278 
2288 {
2289  Q_ASSERT(m_type == RadialGradient);
2290  return m_data.radial.fradius;
2291 }
2292 
2300 {
2301  Q_ASSERT(m_type == RadialGradient);
2302  m_data.radial.fradius = radius;
2303 }
2304 
2313 {
2314  Q_ASSERT(m_type == RadialGradient);
2315  return QPointF(m_data.radial.fx, m_data.radial.fy);
2316 }
2317 
2339 {
2340  Q_ASSERT(m_type == RadialGradient);
2341  m_data.radial.fx = focalPoint.x();
2342  m_data.radial.fy = focalPoint.y();
2343 }
2344 
2345 
2346 
2393 {
2394  m_type = ConicalGradient;
2395  m_spread = PadSpread;
2396  m_data.conical.cx = center.x();
2397  m_data.conical.cy = center.y();
2398  m_data.conical.angle = angle;
2399 }
2400 
2401 
2411  : QConicalGradient(QPointF(cx, cy), angle)
2412 {
2413 }
2414 
2419 {
2420 }
2421 
2422 
2431 {
2432  m_type = ConicalGradient;
2433  m_spread = PadSpread;
2434  m_data.conical.cx = 0;
2435  m_data.conical.cy = 0;
2436  m_data.conical.angle = 0;
2437 }
2438 
2439 
2448 {
2449  Q_ASSERT(m_type == ConicalGradient);
2450  return QPointF(m_data.conical.cx, m_data.conical.cy);
2451 }
2452 
2453 
2473 {
2474  Q_ASSERT(m_type == ConicalGradient);
2475  m_data.conical.cx = center.x();
2476  m_data.conical.cy = center.y();
2477 }
2478 
2487 {
2488  Q_ASSERT(m_type == ConicalGradient);
2489  return m_data.conical.angle;
2490 }
2491 
2492 
2503 {
2504  Q_ASSERT(m_type == ConicalGradient);
2505  m_data.conical.angle = angle;
2506 }
2507 
2548 
2549 #include "moc_qbrush.cpp"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
Arabic default style
Definition: afstyles.h:94
static QBitmap fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat=QImage::Format_MonoLSB)
Definition: qbitmap.cpp:243
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:66
void setColor(const QColor &color)
Definition: qbrush.cpp:720
void setStyle(Qt::BrushStyle)
Definition: qbrush.cpp:688
void setTransform(const QTransform &)
Definition: qbrush.cpp:900
QBrush & operator=(const QBrush &brush)
Definition: qbrush.cpp:640
void setTextureImage(const QImage &image)
Definition: qbrush.cpp:809
bool operator==(const QBrush &b) const
Definition: qbrush.cpp:931
friend bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush &brush)
Definition: qbrush.cpp:235
bool isOpaque() const
Definition: qbrush.cpp:863
const QGradient * gradient() const
Definition: qbrush.cpp:824
QBrush()
Definition: qbrush.cpp:426
void setTexture(const QPixmap &pixmap)
Definition: qbrush.cpp:761
~QBrush()
Definition: qbrush.cpp:571
QImage textureImage() const
Definition: qbrush.cpp:785
QPixmap texture() const
Definition: qbrush.cpp:744
const QColor & color() const
Definition: qbrush.h:157
std::unique_ptr< QBrushData, QBrushDataPointerDeleter > DataPtr
Definition: qbrush.h:113
Qt::BrushStyle style() const
Definition: qbrush.h:156
QImage getImage(int brushStyle, bool invert) const
Definition: qbrush.cpp:150
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
The QConicalGradient class is used in combination with QBrush to specify a conical gradient brush.
Definition: qbrush.h:482
void setCenter(const QPointF &center)
Definition: qbrush.cpp:2472
qreal angle() const
Definition: qbrush.cpp:2486
void setAngle(qreal angle)
Definition: qbrush.cpp:2502
QPointF center() const
Definition: qbrush.cpp:2447
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:66
operator>>(QDataStream &ds, qfloat16 &f)
Definition: qfloat16.cpp:344
operator<<(QDataStream &ds, qfloat16 f)
Definition: qfloat16.cpp:327
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:65
QDebug & nospace()
Definition: qdebug.h:113
Convenience class for custom QDebug operators.
Definition: qdebug.h:176
The QGradient class is used in combination with QBrush to specify gradient fills.
Definition: qbrush.h:171
QGradientStop
Definition: qbrush.h:165
void setSpread(Spread spread)
Definition: qbrush.h:426
void setCoordinateMode(CoordinateMode mode)
Definition: qbrush.cpp:1716
Spread spread() const
Definition: qbrush.h:383
InterpolationMode
Definition: qbrush.h:197
@ ColorInterpolation
Definition: qbrush.h:198
CoordinateMode coordinateMode() const
Definition: qbrush.cpp:1705
void setStops(const QGradientStops &stops)
Definition: qbrush.cpp:1641
CoordinateMode
Definition: qbrush.h:189
@ ObjectBoundingMode
Definition: qbrush.h:192
@ LogicalMode
Definition: qbrush.h:190
@ ObjectMode
Definition: qbrush.h:193
void setColorAt(qreal pos, const QColor &color)
Definition: qbrush.cpp:1596
InterpolationMode interpolationMode() const
Definition: qbrush.cpp:1739
@ PadSpread
Definition: qbrush.h:183
Type type() const
Definition: qbrush.h:380
void setInterpolationMode(InterpolationMode mode)
Definition: qbrush.cpp:1751
QGradientStops stops() const
Definition: qbrush.cpp:1664
bool operator==(const QGradient &gradient) const
Definition: qbrush.cpp:1772
~QGradient()
Definition: qbrush.cpp:1521
@ LinearGradient
Definition: qbrush.h:175
@ NoGradient
Definition: qbrush.h:178
@ ConicalGradient
Definition: qbrush.h:177
@ RadialGradient
Definition: qbrush.h:176
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:73
bool hasAlphaChannel() const
Definition: qimage.cpp:4539
bool isNull() const
Definition: qimage.cpp:1319
@ Format_MonoLSB
Definition: qimage.h:80
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
The QLineF class provides a two-dimensional vector using floating point precision.
Definition: qline.h:215
The QLinearGradient class is used in combination with QBrush to specify a linear gradient brush.
Definition: qbrush.h:430
QPointF start() const
Definition: qbrush.cpp:1909
QPointF finalStop() const
Definition: qbrush.cpp:1960
void setFinalStop(const QPointF &stop)
Definition: qbrush.cpp:1976
void setStart(const QPointF &start)
Definition: qbrush.cpp:1935
qsizetype size() const noexcept
Definition: qlist.h:414
bool isEmpty() const noexcept
Definition: qlist.h:418
iterator insert(qsizetype i, parameter_type t)
Definition: qlist.h:499
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
void reserve(qsizetype size)
Definition: qlist.h:757
static QList< QGradientStop > fromReadOnlyData(const QGradientStop(&t)[N]) noexcept
Definition: qlist.h:733
void clear()
Definition: qlist.h:445
QBrushData * brush
Definition: qbrush.cpp:354
static bool find(const QString &key, QPixmap *pixmap)
static bool insert(const QString &key, const QPixmap &pixmap)
The QPixmap class is an off-screen image representation that can be used as a paint device.
Definition: qpixmap.h:63
QImage toImage() const
Definition: qpixmap.cpp:443
bool isNull() const
Definition: qpixmap.cpp:491
QPlatformPixmap * handle() const
Definition: qpixmap.cpp:1543
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
Definition: qpixmap.cpp:1474
qint64 cacheKey() const
Definition: qpixmap.cpp:917
bool hasAlphaChannel() const
Definition: qpixmap.cpp:1364
bool isQBitmap() const
Definition: qpixmap.cpp:478
ClassId classId() const
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:242
constexpr qreal x() const noexcept
Definition: qpoint.h:361
constexpr qreal y() const noexcept
Definition: qpoint.h:366
The QRadialGradient class is used in combination with QBrush to specify a radial gradient brush.
Definition: qbrush.h:448
void setCenter(const QPointF &center)
Definition: qbrush.cpp:2216
QPointF center() const
Definition: qbrush.cpp:2190
qreal focalRadius() const
Definition: qbrush.cpp:2287
void setFocalPoint(const QPointF &focalPoint)
Definition: qbrush.cpp:2338
void setCenterRadius(qreal radius)
Definition: qbrush.cpp:2273
QPointF focalPoint() const
Definition: qbrush.cpp:2312
qreal centerRadius() const
Definition: qbrush.cpp:2261
void setFocalRadius(qreal radius)
Definition: qbrush.cpp:2299
qreal radius() const
Definition: qbrush.cpp:2232
void setRadius(qreal radius)
Definition: qbrush.cpp:2247
The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon dest...
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
The QString class provides a Unicode character string.
Definition: qstring.h:388
qsizetype length() const
Definition: qstring.h:415
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:56
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:95
static auto fromValue(const T &value) -> std::enable_if_t< std::is_copy_constructible_v< T >, QVariant >
Definition: qvariant.h:391
QPixmap p2
QPixmap p1
[0]
constexpr QColor White
Definition: qcolor.h:316
constexpr QColor Black
Definition: qcolor.h:315
Definition: qnamespace.h:55
GlobalColor
Definition: qnamespace.h:58
@ black
Definition: qnamespace.h:61
BrushStyle
Definition: qnamespace.h:1139
@ DiagCrossPattern
Definition: qnamespace.h:1154
@ SolidPattern
Definition: qnamespace.h:1141
@ RadialGradientPattern
Definition: qnamespace.h:1156
@ Dense1Pattern
Definition: qnamespace.h:1142
@ TexturePattern
Definition: qnamespace.h:1158
@ LinearGradientPattern
Definition: qnamespace.h:1155
@ NoBrush
Definition: qnamespace.h:1140
@ ConicalGradientPattern
Definition: qnamespace.h:1157
QTextStream & center(QTextStream &stream)
Definition: brush.cpp:52
Definition: image.cpp:51
Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert)
Definition: qbrush.cpp:179
Q_GUI_EXPORT QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
Definition: qbrush.cpp:113
bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush &brush)
Definition: qbrush.cpp:235
QT_BEGIN_NAMESPACE const uchar * qt_patternForBrush(int brushStyle, bool invert)
Definition: qbrush.cpp:65
Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush)
Definition: qbrush.cpp:834
QPair< qreal, QColor > QGradientStop
Definition: qbrush.h:165
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
void qAddPostRoutine(QtCleanUpFunction p)
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition: qfloat16.h:249
bool qIsNaN(qfloat16 f) noexcept
Definition: qfloat16.h:221
unsigned int quint32
Definition: qglobal.h:288
QT_BEGIN_INCLUDE_NAMESPACE typedef unsigned char uchar
Definition: qglobal.h:332
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
long long qint64
Definition: qglobal.h:298
unsigned char quint8
Definition: qglobal.h:284
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition: qlogging.h:179
GLenum type
Definition: qopengl.h:270
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLenum mode
GLuint64 key
GLuint index
[2]
GLuint GLuint focalPoint
GLuint color
[2]
GLfloat angle
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLboolean GLboolean g
GLfloat n
GLuint GLenum GLenum transform
Definition: qopenglext.h:11564
const GLubyte * c
Definition: qopenglext.h:12701
GLint void * img
Definition: qopenglext.h:233
GLuint GLenum matrix
Definition: qopenglext.h:11564
GLdouble s
[6]
Definition: qopenglext.h:235
GLboolean invert
Definition: qopenglext.h:226
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
QDate d1(1995, 5, 17)
[0]
QDate d2(1995, 5, 20)
QSharedPointer< T > other(t)
[5]
widget render & pixmap
http get(QUrl::toPercentEncoding("/index.html"))
void operator()(QBrushData *d) const noexcept
Definition: qbrush.cpp:264
QGradient gradient
Definition: qbrush.cpp:245
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:53
void setImage(const QImage &image)
Definition: qbrush.cpp:208
QPixmap * m_pixmap
Definition: qbrush.cpp:228
QImage & image()
Definition: qbrush.cpp:222
void setPixmap(const QPixmap &pm)
Definition: qbrush.cpp:194
QPixmap & pixmap()
Definition: qbrush.cpp:215
bool m_has_pixmap_texture
Definition: qbrush.cpp:230
#define rhs
C sorted(C c)
struct QGradient::QGradientData::@523 radial
struct QGradient::QGradientData::@524 conical
struct QGradient::QGradientData::@522 linear