1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://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 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39#include "qpen.h"
40#include "qpen_p.h"
41#include "qdatastream.h"
42#include "qvariant.h"
43#include "qbrush.h"
44
45#include <qdebug.h>
46
47QT_BEGIN_NAMESPACE
48
49typedef QPenPrivate QPenData;
50
51/*!
52 \class QPen
53 \inmodule QtGui
54 \ingroup painting
55 \ingroup shared
56
57
58 \brief The QPen class defines how a QPainter should draw lines and outlines
59 of shapes.
60
61 A pen has a style(), width(), brush(), capStyle() and joinStyle().
62
63 The pen style defines the line type. The brush is used to fill
64 strokes generated with the pen. Use the QBrush class to specify
65 fill styles. The cap style determines the line end caps that can
66 be drawn using QPainter, while the join style describes how joins
67 between two lines are drawn. The pen width can be specified in
68 both integer (width()) and floating point (widthF()) precision. A
69 line width of zero indicates a cosmetic pen. This means that the
70 pen width is always drawn one pixel wide, independent of the \l
71 {QPainter#Coordinate Transformations}{transformation} set on the
72 painter.
73
74 The various settings can easily be modified using the
75 corresponding setStyle(), setWidth(), setBrush(), setCapStyle()
76 and setJoinStyle() functions (note that the painter's pen must be
77 reset when altering the pen's properties).
78
79 For example:
80
81 \snippet code/src_gui_painting_qpen.cpp 0
82
83 which is equivalent to
84
85 \snippet code/src_gui_painting_qpen.cpp 1
86
87 The default pen is a solid black brush with 1 width, square
88 cap style (Qt::SquareCap), and bevel join style (Qt::BevelJoin).
89
90 In addition QPen provides the color() and setColor()
91 convenience functions to extract and set the color of the pen's
92 brush, respectively. Pens may also be compared and streamed.
93
94 For more information about painting in general, see the \l{Paint
95 System} documentation.
96
97 \tableofcontents
98
99 \section1 Pen Style
100
101 Qt provides several built-in styles represented by the
102 Qt::PenStyle enum:
103
104 \table
105 \row
106 \li \inlineimage qpen-solid.png
107 \li \inlineimage qpen-dash.png
108 \li \inlineimage qpen-dot.png
109 \row
110 \li Qt::SolidLine
111 \li Qt::DashLine
112 \li Qt::DotLine
113 \row
114 \li \inlineimage qpen-dashdot.png
115 \li \inlineimage qpen-dashdotdot.png
116 \li \inlineimage qpen-custom.png
117 \row
118 \li Qt::DashDotLine
119 \li Qt::DashDotDotLine
120 \li Qt::CustomDashLine
121 \endtable
122
123 Simply use the setStyle() function to convert the pen style to
124 either of the built-in styles, except the Qt::CustomDashLine style
125 which we will come back to shortly. Setting the style to Qt::NoPen
126 tells the painter to not draw lines or outlines. The default pen
127 style is Qt::SolidLine.
128
129 Since Qt 4.1 it is also possible to specify a custom dash pattern
130 using the setDashPattern() function which implicitly converts the
131 style of the pen to Qt::CustomDashLine. The pattern argument, a
132 QVector, must be specified as an even number of \l qreal entries
133 where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the
134 spaces. For example, the custom pattern shown above is created
135 using the following code:
136
137 \snippet code/src_gui_painting_qpen.cpp 2
138
139 Note that the dash pattern is specified in units of the pens
140 width, e.g. a dash of length 5 in width 10 is 50 pixels long.
141
142 The currently set dash pattern can be retrieved using the
143 dashPattern() function. Use the isSolid() function to determine
144 whether the pen has a solid fill, or not.
145
146 \section1 Cap Style
147
148 The cap style defines how the end points of lines are drawn using
149 QPainter. The cap style only apply to wide lines, i.e. when the
150 width is 1 or greater. The Qt::PenCapStyle enum provides the
151 following styles:
152
153 \table
154 \row
155 \li \inlineimage qpen-square.png
156 \li \inlineimage qpen-flat.png
157 \li \inlineimage qpen-roundcap.png
158 \row
159 \li Qt::SquareCap
160 \li Qt::FlatCap
161 \li Qt::RoundCap
162 \endtable
163
164 The Qt::SquareCap style is a square line end that covers the end
165 point and extends beyond it by half the line width. The
166 Qt::FlatCap style is a square line end that does not cover the end
167 point of the line. And the Qt::RoundCap style is a rounded line
168 end covering the end point.
169
170 The default is Qt::SquareCap.
171
172 Whether or not end points are drawn when the pen width is 0 or 1
173 depends on the cap style. Using Qt::SquareCap or Qt::RoundCap they
174 are drawn, using Qt::FlatCap they are not drawn.
175
176 \section1 Join Style
177
178 The join style defines how joins between two connected lines can
179 be drawn using QPainter. The join style only apply to wide lines,
180 i.e. when the width is 1 or greater. The Qt::PenJoinStyle enum
181 provides the following styles:
182
183 \table
184 \row
185 \li \inlineimage qpen-bevel.png
186 \li \inlineimage qpen-miter.png
187 \li \inlineimage qpen-roundjoin.png
188 \row
189 \li Qt::BevelJoin
190 \li Qt::MiterJoin
191 \li Qt::RoundJoin
192 \endtable
193
194 The Qt::BevelJoin style fills the triangular notch between the two
195 lines. The Qt::MiterJoin style extends the lines to meet at an
196 angle. And the Qt::RoundJoin style fills a circular arc between
197 the two lines.
198
199 The default is Qt::BevelJoin.
200
201 \image qpen-miterlimit.png
202
203 When the Qt::MiterJoin style is applied, it is possible to use the
204 setMiterLimit() function to specify how far the miter join can
205 extend from the join point. The miterLimit() is used to reduce
206 artifacts between line joins where the lines are close to
207 parallel.
208
209 The miterLimit() must be specified in units of the pens width,
210 e.g. a miter limit of 5 in width 10 is 50 pixels long. The
211 default miter limit is 2, i.e. twice the pen width in pixels.
212
213 \table 100%
214 \row
215 \li \inlineimage qpen-demo.png
216 \li \b {\l {painting/pathstroke}{The Path Stroking Example}}
217
218 The Path Stroking example shows Qt's built-in dash patterns and shows
219 how custom patterns can be used to extend the range of available
220 patterns.
221 \endtable
222
223 \sa QPainter, QBrush, {painting/pathstroke}{Path Stroking Example},
224 {Scribble Example}
225*/
226
227/*!
228 \internal
229*/
230inline QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle,
231 Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle, bool _defaultWidth)
232 : ref(1), dashOffset(0), miterLimit(2),
233 cosmetic(false), defaultWidth(_defaultWidth)
234{
235 width = _width;
236 brush = _brush;
237 style = penStyle;
238 capStyle = _capStyle;
239 joinStyle = _joinStyle;
240}
241
242static const Qt::PenCapStyle qpen_default_cap = Qt::SquareCap;
243static const Qt::PenJoinStyle qpen_default_join = Qt::BevelJoin;
244
245class QPenDataHolder
246{
247public:
248 QPenData *pen;
249 QPenDataHolder(const QBrush &brush, qreal width, Qt::PenStyle penStyle,
250 Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle)
251 : pen(new QPenData(brush, width, penStyle, penCapStyle, _joinStyle))
252 { }
253 ~QPenDataHolder()
254 {
255 if (!pen->ref.deref())
256 delete pen;
257 pen = nullptr;
258 }
259};
260
261Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, defaultPenInstance,
262 (Qt::black, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join))
263Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance,
264 (Qt::black, 1, Qt::NoPen, qpen_default_cap, qpen_default_join))
265
266/*!
267 Constructs a default black solid line pen with 1 width.
268*/
269
270QPen::QPen()
271{
272 d = defaultPenInstance()->pen;
273 d->ref.ref();
274}
275
276/*!
277 Constructs a black pen with 1 width and the given \a style.
278
279 \sa setStyle()
280*/
281
282QPen::QPen(Qt::PenStyle style)
283{
284 if (style == Qt::NoPen) {
285 d = nullPenInstance()->pen;
286 d->ref.ref();
287 } else {
288 d = new QPenData(Qt::black, 1, style, qpen_default_cap, qpen_default_join);
289 }
290}
291
292
293/*!
294 Constructs a solid line pen with 1 width and the given \a color.
295
296 \sa setBrush(), setColor()
297*/
298
299QPen::QPen(const QColor &color)
300{
301 d = new QPenData(color, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join);
302}
303
304
305/*!
306 \fn QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle style, Qt::PenCapStyle cap, Qt::PenJoinStyle join)
307
308 Constructs a pen with the specified \a brush, \a width, pen \a style,
309 \a cap style and \a join style.
310
311 \sa setBrush(), setWidth(), setStyle(), setCapStyle(), setJoinStyle()
312*/
313
314QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j)
315{
316 d = new QPenData(brush, width, s, c, j, false);
317}
318
319/*!
320 \fn QPen::QPen(const QPen &pen)
321
322 Constructs a pen that is a copy of the given \a pen.
323*/
324
325QPen::QPen(const QPen &p) noexcept
326{
327 d = p.d;
328 if (d)
329 d->ref.ref();
330}
331
332
333/*!
334 \fn QPen::QPen(QPen &&pen)
335 \since 5.4
336
337 Constructs a pen that is moved from the given \a pen.
338
339 The moved-from pen can only be assigned to, copied, or
340 destroyed. Any other operation (prior to assignment) leads to
341 undefined behavior.
342*/
343
344/*!
345 Destroys the pen.
346*/
347
348QPen::~QPen()
349{
350 if (d && !d->ref.deref())
351 delete d;
352}
353
354/*!
355 \fn void QPen::detach()
356 Detaches from shared pen data to make sure that this pen is the
357 only one referring the data.
358
359 If multiple pens share common data, this pen dereferences the data
360 and gets a copy of the data. Nothing is done if there is just a
361 single reference.
362*/
363
364void QPen::detach()
365{
366 if (d->ref.loadRelaxed() == 1)
367 return;
368
369 QPenData *x = new QPenData(*static_cast<QPenData *>(d));
370 if (!d->ref.deref())
371 delete d;
372 x->ref.storeRelaxed(newValue: 1);
373 d = x;
374}
375
376
377/*!
378 \fn QPen &QPen::operator=(const QPen &pen)
379
380 Assigns the given \a pen to this pen and returns a reference to
381 this pen.
382*/
383
384QPen &QPen::operator=(const QPen &p) noexcept
385{
386 QPen(p).swap(other&: *this);
387 return *this;
388}
389
390/*!
391 \fn QPen &QPen::operator=(QPen &&other)
392
393 Move-assigns \a other to this QPen instance.
394
395 \since 5.2
396*/
397
398/*!
399 \fn void QPen::swap(QPen &other)
400 \since 4.8
401
402 Swaps pen \a other with this pen. This operation is very
403 fast and never fails.
404*/
405
406/*!
407 Returns the pen as a QVariant.
408*/
409QPen::operator QVariant() const
410{
411 return QVariant(QMetaType::QPen, this);
412}
413
414/*!
415 \fn Qt::PenStyle QPen::style() const
416
417 Returns the pen style.
418
419 \sa setStyle(), {QPen#Pen Style}{Pen Style}
420*/
421Qt::PenStyle QPen::style() const
422{
423 return d->style;
424}
425/*!
426 \fn void QPen::setStyle(Qt::PenStyle style)
427
428 Sets the pen style to the given \a style.
429
430 See the \l Qt::PenStyle documentation for a list of the available
431 styles. Since Qt 4.1 it is also possible to specify a custom dash
432 pattern using the setDashPattern() function which implicitly
433 converts the style of the pen to Qt::CustomDashLine.
434
435 \note This function resets the dash offset to zero.
436
437 \sa style(), {QPen#Pen Style}{Pen Style}
438*/
439
440void QPen::setStyle(Qt::PenStyle s)
441{
442 if (d->style == s)
443 return;
444 detach();
445 d->style = s;
446 QPenData *dd = static_cast<QPenData *>(d);
447 dd->dashPattern.clear();
448 dd->dashOffset = 0;
449}
450
451/*!
452 Returns the dash pattern of this pen.
453
454 \sa style(), isSolid()
455 */
456QVector<qreal> QPen::dashPattern() const
457{
458 QPenData *dd = static_cast<QPenData *>(d);
459 if (d->style == Qt::SolidLine || d->style == Qt::NoPen) {
460 return QVector<qreal>();
461 } else if (dd->dashPattern.isEmpty()) {
462 const qreal space = 2;
463 const qreal dot = 1;
464 const qreal dash = 4;
465
466 switch (d->style) {
467 case Qt::DashLine:
468 dd->dashPattern.reserve(asize: 2);
469 dd->dashPattern << dash << space;
470 break;
471 case Qt::DotLine:
472 dd->dashPattern.reserve(asize: 2);
473 dd->dashPattern << dot << space;
474 break;
475 case Qt::DashDotLine:
476 dd->dashPattern.reserve(asize: 4);
477 dd->dashPattern << dash << space << dot << space;
478 break;
479 case Qt::DashDotDotLine:
480 dd->dashPattern.reserve(asize: 6);
481 dd->dashPattern << dash << space << dot << space << dot << space;
482 break;
483 default:
484 break;
485 }
486 }
487 return dd->dashPattern;
488}
489
490/*!
491 Sets the dash pattern for this pen to the given \a pattern. This
492 implicitly converts the style of the pen to Qt::CustomDashLine.
493
494 The pattern must be specified as an even number of positive entries
495 where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the
496 spaces. For example:
497
498 \table 100%
499 \row
500 \li \inlineimage qpen-custom.png
501 \li
502 \snippet code/src_gui_painting_qpen.cpp 3
503 \endtable
504
505 The dash pattern is specified in units of the pens width; e.g. a
506 dash of length 5 in width 10 is 50 pixels long. Note that a pen
507 with zero width is equivalent to a cosmetic pen with a width of 1
508 pixel.
509
510 Each dash is also subject to cap styles so a dash of 1 with square
511 cap set will extend 0.5 pixels out in each direction resulting in
512 a total width of 2.
513
514 Note that the default cap style is Qt::SquareCap, meaning that a
515 square line end covers the end point and extends beyond it by half
516 the line width.
517
518 \sa setStyle(), dashPattern(), setCapStyle(), setCosmetic()
519 */
520void QPen::setDashPattern(const QVector<qreal> &pattern)
521{
522 if (pattern.isEmpty())
523 return;
524 detach();
525
526 QPenData *dd = static_cast<QPenData *>(d);
527 dd->dashPattern = pattern;
528 d->style = Qt::CustomDashLine;
529
530 if ((dd->dashPattern.size() % 2) == 1) {
531 qWarning(msg: "QPen::setDashPattern: Pattern not of even length");
532 dd->dashPattern << 1;
533 }
534}
535
536
537/*!
538 Returns the dash offset for the pen.
539
540 \sa setDashOffset()
541*/
542qreal QPen::dashOffset() const
543{
544 QPenData *dd = static_cast<QPenData *>(d);
545 return dd->dashOffset;
546}
547/*!
548 Sets the dash offset (the starting point on the dash pattern) for this pen
549 to the \a offset specified. The offset is measured in terms of the units used
550 to specify the dash pattern.
551
552 \table
553 \row \li \inlineimage qpen-dashpattern.png
554 \li For example, a pattern where each stroke is four units long, followed by a gap
555 of two units, will begin with the stroke when drawn as a line.
556
557 However, if the dash offset is set to 4.0, any line drawn will begin with the gap.
558 Values of the offset up to 4.0 will cause part of the stroke to be drawn first,
559 and values of the offset between 4.0 and 6.0 will cause the line to begin with
560 part of the gap.
561 \endtable
562
563 \note This implicitly converts the style of the pen to Qt::CustomDashLine.
564*/
565void QPen::setDashOffset(qreal offset)
566{
567 if (qFuzzyCompare(p1: offset, p2: static_cast<QPenData *>(d)->dashOffset))
568 return;
569 detach();
570 QPenData *dd = static_cast<QPenData *>(d);
571 dd->dashOffset = offset;
572 if (d->style != Qt::CustomDashLine) {
573 dd->dashPattern = dashPattern();
574 d->style = Qt::CustomDashLine;
575 }
576}
577
578/*!
579 Returns the miter limit of the pen. The miter limit is only
580 relevant when the join style is set to Qt::MiterJoin.
581
582 \sa setMiterLimit(), {QPen#Join Style}{Join Style}
583*/
584qreal QPen::miterLimit() const
585{
586 const QPenData *dd = static_cast<QPenData *>(d);
587 return dd->miterLimit;
588}
589
590/*!
591 Sets the miter limit of this pen to the given \a limit.
592
593 \image qpen-miterlimit.png
594
595 The miter limit describes how far a miter join can extend from the
596 join point. This is used to reduce artifacts between line joins
597 where the lines are close to parallel.
598
599 This value does only have effect when the pen style is set to
600 Qt::MiterJoin. The value is specified in units of the pen's width,
601 e.g. a miter limit of 5 in width 10 is 50 pixels long. The default
602 miter limit is 2, i.e. twice the pen width in pixels.
603
604 \sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style}
605*/
606void QPen::setMiterLimit(qreal limit)
607{
608 detach();
609 QPenData *dd = static_cast<QPenData *>(d);
610 dd->miterLimit = limit;
611}
612
613
614/*!
615 \fn qreal QPen::width() const
616
617 Returns the pen width with integer precision.
618
619 \sa setWidth(), widthF()
620*/
621
622int QPen::width() const
623{
624 return qRound(d: d->width);
625}
626
627/*!
628 \fn qreal QPen::widthF() const
629
630 Returns the pen width with floating point precision.
631
632 \sa setWidthF(), width()
633*/
634qreal QPen::widthF() const
635{
636 return d->width;
637}
638
639/*!
640 \fn QPen::setWidth(int width)
641
642 Sets the pen width to the given \a width in pixels with integer
643 precision.
644
645 A line width of zero indicates a cosmetic pen. This means that the
646 pen width is always drawn one pixel wide, independent of the \l
647 {QPainter#Coordinate Transformations}{transformation} set on the
648 painter.
649
650 Setting a pen width with a negative value is not supported.
651
652 \sa setWidthF(), width()
653*/
654void QPen::setWidth(int width)
655{
656 if (width < 0 || width >= (1 << 15)) {
657 qWarning(msg: "QPen::setWidth: Setting a pen width that is out of range");
658 return;
659 }
660 if ((qreal)width == d->width)
661 return;
662 detach();
663 d->width = width;
664 d->defaultWidth = false;
665}
666
667/*!
668 Sets the pen width to the given \a width in pixels with floating point
669 precision.
670
671 A line width of zero indicates a cosmetic pen. This means that the
672 pen width is always drawn one pixel wide, independent of the \l
673 {QPainter#Coordinate Transformations}{transformation} on the
674 painter.
675
676 Setting a pen width with a negative value is not supported.
677
678 \sa setWidth(), widthF()
679*/
680
681void QPen::setWidthF(qreal width)
682{
683 if (width < 0.f || width >= (1 << 15)) {
684 qWarning(msg: "QPen::setWidthF: Setting a pen width that is out of range");
685 return;
686 }
687 if (qAbs(t: d->width - width) < 0.00000001f)
688 return;
689 detach();
690 d->width = width;
691 d->defaultWidth = false;
692}
693
694
695/*!
696 Returns the pen's cap style.
697
698 \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
699*/
700Qt::PenCapStyle QPen::capStyle() const
701{
702 return d->capStyle;
703}
704
705/*!
706 \fn void QPen::setCapStyle(Qt::PenCapStyle style)
707
708 Sets the pen's cap style to the given \a style. The default value
709 is Qt::SquareCap.
710
711 \sa capStyle(), {QPen#Cap Style}{Cap Style}
712*/
713
714void QPen::setCapStyle(Qt::PenCapStyle c)
715{
716 if (d->capStyle == c)
717 return;
718 detach();
719 d->capStyle = c;
720}
721
722/*!
723 Returns the pen's join style.
724
725 \sa setJoinStyle(), {QPen#Join Style}{Join Style}
726*/
727Qt::PenJoinStyle QPen::joinStyle() const
728{
729 return d->joinStyle;
730}
731
732/*!
733 \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
734
735 Sets the pen's join style to the given \a style. The default value
736 is Qt::BevelJoin.
737
738 \sa joinStyle(), {QPen#Join Style}{Join Style}
739*/
740
741void QPen::setJoinStyle(Qt::PenJoinStyle j)
742{
743 if (d->joinStyle == j)
744 return;
745 detach();
746 d->joinStyle = j;
747}
748
749/*!
750 \fn const QColor &QPen::color() const
751
752 Returns the color of this pen's brush.
753
754 \sa brush(), setColor()
755*/
756QColor QPen::color() const
757{
758 return d->brush.color();
759}
760
761/*!
762 \fn void QPen::setColor(const QColor &color)
763
764 Sets the color of this pen's brush to the given \a color.
765
766 \sa setBrush(), color()
767*/
768
769void QPen::setColor(const QColor &c)
770{
771 detach();
772 d->brush = QBrush(c);
773}
774
775
776/*!
777 Returns the brush used to fill strokes generated with this pen.
778*/
779QBrush QPen::brush() const
780{
781 return d->brush;
782}
783
784/*!
785 Sets the brush used to fill strokes generated with this pen to the given
786 \a brush.
787
788 \sa brush(), setColor()
789*/
790void QPen::setBrush(const QBrush &brush)
791{
792 detach();
793 d->brush = brush;
794}
795
796
797/*!
798 Returns \c true if the pen has a solid fill, otherwise false.
799
800 \sa style(), dashPattern()
801*/
802bool QPen::isSolid() const
803{
804 return d->brush.style() == Qt::SolidPattern;
805}
806
807
808/*!
809 Returns \c true if the pen is cosmetic; otherwise returns \c false.
810
811 Cosmetic pens are used to draw strokes that have a constant width
812 regardless of any transformations applied to the QPainter they are
813 used with. Drawing a shape with a cosmetic pen ensures that its
814 outline will have the same thickness at different scale factors.
815
816 A zero width pen is cosmetic by default.
817
818 \sa setCosmetic(), widthF()
819*/
820
821bool QPen::isCosmetic() const
822{
823 QPenData *dd = static_cast<QPenData *>(d);
824 return (dd->cosmetic == true) || d->width == 0;
825}
826
827
828/*!
829 Sets this pen to cosmetic or non-cosmetic, depending on the value of
830 \a cosmetic.
831
832 \sa isCosmetic()
833*/
834
835void QPen::setCosmetic(bool cosmetic)
836{
837 detach();
838 QPenData *dd = static_cast<QPenData *>(d);
839 dd->cosmetic = cosmetic;
840}
841
842
843
844/*!
845 \fn bool QPen::operator!=(const QPen &pen) const
846
847 Returns \c true if the pen is different from the given \a pen;
848 otherwise false. Two pens are different if they have different
849 styles, widths or colors.
850
851 \sa operator==()
852*/
853
854/*!
855 \fn bool QPen::operator==(const QPen &pen) const
856
857 Returns \c true if the pen is equal to the given \a pen; otherwise
858 false. Two pens are equal if they have equal styles, widths and
859 colors.
860
861 \sa operator!=()
862*/
863
864bool QPen::operator==(const QPen &p) const
865{
866 QPenData *dd = static_cast<QPenData *>(d);
867 QPenData *pdd = static_cast<QPenData *>(p.d);
868 return (p.d == d)
869 || (p.d->style == d->style
870 && p.d->capStyle == d->capStyle
871 && p.d->joinStyle == d->joinStyle
872 && p.d->width == d->width
873 && pdd->miterLimit == dd->miterLimit
874 && (d->style != Qt::CustomDashLine
875 || (qFuzzyCompare(p1: pdd->dashOffset, p2: dd->dashOffset) &&
876 pdd->dashPattern == dd->dashPattern))
877 && p.d->brush == d->brush
878 && pdd->cosmetic == dd->cosmetic
879 && pdd->defaultWidth == dd->defaultWidth);
880}
881
882
883/*!
884 \fn bool QPen::isDetached()
885
886 \internal
887*/
888
889bool QPen::isDetached()
890{
891 return d->ref.loadRelaxed() == 1;
892}
893
894
895/*****************************************************************************
896 QPen stream functions
897 *****************************************************************************/
898#ifndef QT_NO_DATASTREAM
899/*!
900 \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
901 \relates QPen
902
903 Writes the given \a pen to the given \a stream and returns a reference to
904 the \a stream.
905
906 \sa {Serializing Qt Data Types}
907*/
908
909QDataStream &operator<<(QDataStream &s, const QPen &p)
910{
911 QPenData *dd = static_cast<QPenData *>(p.d);
912 if (s.version() < 3) {
913 s << (quint8)p.style();
914 } else if (s.version() < QDataStream::Qt_4_3) {
915 s << (quint8)(p.style() | p.capStyle() | p.joinStyle());
916 } else {
917 s << (quint16)(p.style() | p.capStyle() | p.joinStyle());
918 s << (bool)(dd->cosmetic);
919 }
920
921 if (s.version() < 7) {
922 s << (quint8)p.width();
923 s << p.color();
924 } else {
925 s << double(p.widthF());
926 s << p.brush();
927 s << double(p.miterLimit());
928 if (sizeof(qreal) == sizeof(double)) {
929 s << p.dashPattern();
930 } else {
931 // ensure that we write doubles here instead of streaming the pattern
932 // directly; otherwise, platforms that redefine qreal might generate
933 // data that cannot be read on other platforms.
934 QVector<qreal> pattern = p.dashPattern();
935 s << quint32(pattern.size());
936 for (int i = 0; i < pattern.size(); ++i)
937 s << double(pattern.at(i));
938 }
939 if (s.version() >= 9)
940 s << double(p.dashOffset());
941 if (s.version() >= QDataStream::Qt_5_0)
942 s << bool(dd->defaultWidth);
943 }
944 return s;
945}
946
947/*!
948 \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
949 \relates QPen
950
951 Reads a pen from the given \a stream into the given \a pen and
952 returns a reference to the \a stream.
953
954 \sa {Serializing Qt Data Types}
955*/
956
957QDataStream &operator>>(QDataStream &s, QPen &p)
958{
959 quint16 style;
960 quint8 width8 = 0;
961 double width = 0;
962 QColor color;
963 QBrush brush;
964 double miterLimit = 2;
965 QVector<qreal> dashPattern;
966 double dashOffset = 0;
967 bool cosmetic = false;
968 bool defaultWidth = false;
969 if (s.version() < QDataStream::Qt_4_3) {
970 quint8 style8;
971 s >> style8;
972 style = style8;
973 } else {
974 s >> style;
975 s >> cosmetic;
976 }
977 if (s.version() < 7) {
978 s >> width8;
979 s >> color;
980 brush = color;
981 width = width8;
982 } else {
983 s >> width;
984 s >> brush;
985 s >> miterLimit;
986 if (sizeof(qreal) == sizeof(double)) {
987 s >> dashPattern;
988 } else {
989 quint32 numDashes;
990 s >> numDashes;
991 double dash;
992 dashPattern.reserve(asize: numDashes);
993 for (quint32 i = 0; i < numDashes; ++i) {
994 s >> dash;
995 dashPattern << dash;
996 }
997 }
998 if (s.version() >= 9)
999 s >> dashOffset;
1000 }
1001
1002 if (s.version() >= QDataStream::Qt_5_0) {
1003 s >> defaultWidth;
1004 } else {
1005 // best we can do for legacy pens
1006 defaultWidth = qFuzzyIsNull(d: width);
1007 }
1008
1009 p.detach();
1010 QPenData *dd = static_cast<QPenData *>(p.d);
1011 dd->width = width;
1012 dd->brush = brush;
1013 dd->style = Qt::PenStyle(style & Qt::MPenStyle);
1014 dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
1015 dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
1016 dd->dashPattern = dashPattern;
1017 dd->miterLimit = miterLimit;
1018 dd->dashOffset = dashOffset;
1019 dd->cosmetic = cosmetic;
1020 dd->defaultWidth = defaultWidth;
1021
1022 return s;
1023}
1024#endif //QT_NO_DATASTREAM
1025
1026#ifndef QT_NO_DEBUG_STREAM
1027QDebug operator<<(QDebug dbg, const QPen &p)
1028{
1029 const char *PEN_STYLES[] = {
1030 "NoPen",
1031 "SolidLine",
1032 "DashLine",
1033 "DotLine",
1034 "DashDotLine",
1035 "DashDotDotLine",
1036 "CustomDashLine"
1037 };
1038
1039 QDebugStateSaver saver(dbg);
1040 dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
1041 << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
1042 << ',' << int(p.joinStyle()) << ',' << p.dashPattern()
1043 << ',' << p.dashOffset()
1044 << ',' << p.miterLimit() << ')';
1045 return dbg;
1046}
1047#endif
1048
1049/*!
1050 \fn DataPtr &QPen::data_ptr()
1051 \internal
1052*/
1053
1054/*!
1055 \typedef QPen::DataPtr
1056
1057 \internal
1058*/
1059
1060QT_END_NAMESPACE
1061
1062#undef QT_COMPILING_QPEN
1063

source code of qtbase/src/gui/painting/qpen.cpp