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