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

Provided by KDAB

Privacy Policy
Start learning QML with our Intro Training
Find out more

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