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 1 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, bool _defaultWidth)
234
: ref(1), dashOffset(0), miterLimit(2),
235
cosmetic(false), defaultWidth(_defaultWidth)
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, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join))
265
Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance,
266
(Qt::black, 1, Qt::NoPen, qpen_default_cap, qpen_default_join))
269
Constructs a default black solid line pen with 1 width.
274
d = defaultPenInstance()->pen;
279
Constructs a black pen with 1 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, 1, style, qpen_default_cap, qpen_default_join);
296
Constructs a solid line pen with 1 width and the given \a color.
298
\sa setBrush(), setColor()
301
QPen::QPen(const QColor &color)
303
d = new QPenData(color, 1, 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, false);
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");
662
if (qAbs(d->width - width) < 0.00000001f)
666
d->defaultWidth = false;
671
Returns the pen's cap style.
673
\sa setCapStyle(), {QPen#Cap Style}{Cap Style}
675
Qt::PenCapStyle QPen::capStyle() const
681
\fn void QPen::setCapStyle(Qt::PenCapStyle style)
683
Sets the pen's cap style to the given \a style. The default value
686
\sa capStyle(), {QPen#Cap Style}{Cap Style}
689
void QPen::setCapStyle(Qt::PenCapStyle c)
691
if (d->capStyle == c)
698
Returns the pen's join style.
700
\sa setJoinStyle(), {QPen#Join Style}{Join Style}
702
Qt::PenJoinStyle QPen::joinStyle() const
708
\fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
710
Sets the pen's join style to the given \a style. The default value
713
\sa joinStyle(), {QPen#Join Style}{Join Style}
716
void QPen::setJoinStyle(Qt::PenJoinStyle j)
718
if (d->joinStyle == j)
725
\fn const QColor &QPen::color() const
727
Returns the color of this pen's brush.
729
\sa brush(), setColor()
731
QColor QPen::color() const
733
return d->brush.color();
737
\fn void QPen::setColor(const QColor &color)
739
Sets the color of this pen's brush to the given \a color.
741
\sa setBrush(), color()
744
void QPen::setColor(const QColor &c)
747
d->brush = QBrush(c);
752
Returns the brush used to fill strokes generated with this pen.
754
QBrush QPen::brush() const
760
Sets the brush used to fill strokes generated with this pen to the given
763
\sa brush(), setColor()
765
void QPen::setBrush(const QBrush &brush)
773
Returns true if the pen has a solid fill, otherwise false.
775
\sa style(), dashPattern()
777
bool QPen::isSolid() const
779
return d->brush.style() == Qt::SolidPattern;
784
Returns true if the pen is cosmetic; otherwise returns false.
786
Cosmetic pens are used to draw strokes that have a constant width
787
regardless of any transformations applied to the QPainter they are
788
used with. Drawing a shape with a cosmetic pen ensures that its
789
outline will have the same thickness at different scale factors.
791
A zero width pen is cosmetic by default.
793
\sa setCosmetic(), widthF()
796
bool QPen::isCosmetic() const
798
QPenData *dd = static_cast<QPenData *>(d);
799
return (dd->cosmetic == true) || d->width == 0;
804
Sets this pen to cosmetic or non-cosmetic, depending on the value of
810
void QPen::setCosmetic(bool cosmetic)
813
QPenData *dd = static_cast<QPenData *>(d);
814
dd->cosmetic = cosmetic;
820
\fn bool QPen::operator!=(const QPen &pen) const
822
Returns true if the pen is different from the given \a pen;
823
otherwise false. Two pens are different if they have different
824
styles, widths or colors.
830
\fn bool QPen::operator==(const QPen &pen) const
832
Returns true if the pen is equal to the given \a pen; otherwise
833
false. Two pens are equal if they have equal styles, widths and
839
bool QPen::operator==(const QPen &p) const
841
QPenData *dd = static_cast<QPenData *>(d);
842
QPenData *pdd = static_cast<QPenData *>(p.d);
844
|| (p.d->style == d->style
845
&& p.d->capStyle == d->capStyle
846
&& p.d->joinStyle == d->joinStyle
847
&& p.d->width == d->width
848
&& pdd->miterLimit == dd->miterLimit
849
&& (d->style != Qt::CustomDashLine
850
|| (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
851
pdd->dashPattern == dd->dashPattern))
852
&& p.d->brush == d->brush
853
&& pdd->cosmetic == dd->cosmetic
854
&& pdd->defaultWidth == dd->defaultWidth);
859
\fn bool QPen::isDetached()
864
bool QPen::isDetached()
866
return d->ref.load() == 1;
870
/*****************************************************************************
871
QPen stream functions
872
*****************************************************************************/
873
#ifndef QT_NO_DATASTREAM
875
\fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
878
Writes the given \a pen to the given \a stream and returns a reference to
881
\sa {Serializing Qt Data Types}
884
QDataStream &operator<<(QDataStream &s, const QPen &p)
886
QPenData *dd = static_cast<QPenData *>(p.d);
887
if (s.version() < 3) {
888
s << (quint8)p.style();
889
} else if (s.version() < QDataStream::Qt_4_3) {
890
s << (quint8)(p.style() | p.capStyle() | p.joinStyle());
892
s << (quint16)(p.style() | p.capStyle() | p.joinStyle());
893
s << (bool)(dd->cosmetic);
896
if (s.version() < 7) {
897
s << (quint8)p.width();
900
s << double(p.widthF());
902
s << double(p.miterLimit());
903
if (sizeof(qreal) == sizeof(double)) {
904
s << p.dashPattern();
906
// ensure that we write doubles here instead of streaming the pattern
907
// directly; otherwise, platforms that redefine qreal might generate
908
// data that cannot be read on other platforms.
909
QVector<qreal> pattern = p.dashPattern();
910
s << quint32(pattern.size());
911
for (int i = 0; i < pattern.size(); ++i)
912
s << double(pattern.at(i));
914
if (s.version() >= 9)
915
s << double(p.dashOffset());
916
if (s.version() >= QDataStream::Qt_5_0)
917
s << bool(dd->defaultWidth);
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
bool defaultWidth = false;
944
if (s.version() < QDataStream::Qt_4_3) {
952
if (s.version() < 7) {
961
if (sizeof(qreal) == sizeof(double)) {
967
for (quint32 i = 0; i < numDashes; ++i) {
972
if (s.version() >= 9)
976
if (s.version() >= QDataStream::Qt_5_0) {
979
// best we can do for legacy pens
980
defaultWidth = qFuzzyIsNull(width);
984
QPenData *dd = static_cast<QPenData *>(p.d);
987
dd->style = Qt::PenStyle(style & Qt::MPenStyle);
988
dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
989
dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
990
dd->dashPattern = dashPattern;
991
dd->miterLimit = miterLimit;
992
dd->dashOffset = dashOffset;
993
dd->cosmetic = cosmetic;
994
dd->defaultWidth = defaultWidth;
998
#endif //QT_NO_DATASTREAM
1000
#ifndef QT_NO_DEBUG_STREAM
1001
QDebug operator<<(QDebug dbg, const QPen &p)
1003
const char *PEN_STYLES[] = {
1013
dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
1014
<< ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
1015
<< ',' << int(p.joinStyle()) << ',' << p.dashPattern()
1016
<< ',' << p.dashOffset()
1017
<< ',' << p.miterLimit() << ')';
1023
\fn DataPtr &QPen::data_ptr()
1028
\typedef QPen::DataPtr
1035
#undef QT_COMPILING_QPEN