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. The Qt::SvgMiterJoin style is a miter join as defined
159 by SVG and PDF, and differs from Qt::MiterJoin in how it applies the
160 miter limit.
161
162 The default is Qt::BevelJoin.
163
164 \image qpen-miterlimit.png {Illustration showing how miterLimit controls
165 the length of the sharp corner for miterJoin}
166
167 When the Qt::MiterJoin or Qt::SvgMiterJoin style is applied, it is
168 possible to use the setMiterLimit() function to specify how far the
169 miter join can extend from the join point. The miterLimit() is used
170 to reduce artifacts between line joins where the lines are close to
171 parallel.
172
173 The miterLimit() must be specified in units of the pen's width.
174 With Qt::MiterJoin, a miter limit of 5 in width 10 is 50 pixels long,
175 and a longer miter is cut off at that length. With Qt::SvgMiterJoin,
176 the miter limit is the largest allowed ratio of the miter's length to
177 the pen's width, and a join that exceeds it is drawn as a bevel join
178 instead. The default miter limit is 2.
179
180 \table 100%
181 \row
182 \li \inlineimage qpen-demo.png {Path Stroking application with pen options}
183 \li \b {\l {painting/pathstroke}{The Path Stroking Example}}
184
185 The Path Stroking example shows Qt's built-in dash patterns and shows
186 how custom patterns can be used to extend the range of available
187 patterns.
188 \endtable
189
190 \sa QPainter, QBrush, {painting/pathstroke}{Path Stroking Example},
191 {Scribble Example}
192*/
193
194/*!
195 \internal
196*/
197QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle,
198 Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle)
199 : dashOffset(0), miterLimit(2),
200 cosmetic(false)
201{
202 width = _width;
203 brush = _brush;
204 style = penStyle;
205 capStyle = _capStyle;
206 joinStyle = _joinStyle;
207}
208
209static constexpr Qt::PenCapStyle qpen_default_cap = Qt::SquareCap;
210static constexpr Qt::PenJoinStyle qpen_default_join = Qt::BevelJoin;
211
213{
214public:
216 QPenDataHolder(const QBrush &brush, qreal width, Qt::PenStyle penStyle,
217 Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle)
219 { }
220 ~QPenDataHolder() = default;
222};
223
224Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, defaultPenInstance,
225 (Qt::black, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join))
226Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance,
227 (Qt::black, 1, Qt::NoPen, qpen_default_cap, qpen_default_join))
228
229/*!
230 Constructs a default black solid line pen with 1 width.
231*/
232
233QPen::QPen()
234{
235 d = defaultPenInstance()->pen;
236}
237
238/*!
239 Constructs a black pen with 1 width and the given \a style.
240
241 \sa setStyle()
242*/
243
244QPen::QPen(Qt::PenStyle style)
245{
246 if (style == Qt::NoPen) {
247 d = nullPenInstance()->pen;
248 } else {
249 d = new QPenPrivate(Qt::black, 1, style, qpen_default_cap, qpen_default_join);
250 }
251}
252
253
254/*!
255 Constructs a solid line pen with 1 width and the given \a color.
256
257 \sa setBrush(), setColor()
258*/
259
260QPen::QPen(const QColor &color)
261{
262 d = new QPenPrivate(color, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join);
263}
264
265
266/*!
267 \fn QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle style, Qt::PenCapStyle cap, Qt::PenJoinStyle join)
268
269 Constructs a pen with the specified \a brush, \a width, pen \a style,
270 \a cap style and \a join style.
271
272 \sa setBrush(), setWidth(), setStyle(), setCapStyle(), setJoinStyle()
273*/
274
275QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j)
276{
277 d = new QPenPrivate(brush, width, s, c, j);
278}
279
280/*!
281 \fn QPen::QPen(const QPen &pen)
282
283 Constructs a pen that is a copy of the given \a pen.
284*/
285
286QPen::QPen(const QPen &p) noexcept
287 : d(p.d)
288{
289}
290
291
292/*!
293 \fn QPen::QPen(QPen &&pen)
294 \since 5.4
295
296 Constructs a pen that is moved from the given \a pen.
297
298 The moved-from pen can only be assigned to, copied, or
299 destroyed. Any other operation (prior to assignment) leads to
300 undefined behavior.
301*/
302
303/*!
304 Destroys the pen.
305*/
306
307QPen::~QPen() = default;
308
309QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QPenPrivate)
310
311/*!
312 \fn void QPen::detach()
313 Detaches from shared pen data to make sure that this pen is the
314 only one referring the data.
315
316 If multiple pens share common data, this pen dereferences the data
317 and gets a copy of the data. Nothing is done if there is just a
318 single reference.
319*/
320
321void QPen::detach()
322{
323 d.detach();
324}
325
326
327/*!
328 \fn QPen &QPen::operator=(const QPen &pen)
329
330 Assigns the given \a pen to this pen and returns a reference to
331 this pen.
332*/
333
334QPen &QPen::operator=(const QPen &p) noexcept
335{
336 QPen(p).swap(*this);
337 return *this;
338}
339
340/*!
341 \fn QPen &QPen::operator=(QPen &&other)
342
343 Move-assigns \a other to this QPen instance.
344
345 \since 5.2
346*/
347
348/*!
349 \fn void QPen::swap(QPen &other)
350 \since 4.8
351 \memberswap{pen}
352*/
353
354/*!
355 \overload
356 \since 6.9
357
358 Makes this pen a solid pen with the given color, and default
359 cap and join styles, and returns a reference to \e this pen.
360*/
361QPen &QPen::operator=(QColor color)
362{
363 detach();
364 d->brush = color;
365 d->width = 1;
366 d->style = Qt::SolidLine;
367 d->capStyle = qpen_default_cap;
368 d->joinStyle = qpen_default_join;
369
370 return *this;
371}
372
373/*!
374 \overload
375 \since 6.9
376
377 Makes this pen a solid, black pen with default cap and join styles,
378 and returns a reference to \e this pen.
379*/
380QPen &QPen::operator=(Qt::PenStyle style)
381{
382 detach();
383 if (style == Qt::NoPen) {
384 d = nullPenInstance()->pen;
385 } else {
386 d->brush = Qt::black;
387 d->width = 1;
388 d->style = style;
389 d->capStyle = qpen_default_cap;
390 d->joinStyle = qpen_default_join;
391 }
392 return *this;
393}
394
395/*!
396 Returns the pen as a QVariant.
397*/
398QPen::operator QVariant() const
399{
400 return QVariant::fromValue(*this);
401}
402
403/*!
404 \fn Qt::PenStyle QPen::style() const
405
406 Returns the pen style.
407
408 \sa setStyle(), {QPen#Pen Style}{Pen Style}
409*/
410Qt::PenStyle QPen::style() const
411{
412 return d->style;
413}
414/*!
415 \fn void QPen::setStyle(Qt::PenStyle style)
416
417 Sets the pen style to the given \a style.
418
419 See the \l Qt::PenStyle documentation for a list of the available
420 styles. Since Qt 4.1 it is also possible to specify a custom dash
421 pattern using the setDashPattern() function which implicitly
422 converts the style of the pen to Qt::CustomDashLine.
423
424 \note This function resets the dash offset to zero.
425
426 \sa style(), {QPen#Pen Style}{Pen Style}
427*/
428
429void QPen::setStyle(Qt::PenStyle s)
430{
431 if (d->style == s)
432 return;
433 detach();
434 d->style = s;
435 d->dashPattern.clear();
436 d->dashOffset = 0;
437}
438
439/*!
440 Returns the dash pattern of this pen.
441
442 \sa style(), isSolid()
443 */
444QList<qreal> QPen::dashPattern() const
445{
446 if (d->style == Qt::SolidLine || d->style == Qt::NoPen) {
447 return QList<qreal>();
448 } else if (d->dashPattern.isEmpty()) {
449 const qreal space = 2;
450 const qreal dot = 1;
451 const qreal dash = 4;
452
453 switch (d->style) {
454 case Qt::DashLine:
455 d->dashPattern.reserve(2);
456 d->dashPattern << dash << space;
457 break;
458 case Qt::DotLine:
459 d->dashPattern.reserve(2);
460 d->dashPattern << dot << space;
461 break;
462 case Qt::DashDotLine:
463 d->dashPattern.reserve(4);
464 d->dashPattern << dash << space << dot << space;
465 break;
466 case Qt::DashDotDotLine:
467 d->dashPattern.reserve(6);
468 d->dashPattern << dash << space << dot << space << dot << space;
469 break;
470 default:
471 break;
472 }
473 }
474 return d->dashPattern;
475}
476
477/*!
478 Sets the dash pattern for this pen to the given \a pattern. This
479 implicitly converts the style of the pen to Qt::CustomDashLine.
480
481 The pattern must be specified as an even number of positive entries
482 where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the
483 spaces. For example:
484
485 \table 100%
486 \row
487 \li \inlineimage qpen-custom.png {Custom dash line}
488 \li
489 \snippet code/src_gui_painting_qpen.cpp 3
490 \endtable
491
492 The dash pattern is specified in units of the pens width; e.g. a
493 dash of length 5 in width 10 is 50 pixels long. Note that a pen
494 with zero width is equivalent to a cosmetic pen with a width of 1
495 pixel.
496
497 Each dash is also subject to cap styles so a dash of 1 with square
498 cap set will extend 0.5 pixels out in each direction resulting in
499 a total width of 2.
500
501 Note that the default cap style is Qt::SquareCap, meaning that a
502 square line end covers the end point and extends beyond it by half
503 the line width.
504
505 \sa setStyle(), dashPattern(), setCapStyle(), setCosmetic()
506 */
507void QPen::setDashPattern(const QList<qreal> &pattern)
508{
509 if (pattern.isEmpty())
510 return;
511 detach();
512
513 d->dashPattern = pattern;
514 d->style = Qt::CustomDashLine;
515
516 if ((d->dashPattern.size() % 2) == 1) {
517 qWarning("QPen::setDashPattern: Pattern not of even length");
518 d->dashPattern << 1;
519 }
520}
521
522
523/*!
524 Returns the dash offset for the pen.
525
526 \sa setDashOffset()
527*/
528qreal QPen::dashOffset() const
529{
530 return d->dashOffset;
531}
532/*!
533 Sets the dash offset (the starting point on the dash pattern) for this pen
534 to the \a offset specified. The offset is measured in terms of the units used
535 to specify the dash pattern.
536
537 \table
538 \row \li \inlineimage qpen-dashpattern.png
539 {Dash patterns with different offsets}
540 \li For example, a pattern where each stroke is four units long, followed by a gap
541 of two units, will begin with the stroke when drawn as a line.
542
543 However, if the dash offset is set to 4.0, any line drawn will begin with the gap.
544 Values of the offset up to 4.0 will cause part of the stroke to be drawn first,
545 and values of the offset between 4.0 and 6.0 will cause the line to begin with
546 part of the gap.
547 \endtable
548
549 \note This implicitly converts the style of the pen to Qt::CustomDashLine.
550*/
551void QPen::setDashOffset(qreal offset)
552{
553 if (qFuzzyCompare(offset, d->dashOffset))
554 return;
555 detach();
556 d->dashOffset = offset;
557 if (d->style != Qt::CustomDashLine) {
558 d->dashPattern = dashPattern();
559 d->style = Qt::CustomDashLine;
560 }
561}
562
563/*!
564 Returns the miter limit of the pen. The miter limit is only
565 relevant when the join style is set to Qt::MiterJoin or
566 Qt::SvgMiterJoin.
567
568 \sa setMiterLimit(), {QPen#Join Style}{Join Style}
569*/
570qreal QPen::miterLimit() const
571{
572 return d->miterLimit;
573}
574
575/*!
576 Sets the miter limit of this pen to the given \a limit.
577
578 \image qpen-miterlimit.png {Miter join with width and miterLimit labeled}
579
580 The miter limit describes how far a miter join can extend from the
581 join point. This is used to reduce artifacts between line joins
582 where the lines are close to parallel.
583
584 This value only has an effect when the join style is set to
585 Qt::MiterJoin or Qt::SvgMiterJoin, which apply it differently. The
586 value is specified in units of the pen's width. The default miter
587 limit is 2. See \l {QPen#Join Style}{Join Style} for details.
588
589 \sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style}
590*/
591void QPen::setMiterLimit(qreal limit)
592{
593 detach();
594 d->miterLimit = limit;
595}
596
597
598/*!
599 \fn qreal QPen::width() const
600
601 Returns the pen width with integer precision.
602
603 \sa setWidth(), widthF()
604*/
605
606int QPen::width() const
607{
608 return qRound(d->width);
609}
610
611/*!
612 \fn qreal QPen::widthF() const
613
614 Returns the pen width with floating point precision.
615
616 \sa setWidthF(), width()
617*/
618qreal QPen::widthF() const
619{
620 return d->width;
621}
622
623/*!
624 \fn QPen::setWidth(int width)
625
626 Sets the pen width to the given \a width in pixels with integer
627 precision.
628
629 A line width of zero indicates a cosmetic pen. This means that the
630 pen width is always drawn one pixel wide, independent of the \l
631 {QPainter#Coordinate Transformations}{transformation} set on the
632 painter.
633
634 Setting a pen width with a negative value is not supported.
635
636 \sa setWidthF(), width()
637*/
638void QPen::setWidth(int width)
639{
640 if (width < 0 || width >= (1 << 15)) {
641 qWarning("QPen::setWidth: Setting a pen width that is out of range");
642 return;
643 }
644 if ((qreal)width == d->width)
645 return;
646 detach();
647 d->width = width;
648}
649
650/*!
651 Sets the pen width to the given \a width in pixels with floating point
652 precision.
653
654 A line width of zero indicates a cosmetic pen. This means that the
655 pen width is always drawn one pixel wide, independent of the \l
656 {QPainter#Coordinate Transformations}{transformation} on the
657 painter.
658
659 Setting a pen width with a negative value is not supported.
660
661 \sa setWidth(), widthF()
662*/
663
664void QPen::setWidthF(qreal width)
665{
666 if (width < 0.f || width >= (1 << 15)) {
667 qWarning("QPen::setWidthF: Setting a pen width that is out of range");
668 return;
669 }
670 if (qAbs(d->width - width) < 0.00000001f)
671 return;
672 detach();
673 d->width = width;
674}
675
676
677/*!
678 Returns the pen's cap style.
679
680 \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
681*/
682Qt::PenCapStyle QPen::capStyle() const
683{
684 return d->capStyle;
685}
686
687/*!
688 \fn void QPen::setCapStyle(Qt::PenCapStyle style)
689
690 Sets the pen's cap style to the given \a style. The default value
691 is Qt::SquareCap.
692
693 \sa capStyle(), {QPen#Cap Style}{Cap Style}
694*/
695
696void QPen::setCapStyle(Qt::PenCapStyle c)
697{
698 if (d->capStyle == c)
699 return;
700 detach();
701 d->capStyle = c;
702}
703
704/*!
705 Returns the pen's join style.
706
707 \sa setJoinStyle(), {QPen#Join Style}{Join Style}
708*/
709Qt::PenJoinStyle QPen::joinStyle() const
710{
711 return d->joinStyle;
712}
713
714/*!
715 \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
716
717 Sets the pen's join style to the given \a style. The default value
718 is Qt::BevelJoin.
719
720 \sa joinStyle(), {QPen#Join Style}{Join Style}
721*/
722
723void QPen::setJoinStyle(Qt::PenJoinStyle j)
724{
725 if (d->joinStyle == j)
726 return;
727 detach();
728 d->joinStyle = j;
729}
730
731/*!
732 \fn const QColor &QPen::color() const
733
734 Returns the color of this pen's brush.
735
736 \sa brush(), setColor()
737*/
738QColor QPen::color() const
739{
740 return d->brush.color();
741}
742
743/*!
744 \fn void QPen::setColor(const QColor &color)
745
746 Sets the color of this pen's brush to the given \a color.
747
748 \sa setBrush(), color()
749*/
750
751void QPen::setColor(const QColor &c)
752{
753 detach();
754 d->brush = QBrush(c);
755}
756
757
758/*!
759 Returns the brush used to fill strokes generated with this pen.
760*/
761QBrush QPen::brush() const
762{
763 return d->brush;
764}
765
766/*!
767 Sets the brush used to fill strokes generated with this pen to the given
768 \a brush.
769
770 \sa brush(), setColor()
771*/
772void QPen::setBrush(const QBrush &brush)
773{
774 detach();
775 d->brush = brush;
776}
777
778
779/*!
780 Returns \c true if the pen has a solid fill, otherwise false.
781
782 \sa style(), dashPattern()
783*/
784bool QPen::isSolid() const
785{
786 return d->brush.style() == Qt::SolidPattern;
787}
788
789
790/*!
791 Returns \c true if the pen is cosmetic; otherwise returns \c false.
792
793 Cosmetic pens are used to draw strokes that have a constant width
794 regardless of any transformations applied to the QPainter they are
795 used with. Drawing a shape with a cosmetic pen ensures that its
796 outline will have the same thickness at different scale factors.
797
798 A zero width pen is cosmetic by default.
799
800 \sa setCosmetic(), widthF()
801*/
802
803bool QPen::isCosmetic() const
804{
805 return (d->cosmetic == true) || d->width == 0;
806}
807
808
809/*!
810 Sets this pen to cosmetic or non-cosmetic, depending on the value of
811 \a cosmetic.
812
813 \sa isCosmetic()
814*/
815
816void QPen::setCosmetic(bool cosmetic)
817{
818 detach();
819 d->cosmetic = cosmetic;
820}
821
822/*!
823 \internal
824*/
825bool QPen::isSolidDefaultLine() const noexcept
826{
827 return d->style == Qt::SolidLine && d->width == 1
828 && d->capStyle == qpen_default_cap && d->joinStyle == qpen_default_join
829 && qFuzzyCompare(d->dashOffset, 0) && qFuzzyCompare(d->miterLimit, 2)
830 && d->cosmetic == false;
831}
832
833/*!
834 \fn bool QPen::operator!=(const QPen &pen) const
835
836 Returns \c true if the pen is different from the given \a pen;
837 otherwise false. Two pens are different if they have different
838 styles, widths or colors.
839
840 \sa operator==()
841*/
842
843/*!
844 \fn bool QPen::operator==(const QPen &pen) const
845
846 Returns \c true if the pen is equal to the given \a pen; otherwise
847 false. Two pens are equal if they have equal styles, widths and
848 colors.
849
850 \sa operator!=()
851*/
852
853bool QPen::operator==(const QPen &p) const
854{
855 return (p.d == d)
856 || (p.d->style == d->style
857 && p.d->capStyle == d->capStyle
858 && p.d->joinStyle == d->joinStyle
859 && p.d->width == d->width
860 && p.d->miterLimit == d->miterLimit
861 && (d->style != Qt::CustomDashLine
862 || (qFuzzyCompare(p.d->dashOffset, d->dashOffset) &&
863 p.d->dashPattern == d->dashPattern))
864 && p.d->brush == d->brush
865 && p.d->cosmetic == d->cosmetic);
866}
867
868/*!
869 \internal
870*/
871bool QPen::doCompareEqualColor(QColor rhs) const noexcept
872{
873 return d->brush == rhs && isSolidDefaultLine();
874}
875
876/*!
877 \internal
878*/
879bool QPen::doCompareEqualStyle(Qt::PenStyle rhs) const
880{
881 if (rhs == Qt::NoPen)
882 return style() == Qt::NoPen;
883 return *this == QPen(rhs); // ### optimize (allocates)
884}
885
886/*!
887 \fn bool QPen::isDetached()
888
889 \internal
890*/
891
892bool QPen::isDetached()
893{
894 return d->ref.loadRelaxed() == 1;
895}
896
897
898/*****************************************************************************
899 QPen stream functions
900 *****************************************************************************/
901#ifndef QT_NO_DATASTREAM
902/*!
903 \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
904 \relates QPen
905
906 Writes the given \a pen to the given \a stream and returns a reference to
907 the \a stream.
908
909 \sa {Serializing Qt Data Types}
910*/
911
912QDataStream &operator<<(QDataStream &s, const QPen &p)
913{
914 if (s.version() < 3) {
915 s << (quint8)p.style();
916 } else if (s.version() < QDataStream::Qt_4_3) {
917 s << (quint8)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle()));
918 } else {
919 s << (quint16)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle()));
920 s << (bool)(p.d->cosmetic);
921 }
922
923 if (s.version() < 7) {
924 s << (quint8)p.width();
925 s << p.color();
926 } else {
927 s << double(p.widthF());
928 s << p.brush();
929 s << double(p.miterLimit());
930 if (sizeof(qreal) == sizeof(double)) {
931 s << p.dashPattern();
932 } else {
933 // ensure that we write doubles here instead of streaming the pattern
934 // directly; otherwise, platforms that redefine qreal might generate
935 // data that cannot be read on other platforms.
936 QList<qreal> pattern = p.dashPattern();
937 s << quint32(pattern.size());
938 for (int i = 0; i < pattern.size(); ++i)
939 s << double(pattern.at(i));
940 }
941 if (s.version() >= 9)
942 s << double(p.dashOffset());
943 if (s.version() >= QDataStream::Qt_5_0)
944 s << bool(qFuzzyIsNull(p.widthF()));
945 }
946 return s;
947}
948
949/*!
950 \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
951 \relates QPen
952
953 Reads a pen from the given \a stream into the given \a pen and
954 returns a reference to the \a stream.
955
956 \sa {Serializing Qt Data Types}
957*/
958
959QDataStream &operator>>(QDataStream &s, QPen &p)
960{
961 quint16 style;
962 quint8 width8 = 0;
963 double width = 0;
964 QColor color;
965 QBrush brush;
966 double miterLimit = 2;
967 QList<qreal> dashPattern;
968 double dashOffset = 0;
969 bool cosmetic = false;
970 bool defaultWidth;
971 if (s.version() < QDataStream::Qt_4_3) {
972 quint8 style8;
973 s >> style8;
974 style = style8;
975 } else {
976 s >> style;
977 s >> cosmetic;
978 }
979 if (s.version() < 7) {
980 s >> width8;
981 s >> color;
982 brush = color;
983 width = width8;
984 } else {
985 s >> width;
986 s >> brush;
987 s >> miterLimit;
988 if (sizeof(qreal) == sizeof(double)) {
989 s >> dashPattern;
990 } else {
991 quint32 numDashes;
992 s >> numDashes;
993 double dash;
994 dashPattern.reserve(numDashes);
995 for (quint32 i = 0; i < numDashes; ++i) {
996 s >> dash;
997 dashPattern << dash;
998 }
999 }
1000 if (s.version() >= 9)
1001 s >> dashOffset;
1002 }
1003
1004 if (s.version() >= QDataStream::Qt_5_0) {
1005 s >> defaultWidth;
1006 }
1007
1008 p.detach();
1009 p.d->width = width;
1010 p.d->brush = brush;
1011 p.d->style = Qt::PenStyle(style & Qt::MPenStyle);
1012 p.d->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
1013 p.d->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
1014 p.d->dashPattern = dashPattern;
1015 p.d->miterLimit = miterLimit;
1016 p.d->dashOffset = dashOffset;
1017 p.d->cosmetic = cosmetic;
1018
1019 return s;
1020}
1021#endif //QT_NO_DATASTREAM
1022
1023#ifndef QT_NO_DEBUG_STREAM
1024QDebug operator<<(QDebug dbg, const QPen &p)
1025{
1026 QDebugStateSaver saver(dbg);
1027 dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
1028 << ',' << p.style() << ',' << p.capStyle()
1029 << ',' << p.joinStyle() << ',' << p.dashPattern()
1030 << ',' << p.dashOffset()
1031 << ',' << p.miterLimit() << ')';
1032 return dbg;
1033}
1034#endif
1035
1036/*!
1037 \fn DataPtr &QPen::data_ptr()
1038 \internal
1039*/
1040
1041/*!
1042 \typedef QPen::DataPtr
1043
1044 \internal
1045*/
1046
1047QT_END_NAMESPACE
1048
1049#undef QT_COMPILING_QPEN
QPenDataHolder(const QBrush &brush, qreal width, Qt::PenStyle penStyle, Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle)
Definition qpen.cpp:216
QPen::DataPtr pen
Definition qpen.cpp:215
~QPenDataHolder()=default
Combined button and popup list for selecting options.
QDebug operator<<(QDebug dbg, const QPen &p)
Definition qpen.cpp:1024
static constexpr Qt::PenJoinStyle qpen_default_join
Definition qpen.cpp:210
static constexpr Qt::PenCapStyle qpen_default_cap
Definition qpen.cpp:209
QDataStream & operator>>(QDataStream &s, QPen &p)
Definition qpen.cpp:959