Replace 'i < len-1 && func(i+1)' by 'i+1 < len && func(i+1)'
[profile/ivi/qtbase.git] / src / gui / painting / qbrush.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qbrush.h"
43 #include "qpixmap.h"
44 #include "qbitmap.h"
45 #include "qpixmapcache.h"
46 #include "qdatastream.h"
47 #include "qvariant.h"
48 #include "qline.h"
49 #include "qdebug.h"
50 #include <QtCore/qcoreapplication.h>
51 #include "private/qstylehelper_p.h"
52 #include <QtCore/qnumeric.h>
53
54 QT_BEGIN_NAMESPACE
55
56 const uchar *qt_patternForBrush(int brushStyle, bool invert)
57 {
58     Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
59     if(invert) {
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];
78     }
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];
97 }
98
99 QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
100 {
101
102     QPixmap pm;
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);
110     }
111
112     return pm;
113 }
114
115 static void qt_cleanup_brush_pattern_image_cache();
116 class QBrushPatternImageCache
117 {
118 public:
119     QBrushPatternImageCache()
120         : m_initialized(false)
121     {
122         init();
123     }
124
125     void init()
126     {
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);
132         }
133         m_initialized = true;
134     }
135
136     QImage getImage(int brushStyle, bool invert) const
137     {
138         Q_ASSERT(brushStyle >= Qt::Dense1Pattern && brushStyle <= Qt::DiagCrossPattern);
139         if (!m_initialized)
140             const_cast<QBrushPatternImageCache*>(this)->init();
141         return m_images[brushStyle - Qt::Dense1Pattern][invert];
142     }
143
144     void cleanup() {
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();
149         }
150         m_initialized = false;
151     }
152
153 private:
154     QImage m_images[Qt::DiagCrossPattern - Qt::Dense1Pattern + 1][2];
155     bool m_initialized;
156 };
157
158 Q_GLOBAL_STATIC(QBrushPatternImageCache, qt_brushPatternImageCache)
159
160 static void qt_cleanup_brush_pattern_image_cache()
161 {
162     qt_brushPatternImageCache()->cleanup();
163 }
164
165 Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert)
166 {
167     return qt_brushPatternImageCache()->getImage(brushStyle, invert);
168 }
169
170 struct QTexturedBrushData : public QBrushData
171 {
172     QTexturedBrushData() {
173         m_has_pixmap_texture = false;
174         m_pixmap = 0;
175     }
176     ~QTexturedBrushData() {
177         delete m_pixmap;
178     }
179
180     void setPixmap(const QPixmap &pm) {
181         delete m_pixmap;
182
183         if (pm.isNull()) {
184             m_pixmap = 0;
185             m_has_pixmap_texture = false;
186         } else {
187             m_pixmap = new QPixmap(pm);
188             m_has_pixmap_texture = true;
189         }
190
191         m_image = QImage();
192     }
193
194     void setImage(const QImage &image) {
195         m_image = image;
196         delete m_pixmap;
197         m_pixmap = 0;
198         m_has_pixmap_texture = false;
199     }
200
201     QPixmap &pixmap() {
202         if (!m_pixmap) {
203             m_pixmap = new QPixmap(QPixmap::fromImage(m_image));
204         }
205         return *m_pixmap;
206     }
207
208     QImage &image() {
209         if (m_image.isNull() && m_pixmap)
210             m_image = m_pixmap->toImage();
211         return m_image;
212     }
213
214     QPixmap *m_pixmap;
215     QImage m_image;
216     bool m_has_pixmap_texture;
217 };
218
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)
222 {
223     if (brush.style() != Qt::TexturePattern)
224         return false;
225     QTexturedBrushData *tx_data = static_cast<QTexturedBrushData *>(brush.d.data());
226     return tx_data->m_has_pixmap_texture;
227 }
228
229 struct QGradientBrushData : public QBrushData
230 {
231     QGradient gradient;
232 };
233
234 struct QBrushDataPointerDeleter
235 {
236     static inline void deleteData(QBrushData *d)
237     {
238         switch (d->style) {
239         case Qt::TexturePattern:
240             delete static_cast<QTexturedBrushData*>(d);
241             break;
242         case Qt::LinearGradientPattern:
243         case Qt::RadialGradientPattern:
244         case Qt::ConicalGradientPattern:
245             delete static_cast<QGradientBrushData*>(d);
246             break;
247         default:
248             delete d;
249         }
250     }
251
252     static inline void cleanup(QBrushData *d)
253     {
254         if (d && !d->ref.deref()) {
255             deleteData(d);
256         }
257     }
258 };
259
260 /*!
261     \class QBrush
262     \ingroup painting
263     \ingroup shared
264
265     \brief The QBrush class defines the fill pattern of shapes drawn
266     by QPainter.
267
268     A brush has a style, a color, a gradient and a texture.
269
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
277     constructed.
278
279     \image brush-styles.png Brush Styles
280
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,
285     respectively.
286
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.
294
295     \snippet doc/src/snippets/brush/gradientcreationsnippet.cpp 0
296
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
300     setTexture().
301
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.
307
308     The isOpaque() function returns true if the brush is fully opaque
309     otherwise false. A brush is considered opaque if:
310
311     \list
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.
315     \endlist
316
317     \table 100%
318     \row
319     \o \inlineimage brush-outline.png Outlines
320     \o
321
322     To specify the style and color of lines and outlines, use the
323     QPainter's \l {QPen}{pen} combined with Qt::PenStyle and
324     Qt::GlobalColor:
325
326     \snippet doc/src/snippets/code/src_gui_painting_qbrush.cpp 0
327
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.
331
332     \endtable
333
334     For more information about painting in general, see the \l{Paint
335     System}.
336
337     \sa Qt::BrushStyle, QPainter, QColor
338 */
339
340 class QNullBrushData
341 {
342 public:
343     QBrushData *brush;
344     QNullBrushData() : brush(new QBrushData)
345     {
346         brush->ref = 1;
347         brush->style = Qt::BrushStyle(0);
348         brush->color = Qt::black;
349     }
350     ~QNullBrushData()
351     {
352         if (!brush->ref.deref())
353             delete brush;
354         brush = 0;
355     }
356 };
357
358 Q_GLOBAL_STATIC(QNullBrushData, nullBrushInstance_holder)
359 static QBrushData *nullBrushInstance()
360 {
361     return nullBrushInstance_holder()->brush;
362 }
363
364 static bool qbrush_check_type(Qt::BrushStyle style) {
365     switch (style) {
366     case Qt::TexturePattern:
367          qWarning("QBrush: Incorrect use of TexturePattern");
368          break;
369     case Qt::LinearGradientPattern:
370     case Qt::RadialGradientPattern:
371     case Qt::ConicalGradientPattern:
372         qWarning("QBrush: Wrong use of a gradient pattern");
373         break;
374     default:
375         return true;
376     }
377     return false;
378 }
379
380 /*!
381   \internal
382   Initializes the brush.
383 */
384
385 void QBrush::init(const QColor &color, Qt::BrushStyle style)
386 {
387     switch(style) {
388     case Qt::NoBrush:
389         d.reset(nullBrushInstance());
390         d->ref.ref();
391         if (d->color != color) setColor(color);
392         return;
393     case Qt::TexturePattern:
394         d.reset(new QTexturedBrushData);
395         break;
396     case Qt::LinearGradientPattern:
397     case Qt::RadialGradientPattern:
398     case Qt::ConicalGradientPattern:
399         d.reset(new QGradientBrushData);
400         break;
401     default:
402         d.reset(new QBrushData);
403         break;
404     }
405     d->ref = 1;
406     d->style = style;
407     d->color = color;
408 }
409
410 /*!
411     Constructs a default black brush with the style Qt::NoBrush
412     (i.e. this brush will not fill shapes).
413 */
414
415 QBrush::QBrush()
416     : d(nullBrushInstance())
417 {
418     Q_ASSERT(d);
419     d->ref.ref();
420 }
421
422 /*!
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.
425
426     \sa setTexture()
427 */
428
429 QBrush::QBrush(const QPixmap &pixmap)
430 {
431     init(Qt::black, Qt::TexturePattern);
432     setTexture(pixmap);
433 }
434
435
436 /*!
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.
439
440     \sa setTextureImage()
441 */
442
443 QBrush::QBrush(const QImage &image)
444 {
445     init(Qt::black, Qt::TexturePattern);
446     setTextureImage(image);
447 }
448
449 /*!
450     Constructs a black brush with the given \a style.
451
452     \sa setStyle()
453 */
454
455 QBrush::QBrush(Qt::BrushStyle style)
456 {
457     if (qbrush_check_type(style))
458         init(Qt::black, style);
459     else {
460         d.reset(nullBrushInstance());
461         d->ref.ref();
462     }
463 }
464
465 /*!
466     Constructs a brush with the given \a color and \a style.
467
468     \sa setColor(), setStyle()
469 */
470
471 QBrush::QBrush(const QColor &color, Qt::BrushStyle style)
472 {
473     if (qbrush_check_type(style))
474         init(color, style);
475     else {
476         d.reset(nullBrushInstance());
477         d->ref.ref();
478     }
479 }
480
481 /*!
482     \fn QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style)
483
484     Constructs a brush with the given \a color and \a style.
485
486     \sa setColor(), setStyle()
487 */
488 QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style)
489 {
490     if (qbrush_check_type(style))
491         init(color, style);
492     else {
493         d.reset(nullBrushInstance());
494         d->ref.ref();
495     }
496 }
497
498 /*!
499     Constructs a brush with the given \a color and the custom pattern
500     stored in \a pixmap.
501
502     The style is set to Qt::TexturePattern. The color will only have
503     an effect for QBitmaps.
504
505     \sa setColor(), setPixmap()
506 */
507
508 QBrush::QBrush(const QColor &color, const QPixmap &pixmap)
509 {
510     init(color, Qt::TexturePattern);
511     setTexture(pixmap);
512 }
513
514 /*!
515
516     Constructs a brush with the given \a color and the custom pattern
517     stored in \a pixmap.
518
519     The style is set to Qt::TexturePattern. The color will only have
520     an effect for QBitmaps.
521
522     \sa setColor(), setPixmap()
523 */
524 QBrush::QBrush(Qt::GlobalColor color, const QPixmap &pixmap)
525 {
526     init(color, Qt::TexturePattern);
527     setTexture(pixmap);
528 }
529
530 /*!
531     Constructs a copy of \a other.
532 */
533
534 QBrush::QBrush(const QBrush &other)
535     : d(other.d.data())
536 {
537     d->ref.ref();
538 }
539
540 /*!
541     Constructs a brush based on the given \a gradient.
542
543     The brush style is set to the corresponding gradient style (either
544     Qt::LinearGradientPattern, Qt::RadialGradientPattern or
545     Qt::ConicalGradientPattern).
546 */
547 QBrush::QBrush(const QGradient &gradient)
548 {
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");
552
553     const Qt::BrushStyle enum_table[] = {
554         Qt::LinearGradientPattern,
555         Qt::RadialGradientPattern,
556         Qt::ConicalGradientPattern
557     };
558
559     init(QColor(), enum_table[gradient.type()]);
560     QGradientBrushData *grad = static_cast<QGradientBrushData *>(d.data());
561     grad->gradient = gradient;
562 }
563
564 /*!
565     Destroys the brush.
566 */
567
568 QBrush::~QBrush()
569 {
570 }
571
572 void QBrush::cleanUp(QBrushData *x)
573 {
574     QBrushDataPointerDeleter::deleteData(x);
575 }
576
577
578 void QBrush::detach(Qt::BrushStyle newStyle)
579 {
580     if (newStyle == d->style && d->ref == 1)
581         return;
582
583     QScopedPointer<QBrushData> x;
584     switch(newStyle) {
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());
591             else
592                 tbd->setImage(data->image());
593         }
594         x.reset(tbd);
595         break;
596         }
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;
603         break;
604     default:
605         x.reset(new QBrushData);
606         break;
607     }
608     x->ref = 1;
609     x->style = newStyle;
610     x->color = d->color;
611     x->transform = d->transform;
612     d.reset(x.take());
613 }
614
615
616 /*!
617     \fn QBrush &QBrush::operator=(const QBrush &brush)
618
619     Assigns the given \a brush to \e this brush and returns a
620     reference to \e this brush.
621 */
622
623 QBrush &QBrush::operator=(const QBrush &b)
624 {
625     if (d == b.d)
626         return *this;
627
628     b.d->ref.ref();
629     d.reset(b.d.data());
630     return *this;
631 }
632
633
634 /*!
635     \fn void QBrush::swap(QBrush &other)
636     \since 4.8
637
638     Swaps brush \a other with this brush. This operation is very
639     fast and never fails.
640 */
641
642 /*!
643    Returns the brush as a QVariant
644 */
645 QBrush::operator QVariant() const
646 {
647     return QVariant(QVariant::Brush, this);
648 }
649
650 /*!
651     \fn Qt::BrushStyle QBrush::style() const
652
653     Returns the brush style.
654
655     \sa setStyle()
656 */
657
658 /*!
659     Sets the brush style to \a style.
660
661     \sa style()
662 */
663
664 void QBrush::setStyle(Qt::BrushStyle style)
665 {
666     if (d->style == style)
667         return;
668
669     if (qbrush_check_type(style)) {
670         detach(style);
671         d->style = style;
672     }
673 }
674
675
676 /*!
677     \fn const QColor &QBrush::color() const
678
679     Returns the brush color.
680
681     \sa setColor()
682 */
683
684 /*!
685     \fn void QBrush::setColor(const QColor &color)
686
687     Sets the brush color to the given \a color.
688
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.
692
693     \sa color()
694 */
695
696 void QBrush::setColor(const QColor &c)
697 {
698     detach(d->style);
699     d->color = c;
700 }
701
702 /*!
703     \fn void QBrush::setColor(Qt::GlobalColor color)
704     \overload
705
706     Sets the brush color to the given \a color.
707 */
708
709
710 #ifdef QT3_SUPPORT
711
712 /*!
713     \fn void QBrush::setPixmap(const QPixmap &pixmap)
714
715     \compat
716
717     Sets a custom pattern for this brush.
718
719     Use setTexture() instead.
720 */
721
722 /*!
723     \fn QPixmap *QBrush::pixmap() const
724
725     Returns a pointer to the custom brush pattern.
726
727     Use texture() instead.
728 */
729 QPixmap *QBrush::pixmap() const
730 {
731     if (d->style != Qt::TexturePattern)
732         return 0;
733     QTexturedBrushData *data  = static_cast<QTexturedBrushData*>(d.data());
734     QPixmap &pixmap = data->pixmap();
735     return pixmap.isNull() ? 0 : &pixmap;
736 }
737 #endif
738
739 /*!
740     \fn QPixmap QBrush::texture() const
741
742     Returns the custom brush pattern, or a null pixmap if no custom brush pattern
743     has been set.
744
745     \sa setTexture()
746 */
747 QPixmap QBrush::texture() const
748 {
749     return d->style == Qt::TexturePattern
750                      ? (static_cast<QTexturedBrushData *>(d.data()))->pixmap()
751                      : QPixmap();
752 }
753
754 /*!
755     Sets the brush pixmap to \a pixmap. The style is set to
756     Qt::TexturePattern.
757
758     The current brush color will only have an effect for monochrome
759     pixmaps, i.e. for QPixmap::depth() == 1 (\l {QBitmap}{QBitmaps}).
760
761     \sa texture()
762 */
763
764 void QBrush::setTexture(const QPixmap &pixmap)
765 {
766     if (!pixmap.isNull()) {
767         detach(Qt::TexturePattern);
768         QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data());
769         data->setPixmap(pixmap);
770     } else {
771         detach(Qt::NoBrush);
772     }
773 }
774
775
776 /*!
777     \since 4.2
778
779     Returns the custom brush pattern, or a null image if no custom
780     brush pattern has been set.
781
782     If the texture was set as a QPixmap it will be converted to a
783     QImage.
784
785     \sa setTextureImage()
786 */
787
788 QImage QBrush::textureImage() const
789 {
790     return d->style == Qt::TexturePattern
791                      ? (static_cast<QTexturedBrushData *>(d.data()))->image()
792                      : QImage();
793 }
794
795
796 /*!
797     \since 4.2
798
799     Sets the brush image to \a image. The style is set to
800     Qt::TexturePattern.
801
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.
808
809     \sa textureImage(), setTexture()
810 */
811
812 void QBrush::setTextureImage(const QImage &image)
813 {
814     if (!image.isNull()) {
815         detach(Qt::TexturePattern);
816         QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data());
817         data->setImage(image);
818     } else {
819         detach(Qt::NoBrush);
820     }
821 }
822
823
824 /*!
825     Returns the gradient describing this brush.
826 */
827 const QGradient *QBrush::gradient() const
828 {
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;
833     }
834     return 0;
835 }
836
837 Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush)
838 {
839     if (brush.style() == Qt::RadialGradientPattern) {
840         const QGradient *g = brush.gradient();
841         const QRadialGradient *rg = static_cast<const QRadialGradient *>(g);
842
843         if (!qFuzzyIsNull(rg->focalRadius()))
844             return true;
845
846         QPointF delta = rg->focalPoint() - rg->center();
847         if (delta.x() * delta.x() + delta.y() * delta.y() > rg->radius() * rg->radius())
848             return true;
849     }
850
851     return false;
852 }
853
854 /*!
855     Returns true if the brush is fully opaque otherwise false. A brush
856     is considered opaque if:
857
858     \list
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.
863     \endlist
864 */
865
866 bool QBrush::isOpaque() const
867 {
868     bool opaqueColor = d->color.alpha() == 255;
869
870     // Test awfully simple case first
871     if (d->style == Qt::SolidPattern)
872         return opaqueColor;
873
874     if (qt_isExtendedRadialGradient(*this))
875         return false;
876
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)
883                 return false;
884         return true;
885     } else if (d->style == Qt::TexturePattern) {
886         return qHasPixmapTexture(*this)
887             ? !texture().hasAlphaChannel() && !texture().isQBitmap()
888             : !textureImage().hasAlphaChannel();
889     }
890
891     return false;
892 }
893
894
895 /*!
896     \since 4.2
897
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.
901
902     \sa matrix()
903 */
904 void QBrush::setMatrix(const QMatrix &matrix)
905 {
906     setTransform(QTransform(matrix));
907 }
908
909 /*!
910     \since 4.3
911
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.
915
916     \sa transform()
917 */
918 void QBrush::setTransform(const QTransform &matrix)
919 {
920     detach(d->style);
921     d->transform = matrix;
922 }
923
924
925 /*!
926     \fn void QBrush::matrix() const
927     \since 4.2
928
929     Returns the current transformation matrix for the brush.
930
931     \sa setMatrix()
932 */
933
934 /*!
935     \fn bool QBrush::operator!=(const QBrush &brush) const
936
937     Returns true if the brush is different from the given \a brush;
938     otherwise returns false.
939
940     Two brushes are different if they have different styles, colors or
941     transforms or different pixmaps or gradients depending on the style.
942
943     \sa operator==()
944 */
945
946 /*!
947     \fn bool QBrush::operator==(const QBrush &brush) const
948
949     Returns true if the brush is equal to the given \a brush;
950     otherwise returns false.
951
952     Two brushes are equal if they have equal styles, colors and
953     transforms and equal pixmaps or gradients depending on the style.
954
955     \sa operator!=()
956 */
957
958 bool QBrush::operator==(const QBrush &b) const
959 {
960     if (b.d == d)
961         return true;
962     if (b.d->style != d->style || b.d->color != d->color || b.d->transform != d->transform)
963         return false;
964     switch (d->style) {
965     case Qt::TexturePattern:
966         {
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());
970         }
971     case Qt::LinearGradientPattern:
972     case Qt::RadialGradientPattern:
973     case Qt::ConicalGradientPattern:
974         {
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;
978         }
979     default:
980         return true;
981     }
982 }
983
984 /*!
985     \fn QBrush::operator const QColor&() const
986
987     Returns the brush's color.
988
989     Use color() instead.
990 */
991
992 #ifndef QT_NO_DEBUG_STREAM
993 /*!
994   \internal
995 */
996 QDebug operator<<(QDebug dbg, const QBrush &b)
997 {
998 #ifndef Q_BROKEN_DEBUG_STREAM
999     static const char *BRUSH_STYLES[] = {
1000      "NoBrush",
1001      "SolidPattern",
1002      "Dense1Pattern",
1003      "Dense2Pattern",
1004      "Dense3Pattern",
1005      "Dense4Pattern",
1006      "Dense5Pattern",
1007      "Dense6Pattern",
1008      "Dense7Pattern",
1009      "HorPattern",
1010      "VerPattern",
1011      "CrossPattern",
1012      "BDiagPattern",
1013      "FDiagPattern",
1014      "DiagCrossPattern",
1015      "LinearGradientPattern",
1016      "RadialGradientPattern",
1017      "ConicalGradientPattern",
1018      0, 0, 0, 0, 0, 0,
1019      "TexturePattern" // 24
1020     };
1021
1022     dbg.nospace() << "QBrush(" << b.color() << ',' << BRUSH_STYLES[b.style()] << ')';
1023     return dbg.space();
1024 #else
1025     qWarning("This compiler doesn't support streaming QBrush to QDebug");
1026     return dbg;
1027     Q_UNUSED(b);
1028 #endif
1029 }
1030 #endif
1031
1032 /*****************************************************************************
1033   QBrush stream functions
1034  *****************************************************************************/
1035 #ifndef QT_NO_DATASTREAM
1036 /*!
1037     \fn QDataStream &operator<<(QDataStream &stream, const QBrush &brush)
1038     \relates QBrush
1039
1040     Writes the given \a brush to the given \a stream and returns a
1041     reference to the \a stream.
1042
1043     \sa {Serializing Qt Data Types}
1044 */
1045
1046 QDataStream &operator<<(QDataStream &s, const QBrush &b)
1047 {
1048     quint8 style = (quint8) b.style();
1049     bool gradient_style = false;
1050
1051     if (style == Qt::LinearGradientPattern || style == Qt::RadialGradientPattern
1052         || style == Qt::ConicalGradientPattern)
1053         gradient_style = true;
1054
1055     if (s.version() < QDataStream::Qt_4_0 && gradient_style)
1056         style = Qt::NoBrush;
1057
1058     s << style << b.color();
1059     if (b.style() == Qt::TexturePattern) {
1060         s << b.texture();
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());
1064         s << type_as_int;
1065         if (s.version() >= QDataStream::Qt_4_3) {
1066             s << int(gradient->spread());
1067             s << int(gradient->coordinateMode());
1068         }
1069
1070         if (s.version() >= QDataStream::Qt_4_5)
1071             s << int(gradient->interpolationMode());
1072
1073         if (sizeof(qreal) == sizeof(double)) {
1074             s << gradient->stops();
1075         } else {
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);
1084             }
1085         }
1086
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();
1097         }
1098     }
1099     if (s.version() >= QDataStream::Qt_4_3)
1100         s << b.transform();
1101     return s;
1102 }
1103
1104 /*!
1105     \fn QDataStream &operator>>(QDataStream &stream, QBrush &brush)
1106     \relates QBrush
1107
1108     Reads the given \a brush from the given \a stream and returns a
1109     reference to the \a stream.
1110
1111     \sa {Serializing Qt Data Types}
1112 */
1113
1114 QDataStream &operator>>(QDataStream &s, QBrush &b)
1115 {
1116     quint8 style;
1117     QColor color;
1118     s >> style;
1119     s >> color;
1120     if (style == Qt::TexturePattern) {
1121         QPixmap pm;
1122         s >> pm;
1123         b = QBrush(color, pm);
1124     } else if (style == Qt::LinearGradientPattern
1125                || style == Qt::RadialGradientPattern
1126                || style == Qt::ConicalGradientPattern) {
1127
1128         int type_as_int;
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;
1134
1135         s >> type_as_int;
1136         type = QGradient::Type(type_as_int);
1137         if (s.version() >= QDataStream::Qt_4_3) {
1138             s >> type_as_int;
1139             spread = QGradient::Spread(type_as_int);
1140             s >> type_as_int;
1141             cmode = QGradient::CoordinateMode(type_as_int);
1142         }
1143
1144         if (s.version() >= QDataStream::Qt_4_5) {
1145             s >> type_as_int;
1146             imode = QGradient::InterpolationMode(type_as_int);
1147         }
1148
1149         if (sizeof(qreal) == sizeof(double)) {
1150             s >> stops;
1151         } else {
1152             quint32 numStops;
1153             double n;
1154             QColor c;
1155
1156             s >> numStops;
1157             for (quint32 i = 0; i < numStops; ++i) {
1158                 s >> n >> c;
1159                 stops << QPair<qreal, QColor>(n, c);
1160             }
1161         }
1162
1163         if (type == QGradient::LinearGradient) {
1164             QPointF p1, p2;
1165             s >> p1;
1166             s >> p2;
1167             QLinearGradient lg(p1, p2);
1168             lg.setStops(stops);
1169             lg.setSpread(spread);
1170             lg.setCoordinateMode(cmode);
1171             lg.setInterpolationMode(imode);
1172             b = QBrush(lg);
1173         } else if (type == QGradient::RadialGradient) {
1174             QPointF center, focal;
1175             double radius;
1176             s >> center;
1177             s >> focal;
1178             s >> radius;
1179             QRadialGradient rg(center, radius, focal);
1180             rg.setStops(stops);
1181             rg.setSpread(spread);
1182             rg.setCoordinateMode(cmode);
1183             rg.setInterpolationMode(imode);
1184             b = QBrush(rg);
1185         } else { // type == QGradient::ConicalGradient
1186             QPointF center;
1187             double angle;
1188             s >> center;
1189             s >> angle;
1190             QConicalGradient cg(center, angle);
1191             cg.setStops(stops);
1192             cg.setSpread(spread);
1193             cg.setCoordinateMode(cmode);
1194             cg.setInterpolationMode(imode);
1195             b = QBrush(cg);
1196         }
1197     } else {
1198         b = QBrush(color, (Qt::BrushStyle)style);
1199     }
1200     if (s.version() >= QDataStream::Qt_4_3) {
1201         QTransform transform;
1202         s >> transform;
1203         b.setTransform(transform);
1204     }
1205     return s;
1206 }
1207 #endif // QT_NO_DATASTREAM
1208
1209 /*******************************************************************************
1210  * QGradient implementations
1211  */
1212
1213
1214 /*!
1215     \class QGradient
1216     \ingroup painting
1217     \ingroup shared
1218
1219     \brief The QGradient class is used in combination with QBrush to
1220     specify gradient fills.
1221
1222     Qt currently supports three types of gradient fills:
1223
1224     \list
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
1229         a focal circle.
1230     \o \e Conical gradients interpolate colors around a center point.
1231     \endlist
1232
1233     A gradient's type can be retrieved using the type() function.
1234     Each of the types is represented by a subclass of QGradient:
1235
1236     \table
1237     \header
1238     \o QLinearGradient
1239     \o QRadialGradient
1240     \o QConicalGradient
1241     \row
1242     \o \inlineimage qgradient-linear.png
1243     \o \inlineimage qgradient-radial.png
1244     \o \inlineimage qgradient-conical.png
1245     \endtable
1246
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.
1252
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.
1257
1258     A diagonal linear gradient from black at (100, 100) to white at
1259     (200, 200) could be specified like this:
1260
1261     \snippet doc/src/snippets/brush/brush.cpp 0
1262
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:
1266
1267     \snippet doc/src/snippets/brush/brush.cpp 1
1268
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
1275     different methods:
1276
1277     \table
1278     \row
1279     \o \inlineimage qradialgradient-pad.png
1280     \o \inlineimage qradialgradient-repeat.png
1281     \o \inlineimage qradialgradient-reflect.png
1282     \row
1283     \o \l {QGradient::PadSpread}{PadSpread}
1284     \o \l {QGradient::RepeatSpread}{RepeatSpread}
1285     \o \l {QGradient::ReflectSpread}{ReflectSpread}
1286     \endtable
1287
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.
1294
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().
1302
1303
1304     \sa {painting/gradients}{The Gradients Example}, QBrush
1305 */
1306
1307 /*!
1308     \internal
1309 */
1310 QGradient::QGradient()
1311     : m_type(NoGradient), dummy(0)
1312 {
1313 }
1314
1315
1316 /*!
1317     \enum QGradient::Type
1318
1319     Specifies the type of gradient.
1320
1321     \value LinearGradient  Interpolates colors between start and end points
1322     (QLinearGradient).
1323
1324     \value RadialGradient Interpolate colors between a focal point and end
1325     points on a circle surrounding it (QRadialGradient).
1326
1327     \value ConicalGradient Interpolate colors around a center point (QConicalGradient).
1328     \value NoGradient No gradient is used.
1329
1330     \sa type()
1331 */
1332
1333 /*!
1334     \enum QGradient::Spread
1335
1336     Specifies how the area outside the gradient area should be
1337     filled.
1338
1339     \value PadSpread The area is filled with the closest stop
1340     color. This is the default.
1341
1342     \value RepeatSpread The gradient  is repeated outside the gradient
1343     area.
1344
1345     \value ReflectSpread The gradient is reflected outside the
1346     gradient area.
1347
1348     \sa spread(), setSpread()
1349 */
1350
1351 /*!
1352     \fn void QGradient::setSpread(Spread method)
1353
1354     Specifies the spread \a method that should be used for this
1355     gradient.
1356
1357     Note that this function only has effect for linear and radial
1358     gradients.
1359
1360     \sa spread()
1361 */
1362
1363 /*!
1364     \fn QGradient::Spread QGradient::spread() const
1365
1366     Returns the spread method use by this gradient. The default is
1367     PadSpread.
1368
1369     \sa setSpread()
1370 */
1371
1372 /*!
1373     \fn QGradient::Type QGradient::type() const
1374
1375     Returns the type of gradient.
1376 */
1377
1378 /*!
1379     \fn void QGradient::setColorAt(qreal position, const QColor &color)
1380
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.
1383
1384     \sa setStops(), stops()
1385 */
1386
1387 void QGradient::setColorAt(qreal pos, const QColor &color)
1388 {
1389     if ((pos > 1 || pos < 0) && !qIsNaN(pos)) {
1390         qWarning("QGradient::setColorAt: Color position must be specified in the range 0 to 1");
1391         return;
1392     }
1393
1394     int index = 0;
1395     if (!qIsNaN(pos))
1396         while (index < m_stops.size() && m_stops.at(index).first < pos) ++index;
1397
1398     if (index < m_stops.size() && m_stops.at(index).first == pos)
1399         m_stops[index].second = color;
1400     else
1401         m_stops.insert(index, QGradientStop(pos, color));
1402 }
1403
1404 /*!
1405     \fn void QGradient::setStops(const QGradientStops &stopPoints)
1406
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.
1410
1411     \sa setColorAt(), stops()
1412 */
1413 void QGradient::setStops(const QGradientStops &stops)
1414 {
1415     m_stops.clear();
1416     for (int i=0; i<stops.size(); ++i)
1417         setColorAt(stops.at(i).first, stops.at(i).second);
1418 }
1419
1420
1421 /*!
1422     Returns the stop points for this gradient.
1423
1424     If no stop points have been specified, a gradient of black at 0 to white
1425     at 1 is used.
1426
1427     \sa setStops(), setColorAt()
1428 */
1429 QGradientStops QGradient::stops() const
1430 {
1431     if (m_stops.isEmpty()) {
1432         QGradientStops tmp;
1433         tmp << QGradientStop(0, Qt::black) << QGradientStop(1, Qt::white);
1434         return tmp;
1435     }
1436     return m_stops;
1437 }
1438
1439 #define Q_DUMMY_ACCESSOR union {void *p; uint i;}; p = dummy;
1440
1441 /*!
1442     \enum QGradient::CoordinateMode
1443     \since 4.4
1444
1445     This enum specifies how gradient coordinates map to the paint
1446     device on which the gradient is used.
1447
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.
1458 */
1459
1460 /*!
1461     \since 4.4
1462
1463     Returns the coordinate mode of this gradient. The default mode is
1464     LogicalMode.
1465 */
1466 QGradient::CoordinateMode QGradient::coordinateMode() const
1467 {
1468     Q_DUMMY_ACCESSOR
1469     return CoordinateMode(i & 0x03);
1470 }
1471
1472 /*!
1473     \since 4.4
1474
1475     Sets the coordinate mode of this gradient to \a mode. The default
1476     mode is LogicalMode.
1477 */
1478 void QGradient::setCoordinateMode(CoordinateMode mode)
1479 {
1480     Q_DUMMY_ACCESSOR
1481     i &= ~0x03;
1482     i |= uint(mode);
1483     dummy = p;
1484 }
1485
1486 /*!
1487     \enum QGradient::InterpolationMode
1488     \since 4.5
1489     \internal
1490
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.
1495 */
1496
1497 /*!
1498     \since 4.5
1499     \internal
1500
1501     Returns the interpolation mode of this gradient. The default mode is
1502     ColorInterpolation.
1503 */
1504 QGradient::InterpolationMode QGradient::interpolationMode() const
1505 {
1506     Q_DUMMY_ACCESSOR
1507     return InterpolationMode((i >> 2) & 0x01);
1508 }
1509
1510 /*!
1511     \since 4.5
1512     \internal
1513
1514     Sets the interpolation mode of this gradient to \a mode. The default
1515     mode is ColorInterpolation.
1516 */
1517 void QGradient::setInterpolationMode(InterpolationMode mode)
1518 {
1519     Q_DUMMY_ACCESSOR
1520     i &= ~(1 << 2);
1521     i |= (uint(mode) << 2);
1522     dummy = p;
1523 }
1524
1525 /*!
1526     \fn bool QGradient::operator!=(const QGradient &gradient) const
1527     \since 4.2
1528
1529     Returns true if the gradient is the same as the other \a gradient
1530     specified; otherwise returns false.
1531
1532     \sa operator==()
1533 */
1534
1535 /*!
1536     Returns true if the gradient is the same as the other \a gradient
1537     specified; otherwise returns false.
1538
1539     \sa operator!=()
1540 */
1541 bool QGradient::operator==(const QGradient &gradient) const
1542 {
1543     if (gradient.m_type != m_type
1544         || gradient.m_spread != m_spread
1545         || gradient.dummy != dummy) return false;
1546
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)
1552             return false;
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)
1559             return false;
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)
1564             return false;
1565     }
1566
1567     return stops() == gradient.stops();
1568 }
1569
1570 /*!
1571     \class QLinearGradient
1572     \ingroup painting
1573
1574     \brief The QLinearGradient class is used in combination with QBrush to
1575     specify a linear gradient brush.
1576
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:
1581
1582     \table
1583     \row
1584     \o \inlineimage qlineargradient-pad.png
1585     \o \inlineimage qlineargradient-reflect.png
1586     \o \inlineimage qlineargradient-repeat.png
1587     \row
1588     \o \l {QGradient::PadSpread}{PadSpread} (default)
1589     \o \l {QGradient::ReflectSpread}{ReflectSpread}
1590     \o \l {QGradient::RepeatSpread}{RepeatSpread}
1591     \endtable
1592
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
1599     white at 1 is used.
1600
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.
1605
1606     \sa QRadialGradient, QConicalGradient, {painting/gradients}{The
1607     Gradients Example}
1608 */
1609
1610
1611 /*!
1612     Constructs a default linear gradient with interpolation area
1613     between (0, 0) and (1, 1).
1614
1615     \sa QGradient::setColorAt(), setStart(), setFinalStop()
1616 */
1617
1618 QLinearGradient::QLinearGradient()
1619 {
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;
1626 }
1627
1628
1629 /*!
1630     Constructs a linear gradient with interpolation area between the
1631     given \a start point and \a finalStop.
1632
1633     \note The expected parameter values are in pixels.
1634
1635     \sa QGradient::setColorAt(), QGradient::setStops()
1636 */
1637 QLinearGradient::QLinearGradient(const QPointF &start, const QPointF &finalStop)
1638 {
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();
1645 }
1646
1647 /*!
1648     \fn QLinearGradient::QLinearGradient(qreal x1, qreal y1, qreal x2, qreal y2)
1649
1650     Constructs a linear gradient with interpolation area between (\a
1651     x1, \a y1) and (\a x2, \a y2).
1652
1653     \note The expected parameter values are in pixels.
1654
1655     \sa QGradient::setColorAt(), QGradient::setStops()
1656 */
1657 QLinearGradient::QLinearGradient(qreal xStart, qreal yStart, qreal xFinalStop, qreal yFinalStop)
1658 {
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;
1665 }
1666
1667
1668 /*!
1669     Returns the start point of this linear gradient in logical coordinates.
1670
1671     \sa QGradient::stops()
1672 */
1673
1674 QPointF QLinearGradient::start() const
1675 {
1676     Q_ASSERT(m_type == LinearGradient);
1677     return QPointF(m_data.linear.x1, m_data.linear.y1);
1678 }
1679
1680 /*!
1681     \fn void QLinearGradient::setStart(qreal x, qreal y)
1682     \overload
1683     \since 4.2
1684
1685     Sets the start point of this linear gradient in logical
1686     coordinates to \a x, \a y.
1687
1688     \sa start()
1689 */
1690
1691 /*!
1692     \since 4.2
1693
1694     Sets the start point of this linear gradient in logical
1695     coordinates to \a start.
1696
1697     \sa start()
1698 */
1699
1700 void QLinearGradient::setStart(const QPointF &start)
1701 {
1702     Q_ASSERT(m_type == LinearGradient);
1703     m_data.linear.x1 = start.x();
1704     m_data.linear.y1 = start.y();
1705 }
1706
1707
1708 /*!
1709     \fn void QLinearGradient::setFinalStop(qreal x, qreal y)
1710     \overload
1711     \since 4.2
1712
1713     Sets the final stop point of this linear gradient in logical
1714     coordinates to \a x, \a y.
1715
1716     \sa start()
1717 */
1718
1719 /*!
1720     Returns the final stop point of this linear gradient in logical coordinates.
1721
1722     \sa QGradient::stops()
1723 */
1724
1725 QPointF QLinearGradient::finalStop() const
1726 {
1727     Q_ASSERT(m_type == LinearGradient);
1728     return QPointF(m_data.linear.x2, m_data.linear.y2);
1729 }
1730
1731
1732 /*!
1733     \since 4.2
1734
1735     Sets the final stop point of this linear gradient in logical
1736     coordinates to \a stop.
1737
1738     \sa finalStop()
1739 */
1740
1741 void QLinearGradient::setFinalStop(const QPointF &stop)
1742 {
1743     Q_ASSERT(m_type == LinearGradient);
1744     m_data.linear.x2 = stop.x();
1745     m_data.linear.y2 = stop.y();
1746 }
1747
1748
1749 /*!
1750     \class QRadialGradient
1751     \ingroup painting
1752
1753     \brief The QRadialGradient class is used in combination with QBrush to
1754     specify a radial gradient brush.
1755
1756     Qt supports both simple and extended radial gradients.
1757
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.
1764
1765     Outside the end points the gradient is either padded, reflected or repeated
1766     depending on the currently set \l {QGradient::Spread}{spread} method:
1767
1768     \table
1769     \row
1770     \o \inlineimage qradialgradient-pad.png
1771     \o \inlineimage qradialgradient-reflect.png
1772     \o \inlineimage qradialgradient-repeat.png
1773     \row
1774     \o \l {QGradient::PadSpread}{PadSpread} (default)
1775     \o \l {QGradient::ReflectSpread}{ReflectSpread}
1776     \o \l {QGradient::RepeatSpread}{RepeatSpread}
1777     \endtable
1778
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
1785     white at 1 is used.
1786
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.
1791
1792     \sa QLinearGradient, QConicalGradient, {painting/gradients}{The
1793     Gradients Example}
1794 */
1795
1796 static QPointF qt_radial_gradient_adapt_focal_point(const QPointF &center,
1797                                                     qreal radius,
1798                                                     const QPointF &focalPoint)
1799 {
1800     // We have a one pixel buffer zone to avoid numerical instability on the
1801     // circle border
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);
1807     return line.p2();
1808 }
1809
1810 /*!
1811     Constructs a simple radial gradient with the given \a center, \a
1812     radius and \a focalPoint.
1813
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
1817     \a focalPoint.
1818
1819     \sa QGradient::setColorAt(), QGradient::setStops()
1820 */
1821
1822 QRadialGradient::QRadialGradient(const QPointF &center, qreal radius, const QPointF &focalPoint)
1823 {
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;
1829
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();
1833 }
1834
1835 /*!
1836     Constructs a simple radial gradient with the given \a center, \a
1837     radius and the focal point in the circle center.
1838
1839     \sa QGradient::setColorAt(), QGradient::setStops()
1840 */
1841 QRadialGradient::QRadialGradient(const QPointF &center, qreal radius)
1842 {
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();
1850 }
1851
1852
1853 /*!
1854     Constructs a simple radial gradient with the given center (\a cx, \a cy),
1855     \a radius and focal point (\a fx, \a fy).
1856
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
1860     and the circle.
1861
1862     \sa QGradient::setColorAt(), QGradient::setStops()
1863 */
1864
1865 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius, qreal fx, qreal fy)
1866 {
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;
1872
1873     QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(QPointF(cx, cy),
1874                                                                  radius,
1875                                                                  QPointF(fx, fy));
1876
1877     m_data.radial.fx = adapted_focal.x();
1878     m_data.radial.fy = adapted_focal.y();
1879 }
1880
1881 /*!
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.
1884
1885     \sa QGradient::setColorAt(), QGradient::setStops()
1886  */
1887 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius)
1888 {
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;
1896 }
1897
1898
1899 /*!
1900     Constructs a simple radial gradient with the center and focal point at
1901     (0, 0) with a radius of 1.
1902 */
1903 QRadialGradient::QRadialGradient()
1904 {
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;
1912 }
1913
1914 /*!
1915     \since 4.8
1916
1917     Constructs an extended radial gradient with the given \a center, \a
1918     centerRadius, \a focalPoint, and \a focalRadius.
1919 */
1920 QRadialGradient::QRadialGradient(const QPointF &center, qreal centerRadius, const QPointF &focalPoint, qreal focalRadius)
1921 {
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;
1927
1928     m_data.radial.fx = focalPoint.x();
1929     m_data.radial.fy = focalPoint.y();
1930     setFocalRadius(focalRadius);
1931 }
1932
1933 /*!
1934     \since 4.8
1935
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.
1939 */
1940 QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius)
1941 {
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;
1947
1948     m_data.radial.fx = fx;
1949     m_data.radial.fy = fy;
1950     setFocalRadius(focalRadius);
1951 }
1952
1953 /*!
1954     Returns the center of this radial gradient in logical coordinates.
1955
1956     \sa QGradient::stops()
1957 */
1958
1959 QPointF QRadialGradient::center() const
1960 {
1961     Q_ASSERT(m_type == RadialGradient);
1962     return QPointF(m_data.radial.cx, m_data.radial.cy);
1963 }
1964
1965 /*!
1966     \fn void QRadialGradient::setCenter(qreal x, qreal y)
1967     \overload
1968     \since 4.2
1969
1970     Sets the center of this radial gradient in logical coordinates
1971     to (\a x, \a y).
1972
1973     \sa center()
1974 */
1975
1976 /*!
1977     \since 4.2
1978
1979     Sets the center of this radial gradient in logical coordinates
1980     to \a center.
1981
1982     \sa center()
1983 */
1984
1985 void QRadialGradient::setCenter(const QPointF &center)
1986 {
1987     Q_ASSERT(m_type == RadialGradient);
1988     m_data.radial.cx = center.x();
1989     m_data.radial.cy = center.y();
1990 }
1991
1992
1993 /*!
1994     Returns the radius of this radial gradient in logical coordinates.
1995
1996     Equivalent to centerRadius()
1997
1998     \sa QGradient::stops()
1999 */
2000
2001 qreal QRadialGradient::radius() const
2002 {
2003     Q_ASSERT(m_type == RadialGradient);
2004     return m_data.radial.cradius;
2005 }
2006
2007
2008 /*!
2009     \since 4.2
2010
2011     Sets the radius of this radial gradient in logical coordinates
2012     to \a radius
2013
2014     Equivalent to setCenterRadius()
2015 */
2016 void QRadialGradient::setRadius(qreal radius)
2017 {
2018     Q_ASSERT(m_type == RadialGradient);
2019     m_data.radial.cradius = radius;
2020 }
2021
2022 /*!
2023     \since 4.8
2024
2025     Returns the center radius of this radial gradient in logical
2026     coordinates.
2027
2028     \sa QGradient::stops()
2029 */
2030 qreal QRadialGradient::centerRadius() const
2031 {
2032     Q_ASSERT(m_type == RadialGradient);
2033     return m_data.radial.cradius;
2034 }
2035
2036 /*!
2037    \since 4.8
2038
2039    Sets the center radius of this radial gradient in logical coordinates
2040    to \a radius
2041 */
2042 void QRadialGradient::setCenterRadius(qreal radius)
2043 {
2044     Q_ASSERT(m_type == RadialGradient);
2045     m_data.radial.cradius = radius;
2046 }
2047
2048 /*!
2049     \since 4.8
2050
2051     Returns the focal radius of this radial gradient in logical
2052     coordinates.
2053
2054     \sa QGradient::stops()
2055 */
2056 qreal QRadialGradient::focalRadius() const
2057 {
2058     Q_ASSERT(m_type == RadialGradient);
2059     Q_DUMMY_ACCESSOR
2060
2061     // mask away low three bits
2062     union { float f; quint32 i; } u;
2063     u.i = i & ~0x07;
2064     return u.f;
2065 }
2066
2067 /*!
2068    \since 4.8
2069
2070    Sets the focal radius of this radial gradient in logical coordinates
2071    to \a radius
2072 */
2073 void QRadialGradient::setFocalRadius(qreal radius)
2074 {
2075     Q_ASSERT(m_type == RadialGradient);
2076     Q_DUMMY_ACCESSOR
2077
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;
2086     dummy = p;
2087 }
2088
2089 /*!
2090     Returns the focal point of this radial gradient in logical
2091     coordinates.
2092
2093     \sa QGradient::stops()
2094 */
2095
2096 QPointF QRadialGradient::focalPoint() const
2097 {
2098     Q_ASSERT(m_type == RadialGradient);
2099     return QPointF(m_data.radial.fx, m_data.radial.fy);
2100 }
2101
2102 /*!
2103     \fn void QRadialGradient::setFocalPoint(qreal x, qreal y)
2104     \overload
2105     \since 4.2
2106
2107     Sets the focal point of this radial gradient in logical
2108     coordinates to (\a x, \a y).
2109
2110     \sa focalPoint()
2111 */
2112
2113 /*!
2114     \since 4.2
2115
2116     Sets the focal point of this radial gradient in logical
2117     coordinates to \a focalPoint.
2118
2119     \sa focalPoint()
2120 */
2121
2122 void QRadialGradient::setFocalPoint(const QPointF &focalPoint)
2123 {
2124     Q_ASSERT(m_type == RadialGradient);
2125     m_data.radial.fx = focalPoint.x();
2126     m_data.radial.fy = focalPoint.y();
2127 }
2128
2129
2130
2131 /*!
2132     \class QConicalGradient
2133     \ingroup painting
2134
2135     \brief The QConicalGradient class is used in combination with QBrush to
2136     specify a conical gradient brush.
2137
2138     Conical gradients interpolate interpolate colors counter-clockwise
2139     around a center point.
2140
2141     \image qconicalgradient.png
2142
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
2149     white at 1 is used.
2150
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.
2154
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,
2160     respectively.
2161
2162     \sa QLinearGradient, QRadialGradient, {painting/gradients}{The
2163     Gradients Example}
2164 */
2165
2166
2167 /*!
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.
2171
2172     \sa QGradient::setColorAt(), QGradient::setStops()
2173 */
2174
2175 QConicalGradient::QConicalGradient(const QPointF &center, qreal angle)
2176 {
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;
2182 }
2183
2184
2185 /*!
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.
2189
2190     \sa QGradient::setColorAt(), QGradient::setStops()
2191 */
2192
2193 QConicalGradient::QConicalGradient(qreal cx, qreal cy, qreal angle)
2194 {
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;
2200 }
2201
2202
2203 /*!
2204     Constructs a conical with center at (0, 0) starting the
2205     interpolation at angle 0.
2206
2207     \sa QGradient::setColorAt(), setCenter(), setAngle()
2208 */
2209
2210 QConicalGradient::QConicalGradient()
2211 {
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;
2217 }
2218
2219
2220 /*!
2221     Returns the center of the conical gradient in logical
2222     coordinates.
2223
2224     \sa stops()
2225 */
2226
2227 QPointF QConicalGradient::center() const
2228 {
2229     Q_ASSERT(m_type == ConicalGradient);
2230     return QPointF(m_data.conical.cx, m_data.conical.cy);
2231 }
2232
2233
2234 /*!
2235     \fn void QConicalGradient::setCenter(qreal x, qreal y)
2236
2237     \overload
2238
2239     Sets the center of this conical gradient in logical coordinates to
2240     (\a x, \a y).
2241
2242     \sa center()
2243 */
2244
2245 /*!
2246     Sets the center of this conical gradient in logical coordinates to
2247     \a center.
2248
2249     \sa center()
2250 */
2251
2252 void QConicalGradient::setCenter(const QPointF &center)
2253 {
2254     Q_ASSERT(m_type == ConicalGradient);
2255     m_data.conical.cx = center.x();
2256     m_data.conical.cy = center.y();
2257 }
2258
2259 /*!
2260     Returns the start angle of the conical gradient in logical
2261     coordinates.
2262
2263     \sa stops()
2264 */
2265
2266 qreal QConicalGradient::angle() const
2267 {
2268     Q_ASSERT(m_type == ConicalGradient);
2269     return m_data.conical.angle;
2270 }
2271
2272
2273 /*!
2274     \since 4.2
2275
2276     Sets \a angle to be the start angle for this conical gradient in
2277     logical coordinates.
2278
2279     \sa angle()
2280 */
2281
2282 void QConicalGradient::setAngle(qreal angle)
2283 {
2284     Q_ASSERT(m_type == ConicalGradient);
2285     m_data.conical.angle = angle;
2286 }
2287
2288 /*!
2289     \typedef QGradientStop
2290     \relates QGradient
2291
2292     Typedef for QPair<\l qreal, QColor>.
2293 */
2294
2295 /*!
2296     \typedef QGradientStops
2297     \relates QGradient
2298
2299     Typedef for QVector<QGradientStop>.
2300 */
2301
2302 /*!
2303     \typedef QBrush::DataPtr
2304     \internal
2305 */
2306
2307 /*!
2308     \fn DataPtr &QBrush::data_ptr()
2309     \internal
2310 */
2311
2312
2313 /*!
2314     \fn bool QBrush::isDetached() const
2315     \internal
2316 */
2317
2318 /*!
2319     \fn QTransform QBrush::transform() const
2320     \since 4.3
2321
2322     Returns the current transformation matrix for the brush.
2323
2324     \sa setTransform()
2325 */
2326
2327 #undef Q_DUMMY_ACCESSOR
2328
2329 QT_END_NAMESPACE