Make QPen default to 1-width non-cosmetic.
[profile/ivi/qtbase.git] / src / gui / painting / qpen.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights.  These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file.  Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include "qpen.h"
42 #include "qpen_p.h"
43 #include "qdatastream.h"
44 #include "qvariant.h"
45 #include "qbrush.h"
46
47 #include <qdebug.h>
48
49 QT_BEGIN_NAMESPACE
50
51 typedef QPenPrivate QPenData;
52
53 /*!
54     \class QPen
55     \inmodule QtGui
56     \ingroup painting
57     \ingroup shared
58
59
60     \brief The QPen class defines how a QPainter should draw lines and outlines
61     of shapes.
62
63     A pen has a style(), width(), brush(), capStyle() and joinStyle().
64
65     The pen style defines the line type. The brush is used to fill
66     strokes generated with the pen. Use the QBrush class to specify
67     fill styles.  The cap style determines the line end caps that can
68     be drawn using QPainter, while the join style describes how joins
69     between two lines are drawn. The pen width can be specified in
70     both integer (width()) and floating point (widthF()) precision. A
71     line width of zero indicates a cosmetic pen.  This means that the
72     pen width is always drawn one pixel wide, independent of the \l
73     {QPainter#Coordinate Transformations}{transformation} set on the
74     painter.
75
76     The various settings can easily be modified using the
77     corresponding setStyle(), setWidth(), setBrush(), setCapStyle()
78     and setJoinStyle() functions (note that the painter's pen must be
79     reset when altering the pen's properties).
80
81     For example:
82
83     \snippet code/src_gui_painting_qpen.cpp 0
84
85     which is equivalent to
86
87     \snippet code/src_gui_painting_qpen.cpp 1
88
89     The default pen is a solid black brush with 1 width, square
90     cap style (Qt::SquareCap), and  bevel join style (Qt::BevelJoin).
91
92     In addition QPen provides the color() and setColor()
93     convenience functions to extract and set the color of the pen's
94     brush, respectively. Pens may also be compared and streamed.
95
96     For more information about painting in general, see the \l{Paint
97     System} documentation.
98
99     \tableofcontents
100
101     \section1 Pen Style
102
103     Qt provides several built-in styles represented by the
104     Qt::PenStyle enum:
105
106     \table
107     \row
108     \li \inlineimage qpen-solid.png
109     \li \inlineimage qpen-dash.png
110     \li \inlineimage qpen-dot.png
111     \row
112     \li Qt::SolidLine
113     \li Qt::DashLine
114     \li Qt::DotLine
115     \row
116     \li \inlineimage qpen-dashdot.png
117     \li \inlineimage qpen-dashdotdot.png
118     \li \inlineimage qpen-custom.png
119     \row
120     \li Qt::DashDotLine
121     \li Qt::DashDotDotLine
122     \li Qt::CustomDashLine
123     \endtable
124
125     Simply use the setStyle() function to convert the pen style to
126     either of the built-in styles, except the Qt::CustomDashLine style
127     which we will come back to shortly. Setting the style to Qt::NoPen
128     tells the painter to not draw lines or outlines. The default pen
129     style is Qt::SolidLine.
130
131     Since Qt 4.1 it is also possible to specify a custom dash pattern
132     using the setDashPattern() function which implicitly converts the
133     style of the pen to Qt::CustomDashLine. The pattern argument, a
134     QVector, must be specified as an even number of \l qreal entries
135     where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the
136     spaces. For example, the custom pattern shown above is created
137     using the following code:
138
139     \snippet code/src_gui_painting_qpen.cpp 2
140
141     Note that the dash pattern is specified in units of the pens
142     width, e.g. a dash of length 5 in width 10 is 50 pixels long.
143
144     The currently set dash pattern can be retrieved using the
145     dashPattern() function. Use the isSolid() function to determine
146     whether the pen has a solid fill, or not.
147
148     \section1 Cap Style
149
150     The cap style defines how the end points of lines are drawn using
151     QPainter.  The cap style only apply to wide lines, i.e. when the
152     width is 1 or greater. The Qt::PenCapStyle enum provides the
153     following styles:
154
155     \table
156     \row
157     \li \inlineimage qpen-square.png
158     \li \inlineimage qpen-flat.png
159     \li \inlineimage qpen-roundcap.png
160     \row
161     \li Qt::SquareCap
162     \li Qt::FlatCap
163     \li Qt::RoundCap
164     \endtable
165
166     The Qt::SquareCap style is a square line end that covers the end
167     point and extends beyond it by half the line width. The
168     Qt::FlatCap style is a square line end that does not cover the end
169     point of the line. And the Qt::RoundCap style is a rounded line
170     end covering the end point.
171
172     The default is Qt::SquareCap.
173
174     Whether or not end points are drawn when the pen width is 0 or 1
175     depends on the cap style. Using Qt::SquareCap or Qt::RoundCap they
176     are drawn, using Qt::FlatCap they are not drawn.
177
178     \section1 Join Style
179
180     The join style defines how joins between two connected lines can
181     be drawn using QPainter. The join style only apply to wide lines,
182     i.e. when the width is 1 or greater. The Qt::PenJoinStyle enum
183     provides the following styles:
184
185     \table
186     \row
187     \li \inlineimage qpen-bevel.png
188     \li \inlineimage qpen-miter.png
189     \li \inlineimage qpen-roundjoin.png
190     \row
191     \li Qt::BevelJoin
192     \li Qt::MiterJoin
193     \li Qt::RoundJoin
194     \endtable
195
196     The Qt::BevelJoin style fills the triangular notch between the two
197     lines. The Qt::MiterJoin style extends the lines to meet at an
198     angle. And the Qt::RoundJoin style fills a circular arc between
199     the two lines.
200
201     The default is Qt::BevelJoin.
202
203     \image qpen-miterlimit.png
204
205     When the Qt::MiterJoin style is applied, it is possible to use the
206     setMiterLimit() function to specify how far the miter join can
207     extend from the join point. The miterLimit() is used to reduce
208     artifacts between line joins where the lines are close to
209     parallel.
210
211     The miterLimit() must be specified in units of the pens width,
212     e.g. a miter limit of 5 in width 10 is 50 pixels long. The
213     default miter limit is 2, i.e. twice the pen width in pixels.
214
215     \table 100%
216     \row
217     \li \inlineimage qpen-demo.png
218     \li \b {\l {painting/pathstroke}{The Path Stroking Example}}
219
220     The Path Stroking example shows Qt's built-in dash patterns and shows
221     how custom patterns can be used to extend the range of available
222     patterns.
223     \endtable
224
225     \sa QPainter, QBrush, {painting/pathstroke}{Path Stroking Example},
226         {Scribble Example}
227 */
228
229 /*!
230   \internal
231 */
232 inline QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle,
233                                 Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle, bool _defaultWidth)
234     : ref(1), dashOffset(0), miterLimit(2),
235       cosmetic(false), defaultWidth(_defaultWidth)
236 {
237     width = _width;
238     brush = _brush;
239     style = penStyle;
240     capStyle = _capStyle;
241     joinStyle = _joinStyle;
242 }
243
244 static const Qt::PenCapStyle qpen_default_cap = Qt::SquareCap;
245 static const Qt::PenJoinStyle qpen_default_join = Qt::BevelJoin;
246
247 class QPenDataHolder
248 {
249 public:
250     QPenData *pen;
251     QPenDataHolder(const QBrush &brush, qreal width, Qt::PenStyle penStyle,
252                    Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle)
253         : pen(new QPenData(brush, width, penStyle, penCapStyle, _joinStyle))
254     { }
255     ~QPenDataHolder()
256     {
257         if (!pen->ref.deref())
258             delete pen;
259         pen = 0;
260     }
261 };
262
263 Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, defaultPenInstance,
264                           (Qt::black, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join))
265 Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance,
266                           (Qt::black, 1, Qt::NoPen, qpen_default_cap, qpen_default_join))
267
268 /*!
269     Constructs a default black solid line pen with 1 width.
270 */
271
272 QPen::QPen()
273 {
274     d = defaultPenInstance()->pen;
275     d->ref.ref();
276 }
277
278 /*!
279     Constructs a black pen with 1 width and the given \a style.
280
281     \sa setStyle()
282 */
283
284 QPen::QPen(Qt::PenStyle style)
285 {
286     if (style == Qt::NoPen) {
287         d = nullPenInstance()->pen;
288         d->ref.ref();
289     } else {
290         d = new QPenData(Qt::black, 1, style, qpen_default_cap, qpen_default_join);
291     }
292 }
293
294
295 /*!
296     Constructs a solid line pen with 1 width and the given \a color.
297
298     \sa setBrush(), setColor()
299 */
300
301 QPen::QPen(const QColor &color)
302 {
303     d = new QPenData(color, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join);
304 }
305
306
307 /*!
308     \fn QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle style, Qt::PenCapStyle cap, Qt::PenJoinStyle join)
309
310     Constructs a pen with the specified \a brush, \a width, pen \a style,
311     \a cap style and \a join style.
312
313     \sa setBrush(), setWidth(), setStyle(), setCapStyle(), setJoinStyle()
314 */
315
316 QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j)
317 {
318     d = new QPenData(brush, width, s, c, j, false);
319 }
320
321 /*!
322     \fn QPen::QPen(const QPen &pen)
323
324     Constructs a pen that is a copy of the given \a pen.
325 */
326
327 QPen::QPen(const QPen &p)
328 {
329     d = p.d;
330     d->ref.ref();
331 }
332
333
334 /*!
335     Destroys the pen.
336 */
337
338 QPen::~QPen()
339 {
340     if (!d->ref.deref())
341         delete d;
342 }
343
344 /*!
345     \fn void QPen::detach()
346     Detaches from shared pen data to make sure that this pen is the
347     only one referring the data.
348
349     If multiple pens share common data, this pen dereferences the data
350     and gets a copy of the data. Nothing is done if there is just a
351     single reference.
352 */
353
354 void QPen::detach()
355 {
356     if (d->ref.load() == 1)
357         return;
358
359     QPenData *x = new QPenData(*static_cast<QPenData *>(d));
360     if (!d->ref.deref())
361         delete d;
362     x->ref.store(1);
363     d = x;
364 }
365
366
367 /*!
368     \fn QPen &QPen::operator=(const QPen &pen)
369
370     Assigns the given \a pen to this pen and returns a reference to
371     this pen.
372 */
373
374 QPen &QPen::operator=(const QPen &p)
375 {
376     qAtomicAssign(d, p.d);
377     return *this;
378 }
379
380 /*!
381     \fn void QPen::swap(QPen &other)
382     \since 4.8
383
384     Swaps pen \a other with this pen. This operation is very
385     fast and never fails.
386 */
387
388 /*!
389    Returns the pen as a QVariant.
390 */
391 QPen::operator QVariant() const
392 {
393     return QVariant(QVariant::Pen, this);
394 }
395
396 /*!
397     \fn Qt::PenStyle QPen::style() const
398
399     Returns the pen style.
400
401     \sa setStyle(), {QPen#Pen Style}{Pen Style}
402 */
403 Qt::PenStyle QPen::style() const
404 {
405     return d->style;
406 }
407 /*!
408     \fn void QPen::setStyle(Qt::PenStyle style)
409
410     Sets the pen style to the given \a style.
411
412     See the \l Qt::PenStyle documentation for a list of the available
413     styles. Since Qt 4.1 it is also possible to specify a custom dash
414     pattern using the setDashPattern() function which implicitly
415     converts the style of the pen to Qt::CustomDashLine.
416
417     \note This function resets the dash offset to zero.
418
419     \sa style(), {QPen#Pen Style}{Pen Style}
420 */
421
422 void QPen::setStyle(Qt::PenStyle s)
423 {
424     if (d->style == s)
425         return;
426     detach();
427     d->style = s;
428     QPenData *dd = static_cast<QPenData *>(d);
429     dd->dashPattern.clear();
430     dd->dashOffset = 0;
431 }
432
433 /*!
434     Returns the dash pattern of this pen.
435
436     \sa style(), isSolid()
437  */
438 QVector<qreal> QPen::dashPattern() const
439 {
440     QPenData *dd = static_cast<QPenData *>(d);
441     if (d->style == Qt::SolidLine || d->style == Qt::NoPen) {
442         return QVector<qreal>();
443     } else if (dd->dashPattern.isEmpty()) {
444         const qreal space = 2;
445         const qreal dot = 1;
446         const qreal dash = 4;
447
448         switch (d->style) {
449         case Qt::DashLine:
450             dd->dashPattern << dash << space;
451             break;
452         case Qt::DotLine:
453             dd->dashPattern << dot << space;
454             break;
455         case Qt::DashDotLine:
456             dd->dashPattern << dash << space << dot << space;
457             break;
458         case Qt::DashDotDotLine:
459             dd->dashPattern << dash << space << dot << space << dot << space;
460             break;
461         default:
462             break;
463         }
464     }
465     return dd->dashPattern;
466 }
467
468 /*!
469     Sets the dash pattern for this pen to the given \a pattern. This
470     implicitly converts the style of the pen to Qt::CustomDashLine.
471
472     The pattern must be specified as an even number of positive entries
473     where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the
474     spaces. For example:
475
476     \table 100%
477     \row
478     \li \inlineimage qpen-custom.png
479     \li
480     \snippet code/src_gui_painting_qpen.cpp 3
481     \endtable
482
483     The dash pattern is specified in units of the pens width; e.g. a
484     dash of length 5 in width 10 is 50 pixels long. Note that a pen
485     with zero width is equivalent to a cosmetic pen with a width of 1
486     pixel.
487
488     Each dash is also subject to cap styles so a dash of 1 with square
489     cap set will extend 0.5 pixels out in each direction resulting in
490     a total width of 2.
491
492     Note that the default cap style is Qt::SquareCap, meaning that a
493     square line end covers the end point and extends beyond it by half
494     the line width.
495
496     \sa setStyle(), dashPattern(), setCapStyle(), setCosmetic()
497  */
498 void QPen::setDashPattern(const QVector<qreal> &pattern)
499 {
500     if (pattern.isEmpty())
501         return;
502     detach();
503
504     QPenData *dd = static_cast<QPenData *>(d);
505     dd->dashPattern = pattern;
506     d->style = Qt::CustomDashLine;
507
508     if ((dd->dashPattern.size() % 2) == 1) {
509         qWarning("QPen::setDashPattern: Pattern not of even length");
510         dd->dashPattern << 1;
511     }
512 }
513
514
515 /*!
516     Returns the dash offset for the pen.
517
518     \sa setDashOffset()
519 */
520 qreal QPen::dashOffset() const
521 {
522     QPenData *dd = static_cast<QPenData *>(d);
523     return dd->dashOffset;
524 }
525 /*!
526     Sets the dash offset (the starting point on the dash pattern) for this pen
527     to the \a offset specified. The offset is measured in terms of the units used
528     to specify the dash pattern.
529
530     \table
531     \row \li \inlineimage qpen-dashpattern.png
532     \li For example, a pattern where each stroke is four units long, followed by a gap
533     of two units, will begin with the stroke when drawn as a line.
534
535     However, if the dash offset is set to 4.0, any line drawn will begin with the gap.
536     Values of the offset up to 4.0 will cause part of the stroke to be drawn first,
537     and values of the offset between 4.0 and 6.0 will cause the line to begin with
538     part of the gap.
539     \endtable
540
541     \note This implicitly converts the style of the pen to Qt::CustomDashLine.
542 */
543 void QPen::setDashOffset(qreal offset)
544 {
545     if (qFuzzyCompare(offset, static_cast<QPenData *>(d)->dashOffset))
546         return;
547     detach();
548     QPenData *dd = static_cast<QPenData *>(d);
549     dd->dashOffset = offset;
550     if (d->style != Qt::CustomDashLine) {
551         dd->dashPattern = dashPattern();
552         d->style = Qt::CustomDashLine;
553     }
554 }
555
556 /*!
557     Returns the miter limit of the pen. The miter limit is only
558     relevant when the join style is set to Qt::MiterJoin.
559
560     \sa setMiterLimit(), {QPen#Join Style}{Join Style}
561 */
562 qreal QPen::miterLimit() const
563 {
564     const QPenData *dd = static_cast<QPenData *>(d);
565     return dd->miterLimit;
566 }
567
568 /*!
569     Sets the miter limit of this pen to the given \a limit.
570
571     \image qpen-miterlimit.png
572
573     The miter limit describes how far a miter join can extend from the
574     join point. This is used to reduce artifacts between line joins
575     where the lines are close to parallel.
576
577     This value does only have effect when the pen style is set to
578     Qt::MiterJoin. The value is specified in units of the pen's width,
579     e.g. a miter limit of 5 in width 10 is 50 pixels long. The default
580     miter limit is 2, i.e. twice the pen width in pixels.
581
582     \sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style}
583 */
584 void QPen::setMiterLimit(qreal limit)
585 {
586     detach();
587     QPenData *dd = static_cast<QPenData *>(d);
588     dd->miterLimit = limit;
589 }
590
591
592 /*!
593     \fn qreal QPen::width() const
594
595     Returns the pen width with integer precision.
596
597     \sa setWidth(), widthF()
598 */
599
600 int QPen::width() const
601 {
602     return qRound(d->width);
603 }
604
605 /*!
606     \fn qreal QPen::widthF() const
607
608     Returns the pen width with floating point precision.
609
610     \sa setWidthF(), width()
611 */
612 qreal QPen::widthF() const
613 {
614     return d->width;
615 }
616
617 /*!
618     \fn QPen::setWidth(int width)
619
620     Sets the pen width to the given \a width in pixels with integer
621     precision.
622
623     A line width of zero indicates a cosmetic pen. This means that the
624     pen width is always drawn one pixel wide, independent of the \l
625     {QPainter#Coordinate Transformations}{transformation} set on the
626     painter.
627
628     Setting a pen width with a negative value is not supported.
629
630     \sa setWidthF(), width()
631 */
632 void QPen::setWidth(int width)
633 {
634     if (width < 0)
635         qWarning("QPen::setWidth: Setting a pen width with a negative value is not defined");
636     if ((qreal)width == d->width)
637         return;
638     detach();
639     d->width = width;
640 }
641
642 /*!
643     Sets the pen width to the given \a width in pixels with floating point
644     precision.
645
646     A line width of zero indicates a cosmetic pen. This means that the
647     pen width is always drawn one pixel wide, independent of the \l
648     {QPainter#Coordinate Transformations}{transformation} on the
649     painter.
650
651     Setting a pen width with a negative value is not supported.
652
653     \sa setWidth(), widthF()
654 */
655
656 void QPen::setWidthF(qreal width)
657 {
658     if (width < 0.f) {
659         qWarning("QPen::setWidthF: Setting a pen width with a negative value is not defined");
660         return;
661     }
662     if (qAbs(d->width - width) < 0.00000001f)
663         return;
664     detach();
665     d->width = width;
666     d->defaultWidth = false;
667 }
668
669
670 /*!
671     Returns the pen's cap style.
672
673     \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
674 */
675 Qt::PenCapStyle QPen::capStyle() const
676 {
677     return d->capStyle;
678 }
679
680 /*!
681     \fn void QPen::setCapStyle(Qt::PenCapStyle style)
682
683     Sets the pen's cap style to the given \a style. The default value
684     is Qt::SquareCap.
685
686     \sa capStyle(), {QPen#Cap Style}{Cap Style}
687 */
688
689 void QPen::setCapStyle(Qt::PenCapStyle c)
690 {
691     if (d->capStyle == c)
692         return;
693     detach();
694     d->capStyle = c;
695 }
696
697 /*!
698     Returns the pen's join style.
699
700     \sa setJoinStyle(), {QPen#Join Style}{Join Style}
701 */
702 Qt::PenJoinStyle QPen::joinStyle() const
703 {
704     return d->joinStyle;
705 }
706
707 /*!
708     \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
709
710     Sets the pen's join style to the given \a style. The default value
711     is Qt::BevelJoin.
712
713     \sa joinStyle(), {QPen#Join Style}{Join Style}
714 */
715
716 void QPen::setJoinStyle(Qt::PenJoinStyle j)
717 {
718     if (d->joinStyle == j)
719         return;
720     detach();
721     d->joinStyle = j;
722 }
723
724 /*!
725     \fn const QColor &QPen::color() const
726
727     Returns the color of this pen's brush.
728
729     \sa brush(), setColor()
730 */
731 QColor QPen::color() const
732 {
733     return d->brush.color();
734 }
735
736 /*!
737     \fn void QPen::setColor(const QColor &color)
738
739     Sets the color of this pen's brush to the given \a color.
740
741     \sa setBrush(), color()
742 */
743
744 void QPen::setColor(const QColor &c)
745 {
746     detach();
747     d->brush = QBrush(c);
748 }
749
750
751 /*!
752     Returns the brush used to fill strokes generated with this pen.
753 */
754 QBrush QPen::brush() const
755 {
756     return d->brush;
757 }
758
759 /*!
760     Sets the brush used to fill strokes generated with this pen to the given
761     \a brush.
762
763     \sa brush(), setColor()
764 */
765 void QPen::setBrush(const QBrush &brush)
766 {
767     detach();
768     d->brush = brush;
769 }
770
771
772 /*!
773     Returns true if the pen has a solid fill, otherwise false.
774
775     \sa style(), dashPattern()
776 */
777 bool QPen::isSolid() const
778 {
779     return d->brush.style() == Qt::SolidPattern;
780 }
781
782
783 /*!
784     Returns true if the pen is cosmetic; otherwise returns false.
785
786     Cosmetic pens are used to draw strokes that have a constant width
787     regardless of any transformations applied to the QPainter they are
788     used with. Drawing a shape with a cosmetic pen ensures that its
789     outline will have the same thickness at different scale factors.
790
791     A zero width pen is cosmetic by default.
792
793     \sa setCosmetic(), widthF()
794 */
795
796 bool QPen::isCosmetic() const
797 {
798     QPenData *dd = static_cast<QPenData *>(d);
799     return (dd->cosmetic == true) || d->width == 0;
800 }
801
802
803 /*!
804     Sets this pen to cosmetic or non-cosmetic, depending on the value of
805     \a cosmetic.
806
807     \sa isCosmetic()
808 */
809
810 void QPen::setCosmetic(bool cosmetic)
811 {
812     detach();
813     QPenData *dd = static_cast<QPenData *>(d);
814     dd->cosmetic = cosmetic;
815 }
816
817
818
819 /*!
820     \fn bool QPen::operator!=(const QPen &pen) const
821
822     Returns true if the pen is different from the given \a pen;
823     otherwise false. Two pens are different if they have different
824     styles, widths or colors.
825
826     \sa operator==()
827 */
828
829 /*!
830     \fn bool QPen::operator==(const QPen &pen) const
831
832     Returns true if the pen is equal to the given \a pen; otherwise
833     false. Two pens are equal if they have equal styles, widths and
834     colors.
835
836     \sa operator!=()
837 */
838
839 bool QPen::operator==(const QPen &p) const
840 {
841     QPenData *dd = static_cast<QPenData *>(d);
842     QPenData *pdd = static_cast<QPenData *>(p.d);
843     return (p.d == d)
844         || (p.d->style == d->style
845             && p.d->capStyle == d->capStyle
846             && p.d->joinStyle == d->joinStyle
847             && p.d->width == d->width
848             && pdd->miterLimit == dd->miterLimit
849             && (d->style != Qt::CustomDashLine
850                 || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
851                     pdd->dashPattern == dd->dashPattern))
852             && p.d->brush == d->brush
853             && pdd->cosmetic == dd->cosmetic
854             && pdd->defaultWidth == dd->defaultWidth);
855 }
856
857
858 /*!
859     \fn bool QPen::isDetached()
860
861     \internal
862 */
863
864 bool QPen::isDetached()
865 {
866     return d->ref.load() == 1;
867 }
868
869
870 /*****************************************************************************
871   QPen stream functions
872  *****************************************************************************/
873 #ifndef QT_NO_DATASTREAM
874 /*!
875     \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
876     \relates QPen
877
878     Writes the given \a pen to the given \a stream and returns a reference to
879     the \a stream.
880
881     \sa {Serializing Qt Data Types}
882 */
883
884 QDataStream &operator<<(QDataStream &s, const QPen &p)
885 {
886     QPenData *dd = static_cast<QPenData *>(p.d);
887     if (s.version() < 3) {
888         s << (quint8)p.style();
889     } else if (s.version() < QDataStream::Qt_4_3) {
890         s << (quint8)(p.style() | p.capStyle() | p.joinStyle());
891     } else {
892         s << (quint16)(p.style() | p.capStyle() | p.joinStyle());
893         s << (bool)(dd->cosmetic);
894     }
895
896     if (s.version() < 7) {
897         s << (quint8)p.width();
898         s << p.color();
899     } else {
900         s << double(p.widthF());
901         s << p.brush();
902         s << double(p.miterLimit());
903         if (sizeof(qreal) == sizeof(double)) {
904             s << p.dashPattern();
905         } else {
906             // ensure that we write doubles here instead of streaming the pattern
907             // directly; otherwise, platforms that redefine qreal might generate
908             // data that cannot be read on other platforms.
909             QVector<qreal> pattern = p.dashPattern();
910             s << quint32(pattern.size());
911             for (int i = 0; i < pattern.size(); ++i)
912                 s << double(pattern.at(i));
913         }
914         if (s.version() >= 9)
915             s << double(p.dashOffset());
916         if (s.version() >= QDataStream::Qt_5_0)
917             s << bool(dd->defaultWidth);
918     }
919     return s;
920 }
921
922 /*!
923     \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
924     \relates QPen
925
926     Reads a pen from the given \a stream into the given \a pen and
927     returns a reference to the \a stream.
928
929     \sa {Serializing Qt Data Types}
930 */
931
932 QDataStream &operator>>(QDataStream &s, QPen &p)
933 {
934     quint16 style;
935     quint8 width8 = 0;
936     double width = 0;
937     QColor color;
938     QBrush brush;
939     double miterLimit = 2;
940     QVector<qreal> dashPattern;
941     double dashOffset = 0;
942     bool cosmetic = false;
943     bool defaultWidth = false;
944     if (s.version() < QDataStream::Qt_4_3) {
945         quint8 style8;
946         s >> style8;
947         style = style8;
948     } else {
949         s >> style;
950         s >> cosmetic;
951     }
952     if (s.version() < 7) {
953         s >> width8;
954         s >> color;
955         brush = color;
956         width = width8;
957     } else {
958         s >> width;
959         s >> brush;
960         s >> miterLimit;
961         if (sizeof(qreal) == sizeof(double)) {
962             s >> dashPattern;
963         } else {
964             quint32 numDashes;
965             s >> numDashes;
966             double dash;
967             for (quint32 i = 0; i < numDashes; ++i) {
968                 s >> dash;
969                 dashPattern << dash;
970             }
971         }
972         if (s.version() >= 9)
973             s >> dashOffset;
974     }
975
976     if (s.version() >= QDataStream::Qt_5_0) {
977         s >> defaultWidth;
978     } else {
979         // best we can do for legacy pens
980         defaultWidth = qFuzzyIsNull(width);
981     }
982
983     p.detach();
984     QPenData *dd = static_cast<QPenData *>(p.d);
985     dd->width = width;
986     dd->brush = brush;
987     dd->style = Qt::PenStyle(style & Qt::MPenStyle);
988     dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
989     dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
990     dd->dashPattern = dashPattern;
991     dd->miterLimit = miterLimit;
992     dd->dashOffset = dashOffset;
993     dd->cosmetic = cosmetic;
994     dd->defaultWidth = defaultWidth;
995
996     return s;
997 }
998 #endif //QT_NO_DATASTREAM
999
1000 #ifndef QT_NO_DEBUG_STREAM
1001 QDebug operator<<(QDebug dbg, const QPen &p)
1002 {
1003     const char *PEN_STYLES[] = {
1004         "NoPen",
1005         "SolidLine",
1006         "DashLine",
1007         "DotLine",
1008         "DashDotLine",
1009         "DashDotDotLine",
1010         "CustomDashLine"
1011     };
1012
1013     dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
1014                   << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
1015                   << ',' << int(p.joinStyle()) << ',' << p.dashPattern()
1016                   << ',' << p.dashOffset()
1017                   << ',' << p.miterLimit() << ')';
1018     return dbg.space();
1019 }
1020 #endif
1021
1022 /*!
1023     \fn DataPtr &QPen::data_ptr()
1024     \internal
1025 */
1026
1027 /*!
1028     \typedef QPen::DataPtr
1029
1030     \internal
1031 */
1032
1033 QT_END_NAMESPACE
1034
1035 #undef QT_COMPILING_QPEN