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