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