|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the QtGui module of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
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 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
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 |
|
49 QT_BEGIN_NAMESPACE |
|
50 |
|
51 typedef 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 \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 */ |
|
231 inline 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 |
|
244 static const Qt::PenCapStyle qpen_default_cap = Qt::SquareCap; |
|
245 static 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 |
|
249 template <> |
|
250 class QGlobalStaticDeleter<QPenPrivate> |
|
251 { |
|
252 public: |
|
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 |
|
268 Q_GLOBAL_STATIC_WITH_ARGS(QPenData, defaultPenInstance, |
|
269 (Qt::black, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join)) |
|
270 Q_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 |
|
277 QPen::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 |
|
289 QPen::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 |
|
306 QPen::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 |
|
321 QPen::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 |
|
332 QPen::QPen(const QPen &p) |
|
333 { |
|
334 d = p.d; |
|
335 d->ref.ref(); |
|
336 } |
|
337 |
|
338 |
|
339 /*! |
|
340 Destroys the pen. |
|
341 */ |
|
342 |
|
343 QPen::~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 |
|
359 void 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 |
|
379 QPen &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 */ |
|
388 QPen::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 */ |
|
400 Qt::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 |
|
419 void 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 */ |
|
435 QVector<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 */ |
|
495 void 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 */ |
|
517 qreal 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 */ |
|
540 void 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 */ |
|
559 qreal 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 */ |
|
581 void 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 |
|
597 int 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 */ |
|
609 qreal 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 */ |
|
629 void 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 |
|
653 void 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 */ |
|
669 Qt::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 |
|
683 void 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 */ |
|
696 Qt::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 |
|
710 void 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 */ |
|
725 QColor 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 |
|
738 void 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 */ |
|
748 QBrush 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 */ |
|
759 void 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 */ |
|
771 bool 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 |
|
791 bool 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 |
|
805 void 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 |
|
834 bool 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) || (p.d->style == d->style |
|
839 && p.d->capStyle == d->capStyle |
|
840 && p.d->joinStyle == d->joinStyle |
|
841 && p.d->width == d->width |
|
842 && pdd->miterLimit == dd->miterLimit |
|
843 && (d->style != Qt::CustomDashLine |
|
844 || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) && |
|
845 pdd->dashPattern == dd->dashPattern)) |
|
846 && p.d->brush == d->brush |
|
847 && pdd->cosmetic == dd->cosmetic); |
|
848 } |
|
849 |
|
850 |
|
851 /*! |
|
852 \fn bool QPen::isDetached() |
|
853 |
|
854 \internal |
|
855 */ |
|
856 |
|
857 bool QPen::isDetached() |
|
858 { |
|
859 return d->ref == 1; |
|
860 } |
|
861 |
|
862 |
|
863 /***************************************************************************** |
|
864 QPen stream functions |
|
865 *****************************************************************************/ |
|
866 #ifndef QT_NO_DATASTREAM |
|
867 /*! |
|
868 \fn QDataStream &operator<<(QDataStream &stream, const QPen &pen) |
|
869 \relates QPen |
|
870 |
|
871 Writes the given \a pen to the given \a stream and returns a reference to |
|
872 the \a stream. |
|
873 |
|
874 \sa {Format of the QDataStream Operators} |
|
875 */ |
|
876 |
|
877 QDataStream &operator<<(QDataStream &s, const QPen &p) |
|
878 { |
|
879 QPenData *dd = static_cast<QPenData *>(p.d); |
|
880 if (s.version() < 3) { |
|
881 s << (quint8)p.style(); |
|
882 } else if (s.version() < QDataStream::Qt_4_3) { |
|
883 s << (quint8)(p.style() | p.capStyle() | p.joinStyle()); |
|
884 } else { |
|
885 s << (quint16)(p.style() | p.capStyle() | p.joinStyle()); |
|
886 s << (bool)(dd->cosmetic); |
|
887 } |
|
888 |
|
889 if (s.version() < 7) { |
|
890 s << (quint8)p.width(); |
|
891 s << p.color(); |
|
892 } else { |
|
893 s << double(p.widthF()); |
|
894 s << p.brush(); |
|
895 s << double(p.miterLimit()); |
|
896 if (sizeof(qreal) == sizeof(double)) { |
|
897 s << p.dashPattern(); |
|
898 } else { |
|
899 // ensure that we write doubles here instead of streaming the pattern |
|
900 // directly; otherwise, platforms that redefine qreal might generate |
|
901 // data that cannot be read on other platforms. |
|
902 QVector<qreal> pattern = p.dashPattern(); |
|
903 s << quint32(pattern.size()); |
|
904 for (int i = 0; i < pattern.size(); ++i) |
|
905 s << double(pattern.at(i)); |
|
906 } |
|
907 if (s.version() >= 9) |
|
908 s << double(p.dashOffset()); |
|
909 } |
|
910 return s; |
|
911 } |
|
912 |
|
913 /*! |
|
914 \fn QDataStream &operator>>(QDataStream &stream, QPen &pen) |
|
915 \relates QPen |
|
916 |
|
917 Reads a pen from the given \a stream into the given \a pen and |
|
918 returns a reference to the \a stream. |
|
919 |
|
920 \sa {Format of the QDataStream Operators} |
|
921 */ |
|
922 |
|
923 QDataStream &operator>>(QDataStream &s, QPen &p) |
|
924 { |
|
925 quint16 style; |
|
926 quint8 width8 = 0; |
|
927 double width = 0; |
|
928 QColor color; |
|
929 QBrush brush; |
|
930 double miterLimit = 2; |
|
931 QVector<qreal> dashPattern; |
|
932 double dashOffset = 0; |
|
933 bool cosmetic = false; |
|
934 if (s.version() < QDataStream::Qt_4_3) { |
|
935 quint8 style8; |
|
936 s >> style8; |
|
937 style = style8; |
|
938 } else { |
|
939 s >> style; |
|
940 s >> cosmetic; |
|
941 } |
|
942 if (s.version() < 7) { |
|
943 s >> width8; |
|
944 s >> color; |
|
945 brush = color; |
|
946 width = width8; |
|
947 } else { |
|
948 s >> width; |
|
949 s >> brush; |
|
950 s >> miterLimit; |
|
951 if (sizeof(qreal) == sizeof(double)) { |
|
952 s >> dashPattern; |
|
953 } else { |
|
954 quint32 numDashes; |
|
955 s >> numDashes; |
|
956 double dash; |
|
957 for (quint32 i = 0; i < numDashes; ++i) { |
|
958 s >> dash; |
|
959 dashPattern << dash; |
|
960 } |
|
961 } |
|
962 if (s.version() >= 9) |
|
963 s >> dashOffset; |
|
964 } |
|
965 |
|
966 p.detach(); |
|
967 QPenData *dd = static_cast<QPenData *>(p.d); |
|
968 dd->width = width; |
|
969 dd->brush = brush; |
|
970 dd->style = Qt::PenStyle(style & Qt::MPenStyle); |
|
971 dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle); |
|
972 dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle); |
|
973 dd->dashPattern = dashPattern; |
|
974 dd->miterLimit = miterLimit; |
|
975 dd->dashOffset = dashOffset; |
|
976 dd->cosmetic = cosmetic; |
|
977 |
|
978 return s; |
|
979 } |
|
980 #endif //QT_NO_DATASTREAM |
|
981 |
|
982 #ifndef QT_NO_DEBUG_STREAM |
|
983 QDebug operator<<(QDebug dbg, const QPen &p) |
|
984 { |
|
985 #ifndef Q_BROKEN_DEBUG_STREAM |
|
986 dbg.nospace() << "QPen(" << p.width() << ',' << p.brush() |
|
987 << ',' << int(p.style()) << ',' << int(p.capStyle()) |
|
988 << ',' << int(p.joinStyle()) << ',' << p.dashPattern() |
|
989 << ',' << p.dashOffset() |
|
990 << ',' << p.miterLimit() << ')'; |
|
991 return dbg.space(); |
|
992 #else |
|
993 qWarning("This compiler doesn't support streaming QPen to QDebug"); |
|
994 return dbg; |
|
995 Q_UNUSED(p); |
|
996 #endif |
|
997 } |
|
998 #endif |
|
999 |
|
1000 /*! |
|
1001 \fn DataPtr &QPen::data_ptr() |
|
1002 \internal |
|
1003 */ |
|
1004 |
|
1005 /*! |
|
1006 \typedef QPen::DataPtr |
|
1007 |
|
1008 \internal |
|
1009 */ |
|
1010 |
|
1011 QT_END_NAMESPACE |
|
1012 |
|
1013 #undef QT_COMPILING_QPEN |