Merge remote branch 'gerrit/master' into refactor
[profile/ivi/qtbase.git] / src / gui / painting / qpen.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #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     : dashOffset(0), miterLimit(2),
234       cosmetic(false)
235 {
236     ref = 1;
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 == 1)
357         return;
358
359     QPenData *x = new QPenData(*static_cast<QPenData *>(d));
360     if (!d->ref.deref())
361         delete d;
362     x->ref = 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     \o \inlineimage qpen-custom.png
479     \o
480     \snippet doc/src/snippets/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 \o \inlineimage qpen-dashpattern.png
532     \o 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 == 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 #ifndef Q_BROKEN_DEBUG_STREAM
990     const char *PEN_STYLES[] = {
991         "NoPen",
992         "SolidLine",
993         "DashLine",
994         "DotLine",
995         "DashDotLine",
996         "DashDotDotLine",
997         "CustomDashLine"
998     };
999
1000     dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
1001                   << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
1002                   << ',' << int(p.joinStyle()) << ',' << p.dashPattern()
1003                   << ',' << p.dashOffset()
1004                   << ',' << p.miterLimit() << ')';
1005     return dbg.space();
1006 #else
1007     qWarning("This compiler doesn't support streaming QPen to QDebug");
1008     return dbg;
1009     Q_UNUSED(p);
1010 #endif
1011 }
1012 #endif
1013
1014 /*!
1015     \fn DataPtr &QPen::data_ptr()
1016     \internal
1017 */
1018
1019 /*!
1020     \typedef QPen::DataPtr
1021
1022     \internal
1023 */
1024
1025 QT_END_NAMESPACE
1026
1027 #undef QT_COMPILING_QPEN