Coverage Report

Created: 2026-05-16 07:21

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