source: trunk/src/gui/painting/qpen.cpp@ 460

Last change on this file since 460 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

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