1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
43 #include "qdatastream.h"
51 typedef QPenPrivate QPenData;
59 \brief The QPen class defines how a QPainter should draw lines and outlines
62 A pen has a style(), width(), brush(), capStyle() and joinStyle().
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
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).
82 \snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 0
84 which is equivalent to
86 \snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 1
88 The default pen is a solid black brush with 0 width, square
89 cap style (Qt::SquareCap), and bevel join style (Qt::BevelJoin).
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.
95 For more information about painting in general, see the \l{Paint
96 System} documentation.
102 Qt provides several built-in styles represented by the
107 \o \inlineimage qpen-solid.png
108 \o \inlineimage qpen-dash.png
109 \o \inlineimage qpen-dot.png
115 \o \inlineimage qpen-dashdot.png
116 \o \inlineimage qpen-dashdotdot.png
117 \o \inlineimage qpen-custom.png
120 \o Qt::DashDotDotLine
121 \o Qt::CustomDashLine
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.
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:
138 \snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 2
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.
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.
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
156 \o \inlineimage qpen-square.png
157 \o \inlineimage qpen-flat.png
158 \o \inlineimage qpen-roundcap.png
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.
171 The default is Qt::SquareCap.
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.
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:
186 \o \inlineimage qpen-bevel.png
187 \o \inlineimage qpen-miter.png
188 \o \inlineimage qpen-roundjoin.png
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
200 The default is Qt::BevelJoin.
202 \image qpen-miterlimit.png
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
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.
216 \o \inlineimage qpen-demo.png
217 \o \bold {\l {demos/pathstroke}{The Path Stroking Demo}}
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
224 \sa QPainter, QBrush, {demos/pathstroke}{Path Stroking Demo},
231 inline QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle,
232 Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle)
233 : dashOffset(0), miterLimit(2),
240 capStyle = _capStyle;
241 joinStyle = _joinStyle;
244 static const Qt::PenCapStyle qpen_default_cap = Qt::SquareCap;
245 static const Qt::PenJoinStyle qpen_default_join = Qt::BevelJoin;
248 // Special deleter that only deletes if the ref-count goes to zero
250 class QGlobalStaticDeleter<QPenPrivate>
253 QGlobalStatic<QPenPrivate> &globalStatic;
254 QGlobalStaticDeleter(QGlobalStatic<QPenPrivate> &_globalStatic)
255 : globalStatic(_globalStatic)
258 inline ~QGlobalStaticDeleter()
260 if (!globalStatic.pointer->ref.deref())
261 delete globalStatic.pointer;
262 globalStatic.pointer = 0;
263 globalStatic.destroyed = true;
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))
274 Constructs a default black solid line pen with 0 width.
279 d = defaultPenInstance();
284 Constructs a black pen with 0 width and the given \a style.
289 QPen::QPen(Qt::PenStyle style)
291 if (style == Qt::NoPen) {
292 d = nullPenInstance();
295 d = new QPenData(Qt::black, 0, style, qpen_default_cap, qpen_default_join);
301 Constructs a solid line pen with 0 width and the given \a color.
303 \sa setBrush(), setColor()
306 QPen::QPen(const QColor &color)
308 d = new QPenData(color, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join);
313 \fn QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle style, Qt::PenCapStyle cap, Qt::PenJoinStyle join)
315 Constructs a pen with the specified \a brush, \a width, pen \a style,
316 \a cap style and \a join style.
318 \sa setBrush(), setWidth(), setStyle(), setCapStyle(), setJoinStyle()
321 QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j)
323 d = new QPenData(brush, width, s, c, j);
327 \fn QPen::QPen(const QPen &pen)
329 Constructs a pen that is a copy of the given \a pen.
332 QPen::QPen(const QPen &p)
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.
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
364 QPenData *x = new QPenData(*static_cast<QPenData *>(d));
373 \fn QPen &QPen::operator=(const QPen &pen)
375 Assigns the given \a pen to this pen and returns a reference to
379 QPen &QPen::operator=(const QPen &p)
381 qAtomicAssign(d, p.d);
386 \fn void QPen::swap(QPen &other)
389 Swaps pen \a other with this pen. This operation is very
390 fast and never fails.
394 Returns the pen as a QVariant.
396 QPen::operator QVariant() const
398 return QVariant(QVariant::Pen, this);
402 \fn Qt::PenStyle QPen::style() const
404 Returns the pen style.
406 \sa setStyle(), {QPen#Pen Style}{Pen Style}
408 Qt::PenStyle QPen::style() const
413 \fn void QPen::setStyle(Qt::PenStyle style)
415 Sets the pen style to the given \a style.
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.
422 \note This function resets the dash offset to zero.
424 \sa style(), {QPen#Pen Style}{Pen Style}
427 void QPen::setStyle(Qt::PenStyle s)
433 QPenData *dd = static_cast<QPenData *>(d);
434 dd->dashPattern.clear();
439 Returns the dash pattern of this pen.
441 \sa style(), isSolid()
443 QVector<qreal> QPen::dashPattern() const
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;
451 const qreal dash = 4;
455 dd->dashPattern << dash << space;
458 dd->dashPattern << dot << space;
460 case Qt::DashDotLine:
461 dd->dashPattern << dash << space << dot << space;
463 case Qt::DashDotDotLine:
464 dd->dashPattern << dash << space << dot << space << dot << space;
470 return dd->dashPattern;
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.
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
483 \o \inlineimage qpen-custom.png
485 \snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 3
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
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
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
501 \sa setStyle(), dashPattern(), setCapStyle(), setCosmetic()
503 void QPen::setDashPattern(const QVector<qreal> &pattern)
505 if (pattern.isEmpty())
509 QPenData *dd = static_cast<QPenData *>(d);
510 dd->dashPattern = pattern;
511 d->style = Qt::CustomDashLine;
513 if ((dd->dashPattern.size() % 2) == 1) {
514 qWarning("QPen::setDashPattern: Pattern not of even length");
515 dd->dashPattern << 1;
521 Returns the dash offset for the pen.
525 qreal QPen::dashOffset() const
527 QPenData *dd = static_cast<QPenData *>(d);
528 return dd->dashOffset;
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.
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.
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
546 \note This implicitly converts the style of the pen to Qt::CustomDashLine.
548 void QPen::setDashOffset(qreal offset)
550 if (qFuzzyCompare(offset, static_cast<QPenData *>(d)->dashOffset))
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;
562 Returns the miter limit of the pen. The miter limit is only
563 relevant when the join style is set to Qt::MiterJoin.
565 \sa setMiterLimit(), {QPen#Join Style}{Join Style}
567 qreal QPen::miterLimit() const
569 const QPenData *dd = static_cast<QPenData *>(d);
570 return dd->miterLimit;
574 Sets the miter limit of this pen to the given \a limit.
576 \image qpen-miterlimit.png
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.
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.
587 \sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style}
589 void QPen::setMiterLimit(qreal limit)
592 QPenData *dd = static_cast<QPenData *>(d);
593 dd->miterLimit = limit;
598 \fn qreal QPen::width() const
600 Returns the pen width with integer precision.
602 \sa setWidth(), widthF()
605 int QPen::width() const
607 return qRound(d->width);
611 \fn qreal QPen::widthF() const
613 Returns the pen width with floating point precision.
615 \sa setWidthF() width()
617 qreal QPen::widthF() const
623 \fn QPen::setWidth(int width)
625 Sets the pen width to the given \a width in pixels with integer
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
633 Setting a pen width with a negative value is not supported.
635 \sa setWidthF(), width()
637 void QPen::setWidth(int width)
640 qWarning("QPen::setWidth: Setting a pen width with a negative value is not defined");
641 if ((qreal)width == d->width)
648 Sets the pen width to the given \a width in pixels with floating point
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
656 Setting a pen width with a negative value is not supported.
658 \sa setWidth() widthF()
661 void QPen::setWidthF(qreal width)
664 qWarning("QPen::setWidthF: Setting a pen width with a negative value is not defined");
665 if (qAbs(d->width - width) < 0.00000001f)
673 Returns the pen's cap style.
675 \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
677 Qt::PenCapStyle QPen::capStyle() const
683 \fn void QPen::setCapStyle(Qt::PenCapStyle style)
685 Sets the pen's cap style to the given \a style. The default value
688 \sa capStyle(), {QPen#Cap Style}{Cap Style}
691 void QPen::setCapStyle(Qt::PenCapStyle c)
693 if (d->capStyle == c)
700 Returns the pen's join style.
702 \sa setJoinStyle(), {QPen#Join Style}{Join Style}
704 Qt::PenJoinStyle QPen::joinStyle() const
710 \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
712 Sets the pen's join style to the given \a style. The default value
715 \sa joinStyle(), {QPen#Join Style}{Join Style}
718 void QPen::setJoinStyle(Qt::PenJoinStyle j)
720 if (d->joinStyle == j)
727 \fn const QColor &QPen::color() const
729 Returns the color of this pen's brush.
731 \sa brush(), setColor()
733 QColor QPen::color() const
735 return d->brush.color();
739 \fn void QPen::setColor(const QColor &color)
741 Sets the color of this pen's brush to the given \a color.
743 \sa setBrush(), color()
746 void QPen::setColor(const QColor &c)
749 d->brush = QBrush(c);
754 Returns the brush used to fill strokes generated with this pen.
756 QBrush QPen::brush() const
762 Sets the brush used to fill strokes generated with this pen to the given
765 \sa brush(), setColor()
767 void QPen::setBrush(const QBrush &brush)
775 Returns true if the pen has a solid fill, otherwise false.
777 \sa style(), dashPattern()
779 bool QPen::isSolid() const
781 return d->brush.style() == Qt::SolidPattern;
786 Returns true if the pen is cosmetic; otherwise returns false.
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.
793 A zero width pen is cosmetic by default; pens with a non-zero width
796 \sa setCosmetic(), widthF()
799 bool QPen::isCosmetic() const
801 QPenData *dd = static_cast<QPenData *>(d);
802 return (dd->cosmetic == true) || d->width == 0;
807 Sets this pen to cosmetic or non-cosmetic, depending on the value of
813 void QPen::setCosmetic(bool cosmetic)
816 QPenData *dd = static_cast<QPenData *>(d);
817 dd->cosmetic = cosmetic;
823 \fn bool QPen::operator!=(const QPen &pen) const
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.
833 \fn bool QPen::operator==(const QPen &pen) const
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
842 bool QPen::operator==(const QPen &p) const
844 QPenData *dd = static_cast<QPenData *>(d);
845 QPenData *pdd = static_cast<QPenData *>(p.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);
861 \fn bool QPen::isDetached()
866 bool QPen::isDetached()
872 /*****************************************************************************
873 QPen stream functions
874 *****************************************************************************/
875 #ifndef QT_NO_DATASTREAM
877 \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
880 Writes the given \a pen to the given \a stream and returns a reference to
883 \sa {Serializing Qt Data Types}
886 QDataStream &operator<<(QDataStream &s, const QPen &p)
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());
894 s << (quint16)(p.style() | p.capStyle() | p.joinStyle());
895 s << (bool)(dd->cosmetic);
898 if (s.version() < 7) {
899 s << (quint8)p.width();
902 s << double(p.widthF());
904 s << double(p.miterLimit());
905 if (sizeof(qreal) == sizeof(double)) {
906 s << p.dashPattern();
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));
916 if (s.version() >= 9)
917 s << double(p.dashOffset());
923 \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
926 Reads a pen from the given \a stream into the given \a pen and
927 returns a reference to the \a stream.
929 \sa {Serializing Qt Data Types}
932 QDataStream &operator>>(QDataStream &s, QPen &p)
939 double miterLimit = 2;
940 QVector<qreal> dashPattern;
941 double dashOffset = 0;
942 bool cosmetic = false;
943 if (s.version() < QDataStream::Qt_4_3) {
951 if (s.version() < 7) {
960 if (sizeof(qreal) == sizeof(double)) {
966 for (quint32 i = 0; i < numDashes; ++i) {
971 if (s.version() >= 9)
976 QPenData *dd = static_cast<QPenData *>(p.d);
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;
989 #endif //QT_NO_DATASTREAM
991 #ifndef QT_NO_DEBUG_STREAM
992 QDebug operator<<(QDebug dbg, const QPen &p)
994 #ifndef Q_BROKEN_DEBUG_STREAM
995 const char *PEN_STYLES[] = {
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() << ')';
1012 qWarning("This compiler doesn't support streaming QPen to QDebug");
1020 \fn DataPtr &QPen::data_ptr()
1025 \typedef QPen::DataPtr
1032 #undef QT_COMPILING_QPEN