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 {Solid line}
68 \li \inlineimage qpen-dash.png {Dashed line}
69 \li \inlineimage qpen-dot.png {Dotted line}
70 \row
71 \li Qt::SolidLine
72 \li Qt::DashLine
73 \li Qt::DotLine
74 \row
75 \li \inlineimage qpen-dashdot.png {Dash-dot line}
76 \li \inlineimage qpen-dashdotdot.png {Dash-dot-dot line}
77 \li \inlineimage qpen-custom.png {Custom dash line}
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 {Square cap}
117 \li \inlineimage qpen-flat.png {Flat cap}
118 \li \inlineimage qpen-roundcap.png {Round cap}
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 {Bevel join}
147 \li \inlineimage qpen-miter.png {Miter join}
148 \li \inlineimage qpen-roundjoin.png {Round join}
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 {Path Stroking application with pen options}
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 {Custom dash line}
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 {Dash patterns with different offsets}
535 \li For example, a pattern where each stroke is four units long, followed by a gap
536 of two units, will begin with the stroke when drawn as a line.
537
538 However, if the dash offset is set to 4.0, any line drawn will begin with the gap.
539 Values of the offset up to 4.0 will cause part of the stroke to be drawn first,
540 and values of the offset between 4.0 and 6.0 will cause the line to begin with
541 part of the gap.
542 \endtable
543
544 \note This implicitly converts the style of the pen to Qt::CustomDashLine.
545*/
546void QPen::setDashOffset(qreal offset)
547{
548 if (qFuzzyCompare(offset, d->dashOffset))
549 return;
550 detach();
551 d->dashOffset = offset;
552 if (d->style != Qt::CustomDashLine) {
553 d->dashPattern = dashPattern();
554 d->style = Qt::CustomDashLine;
555 }
556}
557
558/*!
559 Returns the miter limit of the pen. The miter limit is only
560 relevant when the join style is set to Qt::MiterJoin.
561
562 \sa setMiterLimit(), {QPen#Join Style}{Join Style}
563*/
564qreal QPen::miterLimit() const
565{
566 return d->miterLimit;
567}
568
569/*!
570 Sets the miter limit of this pen to the given \a limit.
571
572 \image qpen-miterlimit.png {Miter join with width and miterLimit labeled}
573
574 The miter limit describes how far a miter join can extend from the
575 join point. This is used to reduce artifacts between line joins
576 where the lines are close to parallel.
577
578 This value does only have effect when the pen style is set to
579 Qt::MiterJoin. The value is specified in units of the pen's width,
580 e.g. a miter limit of 5 in width 10 is 50 pixels long. The default
581 miter limit is 2, i.e. twice the pen width in pixels.
582
583 \sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style}
584*/
585void QPen::setMiterLimit(qreal limit)
586{
587 detach();
588 d->miterLimit = limit;
589}
590
591
592/*!
593 \fn qreal QPen::width() const
594
595 Returns the pen width with integer precision.
596
597 \sa setWidth(), widthF()
598*/
599
600int QPen::width() const
601{
602 return qRound(d->width);
603}
604
605/*!
606 \fn qreal QPen::widthF() const
607
608 Returns the pen width with floating point precision.
609
610 \sa setWidthF(), width()
611*/
612qreal QPen::widthF() const
613{
614 return d->width;
615}
616
617/*!
618 \fn QPen::setWidth(int width)
619
620 Sets the pen width to the given \a width in pixels with integer
621 precision.
622
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
626 painter.
627
628 Setting a pen width with a negative value is not supported.
629
630 \sa setWidthF(), width()
631*/
632void QPen::setWidth(int width)
633{
634 if (width < 0 || width >= (1 << 15)) {
635 qWarning("QPen::setWidth: Setting a pen width that is out of range");
636 return;
637 }
638 if ((qreal)width == d->width)
639 return;
640 detach();
641 d->width = width;
642}
643
644/*!
645 Sets the pen width to the given \a width in pixels with floating point
646 precision.
647
648 A line width of zero indicates a cosmetic pen. This means that the
649 pen width is always drawn one pixel wide, independent of the \l
650 {QPainter#Coordinate Transformations}{transformation} on the
651 painter.
652
653 Setting a pen width with a negative value is not supported.
654
655 \sa setWidth(), widthF()
656*/
657
658void QPen::setWidthF(qreal width)
659{
660 if (width < 0.f || width >= (1 << 15)) {
661 qWarning("QPen::setWidthF: Setting a pen width that is out of range");
662 return;
663 }
664 if (qAbs(d->width - width) < 0.00000001f)
665 return;
666 detach();
667 d->width = width;
668}
669
670
671/*!
672 Returns the pen's cap style.
673
674 \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
675*/
676Qt::PenCapStyle QPen::capStyle() const
677{
678 return d->capStyle;
679}
680
681/*!
682 \fn void QPen::setCapStyle(Qt::PenCapStyle style)
683
684 Sets the pen's cap style to the given \a style. The default value
685 is Qt::SquareCap.
686
687 \sa capStyle(), {QPen#Cap Style}{Cap Style}
688*/
689
690void QPen::setCapStyle(Qt::PenCapStyle c)
691{
692 if (d->capStyle == c)
693 return;
694 detach();
695 d->capStyle = c;
696}
697
698/*!
699 Returns the pen's join style.
700
701 \sa setJoinStyle(), {QPen#Join Style}{Join Style}
702*/
703Qt::PenJoinStyle QPen::joinStyle() const
704{
705 return d->joinStyle;
706}
707
708/*!
709 \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
710
711 Sets the pen's join style to the given \a style. The default value
712 is Qt::BevelJoin.
713
714 \sa joinStyle(), {QPen#Join Style}{Join Style}
715*/
716
717void QPen::setJoinStyle(Qt::PenJoinStyle j)
718{
719 if (d->joinStyle == j)
720 return;
721 detach();
722 d->joinStyle = j;
723}
724
725/*!
726 \fn const QColor &QPen::color() const
727
728 Returns the color of this pen's brush.
729
730 \sa brush(), setColor()
731*/
732QColor QPen::color() const
733{
734 return d->brush.color();
735}
736
737/*!
738 \fn void QPen::setColor(const QColor &color)
739
740 Sets the color of this pen's brush to the given \a color.
741
742 \sa setBrush(), color()
743*/
744
745void QPen::setColor(const QColor &c)
746{
747 detach();
748 d->brush = QBrush(c);
749}
750
751
752/*!
753 Returns the brush used to fill strokes generated with this pen.
754*/
755QBrush QPen::brush() const
756{
757 return d->brush;
758}
759
760/*!
761 Sets the brush used to fill strokes generated with this pen to the given
762 \a brush.
763
764 \sa brush(), setColor()
765*/
766void QPen::setBrush(const QBrush &brush)
767{
768 detach();
769 d->brush = brush;
770}
771
772
773/*!
774 Returns \c true if the pen has a solid fill, otherwise false.
775
776 \sa style(), dashPattern()
777*/
778bool QPen::isSolid() const
779{
780 return d->brush.style() == Qt::SolidPattern;
781}
782
783
784/*!
785 Returns \c true if the pen is cosmetic; otherwise returns \c false.
786
787 Cosmetic pens are used to draw strokes that have a constant width
788 regardless of any transformations applied to the QPainter they are
789 used with. Drawing a shape with a cosmetic pen ensures that its
790 outline will have the same thickness at different scale factors.
791
792 A zero width pen is cosmetic by default.
793
794 \sa setCosmetic(), widthF()
795*/
796
797bool QPen::isCosmetic() const
798{
799 return (d->cosmetic == true) || d->width == 0;
800}
801
802
803/*!
804 Sets this pen to cosmetic or non-cosmetic, depending on the value of
805 \a cosmetic.
806
807 \sa isCosmetic()
808*/
809
810void QPen::setCosmetic(bool cosmetic)
811{
812 detach();
813 d->cosmetic = cosmetic;
814}
815
816/*!
817 \internal
818*/
819bool QPen::isSolidDefaultLine() const noexcept
820{
821 return d->style == Qt::SolidLine && d->width == 1
822 && d->capStyle == qpen_default_cap && d->joinStyle == qpen_default_join
823 && qFuzzyCompare(d->dashOffset, 0) && qFuzzyCompare(d->miterLimit, 2)
824 && d->cosmetic == false;
825}
826
827/*!
828 \fn bool QPen::operator!=(const QPen &pen) const
829
830 Returns \c true if the pen is different from the given \a pen;
831 otherwise false. Two pens are different if they have different
832 styles, widths or colors.
833
834 \sa operator==()
835*/
836
837/*!
838 \fn bool QPen::operator==(const QPen &pen) const
839
840 Returns \c true if the pen is equal to the given \a pen; otherwise
841 false. Two pens are equal if they have equal styles, widths and
842 colors.
843
844 \sa operator!=()
845*/
846
847bool QPen::operator==(const QPen &p) const
848{
849 return (p.d == d)
850 || (p.d->style == d->style
851 && p.d->capStyle == d->capStyle
852 && p.d->joinStyle == d->joinStyle
853 && p.d->width == d->width
854 && p.d->miterLimit == d->miterLimit
855 && (d->style != Qt::CustomDashLine
856 || (qFuzzyCompare(p.d->dashOffset, d->dashOffset) &&
857 p.d->dashPattern == d->dashPattern))
858 && p.d->brush == d->brush
859 && p.d->cosmetic == d->cosmetic);
860}
861
862/*!
863 \internal
864*/
865bool QPen::doCompareEqualColor(QColor rhs) const noexcept
866{
867 return d->brush == rhs && isSolidDefaultLine();
868}
869
870/*!
871 \internal
872*/
873bool QPen::doCompareEqualStyle(Qt::PenStyle rhs) const
874{
875 if (rhs == Qt::NoPen)
876 return style() == Qt::NoPen;
877 return *this == QPen(rhs); // ### optimize (allocates)
878}
879
880/*!
881 \fn bool QPen::isDetached()
882
883 \internal
884*/
885
886bool QPen::isDetached()
887{
888 return d->ref.loadRelaxed() == 1;
889}
890
891
892/*****************************************************************************
893 QPen stream functions
894 *****************************************************************************/
895#ifndef QT_NO_DATASTREAM
896/*!
897 \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
898 \relates QPen
899
900 Writes the given \a pen to the given \a stream and returns a reference to
901 the \a stream.
902
903 \sa {Serializing Qt Data Types}
904*/
905
906QDataStream &operator<<(QDataStream &s, const QPen &p)
907{
908 if (s.version() < 3) {
909 s << (quint8)p.style();
910 } else if (s.version() < QDataStream::Qt_4_3) {
911 s << (quint8)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle()));
912 } else {
913 s << (quint16)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle()));
914 s << (bool)(p.d->cosmetic);
915 }
916
917 if (s.version() < 7) {
918 s << (quint8)p.width();
919 s << p.color();
920 } else {
921 s << double(p.widthF());
922 s << p.brush();
923 s << double(p.miterLimit());
924 if (sizeof(qreal) == sizeof(double)) {
925 s << p.dashPattern();
926 } else {
927 // ensure that we write doubles here instead of streaming the pattern
928 // directly; otherwise, platforms that redefine qreal might generate
929 // data that cannot be read on other platforms.
930 QList<qreal> pattern = p.dashPattern();
931 s << quint32(pattern.size());
932 for (int i = 0; i < pattern.size(); ++i)
933 s << double(pattern.at(i));
934 }
935 if (s.version() >= 9)
936 s << double(p.dashOffset());
937 if (s.version() >= QDataStream::Qt_5_0)
938 s << bool(qFuzzyIsNull(p.widthF()));
939 }
940 return s;
941}
942
943/*!
944 \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
945 \relates QPen
946
947 Reads a pen from the given \a stream into the given \a pen and
948 returns a reference to the \a stream.
949
950 \sa {Serializing Qt Data Types}
951*/
952
953QDataStream &operator>>(QDataStream &s, QPen &p)
954{
955 quint16 style;
956 quint8 width8 = 0;
957 double width = 0;
958 QColor color;
959 QBrush brush;
960 double miterLimit = 2;
961 QList<qreal> dashPattern;
962 double dashOffset = 0;
963 bool cosmetic = false;
964 bool defaultWidth;
965 if (s.version() < QDataStream::Qt_4_3) {
966 quint8 style8;
967 s >> style8;
968 style = style8;
969 } else {
970 s >> style;
971 s >> cosmetic;
972 }
973 if (s.version() < 7) {
974 s >> width8;
975 s >> color;
976 brush = color;
977 width = width8;
978 } else {
979 s >> width;
980 s >> brush;
981 s >> miterLimit;
982 if (sizeof(qreal) == sizeof(double)) {
983 s >> dashPattern;
984 } else {
985 quint32 numDashes;
986 s >> numDashes;
987 double dash;
988 dashPattern.reserve(numDashes);
989 for (quint32 i = 0; i < numDashes; ++i) {
990 s >> dash;
991 dashPattern << dash;
992 }
993 }
994 if (s.version() >= 9)
995 s >> dashOffset;
996 }
997
998 if (s.version() >= QDataStream::Qt_5_0) {
999 s >> defaultWidth;
1000 }
1001
1002 p.detach();
1003 p.d->width = width;
1004 p.d->brush = brush;
1005 p.d->style = Qt::PenStyle(style & Qt::MPenStyle);
1006 p.d->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
1007 p.d->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
1008 p.d->dashPattern = dashPattern;
1009 p.d->miterLimit = miterLimit;
1010 p.d->dashOffset = dashOffset;
1011 p.d->cosmetic = cosmetic;
1012
1013 return s;
1014}
1015#endif //QT_NO_DATASTREAM
1016
1017#ifndef QT_NO_DEBUG_STREAM
1018QDebug operator<<(QDebug dbg, const QPen &p)
1019{
1020 QDebugStateSaver saver(dbg);
1021 dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
1022 << ',' << p.style() << ',' << p.capStyle()
1023 << ',' << p.joinStyle() << ',' << p.dashPattern()
1024 << ',' << p.dashOffset()
1025 << ',' << p.miterLimit() << ')';
1026 return dbg;
1027}
1028#endif
1029
1030/*!
1031 \fn DataPtr &QPen::data_ptr()
1032 \internal
1033*/
1034
1035/*!
1036 \typedef QPen::DataPtr
1037
1038 \internal
1039*/
1040
1041QT_END_NAMESPACE
1042
1043#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:1018
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:953