Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qpen.cpp
Go to the documentation of this file.
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#include "qpen.h"
4#include "qpen_p.h"
5#include "qdatastream.h"
6#include "qvariant.h"
7#include "qbrush.h"
8
9#include <qdebug.h>
10
12
14
194QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle,
195 Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle)
196 : ref(1), dashOffset(0), miterLimit(2),
197 cosmetic(false)
198{
199 width = _width;
200 brush = _brush;
201 style = penStyle;
202 capStyle = _capStyle;
203 joinStyle = _joinStyle;
204}
205
208
210{
211public:
214 Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle)
215 : pen(new QPenData(brush, width, penStyle, penCapStyle, _joinStyle))
216 { }
218 {
219 if (!pen->ref.deref())
220 delete pen;
221 pen = nullptr;
222 }
223};
224
229
235{
236 d = defaultPenInstance()->pen;
237 d->ref.ref();
238}
239
247{
248 if (style == Qt::NoPen) {
249 d = nullPenInstance()->pen;
250 d->ref.ref();
251 } else {
253 }
254}
255
256
264{
266}
267
268
279{
280 d = new QPenData(brush, width, s, c, j);
281}
282
289QPen::QPen(const QPen &p) noexcept
290{
291 d = p.d;
292 if (d)
293 d->ref.ref();
294}
295
296
313{
314 if (d && !d->ref.deref())
315 delete d;
316}
317
328void QPen::detach()
329{
330 if (d->ref.loadRelaxed() == 1)
331 return;
332
333 QPenData *x = new QPenData(*static_cast<QPenData *>(d));
334 if (!d->ref.deref())
335 delete d;
336 x->ref.storeRelaxed(1);
337 d = x;
338}
339
340
348QPen &QPen::operator=(const QPen &p) noexcept
349{
350 QPen(p).swap(*this);
351 return *this;
352}
353
373QPen::operator QVariant() const
374{
375 return QVariant::fromValue(*this);
376}
377
386{
387 return d->style;
388}
405{
406 if (d->style == s)
407 return;
408 detach();
409 d->style = s;
410 QPenData *dd = static_cast<QPenData *>(d);
411 dd->dashPattern.clear();
412 dd->dashOffset = 0;
413}
414
421{
422 QPenData *dd = static_cast<QPenData *>(d);
423 if (d->style == Qt::SolidLine || d->style == Qt::NoPen) {
424 return QList<qreal>();
425 } else if (dd->dashPattern.isEmpty()) {
426 const qreal space = 2;
427 const qreal dot = 1;
428 const qreal dash = 4;
429
430 switch (d->style) {
431 case Qt::DashLine:
432 dd->dashPattern.reserve(2);
433 dd->dashPattern << dash << space;
434 break;
435 case Qt::DotLine:
436 dd->dashPattern.reserve(2);
437 dd->dashPattern << dot << space;
438 break;
439 case Qt::DashDotLine:
440 dd->dashPattern.reserve(4);
441 dd->dashPattern << dash << space << dot << space;
442 break;
444 dd->dashPattern.reserve(6);
445 dd->dashPattern << dash << space << dot << space << dot << space;
446 break;
447 default:
448 break;
449 }
450 }
451 return dd->dashPattern;
452}
453
485{
486 if (pattern.isEmpty())
487 return;
488 detach();
489
490 QPenData *dd = static_cast<QPenData *>(d);
491 dd->dashPattern = pattern;
493
494 if ((dd->dashPattern.size() % 2) == 1) {
495 qWarning("QPen::setDashPattern: Pattern not of even length");
496 dd->dashPattern << 1;
497 }
498}
499
500
507{
508 QPenData *dd = static_cast<QPenData *>(d);
509 return dd->dashOffset;
510}
530{
531 if (qFuzzyCompare(offset, static_cast<QPenData *>(d)->dashOffset))
532 return;
533 detach();
534 QPenData *dd = static_cast<QPenData *>(d);
535 dd->dashOffset = offset;
536 if (d->style != Qt::CustomDashLine) {
537 dd->dashPattern = dashPattern();
539 }
540}
541
549{
550 const QPenData *dd = static_cast<QPenData *>(d);
551 return dd->miterLimit;
552}
553
571{
572 detach();
573 QPenData *dd = static_cast<QPenData *>(d);
574 dd->miterLimit = limit;
575}
576
577
586int QPen::width() const
587{
588 return qRound(d->width);
589}
590
599{
600 return d->width;
601}
602
619{
620 if (width < 0 || width >= (1 << 15)) {
621 qWarning("QPen::setWidth: Setting a pen width that is out of range");
622 return;
623 }
624 if ((qreal)width == d->width)
625 return;
626 detach();
627 d->width = width;
628}
629
645{
646 if (width < 0.f || width >= (1 << 15)) {
647 qWarning("QPen::setWidthF: Setting a pen width that is out of range");
648 return;
649 }
650 if (qAbs(d->width - width) < 0.00000001f)
651 return;
652 detach();
653 d->width = width;
654}
655
656
663{
664 return d->capStyle;
665}
666
677{
678 if (d->capStyle == c)
679 return;
680 detach();
681 d->capStyle = c;
682}
683
690{
691 return d->joinStyle;
692}
693
704{
705 if (d->joinStyle == j)
706 return;
707 detach();
708 d->joinStyle = j;
709}
710
719{
720 return d->brush.color();
721}
722
732{
733 detach();
734 d->brush = QBrush(c);
735}
736
737
742{
743 return d->brush;
744}
745
753{
754 detach();
755 d->brush = brush;
756}
757
758
764bool QPen::isSolid() const
765{
766 return d->brush.style() == Qt::SolidPattern;
767}
768
769
784{
785 QPenData *dd = static_cast<QPenData *>(d);
786 return (dd->cosmetic == true) || d->width == 0;
787}
788
789
797void QPen::setCosmetic(bool cosmetic)
798{
799 detach();
800 QPenData *dd = static_cast<QPenData *>(d);
801 dd->cosmetic = cosmetic;
802}
803
804
805
826bool QPen::operator==(const QPen &p) const
827{
828 QPenData *dd = static_cast<QPenData *>(d);
829 QPenData *pdd = static_cast<QPenData *>(p.d);
830 return (p.d == d)
831 || (p.d->style == d->style
832 && p.d->capStyle == d->capStyle
833 && p.d->joinStyle == d->joinStyle
834 && p.d->width == d->width
835 && pdd->miterLimit == dd->miterLimit
836 && (d->style != Qt::CustomDashLine
837 || (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) &&
838 pdd->dashPattern == dd->dashPattern))
839 && p.d->brush == d->brush
840 && pdd->cosmetic == dd->cosmetic);
841}
842
843
851{
852 return d->ref.loadRelaxed() == 1;
853}
854
855
856/*****************************************************************************
857 QPen stream functions
858 *****************************************************************************/
859#ifndef QT_NO_DATASTREAM
871{
872 QPenData *dd = static_cast<QPenData *>(p.d);
873 if (s.version() < 3) {
874 s << (quint8)p.style();
875 } else if (s.version() < QDataStream::Qt_4_3) {
876 s << (quint8)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle()));
877 } else {
878 s << (quint16)(uint(p.style()) | uint(p.capStyle()) | uint(p.joinStyle()));
879 s << (bool)(dd->cosmetic);
880 }
881
882 if (s.version() < 7) {
883 s << (quint8)p.width();
884 s << p.color();
885 } else {
886 s << double(p.widthF());
887 s << p.brush();
888 s << double(p.miterLimit());
889 if (sizeof(qreal) == sizeof(double)) {
890 s << p.dashPattern();
891 } else {
892 // ensure that we write doubles here instead of streaming the pattern
893 // directly; otherwise, platforms that redefine qreal might generate
894 // data that cannot be read on other platforms.
895 QList<qreal> pattern = p.dashPattern();
896 s << quint32(pattern.size());
897 for (int i = 0; i < pattern.size(); ++i)
898 s << double(pattern.at(i));
899 }
900 if (s.version() >= 9)
901 s << double(p.dashOffset());
902 if (s.version() >= QDataStream::Qt_5_0)
903 s << bool(qFuzzyIsNull(p.widthF()));
904 }
905 return s;
906}
907
919{
920 quint16 style;
921 quint8 width8 = 0;
922 double width = 0;
925 double miterLimit = 2;
926 QList<qreal> dashPattern;
927 double dashOffset = 0;
928 bool cosmetic = false;
929 bool defaultWidth;
930 if (s.version() < QDataStream::Qt_4_3) {
931 quint8 style8;
932 s >> style8;
933 style = style8;
934 } else {
935 s >> style;
936 s >> cosmetic;
937 }
938 if (s.version() < 7) {
939 s >> width8;
940 s >> color;
941 brush = color;
942 width = width8;
943 } else {
944 s >> width;
945 s >> brush;
946 s >> miterLimit;
947 if (sizeof(qreal) == sizeof(double)) {
948 s >> dashPattern;
949 } else {
950 quint32 numDashes;
951 s >> numDashes;
952 double dash;
953 dashPattern.reserve(numDashes);
954 for (quint32 i = 0; i < numDashes; ++i) {
955 s >> dash;
956 dashPattern << dash;
957 }
958 }
959 if (s.version() >= 9)
960 s >> dashOffset;
961 }
962
963 if (s.version() >= QDataStream::Qt_5_0) {
964 s >> defaultWidth;
965 }
966
967 p.detach();
968 QPenData *dd = static_cast<QPenData *>(p.d);
969 dd->width = width;
970 dd->brush = brush;
971 dd->style = Qt::PenStyle(style & Qt::MPenStyle);
972 dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle);
973 dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle);
974 dd->dashPattern = dashPattern;
975 dd->miterLimit = miterLimit;
976 dd->dashOffset = dashOffset;
977 dd->cosmetic = cosmetic;
978
979 return s;
980}
981#endif //QT_NO_DATASTREAM
982
983#ifndef QT_NO_DEBUG_STREAM
985{
986 const char *PEN_STYLES[] = {
987 "NoPen",
988 "SolidLine",
989 "DashLine",
990 "DotLine",
991 "DashDotLine",
992 "DashDotDotLine",
993 "CustomDashLine"
994 };
995
996 QDebugStateSaver saver(dbg);
997 dbg.nospace() << "QPen(" << p.width() << ',' << p.brush()
998 << ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle())
999 << ',' << int(p.joinStyle()) << ',' << p.dashPattern()
1000 << ',' << p.dashOffset()
1001 << ',' << p.miterLimit() << ')';
1002 return dbg;
1003}
1004#endif
1005
1018
1019#undef QT_COMPILING_QPEN
bool ref() noexcept
bool deref() noexcept
void storeRelaxed(T newValue) noexcept
T loadRelaxed() const noexcept
\inmodule QtGui
Definition qbrush.h:30
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
Qt::BrushStyle style() const
Returns the brush style.
Definition qbrush.h:120
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtCore\reentrant
Definition qdatastream.h:30
\inmodule QtCore
\inmodule QtCore
Definition qlist.h:74
void detach()
Definition qlist.h:409
void reserve(qsizetype size)
Definition qlist.h:746
void clear()
Definition qlist.h:417
QPenData * pen
Definition qpen.cpp:212
QPenDataHolder(const QBrush &brush, qreal width, Qt::PenStyle penStyle, Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle)
Definition qpen.cpp:213
qreal dashOffset
Definition qpen_p.h:33
qreal width
Definition qpen_p.h:27
Qt::PenStyle style
Definition qpen_p.h:29
QPenPrivate(const QBrush &brush, qreal width, Qt::PenStyle, Qt::PenCapStyle, Qt::PenJoinStyle _joinStyle)
Definition qpen.cpp:194
Qt::PenCapStyle capStyle
Definition qpen_p.h:30
QBrush brush
Definition qpen_p.h:28
QList< qreal > dashPattern
Definition qpen_p.h:32
QAtomicInt ref
Definition qpen_p.h:26
Qt::PenJoinStyle joinStyle
Definition qpen_p.h:31
uint cosmetic
Definition qpen_p.h:35
qreal miterLimit
Definition qpen_p.h:34
\inmodule QtGui
Definition qpen.h:25
void setCapStyle(Qt::PenCapStyle pcs)
Sets the pen's cap style to the given style.
Definition qpen.cpp:676
qreal widthF() const
Returns the pen width with floating point precision.
Definition qpen.cpp:598
void setStyle(Qt::PenStyle)
[0]
QList< qreal > dashPattern() const
Returns the dash pattern of this pen.
Definition qpen.cpp:420
QPen()
Constructs a default black solid line pen with 1 width.
Definition qpen.cpp:234
bool isCosmetic() const
Returns true if the pen is cosmetic; otherwise returns false.
Definition qpen.cpp:783
void setWidth(int width)
Sets the pen width to the given width in pixels with integer precision.
Definition qpen.cpp:618
QColor color() const
Returns the color of this pen's brush.
Definition qpen.cpp:718
~QPen()
Destroys the pen.
Definition qpen.cpp:312
void setWidthF(qreal width)
Sets the pen width to the given width in pixels with floating point precision.
Definition qpen.cpp:644
int width() const
Returns the pen width with integer precision.
Definition qpen.cpp:586
Qt::PenCapStyle capStyle() const
Returns the pen's cap style.
Definition qpen.cpp:662
void swap(QPen &other) noexcept
Definition qpen.h:40
void setColor(const QColor &color)
Sets the color of this pen's brush to the given color.
Definition qpen.cpp:731
void setBrush(const QBrush &brush)
Sets the brush used to fill strokes generated with this pen to the given brush.
Definition qpen.cpp:752
void setJoinStyle(Qt::PenJoinStyle pcs)
Sets the pen's join style to the given style.
Definition qpen.cpp:703
void setDashOffset(qreal doffset)
Sets the dash offset (the starting point on the dash pattern) for this pen to the offset specified.
Definition qpen.cpp:529
bool isDetached()
Definition qpen.cpp:850
void setMiterLimit(qreal limit)
Sets the miter limit of this pen to the given limit.
Definition qpen.cpp:570
QPen & operator=(const QPen &pen) noexcept
Assigns the given pen to this pen and returns a reference to this pen.
Definition qpen.cpp:348
bool operator==(const QPen &p) const
Returns true if the pen is equal to the given pen; otherwise false.
Definition qpen.cpp:826
bool isSolid() const
Returns true if the pen has a solid fill, otherwise false.
Definition qpen.cpp:764
Qt::PenJoinStyle joinStyle() const
Returns the pen's join style.
Definition qpen.cpp:689
void setCosmetic(bool cosmetic)
Sets this pen to cosmetic or non-cosmetic, depending on the value of cosmetic.
Definition qpen.cpp:797
void setDashPattern(const QList< qreal > &pattern)
Sets the dash pattern for this pen to the given pattern.
Definition qpen.cpp:484
qreal miterLimit() const
Returns the miter limit of the pen.
Definition qpen.cpp:548
QBrush brush() const
Returns the brush used to fill strokes generated with this pen.
Definition qpen.cpp:741
qreal dashOffset() const
Returns the dash offset for the pen.
Definition qpen.cpp:506
Qt::PenStyle style() const
Returns the pen style.
Definition qpen.cpp:385
\inmodule QtCore
Definition qvariant.h:64
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:531
Combined button and popup list for selecting options.
@ black
Definition qnamespace.h:29
@ CustomDashLine
@ DashDotDotLine
@ DotLine
@ SolidLine
@ MPenStyle
@ DashDotLine
@ DashLine
@ NoPen
PenJoinStyle
@ BevelJoin
@ MPenJoinStyle
@ SolidPattern
PenCapStyle
@ SquareCap
@ MPenCapStyle
Definition brush.cpp:5
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:287
bool qFuzzyIsNull(qfloat16 f) noexcept
Definition qfloat16.h:303
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:281
#define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS)
#define qWarning
Definition qlogging.h:162
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei width
GLenum GLuint GLintptr offset
GLint ref
const GLubyte * c
GLint limit
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat p
[1]
GLubyte * pattern
static qreal dot(const QPointF &a, const QPointF &b)
static const Qt::PenCapStyle qpen_default_cap
Definition qpen.cpp:206
static const Qt::PenJoinStyle qpen_default_join
Definition qpen.cpp:207
QDataStream & operator>>(QDataStream &s, QPen &p)
Definition qpen.cpp:918
nullPenInstance
Definition qpen.cpp:227
QT_BEGIN_NAMESPACE typedef QPenPrivate QPenData
Definition qpen.cpp:13
QDataStream & operator<<(QDataStream &s, const QPen &p)
Definition qpen.cpp:870
unsigned int quint32
Definition qtypes.h:45
unsigned short quint16
Definition qtypes.h:43
unsigned int uint
Definition qtypes.h:29
double qreal
Definition qtypes.h:92
unsigned char quint8
Definition qtypes.h:41
QGraphicsSvgItem * black