1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
45 #include "qpixmapcache.h"
46 #include "qdatastream.h"
50 #include <QtCore/qcoreapplication.h>
51 #include "private/qhexstring_p.h"
52 #include <QtCore/qnumeric.h>
56 const uchar *qt_patternForBrush(int brushStyle, bool invert)
58 Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
60 static const uchar dense1_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
61 static const uchar dense2_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
62 static const uchar dense3_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
63 static const uchar dense4_pat[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
64 static const uchar dense5_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
65 static const uchar dense6_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
66 static const uchar dense7_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
67 static const uchar hor_pat[] = { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 };
68 static const uchar ver_pat[] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 };
69 static const uchar cross_pat[] = { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 };
70 static const uchar bdiag_pat[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
71 static const uchar fdiag_pat[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
72 static const uchar dcross_pat[] = { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 };
73 static const uchar *const pat_tbl[] = {
74 dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
75 dense6_pat, dense7_pat,
76 hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
77 return pat_tbl[brushStyle - Qt::Dense1Pattern];
79 static const uchar dense1_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
80 static const uchar dense2_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
81 static const uchar dense3_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
82 static const uchar dense4_pat[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };
83 static const uchar dense5_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
84 static const uchar dense6_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
85 static const uchar dense7_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
86 static const uchar hor_pat[] = { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff };
87 static const uchar ver_pat[] = { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef };
88 static const uchar cross_pat[] = { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef };
89 static const uchar bdiag_pat[] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
90 static const uchar fdiag_pat[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
91 static const uchar dcross_pat[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e };
92 static const uchar *const pat_tbl[] = {
93 dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
94 dense6_pat, dense7_pat,
95 hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
96 return pat_tbl[brushStyle - Qt::Dense1Pattern];
99 QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
103 QString key = QLatin1String("$qt-brush$")
104 % HexString<uint>(brushStyle)
105 % QLatin1Char(invert ? '1' : '0');
106 if (!QPixmapCache::find(key, pm)) {
107 pm = QBitmap::fromData(QSize(8, 8), qt_patternForBrush(brushStyle, invert),
108 QImage::Format_MonoLSB);
109 QPixmapCache::insert(key, pm);
115 static void qt_cleanup_brush_pattern_image_cache();
116 class QBrushPatternImageCache
119 QBrushPatternImageCache()
120 : m_initialized(false)
127 qAddPostRoutine(qt_cleanup_brush_pattern_image_cache);
128 for (int style = Qt::Dense1Pattern; style <= Qt::DiagCrossPattern; ++style) {
129 int i = style - Qt::Dense1Pattern;
130 m_images[i][0] = QImage(qt_patternForBrush(style, 0), 8, 8, 1, QImage::Format_MonoLSB);
131 m_images[i][1] = QImage(qt_patternForBrush(style, 1), 8, 8, 1, QImage::Format_MonoLSB);
133 m_initialized = true;
136 QImage getImage(int brushStyle, bool invert) const
138 Q_ASSERT(brushStyle >= Qt::Dense1Pattern && brushStyle <= Qt::DiagCrossPattern);
140 const_cast<QBrushPatternImageCache*>(this)->init();
141 return m_images[brushStyle - Qt::Dense1Pattern][invert];
145 for (int style = Qt::Dense1Pattern; style <= Qt::DiagCrossPattern; ++style) {
146 int i = style - Qt::Dense1Pattern;
147 m_images[i][0] = QImage();
148 m_images[i][1] = QImage();
150 m_initialized = false;
154 QImage m_images[Qt::DiagCrossPattern - Qt::Dense1Pattern + 1][2];
158 Q_GLOBAL_STATIC(QBrushPatternImageCache, qt_brushPatternImageCache)
160 static void qt_cleanup_brush_pattern_image_cache()
162 qt_brushPatternImageCache()->cleanup();
165 Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert)
167 return qt_brushPatternImageCache()->getImage(brushStyle, invert);
170 struct QTexturedBrushData : public QBrushData
172 QTexturedBrushData() {
173 m_has_pixmap_texture = false;
176 ~QTexturedBrushData() {
180 void setPixmap(const QPixmap &pm) {
185 m_has_pixmap_texture = false;
187 m_pixmap = new QPixmap(pm);
188 m_has_pixmap_texture = true;
194 void setImage(const QImage &image) {
198 m_has_pixmap_texture = false;
203 m_pixmap = new QPixmap(QPixmap::fromImage(m_image));
209 if (m_image.isNull() && m_pixmap)
210 m_image = m_pixmap->toImage();
216 bool m_has_pixmap_texture;
219 // returns true if the brush has a pixmap (or bitmap) set as the
220 // brush texture, false otherwise
221 bool Q_GUI_EXPORT qHasPixmapTexture(const QBrush& brush)
223 if (brush.style() != Qt::TexturePattern)
225 QTexturedBrushData *tx_data = static_cast<QTexturedBrushData *>(brush.d.data());
226 return tx_data->m_has_pixmap_texture;
229 struct QGradientBrushData : public QBrushData
234 struct QBrushDataPointerDeleter
236 static inline void deleteData(QBrushData *d)
239 case Qt::TexturePattern:
240 delete static_cast<QTexturedBrushData*>(d);
242 case Qt::LinearGradientPattern:
243 case Qt::RadialGradientPattern:
244 case Qt::ConicalGradientPattern:
245 delete static_cast<QGradientBrushData*>(d);
252 static inline void cleanup(QBrushData *d)
254 if (d && !d->ref.deref()) {
265 \brief The QBrush class defines the fill pattern of shapes drawn
268 A brush has a style, a color, a gradient and a texture.
270 The brush style() defines the fill pattern using the
271 Qt::BrushStyle enum. The default brush style is Qt::NoBrush
272 (depending on how you construct a brush). This style tells the
273 painter to not fill shapes. The standard style for filling is
274 Qt::SolidPattern. The style can be set when the brush is created
275 using the appropriate constructor, and in addition the setStyle()
276 function provides means for altering the style once the brush is
279 \image brush-styles.png Brush Styles
281 The brush color() defines the color of the fill pattern. The color
282 can either be one of Qt's predefined colors, Qt::GlobalColor, or
283 any other custom QColor. The currently set color can be retrieved
284 and altered using the color() and setColor() functions,
287 The gradient() defines the gradient fill used when the current
288 style is either Qt::LinearGradientPattern,
289 Qt::RadialGradientPattern or Qt::ConicalGradientPattern. Gradient
290 brushes are created by giving a QGradient as a constructor
291 argument when creating the QBrush. Qt provides three different
292 gradients: QLinearGradient, QConicalGradient, and QRadialGradient
293 - all of which inherit QGradient.
295 \snippet doc/src/snippets/brush/gradientcreationsnippet.cpp 0
297 The texture() defines the pixmap used when the current style is
298 Qt::TexturePattern. You can create a brush with a texture by
299 providing the pixmap when the brush is created or by using
302 Note that applying setTexture() makes style() ==
303 Qt::TexturePattern, regardless of previous style
304 settings. Also, calling setColor() will not make a difference if
305 the style is a gradient. The same is the case if the style is
306 Qt::TexturePattern style unless the current texture is a QBitmap.
308 The isOpaque() function returns true if the brush is fully opaque
309 otherwise false. A brush is considered opaque if:
312 \li The alpha component of the color() is 255.
313 \li Its texture() does not have an alpha channel and is not a QBitmap.
314 \li The colors in the gradient() all have an alpha component that is 255.
319 \li \inlineimage brush-outline.png Outlines
322 To specify the style and color of lines and outlines, use the
323 QPainter's \l {QPen}{pen} combined with Qt::PenStyle and
326 \snippet doc/src/snippets/code/src_gui_painting_qbrush.cpp 0
328 Note that, by default, QPainter renders the outline (using the
329 currently set pen) when drawing shapes. Use \l {Qt::NoPen}{\c
330 painter.setPen(Qt::NoPen)} to disable this behavior.
334 For more information about painting in general, see the \l{Paint
337 \sa Qt::BrushStyle, QPainter, QColor
344 QNullBrushData() : brush(new QBrushData)
347 brush->style = Qt::BrushStyle(0);
348 brush->color = Qt::black;
352 if (!brush->ref.deref())
358 Q_GLOBAL_STATIC(QNullBrushData, nullBrushInstance_holder)
359 static QBrushData *nullBrushInstance()
361 return nullBrushInstance_holder()->brush;
364 static bool qbrush_check_type(Qt::BrushStyle style) {
366 case Qt::TexturePattern:
367 qWarning("QBrush: Incorrect use of TexturePattern");
369 case Qt::LinearGradientPattern:
370 case Qt::RadialGradientPattern:
371 case Qt::ConicalGradientPattern:
372 qWarning("QBrush: Wrong use of a gradient pattern");
382 Initializes the brush.
385 void QBrush::init(const QColor &color, Qt::BrushStyle style)
389 d.reset(nullBrushInstance());
391 if (d->color != color) setColor(color);
393 case Qt::TexturePattern:
394 d.reset(new QTexturedBrushData);
396 case Qt::LinearGradientPattern:
397 case Qt::RadialGradientPattern:
398 case Qt::ConicalGradientPattern:
399 d.reset(new QGradientBrushData);
402 d.reset(new QBrushData);
411 Constructs a default black brush with the style Qt::NoBrush
412 (i.e. this brush will not fill shapes).
416 : d(nullBrushInstance())
423 Constructs a brush with a black color and a texture set to the
424 given \a pixmap. The style is set to Qt::TexturePattern.
429 QBrush::QBrush(const QPixmap &pixmap)
431 init(Qt::black, Qt::TexturePattern);
437 Constructs a brush with a black color and a texture set to the
438 given \a image. The style is set to Qt::TexturePattern.
440 \sa setTextureImage()
443 QBrush::QBrush(const QImage &image)
445 init(Qt::black, Qt::TexturePattern);
446 setTextureImage(image);
450 Constructs a black brush with the given \a style.
455 QBrush::QBrush(Qt::BrushStyle style)
457 if (qbrush_check_type(style))
458 init(Qt::black, style);
460 d.reset(nullBrushInstance());
466 Constructs a brush with the given \a color and \a style.
468 \sa setColor(), setStyle()
471 QBrush::QBrush(const QColor &color, Qt::BrushStyle style)
473 if (qbrush_check_type(style))
476 d.reset(nullBrushInstance());
482 \fn QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style)
484 Constructs a brush with the given \a color and \a style.
486 \sa setColor(), setStyle()
488 QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style)
490 if (qbrush_check_type(style))
493 d.reset(nullBrushInstance());
499 Constructs a brush with the given \a color and the custom pattern
502 The style is set to Qt::TexturePattern. The color will only have
503 an effect for QBitmaps.
505 \sa setColor(), setPixmap()
508 QBrush::QBrush(const QColor &color, const QPixmap &pixmap)
510 init(color, Qt::TexturePattern);
516 Constructs a brush with the given \a color and the custom pattern
519 The style is set to Qt::TexturePattern. The color will only have
520 an effect for QBitmaps.
522 \sa setColor(), setPixmap()
524 QBrush::QBrush(Qt::GlobalColor color, const QPixmap &pixmap)
526 init(color, Qt::TexturePattern);
531 Constructs a copy of \a other.
534 QBrush::QBrush(const QBrush &other)
541 Constructs a brush based on the given \a gradient.
543 The brush style is set to the corresponding gradient style (either
544 Qt::LinearGradientPattern, Qt::RadialGradientPattern or
545 Qt::ConicalGradientPattern).
547 QBrush::QBrush(const QGradient &gradient)
549 Q_ASSERT_X(gradient.type() != QGradient::NoGradient, "QBrush::QBrush",
550 "QGradient should not be used directly, use the linear, radial\n"
551 "or conical gradients instead");
553 const Qt::BrushStyle enum_table[] = {
554 Qt::LinearGradientPattern,
555 Qt::RadialGradientPattern,
556 Qt::ConicalGradientPattern
559 init(QColor(), enum_table[gradient.type()]);
560 QGradientBrushData *grad = static_cast<QGradientBrushData *>(d.data());
561 grad->gradient = gradient;
572 void QBrush::cleanUp(QBrushData *x)
574 QBrushDataPointerDeleter::deleteData(x);
578 void QBrush::detach(Qt::BrushStyle newStyle)
580 if (newStyle == d->style && d->ref.load() == 1)
583 QScopedPointer<QBrushData> x;
585 case Qt::TexturePattern: {
586 QTexturedBrushData *tbd = new QTexturedBrushData;
587 if (d->style == Qt::TexturePattern) {
588 QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data());
589 if (data->m_has_pixmap_texture)
590 tbd->setPixmap(data->pixmap());
592 tbd->setImage(data->image());
597 case Qt::LinearGradientPattern:
598 case Qt::RadialGradientPattern:
599 case Qt::ConicalGradientPattern:
600 x.reset(new QGradientBrushData);
601 static_cast<QGradientBrushData *>(x.data())->gradient =
602 static_cast<QGradientBrushData *>(d.data())->gradient;
605 x.reset(new QBrushData);
611 x->transform = d->transform;
617 \fn QBrush &QBrush::operator=(const QBrush &brush)
619 Assigns the given \a brush to \e this brush and returns a
620 reference to \e this brush.
623 QBrush &QBrush::operator=(const QBrush &b)
635 \fn void QBrush::swap(QBrush &other)
638 Swaps brush \a other with this brush. This operation is very
639 fast and never fails.
643 Returns the brush as a QVariant
645 QBrush::operator QVariant() const
647 return QVariant(QVariant::Brush, this);
651 \fn Qt::BrushStyle QBrush::style() const
653 Returns the brush style.
659 Sets the brush style to \a style.
664 void QBrush::setStyle(Qt::BrushStyle style)
666 if (d->style == style)
669 if (qbrush_check_type(style)) {
677 \fn const QColor &QBrush::color() const
679 Returns the brush color.
685 \fn void QBrush::setColor(const QColor &color)
687 Sets the brush color to the given \a color.
689 Note that calling setColor() will not make a difference if the
690 style is a gradient. The same is the case if the style is
691 Qt::TexturePattern style unless the current texture is a QBitmap.
696 void QBrush::setColor(const QColor &c)
703 \fn void QBrush::setColor(Qt::GlobalColor color)
706 Sets the brush color to the given \a color.
710 \fn QPixmap QBrush::texture() const
712 Returns the custom brush pattern, or a null pixmap if no custom brush pattern
717 QPixmap QBrush::texture() const
719 return d->style == Qt::TexturePattern
720 ? (static_cast<QTexturedBrushData *>(d.data()))->pixmap()
725 Sets the brush pixmap to \a pixmap. The style is set to
728 The current brush color will only have an effect for monochrome
729 pixmaps, i.e. for QPixmap::depth() == 1 (\l {QBitmap}{QBitmaps}).
734 void QBrush::setTexture(const QPixmap &pixmap)
736 if (!pixmap.isNull()) {
737 detach(Qt::TexturePattern);
738 QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data());
739 data->setPixmap(pixmap);
749 Returns the custom brush pattern, or a null image if no custom
750 brush pattern has been set.
752 If the texture was set as a QPixmap it will be converted to a
755 \sa setTextureImage()
758 QImage QBrush::textureImage() const
760 return d->style == Qt::TexturePattern
761 ? (static_cast<QTexturedBrushData *>(d.data()))->image()
769 Sets the brush image to \a image. The style is set to
772 Note the current brush color will \e not have any affect on
773 monochrome images, as opposed to calling setTexture() with a
774 QBitmap. If you want to change the color of monochrome image
775 brushes, either convert the image to QBitmap with \c
776 QBitmap::fromImage() and set the resulting QBitmap as a texture,
777 or change the entries in the color table for the image.
779 \sa textureImage(), setTexture()
782 void QBrush::setTextureImage(const QImage &image)
784 if (!image.isNull()) {
785 detach(Qt::TexturePattern);
786 QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data());
787 data->setImage(image);
795 Returns the gradient describing this brush.
797 const QGradient *QBrush::gradient() const
799 if (d->style == Qt::LinearGradientPattern
800 || d->style == Qt::RadialGradientPattern
801 || d->style == Qt::ConicalGradientPattern) {
802 return &static_cast<const QGradientBrushData *>(d.data())->gradient;
807 Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush)
809 if (brush.style() == Qt::RadialGradientPattern) {
810 const QGradient *g = brush.gradient();
811 const QRadialGradient *rg = static_cast<const QRadialGradient *>(g);
813 if (!qFuzzyIsNull(rg->focalRadius()))
816 QPointF delta = rg->focalPoint() - rg->center();
817 if (delta.x() * delta.x() + delta.y() * delta.y() > rg->radius() * rg->radius())
825 Returns true if the brush is fully opaque otherwise false. A brush
826 is considered opaque if:
829 \li The alpha component of the color() is 255.
830 \li Its texture() does not have an alpha channel and is not a QBitmap.
831 \li The colors in the gradient() all have an alpha component that is 255.
832 \li It is an extended radial gradient.
836 bool QBrush::isOpaque() const
838 bool opaqueColor = d->color.alpha() == 255;
840 // Test awfully simple case first
841 if (d->style == Qt::SolidPattern)
844 if (qt_isExtendedRadialGradient(*this))
847 if (d->style == Qt::LinearGradientPattern
848 || d->style == Qt::RadialGradientPattern
849 || d->style == Qt::ConicalGradientPattern) {
850 QGradientStops stops = gradient()->stops();
851 for (int i=0; i<stops.size(); ++i)
852 if (stops.at(i).second.alpha() != 255)
855 } else if (d->style == Qt::TexturePattern) {
856 return qHasPixmapTexture(*this)
857 ? !texture().hasAlphaChannel() && !texture().isQBitmap()
858 : !textureImage().hasAlphaChannel();
868 Sets \a matrix as an explicit transformation matrix on the
869 current brush. The brush transformation matrix is merged with
870 QPainter transformation matrix to produce the final result.
874 void QBrush::setMatrix(const QMatrix &matrix)
876 setTransform(QTransform(matrix));
882 Sets \a matrix as an explicit transformation matrix on the
883 current brush. The brush transformation matrix is merged with
884 QPainter transformation matrix to produce the final result.
888 void QBrush::setTransform(const QTransform &matrix)
891 d->transform = matrix;
896 \fn void QBrush::matrix() const
899 Returns the current transformation matrix for the brush.
905 \fn bool QBrush::operator!=(const QBrush &brush) const
907 Returns true if the brush is different from the given \a brush;
908 otherwise returns false.
910 Two brushes are different if they have different styles, colors or
911 transforms or different pixmaps or gradients depending on the style.
917 \fn bool QBrush::operator==(const QBrush &brush) const
919 Returns true if the brush is equal to the given \a brush;
920 otherwise returns false.
922 Two brushes are equal if they have equal styles, colors and
923 transforms and equal pixmaps or gradients depending on the style.
928 bool QBrush::operator==(const QBrush &b) const
932 if (b.d->style != d->style || b.d->color != d->color || b.d->transform != d->transform)
935 case Qt::TexturePattern:
937 const QPixmap &us = (static_cast<QTexturedBrushData *>(d.data()))->pixmap();
938 const QPixmap &them = (static_cast<QTexturedBrushData *>(b.d.data()))->pixmap();
939 return ((us.isNull() && them.isNull()) || us.cacheKey() == them.cacheKey());
941 case Qt::LinearGradientPattern:
942 case Qt::RadialGradientPattern:
943 case Qt::ConicalGradientPattern:
945 const QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d.data());
946 const QGradientBrushData *d2 = static_cast<QGradientBrushData *>(b.d.data());
947 return d1->gradient == d2->gradient;
954 #ifndef QT_NO_DEBUG_STREAM
958 QDebug operator<<(QDebug dbg, const QBrush &b)
960 static const char *BRUSH_STYLES[] = {
976 "LinearGradientPattern",
977 "RadialGradientPattern",
978 "ConicalGradientPattern",
980 "TexturePattern" // 24
983 dbg.nospace() << "QBrush(" << b.color() << ',' << BRUSH_STYLES[b.style()] << ')';
988 /*****************************************************************************
989 QBrush stream functions
990 *****************************************************************************/
991 #ifndef QT_NO_DATASTREAM
993 \fn QDataStream &operator<<(QDataStream &stream, const QBrush &brush)
996 Writes the given \a brush to the given \a stream and returns a
997 reference to the \a stream.
999 \sa {Serializing Qt Data Types}
1002 QDataStream &operator<<(QDataStream &s, const QBrush &b)
1004 quint8 style = (quint8) b.style();
1005 bool gradient_style = false;
1007 if (style == Qt::LinearGradientPattern || style == Qt::RadialGradientPattern
1008 || style == Qt::ConicalGradientPattern)
1009 gradient_style = true;
1011 if (s.version() < QDataStream::Qt_4_0 && gradient_style)
1012 style = Qt::NoBrush;
1014 s << style << b.color();
1015 if (b.style() == Qt::TexturePattern) {
1017 } else if (s.version() >= QDataStream::Qt_4_0 && gradient_style) {
1018 const QGradient *gradient = b.gradient();
1019 int type_as_int = int(gradient->type());
1021 if (s.version() >= QDataStream::Qt_4_3) {
1022 s << int(gradient->spread());
1023 s << int(gradient->coordinateMode());
1026 if (s.version() >= QDataStream::Qt_4_5)
1027 s << int(gradient->interpolationMode());
1029 if (sizeof(qreal) == sizeof(double)) {
1030 s << gradient->stops();
1032 // ensure that we write doubles here instead of streaming the stops
1033 // directly; otherwise, platforms that redefine qreal might generate
1034 // data that cannot be read on other platforms.
1035 QVector<QGradientStop> stops = gradient->stops();
1036 s << quint32(stops.size());
1037 for (int i = 0; i < stops.size(); ++i) {
1038 const QGradientStop &stop = stops.at(i);
1039 s << QPair<double, QColor>(double(stop.first), stop.second);
1043 if (gradient->type() == QGradient::LinearGradient) {
1044 s << static_cast<const QLinearGradient *>(gradient)->start();
1045 s << static_cast<const QLinearGradient *>(gradient)->finalStop();
1046 } else if (gradient->type() == QGradient::RadialGradient) {
1047 s << static_cast<const QRadialGradient *>(gradient)->center();
1048 s << static_cast<const QRadialGradient *>(gradient)->focalPoint();
1049 s << (double) static_cast<const QRadialGradient *>(gradient)->radius();
1050 } else { // type == Conical
1051 s << static_cast<const QConicalGradient *>(gradient)->center();
1052 s << (double) static_cast<const QConicalGradient *>(gradient)->angle();
1055 if (s.version() >= QDataStream::Qt_4_3)
1061 \fn QDataStream &operator>>(QDataStream &stream, QBrush &brush)
1064 Reads the given \a brush from the given \a stream and returns a
1065 reference to the \a stream.
1067 \sa {Serializing Qt Data Types}
1070 QDataStream &operator>>(QDataStream &s, QBrush &b)
1076 if (style == Qt::TexturePattern) {
1079 b = QBrush(color, pm);
1080 } else if (style == Qt::LinearGradientPattern
1081 || style == Qt::RadialGradientPattern
1082 || style == Qt::ConicalGradientPattern) {
1085 QGradient::Type type;
1086 QGradientStops stops;
1087 QGradient::CoordinateMode cmode = QGradient::LogicalMode;
1088 QGradient::Spread spread = QGradient::PadSpread;
1089 QGradient::InterpolationMode imode = QGradient::ColorInterpolation;
1092 type = QGradient::Type(type_as_int);
1093 if (s.version() >= QDataStream::Qt_4_3) {
1095 spread = QGradient::Spread(type_as_int);
1097 cmode = QGradient::CoordinateMode(type_as_int);
1100 if (s.version() >= QDataStream::Qt_4_5) {
1102 imode = QGradient::InterpolationMode(type_as_int);
1105 if (sizeof(qreal) == sizeof(double)) {
1113 for (quint32 i = 0; i < numStops; ++i) {
1115 stops << QPair<qreal, QColor>(n, c);
1119 if (type == QGradient::LinearGradient) {
1123 QLinearGradient lg(p1, p2);
1125 lg.setSpread(spread);
1126 lg.setCoordinateMode(cmode);
1127 lg.setInterpolationMode(imode);
1129 } else if (type == QGradient::RadialGradient) {
1130 QPointF center, focal;
1135 QRadialGradient rg(center, radius, focal);
1137 rg.setSpread(spread);
1138 rg.setCoordinateMode(cmode);
1139 rg.setInterpolationMode(imode);
1141 } else { // type == QGradient::ConicalGradient
1146 QConicalGradient cg(center, angle);
1148 cg.setSpread(spread);
1149 cg.setCoordinateMode(cmode);
1150 cg.setInterpolationMode(imode);
1154 b = QBrush(color, (Qt::BrushStyle)style);
1156 if (s.version() >= QDataStream::Qt_4_3) {
1157 QTransform transform;
1159 b.setTransform(transform);
1163 #endif // QT_NO_DATASTREAM
1165 /*******************************************************************************
1166 * QGradient implementations
1175 \brief The QGradient class is used in combination with QBrush to
1176 specify gradient fills.
1178 Qt currently supports three types of gradient fills:
1181 \li \e Linear gradients interpolate colors between start and end points.
1182 \li \e Simple radial gradients interpolate colors between a focal point
1183 and end points on a circle surrounding it.
1184 \li \e Extended radial gradients interpolate colors between a center and
1186 \li \e Conical gradients interpolate colors around a center point.
1189 A gradient's type can be retrieved using the type() function.
1190 Each of the types is represented by a subclass of QGradient:
1196 \li QConicalGradient
1198 \li \inlineimage qgradient-linear.png
1199 \li \inlineimage qgradient-radial.png
1200 \li \inlineimage qgradient-conical.png
1203 The colors in a gradient are defined using stop points of the
1204 QGradientStop type; i.e., a position and a color. Use the setColorAt()
1205 function to define a single stop point. Alternatively, use the
1206 setStops() function to define several stop points in one go. Note that
1207 the latter function \e replaces the current set of stop points.
1209 It is the gradient's complete set of stop points (accessible
1210 through the stops() function) that describes how the gradient area
1211 should be filled. If no stop points have been specified, a gradient
1212 of black at 0 to white at 1 is used.
1214 A diagonal linear gradient from black at (100, 100) to white at
1215 (200, 200) could be specified like this:
1217 \snippet doc/src/snippets/brush/brush.cpp 0
1219 A gradient can have an arbitrary number of stop points. The
1220 following would create a radial gradient starting with
1221 red in the center, blue and then green on the edges:
1223 \snippet doc/src/snippets/brush/brush.cpp 1
1225 It is possible to repeat or reflect the gradient outside its area
1226 by specifiying the \l {QGradient::Spread}{spread method} using the
1227 setSpread() function. The default is to pad the outside area with
1228 the color at the closest stop point. The currently set \l
1229 {QGradient::Spread}{spread method} can be retrieved using the
1230 spread() function. The QGradient::Spread enum defines three
1235 \li \inlineimage qradialgradient-pad.png
1236 \li \inlineimage qradialgradient-repeat.png
1237 \li \inlineimage qradialgradient-reflect.png
1239 \li \l {QGradient::PadSpread}{PadSpread}
1240 \li \l {QGradient::RepeatSpread}{RepeatSpread}
1241 \li \l {QGradient::ReflectSpread}{ReflectSpread}
1244 Note that the setSpread() function only has effect for linear and
1245 radial gradients. The reason is that the conical gradient is
1246 closed by definition, i.e. the \e conical gradient fills the
1247 entire circle from 0 - 360 degrees, while the boundary of a radial
1248 or a linear gradient can be specified through its radius or final
1249 stop points, respectively.
1251 The gradient coordinates can be specified in logical coordinates,
1252 relative to device coordinates, or relative to object bounding box coordinates.
1253 The \l {QGradient::CoordinateMode}{coordinate mode} can be set using the
1254 setCoordinateMode() function. The default is LogicalMode, where the
1255 gradient coordinates are specified in the same way as the object
1256 coordinates. To retrieve the currently set \l {QGradient::CoordinateMode}
1257 {coordinate mode} use coordinateMode().
1260 \sa {painting/gradients}{The Gradients Example}, QBrush
1266 QGradient::QGradient()
1267 : m_type(NoGradient), dummy(0)
1273 \enum QGradient::Type
1275 Specifies the type of gradient.
1277 \value LinearGradient Interpolates colors between start and end points
1280 \value RadialGradient Interpolate colors between a focal point and end
1281 points on a circle surrounding it (QRadialGradient).
1283 \value ConicalGradient Interpolate colors around a center point (QConicalGradient).
1284 \value NoGradient No gradient is used.
1290 \enum QGradient::Spread
1292 Specifies how the area outside the gradient area should be
1295 \value PadSpread The area is filled with the closest stop
1296 color. This is the default.
1298 \value RepeatSpread The gradient is repeated outside the gradient
1301 \value ReflectSpread The gradient is reflected outside the
1304 \sa spread(), setSpread()
1308 \fn void QGradient::setSpread(Spread method)
1310 Specifies the spread \a method that should be used for this
1313 Note that this function only has effect for linear and radial
1320 \fn QGradient::Spread QGradient::spread() const
1322 Returns the spread method use by this gradient. The default is
1329 \fn QGradient::Type QGradient::type() const
1331 Returns the type of gradient.
1335 \fn void QGradient::setColorAt(qreal position, const QColor &color)
1337 Creates a stop point at the given \a position with the given \a
1338 color. The given \a position must be in the range 0 to 1.
1340 \sa setStops(), stops()
1343 void QGradient::setColorAt(qreal pos, const QColor &color)
1345 if ((pos > 1 || pos < 0) && !qIsNaN(pos)) {
1346 qWarning("QGradient::setColorAt: Color position must be specified in the range 0 to 1");
1352 while (index < m_stops.size() && m_stops.at(index).first < pos) ++index;
1354 if (index < m_stops.size() && m_stops.at(index).first == pos)
1355 m_stops[index].second = color;
1357 m_stops.insert(index, QGradientStop(pos, color));
1361 \fn void QGradient::setStops(const QGradientStops &stopPoints)
1363 Replaces the current set of stop points with the given \a
1364 stopPoints. The positions of the points must be in the range 0 to
1365 1, and must be sorted with the lowest point first.
1367 \sa setColorAt(), stops()
1369 void QGradient::setStops(const QGradientStops &stops)
1372 for (int i=0; i<stops.size(); ++i)
1373 setColorAt(stops.at(i).first, stops.at(i).second);
1378 Returns the stop points for this gradient.
1380 If no stop points have been specified, a gradient of black at 0 to white
1383 \sa setStops(), setColorAt()
1385 QGradientStops QGradient::stops() const
1387 if (m_stops.isEmpty()) {
1389 tmp << QGradientStop(0, Qt::black) << QGradientStop(1, Qt::white);
1395 #define Q_DUMMY_ACCESSOR union {void *p; uint i;}; p = dummy;
1398 \enum QGradient::CoordinateMode
1401 This enum specifies how gradient coordinates map to the paint
1402 device on which the gradient is used.
1404 \value LogicalMode This is the default mode. The gradient coordinates
1405 are specified logical space just like the object coordinates.
1406 \value StretchToDeviceMode In this mode the gradient coordinates
1407 are relative to the bounding rectangle of the paint device,
1408 with (0,0) in the top left corner, and (1,1) in the bottom right
1409 corner of the paint device.
1410 \value ObjectBoundingMode In this mode the gradient coordinates are
1411 relative to the bounding rectangle of the object being drawn, with
1412 (0,0) in the top left corner, and (1,1) in the bottom right corner
1413 of the object's bounding rectangle.
1419 Returns the coordinate mode of this gradient. The default mode is
1422 QGradient::CoordinateMode QGradient::coordinateMode() const
1425 return CoordinateMode(i & 0x03);
1431 Sets the coordinate mode of this gradient to \a mode. The default
1432 mode is LogicalMode.
1434 void QGradient::setCoordinateMode(CoordinateMode mode)
1443 \enum QGradient::InterpolationMode
1447 \value ComponentInterpolation The color components and the alpha component are
1448 independently linearly interpolated.
1449 \value ColorInterpolation The colors are linearly interpolated in
1450 premultiplied color space.
1457 Returns the interpolation mode of this gradient. The default mode is
1460 QGradient::InterpolationMode QGradient::interpolationMode() const
1463 return InterpolationMode((i >> 2) & 0x01);
1470 Sets the interpolation mode of this gradient to \a mode. The default
1471 mode is ColorInterpolation.
1473 void QGradient::setInterpolationMode(InterpolationMode mode)
1477 i |= (uint(mode) << 2);
1482 \fn bool QGradient::operator!=(const QGradient &gradient) const
1485 Returns true if the gradient is the same as the other \a gradient
1486 specified; otherwise returns false.
1492 Returns true if the gradient is the same as the other \a gradient
1493 specified; otherwise returns false.
1497 bool QGradient::operator==(const QGradient &gradient) const
1499 if (gradient.m_type != m_type
1500 || gradient.m_spread != m_spread
1501 || gradient.dummy != dummy) return false;
1503 if (m_type == LinearGradient) {
1504 if (m_data.linear.x1 != gradient.m_data.linear.x1
1505 || m_data.linear.y1 != gradient.m_data.linear.y1
1506 || m_data.linear.x2 != gradient.m_data.linear.x2
1507 || m_data.linear.y2 != gradient.m_data.linear.y2)
1509 } else if (m_type == RadialGradient) {
1510 if (m_data.radial.cx != gradient.m_data.radial.cx
1511 || m_data.radial.cy != gradient.m_data.radial.cy
1512 || m_data.radial.fx != gradient.m_data.radial.fx
1513 || m_data.radial.fy != gradient.m_data.radial.fy
1514 || m_data.radial.cradius != gradient.m_data.radial.cradius)
1516 } else { // m_type == ConicalGradient
1517 if (m_data.conical.cx != gradient.m_data.conical.cx
1518 || m_data.conical.cy != gradient.m_data.conical.cy
1519 || m_data.conical.angle != gradient.m_data.conical.angle)
1523 return stops() == gradient.stops();
1527 \class QLinearGradient
1530 \brief The QLinearGradient class is used in combination with QBrush to
1531 specify a linear gradient brush.
1533 Linear gradients interpolate colors between start and end
1534 points. Outside these points the gradient is either padded,
1535 reflected or repeated depending on the currently set \l
1536 {QGradient::Spread}{spread} method:
1540 \li \inlineimage qlineargradient-pad.png
1541 \li \inlineimage qlineargradient-reflect.png
1542 \li \inlineimage qlineargradient-repeat.png
1544 \li \l {QGradient::PadSpread}{PadSpread} (default)
1545 \li \l {QGradient::ReflectSpread}{ReflectSpread}
1546 \li \l {QGradient::RepeatSpread}{RepeatSpread}
1549 The colors in a gradient is defined using stop points of the
1550 QGradientStop type, i.e. a position and a color. Use the
1551 QGradient::setColorAt() or the QGradient::setStops() function to
1552 define the stop points. It is the gradient's complete set of stop
1553 points that describes how the gradient area should be filled. If
1554 no stop points have been specified, a gradient of black at 0 to
1557 In addition to the functions inherited from QGradient, the
1558 QLinearGradient class provides the finalStop() function which
1559 returns the final stop point of the gradient, and the start()
1560 function returning the start point of the gradient.
1562 \sa QRadialGradient, QConicalGradient, {painting/gradients}{The
1568 Constructs a default linear gradient with interpolation area
1569 between (0, 0) and (1, 1).
1571 \sa QGradient::setColorAt(), setStart(), setFinalStop()
1574 QLinearGradient::QLinearGradient()
1576 m_type = LinearGradient;
1577 m_spread = PadSpread;
1578 m_data.linear.x1 = 0;
1579 m_data.linear.y1 = 0;
1580 m_data.linear.x2 = 1;
1581 m_data.linear.y2 = 1;
1586 Constructs a linear gradient with interpolation area between the
1587 given \a start point and \a finalStop.
1589 \note The expected parameter values are in pixels.
1591 \sa QGradient::setColorAt(), QGradient::setStops()
1593 QLinearGradient::QLinearGradient(const QPointF &start, const QPointF &finalStop)
1595 m_type = LinearGradient;
1596 m_spread = PadSpread;
1597 m_data.linear.x1 = start.x();
1598 m_data.linear.y1 = start.y();
1599 m_data.linear.x2 = finalStop.x();
1600 m_data.linear.y2 = finalStop.y();
1604 \fn QLinearGradient::QLinearGradient(qreal x1, qreal y1, qreal x2, qreal y2)
1606 Constructs a linear gradient with interpolation area between (\a
1607 x1, \a y1) and (\a x2, \a y2).
1609 \note The expected parameter values are in pixels.
1611 \sa QGradient::setColorAt(), QGradient::setStops()
1613 QLinearGradient::QLinearGradient(qreal xStart, qreal yStart, qreal xFinalStop, qreal yFinalStop)
1615 m_type = LinearGradient;
1616 m_spread = PadSpread;
1617 m_data.linear.x1 = xStart;
1618 m_data.linear.y1 = yStart;
1619 m_data.linear.x2 = xFinalStop;
1620 m_data.linear.y2 = yFinalStop;
1625 Returns the start point of this linear gradient in logical coordinates.
1627 \sa QGradient::stops()
1630 QPointF QLinearGradient::start() const
1632 Q_ASSERT(m_type == LinearGradient);
1633 return QPointF(m_data.linear.x1, m_data.linear.y1);
1637 \fn void QLinearGradient::setStart(qreal x, qreal y)
1641 Sets the start point of this linear gradient in logical
1642 coordinates to \a x, \a y.
1650 Sets the start point of this linear gradient in logical
1651 coordinates to \a start.
1656 void QLinearGradient::setStart(const QPointF &start)
1658 Q_ASSERT(m_type == LinearGradient);
1659 m_data.linear.x1 = start.x();
1660 m_data.linear.y1 = start.y();
1665 \fn void QLinearGradient::setFinalStop(qreal x, qreal y)
1669 Sets the final stop point of this linear gradient in logical
1670 coordinates to \a x, \a y.
1676 Returns the final stop point of this linear gradient in logical coordinates.
1678 \sa QGradient::stops()
1681 QPointF QLinearGradient::finalStop() const
1683 Q_ASSERT(m_type == LinearGradient);
1684 return QPointF(m_data.linear.x2, m_data.linear.y2);
1691 Sets the final stop point of this linear gradient in logical
1692 coordinates to \a stop.
1697 void QLinearGradient::setFinalStop(const QPointF &stop)
1699 Q_ASSERT(m_type == LinearGradient);
1700 m_data.linear.x2 = stop.x();
1701 m_data.linear.y2 = stop.y();
1706 \class QRadialGradient
1709 \brief The QRadialGradient class is used in combination with QBrush to
1710 specify a radial gradient brush.
1712 Qt supports both simple and extended radial gradients.
1714 Simple radial gradients interpolate colors between a focal point and end
1715 points on a circle surrounding it. Extended radial gradients interpolate
1716 colors between a focal circle and a center circle. Points outside the cone
1717 defined by the two circles will be transparent. For simple radial gradients
1718 the focal point is adjusted to lie inside the center circle, whereas the
1719 focal point can have any position in an extended radial gradient.
1721 Outside the end points the gradient is either padded, reflected or repeated
1722 depending on the currently set \l {QGradient::Spread}{spread} method:
1726 \li \inlineimage qradialgradient-pad.png
1727 \li \inlineimage qradialgradient-reflect.png
1728 \li \inlineimage qradialgradient-repeat.png
1730 \li \l {QGradient::PadSpread}{PadSpread} (default)
1731 \li \l {QGradient::ReflectSpread}{ReflectSpread}
1732 \li \l {QGradient::RepeatSpread}{RepeatSpread}
1735 The colors in a gradient is defined using stop points of the
1736 QGradientStop type, i.e. a position and a color. Use the
1737 QGradient::setColorAt() or the QGradient::setStops() function to
1738 define the stop points. It is the gradient's complete set of stop
1739 points that describes how the gradient area should be filled. If
1740 no stop points have been specified, a gradient of black at 0 to
1743 In addition to the functions inherited from QGradient, the
1744 QRadialGradient class provides the center(), focalPoint() and
1745 radius() functions returning the gradient's center, focal point
1746 and radius respectively.
1748 \sa QLinearGradient, QConicalGradient, {painting/gradients}{The
1752 static QPointF qt_radial_gradient_adapt_focal_point(const QPointF ¢er,
1754 const QPointF &focalPoint)
1756 // We have a one pixel buffer zone to avoid numerical instability on the
1758 //### this is hacky because technically we should adjust based on current matrix
1759 const qreal compensated_radius = radius - radius * qreal(0.001);
1760 QLineF line(center, focalPoint);
1761 if (line.length() > (compensated_radius))
1762 line.setLength(compensated_radius);
1767 Constructs a simple radial gradient with the given \a center, \a
1768 radius and \a focalPoint.
1770 \note If the given focal point is outside the circle defined by the
1771 \a center point and \a radius, it will be re-adjusted to lie at a point on
1772 the circle where it intersects with the line from \a center to
1775 \sa QGradient::setColorAt(), QGradient::setStops()
1778 QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius, const QPointF &focalPoint)
1780 m_type = RadialGradient;
1781 m_spread = PadSpread;
1782 m_data.radial.cx = center.x();
1783 m_data.radial.cy = center.y();
1784 m_data.radial.cradius = radius;
1786 QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(center, radius, focalPoint);
1787 m_data.radial.fx = adapted_focal.x();
1788 m_data.radial.fy = adapted_focal.y();
1792 Constructs a simple radial gradient with the given \a center, \a
1793 radius and the focal point in the circle center.
1795 \sa QGradient::setColorAt(), QGradient::setStops()
1797 QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius)
1799 m_type = RadialGradient;
1800 m_spread = PadSpread;
1801 m_data.radial.cx = center.x();
1802 m_data.radial.cy = center.y();
1803 m_data.radial.cradius = radius;
1804 m_data.radial.fx = center.x();
1805 m_data.radial.fy = center.y();
1810 Constructs a simple radial gradient with the given center (\a cx, \a cy),
1811 \a radius and focal point (\a fx, \a fy).
1813 \note If the given focal point is outside the circle defined by the
1814 center (\a cx, \a cy) and the \a radius it will be re-adjusted to
1815 the intersection between the line from the center to the focal point
1818 \sa QGradient::setColorAt(), QGradient::setStops()
1821 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius, qreal fx, qreal fy)
1823 m_type = RadialGradient;
1824 m_spread = PadSpread;
1825 m_data.radial.cx = cx;
1826 m_data.radial.cy = cy;
1827 m_data.radial.cradius = radius;
1829 QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(QPointF(cx, cy),
1833 m_data.radial.fx = adapted_focal.x();
1834 m_data.radial.fy = adapted_focal.y();
1838 Constructs a simple radial gradient with the center at (\a cx, \a cy) and the
1839 specified \a radius. The focal point lies at the center of the circle.
1841 \sa QGradient::setColorAt(), QGradient::setStops()
1843 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius)
1845 m_type = RadialGradient;
1846 m_spread = PadSpread;
1847 m_data.radial.cx = cx;
1848 m_data.radial.cy = cy;
1849 m_data.radial.cradius = radius;
1850 m_data.radial.fx = cx;
1851 m_data.radial.fy = cy;
1856 Constructs a simple radial gradient with the center and focal point at
1857 (0, 0) with a radius of 1.
1859 QRadialGradient::QRadialGradient()
1861 m_type = RadialGradient;
1862 m_spread = PadSpread;
1863 m_data.radial.cx = 0;
1864 m_data.radial.cy = 0;
1865 m_data.radial.cradius = 1;
1866 m_data.radial.fx = 0;
1867 m_data.radial.fy = 0;
1873 Constructs an extended radial gradient with the given \a center, \a
1874 centerRadius, \a focalPoint, and \a focalRadius.
1876 QRadialGradient::QRadialGradient(const QPointF ¢er, qreal centerRadius, const QPointF &focalPoint, qreal focalRadius)
1878 m_type = RadialGradient;
1879 m_spread = PadSpread;
1880 m_data.radial.cx = center.x();
1881 m_data.radial.cy = center.y();
1882 m_data.radial.cradius = centerRadius;
1884 m_data.radial.fx = focalPoint.x();
1885 m_data.radial.fy = focalPoint.y();
1886 setFocalRadius(focalRadius);
1892 Constructs an extended radial gradient with the given center
1893 (\a cx, \a cy), center radius, \a centerRadius, focal point, (\a fx, \a fy),
1894 and focal radius \a focalRadius.
1896 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius)
1898 m_type = RadialGradient;
1899 m_spread = PadSpread;
1900 m_data.radial.cx = cx;
1901 m_data.radial.cy = cy;
1902 m_data.radial.cradius = centerRadius;
1904 m_data.radial.fx = fx;
1905 m_data.radial.fy = fy;
1906 setFocalRadius(focalRadius);
1910 Returns the center of this radial gradient in logical coordinates.
1912 \sa QGradient::stops()
1915 QPointF QRadialGradient::center() const
1917 Q_ASSERT(m_type == RadialGradient);
1918 return QPointF(m_data.radial.cx, m_data.radial.cy);
1922 \fn void QRadialGradient::setCenter(qreal x, qreal y)
1926 Sets the center of this radial gradient in logical coordinates
1935 Sets the center of this radial gradient in logical coordinates
1941 void QRadialGradient::setCenter(const QPointF ¢er)
1943 Q_ASSERT(m_type == RadialGradient);
1944 m_data.radial.cx = center.x();
1945 m_data.radial.cy = center.y();
1950 Returns the radius of this radial gradient in logical coordinates.
1952 Equivalent to centerRadius()
1954 \sa QGradient::stops()
1957 qreal QRadialGradient::radius() const
1959 Q_ASSERT(m_type == RadialGradient);
1960 return m_data.radial.cradius;
1967 Sets the radius of this radial gradient in logical coordinates
1970 Equivalent to setCenterRadius()
1972 void QRadialGradient::setRadius(qreal radius)
1974 Q_ASSERT(m_type == RadialGradient);
1975 m_data.radial.cradius = radius;
1981 Returns the center radius of this radial gradient in logical
1984 \sa QGradient::stops()
1986 qreal QRadialGradient::centerRadius() const
1988 Q_ASSERT(m_type == RadialGradient);
1989 return m_data.radial.cradius;
1995 Sets the center radius of this radial gradient in logical coordinates
1998 void QRadialGradient::setCenterRadius(qreal radius)
2000 Q_ASSERT(m_type == RadialGradient);
2001 m_data.radial.cradius = radius;
2007 Returns the focal radius of this radial gradient in logical
2010 \sa QGradient::stops()
2012 qreal QRadialGradient::focalRadius() const
2014 Q_ASSERT(m_type == RadialGradient);
2017 // mask away low three bits
2018 union { float f; quint32 i; } u;
2026 Sets the focal radius of this radial gradient in logical coordinates
2029 void QRadialGradient::setFocalRadius(qreal radius)
2031 Q_ASSERT(m_type == RadialGradient);
2034 // Since there's no QGradientData, we only have the dummy void * to
2035 // store additional data in. The three lowest bits are already
2036 // taken, thus we cut the three lowest bits from the significand
2037 // and store the radius as a float.
2038 union { float f; quint32 i; } u;
2039 u.f = float(radius);
2040 // add 0x04 to round up when we drop the three lowest bits
2041 i |= (u.i + 0x04) & ~0x07;
2046 Returns the focal point of this radial gradient in logical
2049 \sa QGradient::stops()
2052 QPointF QRadialGradient::focalPoint() const
2054 Q_ASSERT(m_type == RadialGradient);
2055 return QPointF(m_data.radial.fx, m_data.radial.fy);
2059 \fn void QRadialGradient::setFocalPoint(qreal x, qreal y)
2063 Sets the focal point of this radial gradient in logical
2064 coordinates to (\a x, \a y).
2072 Sets the focal point of this radial gradient in logical
2073 coordinates to \a focalPoint.
2078 void QRadialGradient::setFocalPoint(const QPointF &focalPoint)
2080 Q_ASSERT(m_type == RadialGradient);
2081 m_data.radial.fx = focalPoint.x();
2082 m_data.radial.fy = focalPoint.y();
2088 \class QConicalGradient
2091 \brief The QConicalGradient class is used in combination with QBrush to
2092 specify a conical gradient brush.
2094 Conical gradients interpolate interpolate colors counter-clockwise
2095 around a center point.
2097 \image qconicalgradient.png
2099 The colors in a gradient is defined using stop points of the
2100 QGradientStop type, i.e. a position and a color. Use the
2101 QGradient::setColorAt() or the QGradient::setStops() function to
2102 define the stop points. It is the gradient's complete set of stop
2103 points that describes how the gradient area should be filled. If
2104 no stop points have been specified, a gradient of black at 0 to
2107 In addition to the functions inherited from QGradient, the
2108 QConicalGradient class provides the angle() and center() functions
2109 returning the start angle and center of the gradient.
2111 Note that the setSpread() function has no effect for conical
2112 gradients. The reason is that the conical gradient is closed by
2113 definition, i.e. the conical gradient fills the entire circle from
2114 0 - 360 degrees, while the boundary of a radial or a linear
2115 gradient can be specified through its radius or final stop points,
2118 \sa QLinearGradient, QRadialGradient, {painting/gradients}{The
2124 Constructs a conical gradient with the given \a center, starting
2125 the interpolation at the given \a angle. The \a angle must be
2126 specified in degrees between 0 and 360.
2128 \sa QGradient::setColorAt(), QGradient::setStops()
2131 QConicalGradient::QConicalGradient(const QPointF ¢er, qreal angle)
2133 m_type = ConicalGradient;
2134 m_spread = PadSpread;
2135 m_data.conical.cx = center.x();
2136 m_data.conical.cy = center.y();
2137 m_data.conical.angle = angle;
2142 Constructs a conical gradient with the given center (\a cx, \a
2143 cy), starting the interpolation at the given \a angle. The angle
2144 must be specified in degrees between 0 and 360.
2146 \sa QGradient::setColorAt(), QGradient::setStops()
2149 QConicalGradient::QConicalGradient(qreal cx, qreal cy, qreal angle)
2151 m_type = ConicalGradient;
2152 m_spread = PadSpread;
2153 m_data.conical.cx = cx;
2154 m_data.conical.cy = cy;
2155 m_data.conical.angle = angle;
2160 Constructs a conical with center at (0, 0) starting the
2161 interpolation at angle 0.
2163 \sa QGradient::setColorAt(), setCenter(), setAngle()
2166 QConicalGradient::QConicalGradient()
2168 m_type = ConicalGradient;
2169 m_spread = PadSpread;
2170 m_data.conical.cx = 0;
2171 m_data.conical.cy = 0;
2172 m_data.conical.angle = 0;
2177 Returns the center of the conical gradient in logical
2183 QPointF QConicalGradient::center() const
2185 Q_ASSERT(m_type == ConicalGradient);
2186 return QPointF(m_data.conical.cx, m_data.conical.cy);
2191 \fn void QConicalGradient::setCenter(qreal x, qreal y)
2195 Sets the center of this conical gradient in logical coordinates to
2202 Sets the center of this conical gradient in logical coordinates to
2208 void QConicalGradient::setCenter(const QPointF ¢er)
2210 Q_ASSERT(m_type == ConicalGradient);
2211 m_data.conical.cx = center.x();
2212 m_data.conical.cy = center.y();
2216 Returns the start angle of the conical gradient in logical
2222 qreal QConicalGradient::angle() const
2224 Q_ASSERT(m_type == ConicalGradient);
2225 return m_data.conical.angle;
2232 Sets \a angle to be the start angle for this conical gradient in
2233 logical coordinates.
2238 void QConicalGradient::setAngle(qreal angle)
2240 Q_ASSERT(m_type == ConicalGradient);
2241 m_data.conical.angle = angle;
2245 \typedef QGradientStop
2248 Typedef for QPair<\l qreal, QColor>.
2252 \typedef QGradientStops
2255 Typedef for QVector<QGradientStop>.
2259 \typedef QBrush::DataPtr
2264 \fn DataPtr &QBrush::data_ptr()
2270 \fn bool QBrush::isDetached() const
2275 \fn QTransform QBrush::transform() const
2278 Returns the current transformation matrix for the brush.
2283 #undef Q_DUMMY_ACCESSOR