1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** 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/qstylehelper_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 = QLatin1Literal("$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 \o The alpha component of the color() is 255.
313 \o Its texture() does not have an alpha channel and is not a QBitmap.
314 \o The colors in the gradient() all have an alpha component that is 255.
319 \o \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 == 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.
713 \fn void QBrush::setPixmap(const QPixmap &pixmap)
717 Sets a custom pattern for this brush.
719 Use setTexture() instead.
723 \fn QPixmap *QBrush::pixmap() const
725 Returns a pointer to the custom brush pattern.
727 Use texture() instead.
729 QPixmap *QBrush::pixmap() const
731 if (d->style != Qt::TexturePattern)
733 QTexturedBrushData *data = static_cast<QTexturedBrushData*>(d.data());
734 QPixmap &pixmap = data->pixmap();
735 return pixmap.isNull() ? 0 : &pixmap;
740 \fn QPixmap QBrush::texture() const
742 Returns the custom brush pattern, or a null pixmap if no custom brush pattern
747 QPixmap QBrush::texture() const
749 return d->style == Qt::TexturePattern
750 ? (static_cast<QTexturedBrushData *>(d.data()))->pixmap()
755 Sets the brush pixmap to \a pixmap. The style is set to
758 The current brush color will only have an effect for monochrome
759 pixmaps, i.e. for QPixmap::depth() == 1 (\l {QBitmap}{QBitmaps}).
764 void QBrush::setTexture(const QPixmap &pixmap)
766 if (!pixmap.isNull()) {
767 detach(Qt::TexturePattern);
768 QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data());
769 data->setPixmap(pixmap);
779 Returns the custom brush pattern, or a null image if no custom
780 brush pattern has been set.
782 If the texture was set as a QPixmap it will be converted to a
785 \sa setTextureImage()
788 QImage QBrush::textureImage() const
790 return d->style == Qt::TexturePattern
791 ? (static_cast<QTexturedBrushData *>(d.data()))->image()
799 Sets the brush image to \a image. The style is set to
802 Note the current brush color will \e not have any affect on
803 monochrome images, as opposed to calling setTexture() with a
804 QBitmap. If you want to change the color of monochrome image
805 brushes, either convert the image to QBitmap with \c
806 QBitmap::fromImage() and set the resulting QBitmap as a texture,
807 or change the entries in the color table for the image.
809 \sa textureImage(), setTexture()
812 void QBrush::setTextureImage(const QImage &image)
814 if (!image.isNull()) {
815 detach(Qt::TexturePattern);
816 QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data());
817 data->setImage(image);
825 Returns the gradient describing this brush.
827 const QGradient *QBrush::gradient() const
829 if (d->style == Qt::LinearGradientPattern
830 || d->style == Qt::RadialGradientPattern
831 || d->style == Qt::ConicalGradientPattern) {
832 return &static_cast<const QGradientBrushData *>(d.data())->gradient;
837 Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush)
839 if (brush.style() == Qt::RadialGradientPattern) {
840 const QGradient *g = brush.gradient();
841 const QRadialGradient *rg = static_cast<const QRadialGradient *>(g);
843 if (!qFuzzyIsNull(rg->focalRadius()))
846 QPointF delta = rg->focalPoint() - rg->center();
847 if (delta.x() * delta.x() + delta.y() * delta.y() > rg->radius() * rg->radius())
855 Returns true if the brush is fully opaque otherwise false. A brush
856 is considered opaque if:
859 \i The alpha component of the color() is 255.
860 \i Its texture() does not have an alpha channel and is not a QBitmap.
861 \i The colors in the gradient() all have an alpha component that is 255.
862 \i It is an extended radial gradient.
866 bool QBrush::isOpaque() const
868 bool opaqueColor = d->color.alpha() == 255;
870 // Test awfully simple case first
871 if (d->style == Qt::SolidPattern)
874 if (qt_isExtendedRadialGradient(*this))
877 if (d->style == Qt::LinearGradientPattern
878 || d->style == Qt::RadialGradientPattern
879 || d->style == Qt::ConicalGradientPattern) {
880 QGradientStops stops = gradient()->stops();
881 for (int i=0; i<stops.size(); ++i)
882 if (stops.at(i).second.alpha() != 255)
885 } else if (d->style == Qt::TexturePattern) {
886 return qHasPixmapTexture(*this)
887 ? !texture().hasAlphaChannel() && !texture().isQBitmap()
888 : !textureImage().hasAlphaChannel();
898 Sets \a matrix as an explicit transformation matrix on the
899 current brush. The brush transformation matrix is merged with
900 QPainter transformation matrix to produce the final result.
904 void QBrush::setMatrix(const QMatrix &matrix)
906 setTransform(QTransform(matrix));
912 Sets \a matrix as an explicit transformation matrix on the
913 current brush. The brush transformation matrix is merged with
914 QPainter transformation matrix to produce the final result.
918 void QBrush::setTransform(const QTransform &matrix)
921 d->transform = matrix;
926 \fn void QBrush::matrix() const
929 Returns the current transformation matrix for the brush.
935 \fn bool QBrush::operator!=(const QBrush &brush) const
937 Returns true if the brush is different from the given \a brush;
938 otherwise returns false.
940 Two brushes are different if they have different styles, colors or
941 transforms or different pixmaps or gradients depending on the style.
947 \fn bool QBrush::operator==(const QBrush &brush) const
949 Returns true if the brush is equal to the given \a brush;
950 otherwise returns false.
952 Two brushes are equal if they have equal styles, colors and
953 transforms and equal pixmaps or gradients depending on the style.
958 bool QBrush::operator==(const QBrush &b) const
962 if (b.d->style != d->style || b.d->color != d->color || b.d->transform != d->transform)
965 case Qt::TexturePattern:
967 const QPixmap &us = (static_cast<QTexturedBrushData *>(d.data()))->pixmap();
968 const QPixmap &them = (static_cast<QTexturedBrushData *>(b.d.data()))->pixmap();
969 return ((us.isNull() && them.isNull()) || us.cacheKey() == them.cacheKey());
971 case Qt::LinearGradientPattern:
972 case Qt::RadialGradientPattern:
973 case Qt::ConicalGradientPattern:
975 const QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d.data());
976 const QGradientBrushData *d2 = static_cast<QGradientBrushData *>(b.d.data());
977 return d1->gradient == d2->gradient;
985 \fn QBrush::operator const QColor&() const
987 Returns the brush's color.
992 #ifndef QT_NO_DEBUG_STREAM
996 QDebug operator<<(QDebug dbg, const QBrush &b)
998 #ifndef Q_BROKEN_DEBUG_STREAM
999 static const char *BRUSH_STYLES[] = {
1015 "LinearGradientPattern",
1016 "RadialGradientPattern",
1017 "ConicalGradientPattern",
1019 "TexturePattern" // 24
1022 dbg.nospace() << "QBrush(" << b.color() << ',' << BRUSH_STYLES[b.style()] << ')';
1025 qWarning("This compiler doesn't support streaming QBrush to QDebug");
1032 /*****************************************************************************
1033 QBrush stream functions
1034 *****************************************************************************/
1035 #ifndef QT_NO_DATASTREAM
1037 \fn QDataStream &operator<<(QDataStream &stream, const QBrush &brush)
1040 Writes the given \a brush to the given \a stream and returns a
1041 reference to the \a stream.
1043 \sa {Serializing Qt Data Types}
1046 QDataStream &operator<<(QDataStream &s, const QBrush &b)
1048 quint8 style = (quint8) b.style();
1049 bool gradient_style = false;
1051 if (style == Qt::LinearGradientPattern || style == Qt::RadialGradientPattern
1052 || style == Qt::ConicalGradientPattern)
1053 gradient_style = true;
1055 if (s.version() < QDataStream::Qt_4_0 && gradient_style)
1056 style = Qt::NoBrush;
1058 s << style << b.color();
1059 if (b.style() == Qt::TexturePattern) {
1061 } else if (s.version() >= QDataStream::Qt_4_0 && gradient_style) {
1062 const QGradient *gradient = b.gradient();
1063 int type_as_int = int(gradient->type());
1065 if (s.version() >= QDataStream::Qt_4_3) {
1066 s << int(gradient->spread());
1067 s << int(gradient->coordinateMode());
1070 if (s.version() >= QDataStream::Qt_4_5)
1071 s << int(gradient->interpolationMode());
1073 if (sizeof(qreal) == sizeof(double)) {
1074 s << gradient->stops();
1076 // ensure that we write doubles here instead of streaming the stops
1077 // directly; otherwise, platforms that redefine qreal might generate
1078 // data that cannot be read on other platforms.
1079 QVector<QGradientStop> stops = gradient->stops();
1080 s << quint32(stops.size());
1081 for (int i = 0; i < stops.size(); ++i) {
1082 const QGradientStop &stop = stops.at(i);
1083 s << QPair<double, QColor>(double(stop.first), stop.second);
1087 if (gradient->type() == QGradient::LinearGradient) {
1088 s << static_cast<const QLinearGradient *>(gradient)->start();
1089 s << static_cast<const QLinearGradient *>(gradient)->finalStop();
1090 } else if (gradient->type() == QGradient::RadialGradient) {
1091 s << static_cast<const QRadialGradient *>(gradient)->center();
1092 s << static_cast<const QRadialGradient *>(gradient)->focalPoint();
1093 s << (double) static_cast<const QRadialGradient *>(gradient)->radius();
1094 } else { // type == Conical
1095 s << static_cast<const QConicalGradient *>(gradient)->center();
1096 s << (double) static_cast<const QConicalGradient *>(gradient)->angle();
1099 if (s.version() >= QDataStream::Qt_4_3)
1105 \fn QDataStream &operator>>(QDataStream &stream, QBrush &brush)
1108 Reads the given \a brush from the given \a stream and returns a
1109 reference to the \a stream.
1111 \sa {Serializing Qt Data Types}
1114 QDataStream &operator>>(QDataStream &s, QBrush &b)
1120 if (style == Qt::TexturePattern) {
1123 b = QBrush(color, pm);
1124 } else if (style == Qt::LinearGradientPattern
1125 || style == Qt::RadialGradientPattern
1126 || style == Qt::ConicalGradientPattern) {
1129 QGradient::Type type;
1130 QGradientStops stops;
1131 QGradient::CoordinateMode cmode = QGradient::LogicalMode;
1132 QGradient::Spread spread = QGradient::PadSpread;
1133 QGradient::InterpolationMode imode = QGradient::ColorInterpolation;
1136 type = QGradient::Type(type_as_int);
1137 if (s.version() >= QDataStream::Qt_4_3) {
1139 spread = QGradient::Spread(type_as_int);
1141 cmode = QGradient::CoordinateMode(type_as_int);
1144 if (s.version() >= QDataStream::Qt_4_5) {
1146 imode = QGradient::InterpolationMode(type_as_int);
1149 if (sizeof(qreal) == sizeof(double)) {
1157 for (quint32 i = 0; i < numStops; ++i) {
1159 stops << QPair<qreal, QColor>(n, c);
1163 if (type == QGradient::LinearGradient) {
1167 QLinearGradient lg(p1, p2);
1169 lg.setSpread(spread);
1170 lg.setCoordinateMode(cmode);
1171 lg.setInterpolationMode(imode);
1173 } else if (type == QGradient::RadialGradient) {
1174 QPointF center, focal;
1179 QRadialGradient rg(center, radius, focal);
1181 rg.setSpread(spread);
1182 rg.setCoordinateMode(cmode);
1183 rg.setInterpolationMode(imode);
1185 } else { // type == QGradient::ConicalGradient
1190 QConicalGradient cg(center, angle);
1192 cg.setSpread(spread);
1193 cg.setCoordinateMode(cmode);
1194 cg.setInterpolationMode(imode);
1198 b = QBrush(color, (Qt::BrushStyle)style);
1200 if (s.version() >= QDataStream::Qt_4_3) {
1201 QTransform transform;
1203 b.setTransform(transform);
1207 #endif // QT_NO_DATASTREAM
1209 /*******************************************************************************
1210 * QGradient implementations
1219 \brief The QGradient class is used in combination with QBrush to
1220 specify gradient fills.
1222 Qt currently supports three types of gradient fills:
1225 \o \e Linear gradients interpolate colors between start and end points.
1226 \o \e Simple radial gradients interpolate colors between a focal point
1227 and end points on a circle surrounding it.
1228 \o \e Extended radial gradients interpolate colors between a center and
1230 \o \e Conical gradients interpolate colors around a center point.
1233 A gradient's type can be retrieved using the type() function.
1234 Each of the types is represented by a subclass of QGradient:
1242 \o \inlineimage qgradient-linear.png
1243 \o \inlineimage qgradient-radial.png
1244 \o \inlineimage qgradient-conical.png
1247 The colors in a gradient are defined using stop points of the
1248 QGradientStop type; i.e., a position and a color. Use the setColorAt()
1249 function to define a single stop point. Alternatively, use the
1250 setStops() function to define several stop points in one go. Note that
1251 the latter function \e replaces the current set of stop points.
1253 It is the gradient's complete set of stop points (accessible
1254 through the stops() function) that describes how the gradient area
1255 should be filled. If no stop points have been specified, a gradient
1256 of black at 0 to white at 1 is used.
1258 A diagonal linear gradient from black at (100, 100) to white at
1259 (200, 200) could be specified like this:
1261 \snippet doc/src/snippets/brush/brush.cpp 0
1263 A gradient can have an arbitrary number of stop points. The
1264 following would create a radial gradient starting with
1265 red in the center, blue and then green on the edges:
1267 \snippet doc/src/snippets/brush/brush.cpp 1
1269 It is possible to repeat or reflect the gradient outside its area
1270 by specifiying the \l {QGradient::Spread}{spread method} using the
1271 setSpread() function. The default is to pad the outside area with
1272 the color at the closest stop point. The currently set \l
1273 {QGradient::Spread}{spread method} can be retrieved using the
1274 spread() function. The QGradient::Spread enum defines three
1279 \o \inlineimage qradialgradient-pad.png
1280 \o \inlineimage qradialgradient-repeat.png
1281 \o \inlineimage qradialgradient-reflect.png
1283 \o \l {QGradient::PadSpread}{PadSpread}
1284 \o \l {QGradient::RepeatSpread}{RepeatSpread}
1285 \o \l {QGradient::ReflectSpread}{ReflectSpread}
1288 Note that the setSpread() function only has effect for linear and
1289 radial gradients. The reason is that the conical gradient is
1290 closed by definition, i.e. the \e conical gradient fills the
1291 entire circle from 0 - 360 degrees, while the boundary of a radial
1292 or a linear gradient can be specified through its radius or final
1293 stop points, respectively.
1295 The gradient coordinates can be specified in logical coordinates,
1296 relative to device coordinates, or relative to object bounding box coordinates.
1297 The \l {QGradient::CoordinateMode}{coordinate mode} can be set using the
1298 setCoordinateMode() function. The default is LogicalMode, where the
1299 gradient coordinates are specified in the same way as the object
1300 coordinates. To retrieve the currently set \l {QGradient::CoordinateMode}
1301 {coordinate mode} use coordinateMode().
1304 \sa {painting/gradients}{The Gradients Example}, QBrush
1310 QGradient::QGradient()
1311 : m_type(NoGradient), dummy(0)
1317 \enum QGradient::Type
1319 Specifies the type of gradient.
1321 \value LinearGradient Interpolates colors between start and end points
1324 \value RadialGradient Interpolate colors between a focal point and end
1325 points on a circle surrounding it (QRadialGradient).
1327 \value ConicalGradient Interpolate colors around a center point (QConicalGradient).
1328 \value NoGradient No gradient is used.
1334 \enum QGradient::Spread
1336 Specifies how the area outside the gradient area should be
1339 \value PadSpread The area is filled with the closest stop
1340 color. This is the default.
1342 \value RepeatSpread The gradient is repeated outside the gradient
1345 \value ReflectSpread The gradient is reflected outside the
1348 \sa spread(), setSpread()
1352 \fn void QGradient::setSpread(Spread method)
1354 Specifies the spread \a method that should be used for this
1357 Note that this function only has effect for linear and radial
1364 \fn QGradient::Spread QGradient::spread() const
1366 Returns the spread method use by this gradient. The default is
1373 \fn QGradient::Type QGradient::type() const
1375 Returns the type of gradient.
1379 \fn void QGradient::setColorAt(qreal position, const QColor &color)
1381 Creates a stop point at the given \a position with the given \a
1382 color. The given \a position must be in the range 0 to 1.
1384 \sa setStops(), stops()
1387 void QGradient::setColorAt(qreal pos, const QColor &color)
1389 if ((pos > 1 || pos < 0) && !qIsNaN(pos)) {
1390 qWarning("QGradient::setColorAt: Color position must be specified in the range 0 to 1");
1396 while (index < m_stops.size() && m_stops.at(index).first < pos) ++index;
1398 if (index < m_stops.size() && m_stops.at(index).first == pos)
1399 m_stops[index].second = color;
1401 m_stops.insert(index, QGradientStop(pos, color));
1405 \fn void QGradient::setStops(const QGradientStops &stopPoints)
1407 Replaces the current set of stop points with the given \a
1408 stopPoints. The positions of the points must be in the range 0 to
1409 1, and must be sorted with the lowest point first.
1411 \sa setColorAt(), stops()
1413 void QGradient::setStops(const QGradientStops &stops)
1416 for (int i=0; i<stops.size(); ++i)
1417 setColorAt(stops.at(i).first, stops.at(i).second);
1422 Returns the stop points for this gradient.
1424 If no stop points have been specified, a gradient of black at 0 to white
1427 \sa setStops(), setColorAt()
1429 QGradientStops QGradient::stops() const
1431 if (m_stops.isEmpty()) {
1433 tmp << QGradientStop(0, Qt::black) << QGradientStop(1, Qt::white);
1439 #define Q_DUMMY_ACCESSOR union {void *p; uint i;}; p = dummy;
1442 \enum QGradient::CoordinateMode
1445 This enum specifies how gradient coordinates map to the paint
1446 device on which the gradient is used.
1448 \value LogicalMode This is the default mode. The gradient coordinates
1449 are specified logical space just like the object coordinates.
1450 \value StretchToDeviceMode In this mode the gradient coordinates
1451 are relative to the bounding rectangle of the paint device,
1452 with (0,0) in the top left corner, and (1,1) in the bottom right
1453 corner of the paint device.
1454 \value ObjectBoundingMode In this mode the gradient coordinates are
1455 relative to the bounding rectangle of the object being drawn, with
1456 (0,0) in the top left corner, and (1,1) in the bottom right corner
1457 of the object's bounding rectangle.
1463 Returns the coordinate mode of this gradient. The default mode is
1466 QGradient::CoordinateMode QGradient::coordinateMode() const
1469 return CoordinateMode(i & 0x03);
1475 Sets the coordinate mode of this gradient to \a mode. The default
1476 mode is LogicalMode.
1478 void QGradient::setCoordinateMode(CoordinateMode mode)
1487 \enum QGradient::InterpolationMode
1491 \value ComponentInterpolation The color components and the alpha component are
1492 independently linearly interpolated.
1493 \value ColorInterpolation The colors are linearly interpolated in
1494 premultiplied color space.
1501 Returns the interpolation mode of this gradient. The default mode is
1504 QGradient::InterpolationMode QGradient::interpolationMode() const
1507 return InterpolationMode((i >> 2) & 0x01);
1514 Sets the interpolation mode of this gradient to \a mode. The default
1515 mode is ColorInterpolation.
1517 void QGradient::setInterpolationMode(InterpolationMode mode)
1521 i |= (uint(mode) << 2);
1526 \fn bool QGradient::operator!=(const QGradient &gradient) const
1529 Returns true if the gradient is the same as the other \a gradient
1530 specified; otherwise returns false.
1536 Returns true if the gradient is the same as the other \a gradient
1537 specified; otherwise returns false.
1541 bool QGradient::operator==(const QGradient &gradient) const
1543 if (gradient.m_type != m_type
1544 || gradient.m_spread != m_spread
1545 || gradient.dummy != dummy) return false;
1547 if (m_type == LinearGradient) {
1548 if (m_data.linear.x1 != gradient.m_data.linear.x1
1549 || m_data.linear.y1 != gradient.m_data.linear.y1
1550 || m_data.linear.x2 != gradient.m_data.linear.x2
1551 || m_data.linear.y2 != gradient.m_data.linear.y2)
1553 } else if (m_type == RadialGradient) {
1554 if (m_data.radial.cx != gradient.m_data.radial.cx
1555 || m_data.radial.cy != gradient.m_data.radial.cy
1556 || m_data.radial.fx != gradient.m_data.radial.fx
1557 || m_data.radial.fy != gradient.m_data.radial.fy
1558 || m_data.radial.cradius != gradient.m_data.radial.cradius)
1560 } else { // m_type == ConicalGradient
1561 if (m_data.conical.cx != gradient.m_data.conical.cx
1562 || m_data.conical.cy != gradient.m_data.conical.cy
1563 || m_data.conical.angle != gradient.m_data.conical.angle)
1567 return stops() == gradient.stops();
1571 \class QLinearGradient
1574 \brief The QLinearGradient class is used in combination with QBrush to
1575 specify a linear gradient brush.
1577 Linear gradients interpolate colors between start and end
1578 points. Outside these points the gradient is either padded,
1579 reflected or repeated depending on the currently set \l
1580 {QGradient::Spread}{spread} method:
1584 \o \inlineimage qlineargradient-pad.png
1585 \o \inlineimage qlineargradient-reflect.png
1586 \o \inlineimage qlineargradient-repeat.png
1588 \o \l {QGradient::PadSpread}{PadSpread} (default)
1589 \o \l {QGradient::ReflectSpread}{ReflectSpread}
1590 \o \l {QGradient::RepeatSpread}{RepeatSpread}
1593 The colors in a gradient is defined using stop points of the
1594 QGradientStop type, i.e. a position and a color. Use the
1595 QGradient::setColorAt() or the QGradient::setStops() function to
1596 define the stop points. It is the gradient's complete set of stop
1597 points that describes how the gradient area should be filled. If
1598 no stop points have been specified, a gradient of black at 0 to
1601 In addition to the functions inherited from QGradient, the
1602 QLinearGradient class provides the finalStop() function which
1603 returns the final stop point of the gradient, and the start()
1604 function returning the start point of the gradient.
1606 \sa QRadialGradient, QConicalGradient, {painting/gradients}{The
1612 Constructs a default linear gradient with interpolation area
1613 between (0, 0) and (1, 1).
1615 \sa QGradient::setColorAt(), setStart(), setFinalStop()
1618 QLinearGradient::QLinearGradient()
1620 m_type = LinearGradient;
1621 m_spread = PadSpread;
1622 m_data.linear.x1 = 0;
1623 m_data.linear.y1 = 0;
1624 m_data.linear.x2 = 1;
1625 m_data.linear.y2 = 1;
1630 Constructs a linear gradient with interpolation area between the
1631 given \a start point and \a finalStop.
1633 \note The expected parameter values are in pixels.
1635 \sa QGradient::setColorAt(), QGradient::setStops()
1637 QLinearGradient::QLinearGradient(const QPointF &start, const QPointF &finalStop)
1639 m_type = LinearGradient;
1640 m_spread = PadSpread;
1641 m_data.linear.x1 = start.x();
1642 m_data.linear.y1 = start.y();
1643 m_data.linear.x2 = finalStop.x();
1644 m_data.linear.y2 = finalStop.y();
1648 \fn QLinearGradient::QLinearGradient(qreal x1, qreal y1, qreal x2, qreal y2)
1650 Constructs a linear gradient with interpolation area between (\a
1651 x1, \a y1) and (\a x2, \a y2).
1653 \note The expected parameter values are in pixels.
1655 \sa QGradient::setColorAt(), QGradient::setStops()
1657 QLinearGradient::QLinearGradient(qreal xStart, qreal yStart, qreal xFinalStop, qreal yFinalStop)
1659 m_type = LinearGradient;
1660 m_spread = PadSpread;
1661 m_data.linear.x1 = xStart;
1662 m_data.linear.y1 = yStart;
1663 m_data.linear.x2 = xFinalStop;
1664 m_data.linear.y2 = yFinalStop;
1669 Returns the start point of this linear gradient in logical coordinates.
1671 \sa QGradient::stops()
1674 QPointF QLinearGradient::start() const
1676 Q_ASSERT(m_type == LinearGradient);
1677 return QPointF(m_data.linear.x1, m_data.linear.y1);
1681 \fn void QLinearGradient::setStart(qreal x, qreal y)
1685 Sets the start point of this linear gradient in logical
1686 coordinates to \a x, \a y.
1694 Sets the start point of this linear gradient in logical
1695 coordinates to \a start.
1700 void QLinearGradient::setStart(const QPointF &start)
1702 Q_ASSERT(m_type == LinearGradient);
1703 m_data.linear.x1 = start.x();
1704 m_data.linear.y1 = start.y();
1709 \fn void QLinearGradient::setFinalStop(qreal x, qreal y)
1713 Sets the final stop point of this linear gradient in logical
1714 coordinates to \a x, \a y.
1720 Returns the final stop point of this linear gradient in logical coordinates.
1722 \sa QGradient::stops()
1725 QPointF QLinearGradient::finalStop() const
1727 Q_ASSERT(m_type == LinearGradient);
1728 return QPointF(m_data.linear.x2, m_data.linear.y2);
1735 Sets the final stop point of this linear gradient in logical
1736 coordinates to \a stop.
1741 void QLinearGradient::setFinalStop(const QPointF &stop)
1743 Q_ASSERT(m_type == LinearGradient);
1744 m_data.linear.x2 = stop.x();
1745 m_data.linear.y2 = stop.y();
1750 \class QRadialGradient
1753 \brief The QRadialGradient class is used in combination with QBrush to
1754 specify a radial gradient brush.
1756 Qt supports both simple and extended radial gradients.
1758 Simple radial gradients interpolate colors between a focal point and end
1759 points on a circle surrounding it. Extended radial gradients interpolate
1760 colors between a focal circle and a center circle. Points outside the cone
1761 defined by the two circles will be transparent. For simple radial gradients
1762 the focal point is adjusted to lie inside the center circle, whereas the
1763 focal point can have any position in an extended radial gradient.
1765 Outside the end points the gradient is either padded, reflected or repeated
1766 depending on the currently set \l {QGradient::Spread}{spread} method:
1770 \o \inlineimage qradialgradient-pad.png
1771 \o \inlineimage qradialgradient-reflect.png
1772 \o \inlineimage qradialgradient-repeat.png
1774 \o \l {QGradient::PadSpread}{PadSpread} (default)
1775 \o \l {QGradient::ReflectSpread}{ReflectSpread}
1776 \o \l {QGradient::RepeatSpread}{RepeatSpread}
1779 The colors in a gradient is defined using stop points of the
1780 QGradientStop type, i.e. a position and a color. Use the
1781 QGradient::setColorAt() or the QGradient::setStops() function to
1782 define the stop points. It is the gradient's complete set of stop
1783 points that describes how the gradient area should be filled. If
1784 no stop points have been specified, a gradient of black at 0 to
1787 In addition to the functions inherited from QGradient, the
1788 QRadialGradient class provides the center(), focalPoint() and
1789 radius() functions returning the gradient's center, focal point
1790 and radius respectively.
1792 \sa QLinearGradient, QConicalGradient, {painting/gradients}{The
1796 static QPointF qt_radial_gradient_adapt_focal_point(const QPointF ¢er,
1798 const QPointF &focalPoint)
1800 // We have a one pixel buffer zone to avoid numerical instability on the
1802 //### this is hacky because technically we should adjust based on current matrix
1803 const qreal compensated_radius = radius - radius * qreal(0.001);
1804 QLineF line(center, focalPoint);
1805 if (line.length() > (compensated_radius))
1806 line.setLength(compensated_radius);
1811 Constructs a simple radial gradient with the given \a center, \a
1812 radius and \a focalPoint.
1814 \note If the given focal point is outside the circle defined by the
1815 \a center point and \a radius, it will be re-adjusted to lie at a point on
1816 the circle where it intersects with the line from \a center to
1819 \sa QGradient::setColorAt(), QGradient::setStops()
1822 QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius, const QPointF &focalPoint)
1824 m_type = RadialGradient;
1825 m_spread = PadSpread;
1826 m_data.radial.cx = center.x();
1827 m_data.radial.cy = center.y();
1828 m_data.radial.cradius = radius;
1830 QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(center, radius, focalPoint);
1831 m_data.radial.fx = adapted_focal.x();
1832 m_data.radial.fy = adapted_focal.y();
1836 Constructs a simple radial gradient with the given \a center, \a
1837 radius and the focal point in the circle center.
1839 \sa QGradient::setColorAt(), QGradient::setStops()
1841 QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius)
1843 m_type = RadialGradient;
1844 m_spread = PadSpread;
1845 m_data.radial.cx = center.x();
1846 m_data.radial.cy = center.y();
1847 m_data.radial.cradius = radius;
1848 m_data.radial.fx = center.x();
1849 m_data.radial.fy = center.y();
1854 Constructs a simple radial gradient with the given center (\a cx, \a cy),
1855 \a radius and focal point (\a fx, \a fy).
1857 \note If the given focal point is outside the circle defined by the
1858 center (\a cx, \a cy) and the \a radius it will be re-adjusted to
1859 the intersection between the line from the center to the focal point
1862 \sa QGradient::setColorAt(), QGradient::setStops()
1865 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius, qreal fx, qreal fy)
1867 m_type = RadialGradient;
1868 m_spread = PadSpread;
1869 m_data.radial.cx = cx;
1870 m_data.radial.cy = cy;
1871 m_data.radial.cradius = radius;
1873 QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(QPointF(cx, cy),
1877 m_data.radial.fx = adapted_focal.x();
1878 m_data.radial.fy = adapted_focal.y();
1882 Constructs a simple radial gradient with the center at (\a cx, \a cy) and the
1883 specified \a radius. The focal point lies at the center of the circle.
1885 \sa QGradient::setColorAt(), QGradient::setStops()
1887 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius)
1889 m_type = RadialGradient;
1890 m_spread = PadSpread;
1891 m_data.radial.cx = cx;
1892 m_data.radial.cy = cy;
1893 m_data.radial.cradius = radius;
1894 m_data.radial.fx = cx;
1895 m_data.radial.fy = cy;
1900 Constructs a simple radial gradient with the center and focal point at
1901 (0, 0) with a radius of 1.
1903 QRadialGradient::QRadialGradient()
1905 m_type = RadialGradient;
1906 m_spread = PadSpread;
1907 m_data.radial.cx = 0;
1908 m_data.radial.cy = 0;
1909 m_data.radial.cradius = 1;
1910 m_data.radial.fx = 0;
1911 m_data.radial.fy = 0;
1917 Constructs an extended radial gradient with the given \a center, \a
1918 centerRadius, \a focalPoint, and \a focalRadius.
1920 QRadialGradient::QRadialGradient(const QPointF ¢er, qreal centerRadius, const QPointF &focalPoint, qreal focalRadius)
1922 m_type = RadialGradient;
1923 m_spread = PadSpread;
1924 m_data.radial.cx = center.x();
1925 m_data.radial.cy = center.y();
1926 m_data.radial.cradius = centerRadius;
1928 m_data.radial.fx = focalPoint.x();
1929 m_data.radial.fy = focalPoint.y();
1930 setFocalRadius(focalRadius);
1936 Constructs an extended radial gradient with the given center
1937 (\a cx, \a cy), center radius, \a centerRadius, focal point, (\a fx, \a fy),
1938 and focal radius \a focalRadius.
1940 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius)
1942 m_type = RadialGradient;
1943 m_spread = PadSpread;
1944 m_data.radial.cx = cx;
1945 m_data.radial.cy = cy;
1946 m_data.radial.cradius = centerRadius;
1948 m_data.radial.fx = fx;
1949 m_data.radial.fy = fy;
1950 setFocalRadius(focalRadius);
1954 Returns the center of this radial gradient in logical coordinates.
1956 \sa QGradient::stops()
1959 QPointF QRadialGradient::center() const
1961 Q_ASSERT(m_type == RadialGradient);
1962 return QPointF(m_data.radial.cx, m_data.radial.cy);
1966 \fn void QRadialGradient::setCenter(qreal x, qreal y)
1970 Sets the center of this radial gradient in logical coordinates
1979 Sets the center of this radial gradient in logical coordinates
1985 void QRadialGradient::setCenter(const QPointF ¢er)
1987 Q_ASSERT(m_type == RadialGradient);
1988 m_data.radial.cx = center.x();
1989 m_data.radial.cy = center.y();
1994 Returns the radius of this radial gradient in logical coordinates.
1996 Equivalent to centerRadius()
1998 \sa QGradient::stops()
2001 qreal QRadialGradient::radius() const
2003 Q_ASSERT(m_type == RadialGradient);
2004 return m_data.radial.cradius;
2011 Sets the radius of this radial gradient in logical coordinates
2014 Equivalent to setCenterRadius()
2016 void QRadialGradient::setRadius(qreal radius)
2018 Q_ASSERT(m_type == RadialGradient);
2019 m_data.radial.cradius = radius;
2025 Returns the center radius of this radial gradient in logical
2028 \sa QGradient::stops()
2030 qreal QRadialGradient::centerRadius() const
2032 Q_ASSERT(m_type == RadialGradient);
2033 return m_data.radial.cradius;
2039 Sets the center radius of this radial gradient in logical coordinates
2042 void QRadialGradient::setCenterRadius(qreal radius)
2044 Q_ASSERT(m_type == RadialGradient);
2045 m_data.radial.cradius = radius;
2051 Returns the focal radius of this radial gradient in logical
2054 \sa QGradient::stops()
2056 qreal QRadialGradient::focalRadius() const
2058 Q_ASSERT(m_type == RadialGradient);
2061 // mask away low three bits
2062 union { float f; quint32 i; } u;
2070 Sets the focal radius of this radial gradient in logical coordinates
2073 void QRadialGradient::setFocalRadius(qreal radius)
2075 Q_ASSERT(m_type == RadialGradient);
2078 // Since there's no QGradientData, we only have the dummy void * to
2079 // store additional data in. The three lowest bits are already
2080 // taken, thus we cut the three lowest bits from the significand
2081 // and store the radius as a float.
2082 union { float f; quint32 i; } u;
2083 u.f = float(radius);
2084 // add 0x04 to round up when we drop the three lowest bits
2085 i |= (u.i + 0x04) & ~0x07;
2090 Returns the focal point of this radial gradient in logical
2093 \sa QGradient::stops()
2096 QPointF QRadialGradient::focalPoint() const
2098 Q_ASSERT(m_type == RadialGradient);
2099 return QPointF(m_data.radial.fx, m_data.radial.fy);
2103 \fn void QRadialGradient::setFocalPoint(qreal x, qreal y)
2107 Sets the focal point of this radial gradient in logical
2108 coordinates to (\a x, \a y).
2116 Sets the focal point of this radial gradient in logical
2117 coordinates to \a focalPoint.
2122 void QRadialGradient::setFocalPoint(const QPointF &focalPoint)
2124 Q_ASSERT(m_type == RadialGradient);
2125 m_data.radial.fx = focalPoint.x();
2126 m_data.radial.fy = focalPoint.y();
2132 \class QConicalGradient
2135 \brief The QConicalGradient class is used in combination with QBrush to
2136 specify a conical gradient brush.
2138 Conical gradients interpolate interpolate colors counter-clockwise
2139 around a center point.
2141 \image qconicalgradient.png
2143 The colors in a gradient is defined using stop points of the
2144 QGradientStop type, i.e. a position and a color. Use the
2145 QGradient::setColorAt() or the QGradient::setStops() function to
2146 define the stop points. It is the gradient's complete set of stop
2147 points that describes how the gradient area should be filled. If
2148 no stop points have been specified, a gradient of black at 0 to
2151 In addition to the functions inherited from QGradient, the
2152 QConicalGradient class provides the angle() and center() functions
2153 returning the start angle and center of the gradient.
2155 Note that the setSpread() function has no effect for conical
2156 gradients. The reason is that the conical gradient is closed by
2157 definition, i.e. the conical gradient fills the entire circle from
2158 0 - 360 degrees, while the boundary of a radial or a linear
2159 gradient can be specified through its radius or final stop points,
2162 \sa QLinearGradient, QRadialGradient, {painting/gradients}{The
2168 Constructs a conical gradient with the given \a center, starting
2169 the interpolation at the given \a angle. The \a angle must be
2170 specified in degrees between 0 and 360.
2172 \sa QGradient::setColorAt(), QGradient::setStops()
2175 QConicalGradient::QConicalGradient(const QPointF ¢er, qreal angle)
2177 m_type = ConicalGradient;
2178 m_spread = PadSpread;
2179 m_data.conical.cx = center.x();
2180 m_data.conical.cy = center.y();
2181 m_data.conical.angle = angle;
2186 Constructs a conical gradient with the given center (\a cx, \a
2187 cy), starting the interpolation at the given \a angle. The angle
2188 must be specified in degrees between 0 and 360.
2190 \sa QGradient::setColorAt(), QGradient::setStops()
2193 QConicalGradient::QConicalGradient(qreal cx, qreal cy, qreal angle)
2195 m_type = ConicalGradient;
2196 m_spread = PadSpread;
2197 m_data.conical.cx = cx;
2198 m_data.conical.cy = cy;
2199 m_data.conical.angle = angle;
2204 Constructs a conical with center at (0, 0) starting the
2205 interpolation at angle 0.
2207 \sa QGradient::setColorAt(), setCenter(), setAngle()
2210 QConicalGradient::QConicalGradient()
2212 m_type = ConicalGradient;
2213 m_spread = PadSpread;
2214 m_data.conical.cx = 0;
2215 m_data.conical.cy = 0;
2216 m_data.conical.angle = 0;
2221 Returns the center of the conical gradient in logical
2227 QPointF QConicalGradient::center() const
2229 Q_ASSERT(m_type == ConicalGradient);
2230 return QPointF(m_data.conical.cx, m_data.conical.cy);
2235 \fn void QConicalGradient::setCenter(qreal x, qreal y)
2239 Sets the center of this conical gradient in logical coordinates to
2246 Sets the center of this conical gradient in logical coordinates to
2252 void QConicalGradient::setCenter(const QPointF ¢er)
2254 Q_ASSERT(m_type == ConicalGradient);
2255 m_data.conical.cx = center.x();
2256 m_data.conical.cy = center.y();
2260 Returns the start angle of the conical gradient in logical
2266 qreal QConicalGradient::angle() const
2268 Q_ASSERT(m_type == ConicalGradient);
2269 return m_data.conical.angle;
2276 Sets \a angle to be the start angle for this conical gradient in
2277 logical coordinates.
2282 void QConicalGradient::setAngle(qreal angle)
2284 Q_ASSERT(m_type == ConicalGradient);
2285 m_data.conical.angle = angle;
2289 \typedef QGradientStop
2292 Typedef for QPair<\l qreal, QColor>.
2296 \typedef QGradientStops
2299 Typedef for QVector<QGradientStop>.
2303 \typedef QBrush::DataPtr
2308 \fn DataPtr &QBrush::data_ptr()
2314 \fn bool QBrush::isDetached() const
2319 \fn QTransform QBrush::transform() const
2322 Returns the current transformation matrix for the brush.
2327 #undef Q_DUMMY_ACCESSOR