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
11QT_BEGIN_NAMESPACE
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 const Qt::PenCapStyle qpen_default_cap = Qt::SquareCap;
203static const Qt::PenJoinStyle qpen_default_join = Qt::BevelJoin;
204
205class QPenDataHolder
206{
207public:
208 QPen::DataPtr pen;
209 QPenDataHolder(const QBrush &brush, qreal width, Qt::PenStyle penStyle,
210 Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle)
211 : pen(new QPenPrivate(brush, width, penStyle, penCapStyle, _joinStyle))
212 { }
213 ~QPenDataHolder() = default;
214 Q_DISABLE_COPY_MOVE(QPenDataHolder)
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(other&: *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
345 Swaps pen \a other with this pen. This operation is very
346 fast and never fails.
347*/
348
349/*!
350 Returns the pen as a QVariant.
351*/
352QPen::operator QVariant() const
353{
354 return QVariant::fromValue(value: *this);
355}
356
357/*!
358 \fn Qt::PenStyle QPen::style() const
359
360 Returns the pen style.
361
362 \sa setStyle(), {QPen#Pen Style}{Pen Style}
363*/
364Qt::PenStyle QPen::style() const
365{
366 return d->style;
367}
368/*!
369 \fn void QPen::setStyle(Qt::PenStyle style)
370
371 Sets the pen style to the given \a style.
372
373 See the \l Qt::PenStyle documentation for a list of the available
374 styles. Since Qt 4.1 it is also possible to specify a custom dash
375 pattern using the setDashPattern() function which implicitly
376 converts the style of the pen to Qt::CustomDashLine.
377
378 \note This function resets the dash offset to zero.
379
380 \sa style(), {QPen#Pen Style}{Pen Style}
381*/
382
383void QPen::setStyle(Qt::PenStyle s)
384{
385 if (d->style == s)
386 return;
387 detach();
388 d->style = s;
389 d->dashPattern.clear();
390 d->dashOffset = 0;
391}
392
393/*!
394 Returns the dash pattern of this pen.
395
396 \sa style(), isSolid()
397 */
398QList<qreal> QPen::dashPattern() const
399{
400 if (d->style == Qt::SolidLine || d->style == Qt::NoPen) {
401 return QList<qreal>();
402 } else if (d->dashPattern.isEmpty()) {
403 const qreal space = 2;
404 const qreal dot = 1;
405 const qreal dash = 4;
406
407 switch (d->style) {
408 case Qt::DashLine:
409 d->dashPattern.reserve(asize: 2);
410 d->dashPattern << dash << space;
411 break;
412 case Qt::DotLine:
413 d->dashPattern.reserve(asize: 2);
414 d->dashPattern << dot << space;
415 break;
416 case Qt::DashDotLine:
417 d->dashPattern.reserve(asize: 4);
418 d->dashPattern << dash << space << dot << space;
419 break;
420 case Qt::DashDotDotLine:
421 d->dashPattern.reserve(asize: 6);
422 d->dashPattern << dash << space << dot << space << dot << space;
423 break;
424 default:
425 break;
426 }
427 }
428 return d->dashPattern;
429}
430
431/*!
432 Sets the dash pattern for this pen to the given \a pattern. This
433 implicitly converts the style of the pen to Qt::CustomDashLine.
434
435 The pattern must be specified as an even number of positive entries
436 where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the
437 spaces. For example:
438
439 \table 100%
440 \row
441 \li \inlineimage qpen-custom.png
442 \li
443 \snippet code/src_gui_painting_qpen.cpp 3
444 \endtable
445
446 The dash pattern is specified in units of the pens width; e.g. a
447 dash of length 5 in width 10 is 50 pixels long. Note that a pen
448 with zero width is equivalent to a cosmetic pen with a width of 1
449 pixel.
450
451 Each dash is also subject to cap styles so a dash of 1 with square
452 cap set will extend 0.5 pixels out in each direction resulting in
453 a total width of 2.
454
455 Note that the default cap style is Qt::SquareCap, meaning that a
456 square line end covers the end point and extends beyond it by half
457 the line width.
458
459 \sa setStyle(), dashPattern(), setCapStyle(), setCosmetic()
460 */
461void QPen::setDashPattern(const QList<qreal> &pattern)
462{
463 if (pattern.isEmpty())
464 return;
465 detach();
466
467 d->dashPattern = pattern;
468 d->style = Qt::CustomDashLine;
469
470 if ((d->dashPattern.size() % 2) == 1) {
471 qWarning(msg: "QPen::setDashPattern: Pattern not of even length");
472 d->dashPattern << 1;
473 }
474}
475
476
477/*!
478 Returns the dash offset for the pen.
479
480 \sa setDashOffset()
481*/
482qreal QPen::dashOffset() const
483{
484 return d->dashOffset;
485}
486/*!
487 Sets the dash offset (the starting point on the dash pattern) for this pen
488 to the \a offset specified. The offset is measured in terms of the units used
489 to specify the dash pattern.
490
491 \table
492 \row \li \inlineimage qpen-dashpattern.png
493 \li For example, a pattern where each stroke is four units long, followed by a gap
494 of two units, will begin with the stroke when drawn as a line.
495
496 However, if the dash offset is set to 4.0, any line drawn will begin with the gap.
497 Values of the offset up to 4.0 will cause part of the stroke to be drawn first,
498 and values of the offset between 4.0 and 6.0 will cause the line to begin with
499 part of the gap.
500 \endtable
501
502 \note This implicitly converts the style of the pen to Qt::CustomDashLine.
503*/
504void QPen::setDashOffset(qreal offset)
505{
506 if (qFuzzyCompare(p1: offset, p2: d->dashOffset))
507 return;
508 detach();
509 d->dashOffset = offset;
510 if (d->style != Qt::CustomDashLine) {
511 d->dashPattern = dashPattern();
512 d->style = Qt::CustomDashLine;
513 }
514}
515
516/*!
517 Returns the miter limit of the pen. The miter limit is only
518 relevant when the join style is set to Qt::MiterJoin.
519
520 \sa setMiterLimit(), {QPen#Join Style}{Join Style}
521*/
522qreal QPen::miterLimit() const
523{
524 return d->miterLimit;
525}
526
527/*!
528 Sets the miter limit of this pen to the given \a limit.
529
530 \image qpen-miterlimit.png
531
532 The miter limit describes how far a miter join can extend from the
533 join point. This is used to reduce artifacts between line joins
534 where the lines are close to parallel.
535
536 This value does only have effect when the pen style is set to
537 Qt::MiterJoin. The value is specified in units of the pen's width,
538 e.g. a miter limit of 5 in width 10 is 50 pixels long. The default
539 miter limit is 2, i.e. twice the pen width in pixels.
540
541 \sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style}
542*/
543void QPen::setMiterLimit(qreal limit)
544{
545 detach();
546 d->miterLimit = limit;
547}
548
549
550/*!
551 \fn qreal QPen::width() const
552
553 Returns the pen width with integer precision.
554
555 \sa setWidth(), widthF()
556*/
557
558int QPen::width() const
559{
560 return qRound(d: d->width);
561}
562
563/*!
564 \fn qreal QPen::widthF() const
565
566 Returns the pen width with floating point precision.
567
568 \sa setWidthF(), width()
569*/
570qreal QPen::widthF() const
571{
572 return d->width;
573}
574
575/*!
576 \fn QPen::setWidth(int width)
577
578 Sets the pen width to the given \a width in pixels with integer
579 precision.
580
581 A line width of zero indicates a cosmetic pen. This means that the
582 pen width is always drawn one pixel wide, independent of the \l
583 {QPainter#Coordinate Transformations}{transformation} set on the
584 painter.
585
586 Setting a pen width with a negative value is not supported.
587
588 \sa setWidthF(), width()
589*/
590void QPen::setWidth(int width)
591{
592 if (width < 0 || width >= (1 << 15)) {
593 qWarning(msg: "QPen::setWidth: Setting a pen width that is out of range");
594 return;
595 }
596 if ((qreal)width == d->width)
597 return;
598 detach();
599 d->width = width;
600}
601
602/*!
603 Sets the pen width to the given \a width in pixels with floating point
604 precision.
605
606 A line width of zero indicates a cosmetic pen. This means that the
607 pen width is always drawn one pixel wide, independent of the \l
608 {QPainter#Coordinate Transformations}{transformation} on the
609 painter.
610
611 Setting a pen width with a negative value is not supported.
612
613 \sa setWidth(), widthF()
614*/
615
616void QPen::setWidthF(qreal width)
617{
618 if (width < 0.f || width >= (1 << 15)) {
619 qWarning(msg: "QPen::setWidthF: Setting a pen width that is out of range");
620 return;
621 }
622 if (qAbs(t: d->width - width) < 0.00000001f)
623 return;
624 detach();
625 d->width = width;
626}
627
628
629/*!
630 Returns the pen's cap style.
631
632 \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
633*/
634Qt::PenCapStyle QPen::capStyle() const
635{
636 return d->capStyle;
637}
638
639/*!
640 \fn void QPen::setCapStyle(Qt::PenCapStyle style)
641
642 Sets the pen's cap style to the given \a style. The default value
643 is Qt::SquareCap.
644
645 \sa capStyle(), {QPen#Cap Style}{Cap Style}
646*/
647
648void QPen::setCapStyle(Qt::PenCapStyle c)
649{
650 if (d->capStyle == c)
651 return;
652 detach();
653 d->capStyle = c;
654}
655
656/*!
657 Returns the pen's join style.
658
659 \sa setJoinStyle(), {QPen#Join Style}{Join Style}
660*/
661Qt::PenJoinStyle QPen::joinStyle() const
662{
663 return d->joinStyle;
664}
665
666/*!
667 \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
668
669 Sets the pen's join style to the given \a style. The default value
670 is Qt::BevelJoin.
671
672 \sa joinStyle(), {QPen#Join Style}{Join Style}
673*/
674
675void QPen::setJoinStyle(Qt::PenJoinStyle j)
676{
677 if (d->joinStyle == j)
678 return;
679 detach();
680 d->joinStyle = j;
681}
682
683/*!
684 \fn const QColor &QPen::color() const
685
686 Returns the color of this pen's brush.
687
688 \sa brush(), setColor()
689*/
690QColor QPen::color() const
691{
692 return d->brush.color();
693}
694
695/*!
696 \fn void QPen::setColor(const QColor &color)
697
698 Sets the color of this pen's brush to the given \a color.
699
700 \sa setBrush(), color()
701*/
702
703void QPen::setColor(const QColor &c)
704{
705 detach();
706 d->brush = QBrush(c);
707}
708
709
710/*!
711 Returns the brush used to fill strokes generated with this pen.
712*/
713QBrush QPen::brush() const
714{
715 return d->brush;
716}
717
718/*!
719 Sets the brush used to fill strokes generated with this pen to the given
720 \a brush.
721
722 \sa brush(), setColor()
723*/
724void QPen::setBrush(const QBrush &brush)
725{
726 detach();
727 d->brush = brush;
728}
729
730
731/*!
732 Returns \c true if the pen has a solid fill, otherwise false.
733
734 \sa style(), dashPattern()
735*/
736bool QPen::isSolid() const
737{
738 return d->brush.style() == Qt::SolidPattern;
739}
740
741
742/*!
743 Returns \c true if the pen is cosmetic; otherwise returns \c false.
744
745 Cosmetic pens are used to draw strokes that have a constant width
746 regardless of any transformations applied to the QPainter they are
747 used with. Drawing a shape with a cosmetic pen ensures that its
748 outline will have the same thickness at different scale factors.
749
750 A zero width pen is cosmetic by default.
751
752 \sa setCosmetic(), widthF()
753*/
754
755bool QPen::isCosmetic() const
756{
757 return (d->cosmetic == true) || d->width == 0;
758}
759
760
761/*!
762 Sets this pen to cosmetic or non-cosmetic, depending on the value of
763 \a cosmetic.
764
765 \sa isCosmetic()
766*/
767
768void QPen::setCosmetic(bool cosmetic)
769{
770 detach();
771 d->cosmetic = cosmetic;
772}
773
774
775
776/*!
777 \fn bool QPen::operator!=(const QPen &pen) const
778
779 Returns \c true if the pen is different from the given \a pen;
780 otherwise false. Two pens are different if they have different
781 styles, widths or colors.
782
783 \sa operator==()
784*/
785
786/*!
787 \fn bool QPen::operator==(const QPen &pen) const
788
789 Returns \c true if the pen is equal to the given \a pen; otherwise
790 false. Two pens are equal if they have equal styles, widths and
791 colors.
792
793 \sa operator!=()
794*/
795
796bool QPen::operator==(const QPen &p) const
797{
798 return (p.d == d)
799 || (p.d->style == d->style
800 && p.d->capStyle == d->capStyle
801 && p.d->joinStyle == d->joinStyle
802 && p.d->width == d->width
803 && p.d->miterLimit == d->miterLimit
804 && (d->style != Qt::CustomDashLine
805 || (qFuzzyCompare(p1: p.d->dashOffset, p2: d->dashOffset) &&
806 p.d->dashPattern == d->dashPattern))
807 && p.d->brush == d->brush
808 && p.d->cosmetic == d->cosmetic);
809}
810
811
812/*!
813 \fn bool QPen::isDetached()
814
815 \internal
816*/
817
818bool QPen::isDetached()
819{
820 return d->ref.loadRelaxed() == 1;
821}
822
823
824/*****************************************************************************
825 QPen stream functions
826 *****************************************************************************/
827#ifndef QT_NO_DATASTREAM
828/*!
829 \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
830 \relates QPen
831
832 Writes the given \a pen to the given \a stream and returns a reference to
833 the \a stream.
834
835 \sa {Serializing Qt Data Types}
836*/
837
838QDataStream &operator<<(QDataStream &s, const QPen &p)
839{
840 if (s.version() < 3) {
841 s << (quint8)p.style();
842 } else if (s.version() < QDataStream::Qt_4_3) {
843 s << (quint8)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle()));
844 } else {
845 s << (quint16)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle()));
846 s << (bool)(p.d->cosmetic);
847 }
848
849 if (s.version() < 7) {
850 s << (quint8)p.width();
851 s << p.color();
852 } else {
853 s << double(p.widthF());
854 s << p.brush();
855 s << double(p.miterLimit());
856 if (sizeof(qreal) == sizeof(double)) {
857 s << p.dashPattern();
858 } else {
859 // ensure that we write doubles here instead of streaming the pattern
860 // directly; otherwise, platforms that redefine qreal might generate
861 // data that cannot be read on other platforms.
862 QList<qreal> pattern = p.dashPattern();
863 s << quint32(pattern.size());
864 for (int i = 0; i < pattern.size(); ++i)
865 s << double(pattern.at(i));
866 }
867 if (s.version() >= 9)
868 s << double(p.dashOffset());
869 if (s.version() >= QDataStream::Qt_5_0)
870 s << bool(qFuzzyIsNull(d: p.widthF()));
871 }
872 return s;
873}
874
875/*!
876 \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
877 \relates QPen
878
879 Reads a pen from the given \a stream into the given \a pen and
880 returns a reference to the \a stream.
881
882 \sa {Serializing Qt Data Types}
883*/
884
885QDataStream &operator>>(QDataStream &s, QPen &p)
886{
887 quint16 style;
888 quint8 width8 = 0;
889 double width = 0;
890 QColor color;
891 QBrush brush;
892 double miterLimit = 2;
893 QList<qreal> dashPattern;
894 double dashOffset = 0;
895 bool cosmetic = false;
896 bool defaultWidth;
897 if (s.version() < QDataStream::Qt_4_3) {
898 quint8 style8;
899 s >> style8;
900 style = style8;
901 } else {
902 s >> style;
903 s >> cosmetic;
904 }
905 if (s.version() < 7) {
906 s >> width8;
907 s >> color;
908 brush = color;
909 width = width8;
910 } else {
911 s >> width;
912 s >> brush;
913 s >> miterLimit;
914 if (sizeof(qreal) == sizeof(double)) {
915 s >> dashPattern;
916 } else {
917 quint32 numDashes;
918 s >> numDashes;
919 double dash;
920 dashPattern.reserve(asize: numDashes);
921 for (quint32 i = 0; i < numDashes; ++i) {
922 s >> dash;
923 dashPattern << dash;
924 }
925 }
926 if (s.version() >= 9)
927 s >> dashOffset;
928 }
929
930 if (s.version() >= QDataStream::Qt_5_0) {
931 s >> defaultWidth;
932 }
933
934 p.detach();
935 p.d->width = width;
936 p.d->brush = brush;
937 p.d->style = Qt::PenStyle(style & Qt::MPenStyle);
938 p.d->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
939 p.d->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
940 p.d->dashPattern = dashPattern;
941 p.d->miterLimit = miterLimit;
942 p.d->dashOffset = dashOffset;
943 p.d->cosmetic = cosmetic;
944
945 return s;
946}
947#endif //QT_NO_DATASTREAM
948
949#ifndef QT_NO_DEBUG_STREAM
950QDebug operator<<(QDebug dbg, const QPen &p)
951{
952 const char *PEN_STYLES[] = {
953 "NoPen",
954 "SolidLine",
955 "DashLine",
956 "DotLine",
957 "DashDotLine",
958 "DashDotDotLine",
959 "CustomDashLine"
960 };
961
962 QDebugStateSaver saver(dbg);
963 dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
964 << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
965 << ',' << int(p.joinStyle()) << ',' << p.dashPattern()
966 << ',' << p.dashOffset()
967 << ',' << p.miterLimit() << ')';
968 return dbg;
969}
970#endif
971
972/*!
973 \fn DataPtr &QPen::data_ptr()
974 \internal
975*/
976
977/*!
978 \typedef QPen::DataPtr
979
980 \internal
981*/
982
983QT_END_NAMESPACE
984
985#undef QT_COMPILING_QPEN
986

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/gui/painting/qpen.cpp