1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
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 The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
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 {demos/pathstroke}{The Path Stroking Demo}}
218 
219     The Path Stroking demo 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, {demos/pathstroke}{Path Stroking Demo},
225         {Scribble Example}
226 */
227 
228 /*!
229   \internal
230 */
QPenPrivate(const QBrush & _brush,qreal _width,Qt::PenStyle penStyle,Qt::PenCapStyle _capStyle,Qt::PenJoinStyle _joinStyle)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 #ifndef QT_NO_THREAD
248 // Special deleter that only deletes if the ref-count goes to zero
249 template <>
250 class QGlobalStaticDeleter<QPenPrivate>
251 {
252 public:
253     QGlobalStatic<QPenPrivate> &globalStatic;
QGlobalStaticDeleter(QGlobalStatic<QPenPrivate> & _globalStatic)254     QGlobalStaticDeleter(QGlobalStatic<QPenPrivate> &_globalStatic)
255         : globalStatic(_globalStatic)
256     { }
257 
~QGlobalStaticDeleter()258     inline ~QGlobalStaticDeleter()
259     {
260         if (!globalStatic.pointer->ref.deref())
261             delete globalStatic.pointer;
262         globalStatic.pointer = 0;
263         globalStatic.destroyed = true;
264     }
265 };
266 #endif
267 
268 Q_GLOBAL_STATIC_WITH_ARGS(QPenData, defaultPenInstance,
269                           (Qt::black, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join))
270 Q_GLOBAL_STATIC_WITH_ARGS(QPenData, nullPenInstance,
271                           (Qt::black, 0, Qt::NoPen, qpen_default_cap, qpen_default_join))
272 
273 /*!
274     Constructs a default black solid line pen with 0 width.
275 */
276 
QPen()277 QPen::QPen()
278 {
279     d = defaultPenInstance();
280     d->ref.ref();
281 }
282 
283 /*!
284     Constructs a black pen with 0 width and the given \a style.
285 
286     \sa setStyle()
287 */
288 
QPen(Qt::PenStyle style)289 QPen::QPen(Qt::PenStyle style)
290 {
291     if (style == Qt::NoPen) {
292         d = nullPenInstance();
293         d->ref.ref();
294     } else {
295         d = new QPenData(Qt::black, 0, style, qpen_default_cap, qpen_default_join);
296     }
297 }
298 
299 
300 /*!
301     Constructs a solid line pen with 0 width and the given \a color.
302 
303     \sa setBrush(), setColor()
304 */
305 
QPen(const QColor & color)306 QPen::QPen(const QColor &color)
307 {
308     d = new QPenData(color, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join);
309 }
310 
311 
312 /*!
313     \fn QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle style, Qt::PenCapStyle cap, Qt::PenJoinStyle join)
314 
315     Constructs a pen with the specified \a brush, \a width, pen \a style,
316     \a cap style and \a join style.
317 
318     \sa setBrush(), setWidth(), setStyle(),  setCapStyle(), setJoinStyle()
319 */
320 
QPen(const QBrush & brush,qreal width,Qt::PenStyle s,Qt::PenCapStyle c,Qt::PenJoinStyle j)321 QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j)
322 {
323     d = new QPenData(brush, width, s, c, j);
324 }
325 
326 /*!
327     \fn QPen::QPen(const QPen &pen)
328 
329     Constructs a pen that is a copy of the given \a pen.
330 */
331 
QPen(const QPen & p)332 QPen::QPen(const QPen &p)
333 {
334     d = p.d;
335     d->ref.ref();
336 }
337 
338 
339 /*!
340     Destroys the pen.
341 */
342 
~QPen()343 QPen::~QPen()
344 {
345     if (!d->ref.deref())
346         delete d;
347 }
348 
349 /*!
350     \fn void QPen::detach()
351     Detaches from shared pen data to make sure that this pen is the
352     only one referring the data.
353 
354     If multiple pens share common data, this pen dereferences the data
355     and gets a copy of the data. Nothing is done if there is just a
356     single reference.
357 */
358 
detach()359 void QPen::detach()
360 {
361     if (d->ref == 1)
362         return;
363 
364     QPenData *x = new QPenData(*static_cast<QPenData *>(d));
365     if (!d->ref.deref())
366         delete d;
367     x->ref = 1;
368     d = x;
369 }
370 
371 
372 /*!
373     \fn QPen &QPen::operator=(const QPen &pen)
374 
375     Assigns the given \a pen to this pen and returns a reference to
376     this pen.
377 */
378 
operator =(const QPen & p)379 QPen &QPen::operator=(const QPen &p)
380 {
381     qAtomicAssign(d, p.d);
382     return *this;
383 }
384 
385 /*!
386     \fn void QPen::swap(QPen &other)
387     \since 4.8
388 
389     Swaps pen \a other with this pen. This operation is very
390     fast and never fails.
391 */
392 
393 /*!
394    Returns the pen as a QVariant.
395 */
operator QVariant() const396 QPen::operator QVariant() const
397 {
398     return QVariant(QVariant::Pen, this);
399 }
400 
401 /*!
402     \fn Qt::PenStyle QPen::style() const
403 
404     Returns the pen style.
405 
406     \sa setStyle(), {QPen#Pen Style}{Pen Style}
407 */
style() const408 Qt::PenStyle QPen::style() const
409 {
410     return d->style;
411 }
412 /*!
413     \fn void QPen::setStyle(Qt::PenStyle style)
414 
415     Sets the pen style to the given \a style.
416 
417     See the \l Qt::PenStyle documentation for a list of the available
418     styles. Since Qt 4.1 it is also possible to specify a custom dash
419     pattern using the setDashPattern() function which implicitly
420     converts the style of the pen to Qt::CustomDashLine.
421 
422     \note This function resets the dash offset to zero.
423 
424     \sa style(), {QPen#Pen Style}{Pen Style}
425 */
426 
setStyle(Qt::PenStyle s)427 void QPen::setStyle(Qt::PenStyle s)
428 {
429     if (d->style == s)
430         return;
431     detach();
432     d->style = s;
433     QPenData *dd = static_cast<QPenData *>(d);
434     dd->dashPattern.clear();
435     dd->dashOffset = 0;
436 }
437 
438 /*!
439     Returns the dash pattern of this pen.
440 
441     \sa style(), isSolid()
442  */
dashPattern() const443 QVector<qreal> QPen::dashPattern() const
444 {
445     QPenData *dd = static_cast<QPenData *>(d);
446     if (d->style == Qt::SolidLine || d->style == Qt::NoPen) {
447         return QVector<qreal>();
448     } else if (dd->dashPattern.isEmpty()) {
449         const qreal space = 2;
450         const qreal dot = 1;
451         const qreal dash = 4;
452 
453         switch (d->style) {
454         case Qt::DashLine:
455             dd->dashPattern << dash << space;
456             break;
457         case Qt::DotLine:
458             dd->dashPattern << dot << space;
459             break;
460         case Qt::DashDotLine:
461             dd->dashPattern << dash << space << dot << space;
462             break;
463         case Qt::DashDotDotLine:
464             dd->dashPattern << dash << space << dot << space << dot << space;
465             break;
466         default:
467             break;
468         }
469     }
470     return dd->dashPattern;
471 }
472 
473 /*!
474     Sets the dash pattern for this pen to the given \a pattern. This
475     implicitly converts the style of the pen to Qt::CustomDashLine.
476 
477     The pattern must be specified as an even number of positive entries
478     where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the
479     spaces. For example:
480 
481     \table 100%
482     \row
483     \o \inlineimage qpen-custom.png
484     \o
485     \snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 3
486     \endtable
487 
488     The dash pattern is specified in units of the pens width; e.g. a
489     dash of length 5 in width 10 is 50 pixels long. Note that a pen
490     with zero width is equivalent to a cosmetic pen with a width of 1
491     pixel.
492 
493     Each dash is also subject to cap styles so a dash of 1 with square
494     cap set will extend 0.5 pixels out in each direction resulting in
495     a total width of 2.
496 
497     Note that the default cap style is Qt::SquareCap, meaning that a
498     square line end covers the end point and extends beyond it by half
499     the line width.
500 
501     \sa setStyle(), dashPattern(), setCapStyle(), setCosmetic()
502  */
setDashPattern(const QVector<qreal> & pattern)503 void QPen::setDashPattern(const QVector<qreal> &pattern)
504 {
505     if (pattern.isEmpty())
506         return;
507     detach();
508 
509     QPenData *dd = static_cast<QPenData *>(d);
510     dd->dashPattern = pattern;
511     d->style = Qt::CustomDashLine;
512 
513     if ((dd->dashPattern.size() % 2) == 1) {
514         qWarning("QPen::setDashPattern: Pattern not of even length");
515         dd->dashPattern << 1;
516     }
517 }
518 
519 
520 /*!
521     Returns the dash offset for the pen.
522 
523     \sa setDashOffset()
524 */
dashOffset() const525 qreal QPen::dashOffset() const
526 {
527     QPenData *dd = static_cast<QPenData *>(d);
528     return dd->dashOffset;
529 }
530 /*!
531     Sets the dash offset (the starting point on the dash pattern) for this pen
532     to the \a offset specified. The offset is measured in terms of the units used
533     to specify the dash pattern.
534 
535     \table
536     \row \o \inlineimage qpen-dashpattern.png
537     \o For example, a pattern where each stroke is four units long, followed by a gap
538     of two units, will begin with the stroke when drawn as a line.
539 
540     However, if the dash offset is set to 4.0, any line drawn will begin with the gap.
541     Values of the offset up to 4.0 will cause part of the stroke to be drawn first,
542     and values of the offset between 4.0 and 6.0 will cause the line to begin with
543     part of the gap.
544     \endtable
545 
546     \note This implicitly converts the style of the pen to Qt::CustomDashLine.
547 */
setDashOffset(qreal offset)548 void QPen::setDashOffset(qreal offset)
549 {
550     if (qFuzzyCompare(offset, static_cast<QPenData *>(d)->dashOffset))
551         return;
552     detach();
553     QPenData *dd = static_cast<QPenData *>(d);
554     dd->dashOffset = offset;
555     if (d->style != Qt::CustomDashLine) {
556         dd->dashPattern = dashPattern();
557         d->style = Qt::CustomDashLine;
558     }
559 }
560 
561 /*!
562     Returns the miter limit of the pen. The miter limit is only
563     relevant when the join style is set to Qt::MiterJoin.
564 
565     \sa setMiterLimit(),  {QPen#Join Style}{Join Style}
566 */
miterLimit() const567 qreal QPen::miterLimit() const
568 {
569     const QPenData *dd = static_cast<QPenData *>(d);
570     return dd->miterLimit;
571 }
572 
573 /*!
574     Sets the miter limit of this pen to the given \a limit.
575 
576     \image qpen-miterlimit.png
577 
578     The miter limit describes how far a miter join can extend from the
579     join point. This is used to reduce artifacts between line joins
580     where the lines are close to parallel.
581 
582     This value does only have effect when the pen style is set to
583     Qt::MiterJoin. The value is specified in units of the pen's width,
584     e.g. a miter limit of 5 in width 10 is 50 pixels long. The default
585     miter limit is 2, i.e. twice the pen width in pixels.
586 
587     \sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style}
588 */
setMiterLimit(qreal limit)589 void QPen::setMiterLimit(qreal limit)
590 {
591     detach();
592     QPenData *dd = static_cast<QPenData *>(d);
593     dd->miterLimit = limit;
594 }
595 
596 
597 /*!
598     \fn qreal QPen::width() const
599 
600     Returns the pen width with integer precision.
601 
602     \sa setWidth(), widthF()
603 */
604 
width() const605 int QPen::width() const
606 {
607     return qRound(d->width);
608 }
609 
610 /*!
611     \fn qreal QPen::widthF() const
612 
613     Returns the pen width with floating point precision.
614 
615     \sa setWidthF() width()
616 */
widthF() const617 qreal QPen::widthF() const
618 {
619     return d->width;
620 }
621 
622 /*!
623     \fn QPen::setWidth(int width)
624 
625     Sets the pen width to the given \a width in pixels with integer
626     precision.
627 
628     A line width of zero indicates a cosmetic pen. This means that the
629     pen width is always drawn one pixel wide, independent of the \l
630     {QPainter#Coordinate Transformations}{transformation} set on the
631     painter.
632 
633     Setting a pen width with a negative value is not supported.
634 
635     \sa setWidthF(), width()
636 */
setWidth(int width)637 void QPen::setWidth(int width)
638 {
639     if (width < 0)
640         qWarning("QPen::setWidth: Setting a pen width with a negative value is not defined");
641     if ((qreal)width == d->width)
642         return;
643     detach();
644     d->width = width;
645 }
646 
647 /*!
648     Sets the pen width to the given \a width in pixels with floating point
649     precision.
650 
651     A line width of zero indicates a cosmetic pen. This means that the
652     pen width is always drawn one pixel wide, independent of the \l
653     {QPainter#Coordinate Transformations}{transformation} on the
654     painter.
655 
656     Setting a pen width with a negative value is not supported.
657 
658     \sa setWidth() widthF()
659 */
660 
setWidthF(qreal width)661 void QPen::setWidthF(qreal width)
662 {
663     if (width < 0.f)
664         qWarning("QPen::setWidthF: Setting a pen width with a negative value is not defined");
665     if (qAbs(d->width - width) < 0.00000001f)
666         return;
667     detach();
668     d->width = width;
669 }
670 
671 
672 /*!
673     Returns the pen's cap style.
674 
675     \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
676 */
capStyle() const677 Qt::PenCapStyle QPen::capStyle() const
678 {
679     return d->capStyle;
680 }
681 
682 /*!
683     \fn void QPen::setCapStyle(Qt::PenCapStyle style)
684 
685     Sets the pen's cap style to the given \a style. The default value
686     is Qt::SquareCap.
687 
688     \sa capStyle(), {QPen#Cap Style}{Cap Style}
689 */
690 
setCapStyle(Qt::PenCapStyle c)691 void QPen::setCapStyle(Qt::PenCapStyle c)
692 {
693     if (d->capStyle == c)
694         return;
695     detach();
696     d->capStyle = c;
697 }
698 
699 /*!
700     Returns the pen's join style.
701 
702     \sa setJoinStyle(),  {QPen#Join Style}{Join Style}
703 */
joinStyle() const704 Qt::PenJoinStyle QPen::joinStyle() const
705 {
706     return d->joinStyle;
707 }
708 
709 /*!
710     \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
711 
712     Sets the pen's join style to the given \a style. The default value
713     is Qt::BevelJoin.
714 
715     \sa joinStyle(), {QPen#Join Style}{Join Style}
716 */
717 
setJoinStyle(Qt::PenJoinStyle j)718 void QPen::setJoinStyle(Qt::PenJoinStyle j)
719 {
720     if (d->joinStyle == j)
721         return;
722     detach();
723     d->joinStyle = j;
724 }
725 
726 /*!
727     \fn const QColor &QPen::color() const
728 
729     Returns the color of this pen's brush.
730 
731     \sa brush(), setColor()
732 */
color() const733 QColor QPen::color() const
734 {
735     return d->brush.color();
736 }
737 
738 /*!
739     \fn void QPen::setColor(const QColor &color)
740 
741     Sets the color of this pen's brush to the given \a color.
742 
743     \sa setBrush(), color()
744 */
745 
setColor(const QColor & c)746 void QPen::setColor(const QColor &c)
747 {
748     detach();
749     d->brush = QBrush(c);
750 }
751 
752 
753 /*!
754     Returns the brush used to fill strokes generated with this pen.
755 */
brush() const756 QBrush QPen::brush() const
757 {
758     return d->brush;
759 }
760 
761 /*!
762     Sets the brush used to fill strokes generated with this pen to the given
763     \a brush.
764 
765     \sa brush(), setColor()
766 */
setBrush(const QBrush & brush)767 void QPen::setBrush(const QBrush &brush)
768 {
769     detach();
770     d->brush = brush;
771 }
772 
773 
774 /*!
775     Returns true if the pen has a solid fill, otherwise false.
776 
777     \sa style(), dashPattern()
778 */
isSolid() const779 bool QPen::isSolid() const
780 {
781     return d->brush.style() == Qt::SolidPattern;
782 }
783 
784 
785 /*!
786     Returns true if the pen is cosmetic; otherwise returns false.
787 
788     Cosmetic pens are used to draw strokes that have a constant width
789     regardless of any transformations applied to the QPainter they are
790     used with. Drawing a shape with a cosmetic pen ensures that its
791     outline will have the same thickness at different scale factors.
792 
793     A zero width pen is cosmetic by default; pens with a non-zero width
794     are non-cosmetic.
795 
796     \sa setCosmetic(), widthF()
797 */
798 
isCosmetic() const799 bool QPen::isCosmetic() const
800 {
801     QPenData *dd = static_cast<QPenData *>(d);
802     return (dd->cosmetic == true) || d->width == 0;
803 }
804 
805 
806 /*!
807     Sets this pen to cosmetic or non-cosmetic, depending on the value of
808     \a cosmetic.
809 
810     \sa isCosmetic()
811 */
812 
setCosmetic(bool cosmetic)813 void QPen::setCosmetic(bool cosmetic)
814 {
815     detach();
816     QPenData *dd = static_cast<QPenData *>(d);
817     dd->cosmetic = cosmetic;
818 }
819 
820 
821 
822 /*!
823     \fn bool QPen::operator!=(const QPen &pen) const
824 
825     Returns true if the pen is different from the given \a pen;
826     otherwise false. Two pens are different if they have different
827     styles, widths or colors.
828 
829     \sa operator==()
830 */
831 
832 /*!
833     \fn bool QPen::operator==(const QPen &pen) const
834 
835     Returns true if the pen is equal to the given \a pen; otherwise
836     false. Two pens are equal if they have equal styles, widths and
837     colors.
838 
839     \sa operator!=()
840 */
841 
operator ==(const QPen & p) const842 bool QPen::operator==(const QPen &p) const
843 {
844     QPenData *dd = static_cast<QPenData *>(d);
845     QPenData *pdd = static_cast<QPenData *>(p.d);
846     return (p.d == d)
847         || (p.d->style == d->style
848             && p.d->capStyle == d->capStyle
849             && p.d->joinStyle == d->joinStyle
850             && p.d->width == d->width
851             && pdd->miterLimit == dd->miterLimit
852             && (d->style != Qt::CustomDashLine
853                 || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
854                     pdd->dashPattern == dd->dashPattern))
855             && p.d->brush == d->brush
856             && pdd->cosmetic == dd->cosmetic);
857 }
858 
859 
860 /*!
861     \fn bool QPen::isDetached()
862 
863     \internal
864 */
865 
isDetached()866 bool QPen::isDetached()
867 {
868     return d->ref == 1;
869 }
870 
871 
872 /*****************************************************************************
873   QPen stream functions
874  *****************************************************************************/
875 #ifndef QT_NO_DATASTREAM
876 /*!
877     \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
878     \relates QPen
879 
880     Writes the given \a pen to the given \a stream and returns a reference to
881     the \a stream.
882 
883     \sa {Serializing Qt Data Types}
884 */
885 
operator <<(QDataStream & s,const QPen & p)886 QDataStream &operator<<(QDataStream &s, const QPen &p)
887 {
888     QPenData *dd = static_cast<QPenData *>(p.d);
889     if (s.version() < 3) {
890         s << (quint8)p.style();
891     } else if (s.version() < QDataStream::Qt_4_3) {
892         s << (quint8)(p.style() | p.capStyle() | p.joinStyle());
893     } else {
894         s << (quint16)(p.style() | p.capStyle() | p.joinStyle());
895         s << (bool)(dd->cosmetic);
896     }
897 
898     if (s.version() < 7) {
899         s << (quint8)p.width();
900         s << p.color();
901     } else {
902         s << double(p.widthF());
903         s << p.brush();
904         s << double(p.miterLimit());
905         if (sizeof(qreal) == sizeof(double)) {
906             s << p.dashPattern();
907         } else {
908             // ensure that we write doubles here instead of streaming the pattern
909             // directly; otherwise, platforms that redefine qreal might generate
910             // data that cannot be read on other platforms.
911             QVector<qreal> pattern = p.dashPattern();
912             s << quint32(pattern.size());
913             for (int i = 0; i < pattern.size(); ++i)
914                 s << double(pattern.at(i));
915         }
916         if (s.version() >= 9)
917             s << double(p.dashOffset());
918     }
919     return s;
920 }
921 
922 /*!
923     \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
924     \relates QPen
925 
926     Reads a pen from the given \a stream into the given \a pen and
927     returns a reference to the \a stream.
928 
929     \sa {Serializing Qt Data Types}
930 */
931 
operator >>(QDataStream & s,QPen & p)932 QDataStream &operator>>(QDataStream &s, QPen &p)
933 {
934     quint16 style;
935     quint8 width8 = 0;
936     double width = 0;
937     QColor color;
938     QBrush brush;
939     double miterLimit = 2;
940     QVector<qreal> dashPattern;
941     double dashOffset = 0;
942     bool cosmetic = false;
943     if (s.version() < QDataStream::Qt_4_3) {
944         quint8 style8;
945         s >> style8;
946         style = style8;
947     } else {
948         s >> style;
949         s >> cosmetic;
950     }
951     if (s.version() < 7) {
952         s >> width8;
953         s >> color;
954         brush = color;
955         width = width8;
956     } else {
957         s >> width;
958         s >> brush;
959         s >> miterLimit;
960         if (sizeof(qreal) == sizeof(double)) {
961             s >> dashPattern;
962         } else {
963             quint32 numDashes;
964             s >> numDashes;
965             double dash;
966             for (quint32 i = 0; i < numDashes; ++i) {
967                 s >> dash;
968                 dashPattern << dash;
969             }
970         }
971         if (s.version() >= 9)
972             s >> dashOffset;
973     }
974 
975     p.detach();
976     QPenData *dd = static_cast<QPenData *>(p.d);
977     dd->width = width;
978     dd->brush = brush;
979     dd->style = Qt::PenStyle(style & Qt::MPenStyle);
980     dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
981     dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
982     dd->dashPattern = dashPattern;
983     dd->miterLimit = miterLimit;
984     dd->dashOffset = dashOffset;
985     dd->cosmetic = cosmetic;
986 
987     return s;
988 }
989 #endif //QT_NO_DATASTREAM
990 
991 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QPen & p)992 QDebug operator<<(QDebug dbg, const QPen &p)
993 {
994 #ifndef Q_BROKEN_DEBUG_STREAM
995     const char *PEN_STYLES[] = {
996         "NoPen",
997         "SolidLine",
998         "DashLine",
999         "DotLine",
1000         "DashDotLine",
1001         "DashDotDotLine",
1002         "CustomDashLine"
1003     };
1004 
1005     dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
1006                   << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
1007                   << ',' << int(p.joinStyle()) << ',' << p.dashPattern()
1008                   << ',' << p.dashOffset()
1009                   << ',' << p.miterLimit() << ')';
1010     return dbg.space();
1011 #else
1012     qWarning("This compiler doesn't support streaming QPen to QDebug");
1013     return dbg;
1014     Q_UNUSED(p);
1015 #endif
1016 }
1017 #endif
1018 
1019 /*!
1020     \fn DataPtr &QPen::data_ptr()
1021     \internal
1022 */
1023 
1024 /*!
1025     \typedef QPen::DataPtr
1026 
1027     \internal
1028 */
1029 
1030 QT_END_NAMESPACE
1031 
1032 #undef QT_COMPILING_QPEN
1033