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