d86a5f0392185247a2d21d954dcf40c3001d21ce
[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 0 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)
234     : ref(1), dashOffset(0), miterLimit(2),
235       cosmetic(false)
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, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join))
265 Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance,
266                           (Qt::black, 0, Qt::NoPen, qpen_default_cap, qpen_default_join))
267
268 /*!
269     Constructs a default black solid line pen with 0 width.
270 */
271
272 QPen::QPen()
273 {
274     d = defaultPenInstance()->pen;
275     d->ref.ref();
276 }
277
278 /*!
279     Constructs a black pen with 0 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, 0, style, qpen_default_cap, qpen_default_join);
291     }
292 }
293
294
295 /*!
296     Constructs a solid line pen with 0 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, 0, 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);
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     if (qAbs(d->width - width) < 0.00000001f)
661         return;
662     detach();
663     d->width = width;
664 }
665
666
667 /*!
668     Returns the pen's cap style.
669
670     \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
671 */
672 Qt::PenCapStyle QPen::capStyle() const
673 {
674     return d->capStyle;
675 }
676
677 /*!
678     \fn void QPen::setCapStyle(Qt::PenCapStyle style)
679
680     Sets the pen's cap style to the given \a style. The default value
681     is Qt::SquareCap.
682
683     \sa capStyle(), {QPen#Cap Style}{Cap Style}
684 */
685
686 void QPen::setCapStyle(Qt::PenCapStyle c)
687 {
688     if (d->capStyle == c)
689         return;
690     detach();
691     d->capStyle = c;
692 }
693
694 /*!
695     Returns the pen's join style.
696
697     \sa setJoinStyle(), {QPen#Join Style}{Join Style}
698 */
699 Qt::PenJoinStyle QPen::joinStyle() const
700 {
701     return d->joinStyle;
702 }
703
704 /*!
705     \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
706
707     Sets the pen's join style to the given \a style. The default value
708     is Qt::BevelJoin.
709
710     \sa joinStyle(), {QPen#Join Style}{Join Style}
711 */
712
713 void QPen::setJoinStyle(Qt::PenJoinStyle j)
714 {
715     if (d->joinStyle == j)
716         return;
717     detach();
718     d->joinStyle = j;
719 }
720
721 /*!
722     \fn const QColor &QPen::color() const
723
724     Returns the color of this pen's brush.
725
726     \sa brush(), setColor()
727 */
728 QColor QPen::color() const
729 {
730     return d->brush.color();
731 }
732
733 /*!
734     \fn void QPen::setColor(const QColor &color)
735
736     Sets the color of this pen's brush to the given \a color.
737
738     \sa setBrush(), color()
739 */
740
741 void QPen::setColor(const QColor &c)
742 {
743     detach();
744     d->brush = QBrush(c);
745 }
746
747
748 /*!
749     Returns the brush used to fill strokes generated with this pen.
750 */
751 QBrush QPen::brush() const
752 {
753     return d->brush;
754 }
755
756 /*!
757     Sets the brush used to fill strokes generated with this pen to the given
758     \a brush.
759
760     \sa brush(), setColor()
761 */
762 void QPen::setBrush(const QBrush &brush)
763 {
764     detach();
765     d->brush = brush;
766 }
767
768
769 /*!
770     Returns true if the pen has a solid fill, otherwise false.
771
772     \sa style(), dashPattern()
773 */
774 bool QPen::isSolid() const
775 {
776     return d->brush.style() == Qt::SolidPattern;
777 }
778
779
780 /*!
781     Returns true if the pen is cosmetic; otherwise returns false.
782
783     Cosmetic pens are used to draw strokes that have a constant width
784     regardless of any transformations applied to the QPainter they are
785     used with. Drawing a shape with a cosmetic pen ensures that its
786     outline will have the same thickness at different scale factors.
787
788     A zero width pen is cosmetic by default; pens with a non-zero width
789     are non-cosmetic.
790
791     \sa setCosmetic(), widthF()
792 */
793
794 bool QPen::isCosmetic() const
795 {
796     QPenData *dd = static_cast<QPenData *>(d);
797     return (dd->cosmetic == true) || d->width == 0;
798 }
799
800
801 /*!
802     Sets this pen to cosmetic or non-cosmetic, depending on the value of
803     \a cosmetic.
804
805     \sa isCosmetic()
806 */
807
808 void QPen::setCosmetic(bool cosmetic)
809 {
810     detach();
811     QPenData *dd = static_cast<QPenData *>(d);
812     dd->cosmetic = cosmetic;
813 }
814
815
816
817 /*!
818     \fn bool QPen::operator!=(const QPen &pen) const
819
820     Returns true if the pen is different from the given \a pen;
821     otherwise false. Two pens are different if they have different
822     styles, widths or colors.
823
824     \sa operator==()
825 */
826
827 /*!
828     \fn bool QPen::operator==(const QPen &pen) const
829
830     Returns true if the pen is equal to the given \a pen; otherwise
831     false. Two pens are equal if they have equal styles, widths and
832     colors.
833
834     \sa operator!=()
835 */
836
837 bool QPen::operator==(const QPen &p) const
838 {
839     QPenData *dd = static_cast<QPenData *>(d);
840     QPenData *pdd = static_cast<QPenData *>(p.d);
841     return (p.d == d)
842         || (p.d->style == d->style
843             && p.d->capStyle == d->capStyle
844             && p.d->joinStyle == d->joinStyle
845             && p.d->width == d->width
846             && pdd->miterLimit == dd->miterLimit
847             && (d->style != Qt::CustomDashLine
848                 || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
849                     pdd->dashPattern == dd->dashPattern))
850             && p.d->brush == d->brush
851             && pdd->cosmetic == dd->cosmetic);
852 }
853
854
855 /*!
856     \fn bool QPen::isDetached()
857
858     \internal
859 */
860
861 bool QPen::isDetached()
862 {
863     return d->ref.load() == 1;
864 }
865
866
867 /*****************************************************************************
868   QPen stream functions
869  *****************************************************************************/
870 #ifndef QT_NO_DATASTREAM
871 /*!
872     \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
873     \relates QPen
874
875     Writes the given \a pen to the given \a stream and returns a reference to
876     the \a stream.
877
878     \sa {Serializing Qt Data Types}
879 */
880
881 QDataStream &operator<<(QDataStream &s, const QPen &p)
882 {
883     QPenData *dd = static_cast<QPenData *>(p.d);
884     if (s.version() < 3) {
885         s << (quint8)p.style();
886     } else if (s.version() < QDataStream::Qt_4_3) {
887         s << (quint8)(p.style() | p.capStyle() | p.joinStyle());
888     } else {
889         s << (quint16)(p.style() | p.capStyle() | p.joinStyle());
890         s << (bool)(dd->cosmetic);
891     }
892
893     if (s.version() < 7) {
894         s << (quint8)p.width();
895         s << p.color();
896     } else {
897         s << double(p.widthF());
898         s << p.brush();
899         s << double(p.miterLimit());
900         if (sizeof(qreal) == sizeof(double)) {
901             s << p.dashPattern();
902         } else {
903             // ensure that we write doubles here instead of streaming the pattern
904             // directly; otherwise, platforms that redefine qreal might generate
905             // data that cannot be read on other platforms.
906             QVector<qreal> pattern = p.dashPattern();
907             s << quint32(pattern.size());
908             for (int i = 0; i < pattern.size(); ++i)
909                 s << double(pattern.at(i));
910         }
911         if (s.version() >= 9)
912             s << double(p.dashOffset());
913     }
914     return s;
915 }
916
917 /*!
918     \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
919     \relates QPen
920
921     Reads a pen from the given \a stream into the given \a pen and
922     returns a reference to the \a stream.
923
924     \sa {Serializing Qt Data Types}
925 */
926
927 QDataStream &operator>>(QDataStream &s, QPen &p)
928 {
929     quint16 style;
930     quint8 width8 = 0;
931     double width = 0;
932     QColor color;
933     QBrush brush;
934     double miterLimit = 2;
935     QVector<qreal> dashPattern;
936     double dashOffset = 0;
937     bool cosmetic = false;
938     if (s.version() < QDataStream::Qt_4_3) {
939         quint8 style8;
940         s >> style8;
941         style = style8;
942     } else {
943         s >> style;
944         s >> cosmetic;
945     }
946     if (s.version() < 7) {
947         s >> width8;
948         s >> color;
949         brush = color;
950         width = width8;
951     } else {
952         s >> width;
953         s >> brush;
954         s >> miterLimit;
955         if (sizeof(qreal) == sizeof(double)) {
956             s >> dashPattern;
957         } else {
958             quint32 numDashes;
959             s >> numDashes;
960             double dash;
961             for (quint32 i = 0; i < numDashes; ++i) {
962                 s >> dash;
963                 dashPattern << dash;
964             }
965         }
966         if (s.version() >= 9)
967             s >> dashOffset;
968     }
969
970     p.detach();
971     QPenData *dd = static_cast<QPenData *>(p.d);
972     dd->width = width;
973     dd->brush = brush;
974     dd->style = Qt::PenStyle(style & Qt::MPenStyle);
975     dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
976     dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
977     dd->dashPattern = dashPattern;
978     dd->miterLimit = miterLimit;
979     dd->dashOffset = dashOffset;
980     dd->cosmetic = cosmetic;
981
982     return s;
983 }
984 #endif //QT_NO_DATASTREAM
985
986 #ifndef QT_NO_DEBUG_STREAM
987 QDebug operator<<(QDebug dbg, const QPen &p)
988 {
989     const char *PEN_STYLES[] = {
990         "NoPen",
991         "SolidLine",
992         "DashLine",
993         "DotLine",
994         "DashDotLine",
995         "DashDotDotLine",
996         "CustomDashLine"
997     };
998
999     dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
1000                   << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
1001                   << ',' << int(p.joinStyle()) << ',' << p.dashPattern()
1002                   << ',' << p.dashOffset()
1003                   << ',' << p.miterLimit() << ')';
1004     return dbg.space();
1005 }
1006 #endif
1007
1008 /*!
1009     \fn DataPtr &QPen::data_ptr()
1010     \internal
1011 */
1012
1013 /*!
1014     \typedef QPen::DataPtr
1015
1016     \internal
1017 */
1018
1019 QT_END_NAMESPACE
1020
1021 #undef QT_COMPILING_QPEN