~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to src/gui/painting/qpen.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

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