1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
43 #include "qdatastream.h"
51 typedef QPenPrivate QPenData;
60 \brief The QPen class defines how a QPainter should draw lines and outlines
63 A pen has a style(), width(), brush(), capStyle() and joinStyle().
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
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).
83 \snippet code/src_gui_painting_qpen.cpp 0
85 which is equivalent to
87 \snippet code/src_gui_painting_qpen.cpp 1
89 The default pen is a solid black brush with 0 width, square
90 cap style (Qt::SquareCap), and bevel join style (Qt::BevelJoin).
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.
96 For more information about painting in general, see the \l{Paint
97 System} documentation.
103 Qt provides several built-in styles represented by the
108 \li \inlineimage qpen-solid.png
109 \li \inlineimage qpen-dash.png
110 \li \inlineimage qpen-dot.png
116 \li \inlineimage qpen-dashdot.png
117 \li \inlineimage qpen-dashdotdot.png
118 \li \inlineimage qpen-custom.png
121 \li Qt::DashDotDotLine
122 \li Qt::CustomDashLine
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.
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:
139 \snippet code/src_gui_painting_qpen.cpp 2
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.
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.
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
157 \li \inlineimage qpen-square.png
158 \li \inlineimage qpen-flat.png
159 \li \inlineimage qpen-roundcap.png
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.
172 The default is Qt::SquareCap.
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.
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:
187 \li \inlineimage qpen-bevel.png
188 \li \inlineimage qpen-miter.png
189 \li \inlineimage qpen-roundjoin.png
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
201 The default is Qt::BevelJoin.
203 \image qpen-miterlimit.png
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
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.
217 \li \inlineimage qpen-demo.png
218 \li \b {\l {painting/pathstroke}{The Path Stroking Example}}
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
225 \sa QPainter, QBrush, {painting/pathstroke}{Path Stroking Example},
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),
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;
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))
257 if (!pen->ref.deref())
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))
269 Constructs a default black solid line pen with 0 width.
274 d = defaultPenInstance()->pen;
279 Constructs a black pen with 0 width and the given \a style.
284 QPen::QPen(Qt::PenStyle style)
286 if (style == Qt::NoPen) {
287 d = nullPenInstance()->pen;
290 d = new QPenData(Qt::black, 0, style, qpen_default_cap, qpen_default_join);
296 Constructs a solid line pen with 0 width and the given \a color.
298 \sa setBrush(), setColor()
301 QPen::QPen(const QColor &color)
303 d = new QPenData(color, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join);
308 \fn QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle style, Qt::PenCapStyle cap, Qt::PenJoinStyle join)
310 Constructs a pen with the specified \a brush, \a width, pen \a style,
311 \a cap style and \a join style.
313 \sa setBrush(), setWidth(), setStyle(), setCapStyle(), setJoinStyle()
316 QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j)
318 d = new QPenData(brush, width, s, c, j);
322 \fn QPen::QPen(const QPen &pen)
324 Constructs a pen that is a copy of the given \a pen.
327 QPen::QPen(const QPen &p)
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.
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
356 if (d->ref.load() == 1)
359 QPenData *x = new QPenData(*static_cast<QPenData *>(d));
368 \fn QPen &QPen::operator=(const QPen &pen)
370 Assigns the given \a pen to this pen and returns a reference to
374 QPen &QPen::operator=(const QPen &p)
376 qAtomicAssign(d, p.d);
381 \fn void QPen::swap(QPen &other)
384 Swaps pen \a other with this pen. This operation is very
385 fast and never fails.
389 Returns the pen as a QVariant.
391 QPen::operator QVariant() const
393 return QVariant(QVariant::Pen, this);
397 \fn Qt::PenStyle QPen::style() const
399 Returns the pen style.
401 \sa setStyle(), {QPen#Pen Style}{Pen Style}
403 Qt::PenStyle QPen::style() const
408 \fn void QPen::setStyle(Qt::PenStyle style)
410 Sets the pen style to the given \a style.
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.
417 \note This function resets the dash offset to zero.
419 \sa style(), {QPen#Pen Style}{Pen Style}
422 void QPen::setStyle(Qt::PenStyle s)
428 QPenData *dd = static_cast<QPenData *>(d);
429 dd->dashPattern.clear();
434 Returns the dash pattern of this pen.
436 \sa style(), isSolid()
438 QVector<qreal> QPen::dashPattern() const
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;
446 const qreal dash = 4;
450 dd->dashPattern << dash << space;
453 dd->dashPattern << dot << space;
455 case Qt::DashDotLine:
456 dd->dashPattern << dash << space << dot << space;
458 case Qt::DashDotDotLine:
459 dd->dashPattern << dash << space << dot << space << dot << space;
465 return dd->dashPattern;
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.
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
478 \li \inlineimage qpen-custom.png
480 \snippet code/src_gui_painting_qpen.cpp 3
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
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
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
496 \sa setStyle(), dashPattern(), setCapStyle(), setCosmetic()
498 void QPen::setDashPattern(const QVector<qreal> &pattern)
500 if (pattern.isEmpty())
504 QPenData *dd = static_cast<QPenData *>(d);
505 dd->dashPattern = pattern;
506 d->style = Qt::CustomDashLine;
508 if ((dd->dashPattern.size() % 2) == 1) {
509 qWarning("QPen::setDashPattern: Pattern not of even length");
510 dd->dashPattern << 1;
516 Returns the dash offset for the pen.
520 qreal QPen::dashOffset() const
522 QPenData *dd = static_cast<QPenData *>(d);
523 return dd->dashOffset;
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.
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.
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
541 \note This implicitly converts the style of the pen to Qt::CustomDashLine.
543 void QPen::setDashOffset(qreal offset)
545 if (qFuzzyCompare(offset, static_cast<QPenData *>(d)->dashOffset))
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;
557 Returns the miter limit of the pen. The miter limit is only
558 relevant when the join style is set to Qt::MiterJoin.
560 \sa setMiterLimit(), {QPen#Join Style}{Join Style}
562 qreal QPen::miterLimit() const
564 const QPenData *dd = static_cast<QPenData *>(d);
565 return dd->miterLimit;
569 Sets the miter limit of this pen to the given \a limit.
571 \image qpen-miterlimit.png
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.
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.
582 \sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style}
584 void QPen::setMiterLimit(qreal limit)
587 QPenData *dd = static_cast<QPenData *>(d);
588 dd->miterLimit = limit;
593 \fn qreal QPen::width() const
595 Returns the pen width with integer precision.
597 \sa setWidth(), widthF()
600 int QPen::width() const
602 return qRound(d->width);
606 \fn qreal QPen::widthF() const
608 Returns the pen width with floating point precision.
610 \sa setWidthF(), width()
612 qreal QPen::widthF() const
618 \fn QPen::setWidth(int width)
620 Sets the pen width to the given \a width in pixels with integer
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
628 Setting a pen width with a negative value is not supported.
630 \sa setWidthF(), width()
632 void QPen::setWidth(int width)
635 qWarning("QPen::setWidth: Setting a pen width with a negative value is not defined");
636 if ((qreal)width == d->width)
643 Sets the pen width to the given \a width in pixels with floating point
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
651 Setting a pen width with a negative value is not supported.
653 \sa setWidth(), widthF()
656 void QPen::setWidthF(qreal width)
659 qWarning("QPen::setWidthF: Setting a pen width with a negative value is not defined");
660 if (qAbs(d->width - width) < 0.00000001f)
668 Returns the pen's cap style.
670 \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
672 Qt::PenCapStyle QPen::capStyle() const
678 \fn void QPen::setCapStyle(Qt::PenCapStyle style)
680 Sets the pen's cap style to the given \a style. The default value
683 \sa capStyle(), {QPen#Cap Style}{Cap Style}
686 void QPen::setCapStyle(Qt::PenCapStyle c)
688 if (d->capStyle == c)
695 Returns the pen's join style.
697 \sa setJoinStyle(), {QPen#Join Style}{Join Style}
699 Qt::PenJoinStyle QPen::joinStyle() const
705 \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
707 Sets the pen's join style to the given \a style. The default value
710 \sa joinStyle(), {QPen#Join Style}{Join Style}
713 void QPen::setJoinStyle(Qt::PenJoinStyle j)
715 if (d->joinStyle == j)
722 \fn const QColor &QPen::color() const
724 Returns the color of this pen's brush.
726 \sa brush(), setColor()
728 QColor QPen::color() const
730 return d->brush.color();
734 \fn void QPen::setColor(const QColor &color)
736 Sets the color of this pen's brush to the given \a color.
738 \sa setBrush(), color()
741 void QPen::setColor(const QColor &c)
744 d->brush = QBrush(c);
749 Returns the brush used to fill strokes generated with this pen.
751 QBrush QPen::brush() const
757 Sets the brush used to fill strokes generated with this pen to the given
760 \sa brush(), setColor()
762 void QPen::setBrush(const QBrush &brush)
770 Returns true if the pen has a solid fill, otherwise false.
772 \sa style(), dashPattern()
774 bool QPen::isSolid() const
776 return d->brush.style() == Qt::SolidPattern;
781 Returns true if the pen is cosmetic; otherwise returns false.
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.
788 A zero width pen is cosmetic by default; pens with a non-zero width
791 \sa setCosmetic(), widthF()
794 bool QPen::isCosmetic() const
796 QPenData *dd = static_cast<QPenData *>(d);
797 return (dd->cosmetic == true) || d->width == 0;
802 Sets this pen to cosmetic or non-cosmetic, depending on the value of
808 void QPen::setCosmetic(bool cosmetic)
811 QPenData *dd = static_cast<QPenData *>(d);
812 dd->cosmetic = cosmetic;
818 \fn bool QPen::operator!=(const QPen &pen) const
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.
828 \fn bool QPen::operator==(const QPen &pen) const
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
837 bool QPen::operator==(const QPen &p) const
839 QPenData *dd = static_cast<QPenData *>(d);
840 QPenData *pdd = static_cast<QPenData *>(p.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);
856 \fn bool QPen::isDetached()
861 bool QPen::isDetached()
863 return d->ref.load() == 1;
867 /*****************************************************************************
868 QPen stream functions
869 *****************************************************************************/
870 #ifndef QT_NO_DATASTREAM
872 \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
875 Writes the given \a pen to the given \a stream and returns a reference to
878 \sa {Serializing Qt Data Types}
881 QDataStream &operator<<(QDataStream &s, const QPen &p)
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());
889 s << (quint16)(p.style() | p.capStyle() | p.joinStyle());
890 s << (bool)(dd->cosmetic);
893 if (s.version() < 7) {
894 s << (quint8)p.width();
897 s << double(p.widthF());
899 s << double(p.miterLimit());
900 if (sizeof(qreal) == sizeof(double)) {
901 s << p.dashPattern();
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));
911 if (s.version() >= 9)
912 s << double(p.dashOffset());
918 \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
921 Reads a pen from the given \a stream into the given \a pen and
922 returns a reference to the \a stream.
924 \sa {Serializing Qt Data Types}
927 QDataStream &operator>>(QDataStream &s, QPen &p)
934 double miterLimit = 2;
935 QVector<qreal> dashPattern;
936 double dashOffset = 0;
937 bool cosmetic = false;
938 if (s.version() < QDataStream::Qt_4_3) {
946 if (s.version() < 7) {
955 if (sizeof(qreal) == sizeof(double)) {
961 for (quint32 i = 0; i < numDashes; ++i) {
966 if (s.version() >= 9)
971 QPenData *dd = static_cast<QPenData *>(p.d);
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;
984 #endif //QT_NO_DATASTREAM
986 #ifndef QT_NO_DEBUG_STREAM
987 QDebug operator<<(QDebug dbg, const QPen &p)
989 const char *PEN_STYLES[] = {
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() << ')';
1009 \fn DataPtr &QPen::data_ptr()
1014 \typedef QPen::DataPtr
1021 #undef QT_COMPILING_QPEN