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

Last change on this file since 1168 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 26.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this 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 have questions regarding the use of this file, please contact
37** Nokia 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 painting
56 \ingroup shared
57
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 the \l{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 \note This function resets the dash offset to zero.
415
416 \sa style(), {QPen#Pen Style}{Pen Style}
417*/
418
419void QPen::setStyle(Qt::PenStyle s)
420{
421 if (d->style == s)
422 return;
423 detach();
424 d->style = s;
425 QPenData *dd = static_cast<QPenData *>(d);
426 dd->dashPattern.clear();
427 dd->dashOffset = 0;
428}
429
430/*!
431 Returns the dash pattern of this pen.
432
433 \sa style(), isSolid()
434 */
435QVector<qreal> QPen::dashPattern() const
436{
437 QPenData *dd = static_cast<QPenData *>(d);
438 if (d->style == Qt::SolidLine || d->style == Qt::NoPen) {
439 return QVector<qreal>();
440 } else if (dd->dashPattern.isEmpty()) {
441 const qreal space = 2;
442 const qreal dot = 1;
443 const qreal dash = 4;
444
445 switch (d->style) {
446 case Qt::DashLine:
447 dd->dashPattern << dash << space;
448 break;
449 case Qt::DotLine:
450 dd->dashPattern << dot << space;
451 break;
452 case Qt::DashDotLine:
453 dd->dashPattern << dash << space << dot << space;
454 break;
455 case Qt::DashDotDotLine:
456 dd->dashPattern << dash << space << dot << space << dot << space;
457 break;
458 default:
459 break;
460 }
461 }
462 return dd->dashPattern;
463}
464
465/*!
466 Sets the dash pattern for this pen to the given \a pattern. This
467 implicitly converts the style of the pen to Qt::CustomDashLine.
468
469 The pattern must be specified as an even number of positive entries
470 where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the
471 spaces. For example:
472
473 \table 100%
474 \row
475 \o \inlineimage qpen-custom.png
476 \o
477 \snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 3
478 \endtable
479
480 The dash pattern is specified in units of the pens width; e.g. a
481 dash of length 5 in width 10 is 50 pixels long. Note that a pen
482 with zero width is equivalent to a cosmetic pen with a width of 1
483 pixel.
484
485 Each dash is also subject to cap styles so a dash of 1 with square
486 cap set will extend 0.5 pixels out in each direction resulting in
487 a total width of 2.
488
489 Note that the default cap style is Qt::SquareCap, meaning that a
490 square line end covers the end point and extends beyond it by half
491 the line width.
492
493 \sa setStyle(), dashPattern(), setCapStyle(), setCosmetic()
494 */
495void QPen::setDashPattern(const QVector<qreal> &pattern)
496{
497 if (pattern.isEmpty())
498 return;
499 detach();
500
501 QPenData *dd = static_cast<QPenData *>(d);
502 dd->dashPattern = pattern;
503 d->style = Qt::CustomDashLine;
504
505 if ((dd->dashPattern.size() % 2) == 1) {
506 qWarning("QPen::setDashPattern: Pattern not of even length");
507 dd->dashPattern << 1;
508 }
509}
510
511
512/*!
513 Returns the dash offset for the pen.
514
515 \sa setDashOffset()
516*/
517qreal QPen::dashOffset() const
518{
519 QPenData *dd = static_cast<QPenData *>(d);
520 return dd->dashOffset;
521}
522/*!
523 Sets the dash offset (the starting point on the dash pattern) for this pen
524 to the \a offset specified. The offset is measured in terms of the units used
525 to specify the dash pattern.
526
527 \table
528 \row \o \inlineimage qpen-dashpattern.png
529 \o For example, a pattern where each stroke is four units long, followed by a gap
530 of two units, will begin with the stroke when drawn as a line.
531
532 However, if the dash offset is set to 4.0, any line drawn will begin with the gap.
533 Values of the offset up to 4.0 will cause part of the stroke to be drawn first,
534 and values of the offset between 4.0 and 6.0 will cause the line to begin with
535 part of the gap.
536 \endtable
537
538 \note This implicitly converts the style of the pen to Qt::CustomDashLine.
539*/
540void QPen::setDashOffset(qreal offset)
541{
542 if (qFuzzyCompare(offset, static_cast<QPenData *>(d)->dashOffset))
543 return;
544 detach();
545 QPenData *dd = static_cast<QPenData *>(d);
546 dd->dashOffset = offset;
547 if (d->style != Qt::CustomDashLine) {
548 dd->dashPattern = dashPattern();
549 d->style = Qt::CustomDashLine;
550 }
551}
552
553/*!
554 Returns the miter limit of the pen. The miter limit is only
555 relevant when the join style is set to Qt::MiterJoin.
556
557 \sa setMiterLimit(), {QPen#Join Style}{Join Style}
558*/
559qreal QPen::miterLimit() const
560{
561 const QPenData *dd = static_cast<QPenData *>(d);
562 return dd->miterLimit;
563}
564
565/*!
566 Sets the miter limit of this pen to the given \a limit.
567
568 \image qpen-miterlimit.png
569
570 The miter limit describes how far a miter join can extend from the
571 join point. This is used to reduce artifacts between line joins
572 where the lines are close to parallel.
573
574 This value does only have effect when the pen style is set to
575 Qt::MiterJoin. The value is specified in units of the pen's width,
576 e.g. a miter limit of 5 in width 10 is 50 pixels long. The default
577 miter limit is 2, i.e. twice the pen width in pixels.
578
579 \sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style}
580*/
581void QPen::setMiterLimit(qreal limit)
582{
583 detach();
584 QPenData *dd = static_cast<QPenData *>(d);
585 dd->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)
632 qWarning("QPen::setWidth: Setting a pen width with a negative value is not defined");
633 if ((qreal)width == d->width)
634 return;
635 detach();
636 d->width = width;
637}
638
639/*!
640 Sets the pen width to the given \a width in pixels with floating point
641 precision.
642
643 A line width of zero indicates a cosmetic pen. This means that the
644 pen width is always drawn one pixel wide, independent of the \l
645 {QPainter#Coordinate Transformations}{transformation} on the
646 painter.
647
648 Setting a pen width with a negative value is not supported.
649
650 \sa setWidth() widthF()
651*/
652
653void QPen::setWidthF(qreal width)
654{
655 if (width < 0.f)
656 qWarning("QPen::setWidthF: Setting a pen width with a negative value is not defined");
657 if (qAbs(d->width - width) < 0.00000001f)
658 return;
659 detach();
660 d->width = width;
661}
662
663
664/*!
665 Returns the pen's cap style.
666
667 \sa setCapStyle(), {QPen#Cap Style}{Cap Style}
668*/
669Qt::PenCapStyle QPen::capStyle() const
670{
671 return d->capStyle;
672}
673
674/*!
675 \fn void QPen::setCapStyle(Qt::PenCapStyle style)
676
677 Sets the pen's cap style to the given \a style. The default value
678 is Qt::SquareCap.
679
680 \sa capStyle(), {QPen#Cap Style}{Cap Style}
681*/
682
683void QPen::setCapStyle(Qt::PenCapStyle c)
684{
685 if (d->capStyle == c)
686 return;
687 detach();
688 d->capStyle = c;
689}
690
691/*!
692 Returns the pen's join style.
693
694 \sa setJoinStyle(), {QPen#Join Style}{Join Style}
695*/
696Qt::PenJoinStyle QPen::joinStyle() const
697{
698 return d->joinStyle;
699}
700
701/*!
702 \fn void QPen::setJoinStyle(Qt::PenJoinStyle style)
703
704 Sets the pen's join style to the given \a style. The default value
705 is Qt::BevelJoin.
706
707 \sa joinStyle(), {QPen#Join Style}{Join Style}
708*/
709
710void QPen::setJoinStyle(Qt::PenJoinStyle j)
711{
712 if (d->joinStyle == j)
713 return;
714 detach();
715 d->joinStyle = j;
716}
717
718/*!
719 \fn const QColor &QPen::color() const
720
721 Returns the color of this pen's brush.
722
723 \sa brush(), setColor()
724*/
725QColor QPen::color() const
726{
727 return d->brush.color();
728}
729
730/*!
731 \fn void QPen::setColor(const QColor &color)
732
733 Sets the color of this pen's brush to the given \a color.
734
735 \sa setBrush(), color()
736*/
737
738void QPen::setColor(const QColor &c)
739{
740 detach();
741 d->brush = QBrush(c);
742}
743
744
745/*!
746 Returns the brush used to fill strokes generated with this pen.
747*/
748QBrush QPen::brush() const
749{
750 return d->brush;
751}
752
753/*!
754 Sets the brush used to fill strokes generated with this pen to the given
755 \a brush.
756
757 \sa brush(), setColor()
758*/
759void QPen::setBrush(const QBrush &brush)
760{
761 detach();
762 d->brush = brush;
763}
764
765
766/*!
767 Returns true if the pen has a solid fill, otherwise false.
768
769 \sa style(), dashPattern()
770*/
771bool QPen::isSolid() const
772{
773 return d->brush.style() == Qt::SolidPattern;
774}
775
776
777/*!
778 Returns true if the pen is cosmetic; otherwise returns false.
779
780 Cosmetic pens are used to draw strokes that have a constant width
781 regardless of any transformations applied to the QPainter they are
782 used with. Drawing a shape with a cosmetic pen ensures that its
783 outline will have the same thickness at different scale factors.
784
785 A zero width pen is cosmetic by default; pens with a non-zero width
786 are non-cosmetic.
787
788 \sa setCosmetic(), widthF()
789*/
790
791bool QPen::isCosmetic() const
792{
793 QPenData *dd = static_cast<QPenData *>(d);
794 return (dd->cosmetic == true) || d->width == 0;
795}
796
797
798/*!
799 Sets this pen to cosmetic or non-cosmetic, depending on the value of
800 \a cosmetic.
801
802 \sa isCosmetic()
803*/
804
805void QPen::setCosmetic(bool cosmetic)
806{
807 detach();
808 QPenData *dd = static_cast<QPenData *>(d);
809 dd->cosmetic = cosmetic;
810}
811
812
813
814/*!
815 \fn bool QPen::operator!=(const QPen &pen) const
816
817 Returns true if the pen is different from the given \a pen;
818 otherwise false. Two pens are different if they have different
819 styles, widths or colors.
820
821 \sa operator==()
822*/
823
824/*!
825 \fn bool QPen::operator==(const QPen &pen) const
826
827 Returns true if the pen is equal to the given \a pen; otherwise
828 false. Two pens are equal if they have equal styles, widths and
829 colors.
830
831 \sa operator!=()
832*/
833
834bool QPen::operator==(const QPen &p) const
835{
836 QPenData *dd = static_cast<QPenData *>(d);
837 QPenData *pdd = static_cast<QPenData *>(p.d);
838 return (p.d == d)
839 || (p.d->style == d->style
840 && p.d->capStyle == d->capStyle
841 && p.d->joinStyle == d->joinStyle
842 && p.d->width == d->width
843 && pdd->miterLimit == dd->miterLimit
844 && (d->style != Qt::CustomDashLine
845 || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
846 pdd->dashPattern == dd->dashPattern))
847 && p.d->brush == d->brush
848 && pdd->cosmetic == dd->cosmetic);
849}
850
851
852/*!
853 \fn bool QPen::isDetached()
854
855 \internal
856*/
857
858bool QPen::isDetached()
859{
860 return d->ref == 1;
861}
862
863
864/*****************************************************************************
865 QPen stream functions
866 *****************************************************************************/
867#ifndef QT_NO_DATASTREAM
868/*!
869 \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen)
870 \relates QPen
871
872 Writes the given \a pen to the given \a stream and returns a reference to
873 the \a stream.
874
875 \sa {Serializing Qt Data Types}
876*/
877
878QDataStream &operator<<(QDataStream &s, const QPen &p)
879{
880 QPenData *dd = static_cast<QPenData *>(p.d);
881 if (s.version() < 3) {
882 s << (quint8)p.style();
883 } else if (s.version() < QDataStream::Qt_4_3) {
884 s << (quint8)(p.style() | p.capStyle() | p.joinStyle());
885 } else {
886 s << (quint16)(p.style() | p.capStyle() | p.joinStyle());
887 s << (bool)(dd->cosmetic);
888 }
889
890 if (s.version() < 7) {
891 s << (quint8)p.width();
892 s << p.color();
893 } else {
894 s << double(p.widthF());
895 s << p.brush();
896 s << double(p.miterLimit());
897 if (sizeof(qreal) == sizeof(double)) {
898 s << p.dashPattern();
899 } else {
900 // ensure that we write doubles here instead of streaming the pattern
901 // directly; otherwise, platforms that redefine qreal might generate
902 // data that cannot be read on other platforms.
903 QVector<qreal> pattern = p.dashPattern();
904 s << quint32(pattern.size());
905 for (int i = 0; i < pattern.size(); ++i)
906 s << double(pattern.at(i));
907 }
908 if (s.version() >= 9)
909 s << double(p.dashOffset());
910 }
911 return s;
912}
913
914/*!
915 \fn QDataStream &operator>>(QDataStream &stream, QPen &pen)
916 \relates QPen
917
918 Reads a pen from the given \a stream into the given \a pen and
919 returns a reference to the \a stream.
920
921 \sa {Serializing Qt Data Types}
922*/
923
924QDataStream &operator>>(QDataStream &s, QPen &p)
925{
926 quint16 style;
927 quint8 width8 = 0;
928 double width = 0;
929 QColor color;
930 QBrush brush;
931 double miterLimit = 2;
932 QVector<qreal> dashPattern;
933 double dashOffset = 0;
934 bool cosmetic = false;
935 if (s.version() < QDataStream::Qt_4_3) {
936 quint8 style8;
937 s >> style8;
938 style = style8;
939 } else {
940 s >> style;
941 s >> cosmetic;
942 }
943 if (s.version() < 7) {
944 s >> width8;
945 s >> color;
946 brush = color;
947 width = width8;
948 } else {
949 s >> width;
950 s >> brush;
951 s >> miterLimit;
952 if (sizeof(qreal) == sizeof(double)) {
953 s >> dashPattern;
954 } else {
955 quint32 numDashes;
956 s >> numDashes;
957 double dash;
958 for (quint32 i = 0; i < numDashes; ++i) {
959 s >> dash;
960 dashPattern << dash;
961 }
962 }
963 if (s.version() >= 9)
964 s >> dashOffset;
965 }
966
967 p.detach();
968 QPenData *dd = static_cast<QPenData *>(p.d);
969 dd->width = width;
970 dd->brush = brush;
971 dd->style = Qt::PenStyle(style & Qt::MPenStyle);
972 dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
973 dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
974 dd->dashPattern = dashPattern;
975 dd->miterLimit = miterLimit;
976 dd->dashOffset = dashOffset;
977 dd->cosmetic = cosmetic;
978
979 return s;
980}
981#endif //QT_NO_DATASTREAM
982
983#ifndef QT_NO_DEBUG_STREAM
984QDebug operator<<(QDebug dbg, const QPen &p)
985{
986#ifndef Q_BROKEN_DEBUG_STREAM
987 const char *PEN_STYLES[] = {
988 "NoPen",
989 "SolidLine",
990 "DashLine",
991 "DotLine",
992 "DashDotLine",
993 "DashDotDotLine",
994 "CustomDashLine"
995 };
996
997 dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
998 << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
999 << ',' << int(p.joinStyle()) << ',' << p.dashPattern()
1000 << ',' << p.dashOffset()
1001 << ',' << p.miterLimit() << ')';
1002 return dbg.space();
1003#else
1004 qWarning("This compiler doesn't support streaming QPen to QDebug");
1005 return dbg;
1006 Q_UNUSED(p);
1007#endif
1008}
1009#endif
1010
1011/*!
1012 \fn DataPtr &QPen::data_ptr()
1013 \internal
1014*/
1015
1016/*!
1017 \typedef QPen::DataPtr
1018
1019 \internal
1020*/
1021
1022QT_END_NAMESPACE
1023
1024#undef QT_COMPILING_QPEN
Note: See TracBrowser for help on using the repository browser.