/**************************************************************************** | |
** | |
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). | |
** All rights reserved. | |
** Contact: Nokia Corporation (qt-info@nokia.com) | |
** | |
** This file is part of the QtGui module of the Qt Toolkit. | |
** | |
** $QT_BEGIN_LICENSE:LGPL$ | |
** GNU Lesser General Public License Usage | |
** This file may be used under the terms of the GNU Lesser General Public | |
** License version 2.1 as published by the Free Software Foundation and | |
** appearing in the file LICENSE.LGPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU Lesser | |
** General Public License version 2.1 requirements will be met: | |
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
** | |
** In addition, as a special exception, Nokia gives you certain additional | |
** rights. These rights are described in the Nokia Qt LGPL Exception | |
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | |
** | |
** GNU General Public License Usage | |
** Alternatively, this file may be used under the terms of the GNU General | |
** Public License version 3.0 as published by the Free Software Foundation | |
** and appearing in the file LICENSE.GPL included in the packaging of this | |
** file. Please review the following information to ensure the GNU General | |
** Public License version 3.0 requirements will be met: | |
** http://www.gnu.org/copyleft/gpl.html. | |
** | |
** Other Usage | |
** Alternatively, this file may be used in accordance with the terms and | |
** conditions contained in a signed written agreement between you and Nokia. | |
** | |
** | |
** | |
** | |
** | |
** $QT_END_LICENSE$ | |
** | |
****************************************************************************/ | |
#include "qpen.h" | |
#include "qpen_p.h" | |
#include "qdatastream.h" | |
#include "qvariant.h" | |
#include "qbrush.h" | |
#include <qdebug.h> | |
QT_BEGIN_NAMESPACE | |
typedef QPenPrivate QPenData; | |
/*! | |
\class QPen | |
\ingroup painting | |
\ingroup shared | |
\brief The QPen class defines how a QPainter should draw lines and outlines | |
of shapes. | |
A pen has a style(), width(), brush(), capStyle() and joinStyle(). | |
The pen style defines the line type. The brush is used to fill | |
strokes generated with the pen. Use the QBrush class to specify | |
fill styles. The cap style determines the line end caps that can | |
be drawn using QPainter, while the join style describes how joins | |
between two lines are drawn. The pen width can be specified in | |
both integer (width()) and floating point (widthF()) precision. A | |
line width of zero indicates a cosmetic pen. This means that the | |
pen width is always drawn one pixel wide, independent of the \l | |
{QPainter#Coordinate Transformations}{transformation} set on the | |
painter. | |
The various settings can easily be modified using the | |
corresponding setStyle(), setWidth(), setBrush(), setCapStyle() | |
and setJoinStyle() functions (note that the painter's pen must be | |
reset when altering the pen's properties). | |
For example: | |
\snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 0 | |
which is equivalent to | |
\snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 1 | |
The default pen is a solid black brush with 0 width, square | |
cap style (Qt::SquareCap), and bevel join style (Qt::BevelJoin). | |
In addition QPen provides the color() and setColor() | |
convenience functions to extract and set the color of the pen's | |
brush, respectively. Pens may also be compared and streamed. | |
For more information about painting in general, see the \l{Paint | |
System} documentation. | |
\tableofcontents | |
\section1 Pen Style | |
Qt provides several built-in styles represented by the | |
Qt::PenStyle enum: | |
\table | |
\row | |
\o \inlineimage qpen-solid.png | |
\o \inlineimage qpen-dash.png | |
\o \inlineimage qpen-dot.png | |
\row | |
\o Qt::SolidLine | |
\o Qt::DashLine | |
\o Qt::DotLine | |
\row | |
\o \inlineimage qpen-dashdot.png | |
\o \inlineimage qpen-dashdotdot.png | |
\o \inlineimage qpen-custom.png | |
\row | |
\o Qt::DashDotLine | |
\o Qt::DashDotDotLine | |
\o Qt::CustomDashLine | |
\endtable | |
Simply use the setStyle() function to convert the pen style to | |
either of the built-in styles, except the Qt::CustomDashLine style | |
which we will come back to shortly. Setting the style to Qt::NoPen | |
tells the painter to not draw lines or outlines. The default pen | |
style is Qt::SolidLine. | |
Since Qt 4.1 it is also possible to specify a custom dash pattern | |
using the setDashPattern() function which implicitly converts the | |
style of the pen to Qt::CustomDashLine. The pattern argument, a | |
QVector, must be specified as an even number of \l qreal entries | |
where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the | |
spaces. For example, the custom pattern shown above is created | |
using the following code: | |
\snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 2 | |
Note that the dash pattern is specified in units of the pens | |
width, e.g. a dash of length 5 in width 10 is 50 pixels long. | |
The currently set dash pattern can be retrieved using the | |
dashPattern() function. Use the isSolid() function to determine | |
whether the pen has a solid fill, or not. | |
\section1 Cap Style | |
The cap style defines how the end points of lines are drawn using | |
QPainter. The cap style only apply to wide lines, i.e. when the | |
width is 1 or greater. The Qt::PenCapStyle enum provides the | |
following styles: | |
\table | |
\row | |
\o \inlineimage qpen-square.png | |
\o \inlineimage qpen-flat.png | |
\o \inlineimage qpen-roundcap.png | |
\row | |
\o Qt::SquareCap | |
\o Qt::FlatCap | |
\o Qt::RoundCap | |
\endtable | |
The Qt::SquareCap style is a square line end that covers the end | |
point and extends beyond it by half the line width. The | |
Qt::FlatCap style is a square line end that does not cover the end | |
point of the line. And the Qt::RoundCap style is a rounded line | |
end covering the end point. | |
The default is Qt::SquareCap. | |
Whether or not end points are drawn when the pen width is 0 or 1 | |
depends on the cap style. Using Qt::SquareCap or Qt::RoundCap they | |
are drawn, using Qt::FlatCap they are not drawn. | |
\section1 Join Style | |
The join style defines how joins between two connected lines can | |
be drawn using QPainter. The join style only apply to wide lines, | |
i.e. when the width is 1 or greater. The Qt::PenJoinStyle enum | |
provides the following styles: | |
\table | |
\row | |
\o \inlineimage qpen-bevel.png | |
\o \inlineimage qpen-miter.png | |
\o \inlineimage qpen-roundjoin.png | |
\row | |
\o Qt::BevelJoin | |
\o Qt::MiterJoin | |
\o Qt::RoundJoin | |
\endtable | |
The Qt::BevelJoin style fills the triangular notch between the two | |
lines. The Qt::MiterJoin style extends the lines to meet at an | |
angle. And the Qt::RoundJoin style fills a circular arc between | |
the two lines. | |
The default is Qt::BevelJoin. | |
\image qpen-miterlimit.png | |
When the Qt::MiterJoin style is applied, it is possible to use the | |
setMiterLimit() function to specify how far the miter join can | |
extend from the join point. The miterLimit() is used to reduce | |
artifacts between line joins where the lines are close to | |
parallel. | |
The miterLimit() must be specified in units of the pens width, | |
e.g. a miter limit of 5 in width 10 is 50 pixels long. The | |
default miter limit is 2, i.e. twice the pen width in pixels. | |
\table 100% | |
\row | |
\o \inlineimage qpen-demo.png | |
\o \bold {\l {demos/pathstroke}{The Path Stroking Demo}} | |
The Path Stroking demo shows Qt's built-in dash patterns and shows | |
how custom patterns can be used to extend the range of available | |
patterns. | |
\endtable | |
\sa QPainter, QBrush, {demos/pathstroke}{Path Stroking Demo}, | |
{Scribble Example} | |
*/ | |
/*! | |
\internal | |
*/ | |
inline QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle, | |
Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle) | |
: dashOffset(0), miterLimit(2), | |
cosmetic(false) | |
{ | |
ref = 1; | |
width = _width; | |
brush = _brush; | |
style = penStyle; | |
capStyle = _capStyle; | |
joinStyle = _joinStyle; | |
} | |
static const Qt::PenCapStyle qpen_default_cap = Qt::SquareCap; | |
static const Qt::PenJoinStyle qpen_default_join = Qt::BevelJoin; | |
#ifndef QT_NO_THREAD | |
// Special deleter that only deletes if the ref-count goes to zero | |
template <> | |
class QGlobalStaticDeleter<QPenPrivate> | |
{ | |
public: | |
QGlobalStatic<QPenPrivate> &globalStatic; | |
QGlobalStaticDeleter(QGlobalStatic<QPenPrivate> &_globalStatic) | |
: globalStatic(_globalStatic) | |
{ } | |
inline ~QGlobalStaticDeleter() | |
{ | |
if (!globalStatic.pointer->ref.deref()) | |
delete globalStatic.pointer; | |
globalStatic.pointer = 0; | |
globalStatic.destroyed = true; | |
} | |
}; | |
#endif | |
Q_GLOBAL_STATIC_WITH_ARGS(QPenData, defaultPenInstance, | |
(Qt::black, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join)) | |
Q_GLOBAL_STATIC_WITH_ARGS(QPenData, nullPenInstance, | |
(Qt::black, 0, Qt::NoPen, qpen_default_cap, qpen_default_join)) | |
/*! | |
Constructs a default black solid line pen with 0 width. | |
*/ | |
QPen::QPen() | |
{ | |
d = defaultPenInstance(); | |
d->ref.ref(); | |
} | |
/*! | |
Constructs a black pen with 0 width and the given \a style. | |
\sa setStyle() | |
*/ | |
QPen::QPen(Qt::PenStyle style) | |
{ | |
if (style == Qt::NoPen) { | |
d = nullPenInstance(); | |
d->ref.ref(); | |
} else { | |
d = new QPenData(Qt::black, 0, style, qpen_default_cap, qpen_default_join); | |
} | |
} | |
/*! | |
Constructs a solid line pen with 0 width and the given \a color. | |
\sa setBrush(), setColor() | |
*/ | |
QPen::QPen(const QColor &color) | |
{ | |
d = new QPenData(color, 0, Qt::SolidLine, qpen_default_cap, qpen_default_join); | |
} | |
/*! | |
\fn QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle style, Qt::PenCapStyle cap, Qt::PenJoinStyle join) | |
Constructs a pen with the specified \a brush, \a width, pen \a style, | |
\a cap style and \a join style. | |
\sa setBrush(), setWidth(), setStyle(), setCapStyle(), setJoinStyle() | |
*/ | |
QPen::QPen(const QBrush &brush, qreal width, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j) | |
{ | |
d = new QPenData(brush, width, s, c, j); | |
} | |
/*! | |
\fn QPen::QPen(const QPen &pen) | |
Constructs a pen that is a copy of the given \a pen. | |
*/ | |
QPen::QPen(const QPen &p) | |
{ | |
d = p.d; | |
d->ref.ref(); | |
} | |
/*! | |
Destroys the pen. | |
*/ | |
QPen::~QPen() | |
{ | |
if (!d->ref.deref()) | |
delete d; | |
} | |
/*! | |
\fn void QPen::detach() | |
Detaches from shared pen data to make sure that this pen is the | |
only one referring the data. | |
If multiple pens share common data, this pen dereferences the data | |
and gets a copy of the data. Nothing is done if there is just a | |
single reference. | |
*/ | |
void QPen::detach() | |
{ | |
if (d->ref == 1) | |
return; | |
QPenData *x = new QPenData(*static_cast<QPenData *>(d)); | |
if (!d->ref.deref()) | |
delete d; | |
x->ref = 1; | |
d = x; | |
} | |
/*! | |
\fn QPen &QPen::operator=(const QPen &pen) | |
Assigns the given \a pen to this pen and returns a reference to | |
this pen. | |
*/ | |
QPen &QPen::operator=(const QPen &p) | |
{ | |
qAtomicAssign(d, p.d); | |
return *this; | |
} | |
/*! | |
Returns the pen as a QVariant. | |
*/ | |
QPen::operator QVariant() const | |
{ | |
return QVariant(QVariant::Pen, this); | |
} | |
/*! | |
\fn Qt::PenStyle QPen::style() const | |
Returns the pen style. | |
\sa setStyle(), {QPen#Pen Style}{Pen Style} | |
*/ | |
Qt::PenStyle QPen::style() const | |
{ | |
return d->style; | |
} | |
/*! | |
\fn void QPen::setStyle(Qt::PenStyle style) | |
Sets the pen style to the given \a style. | |
See the \l Qt::PenStyle documentation for a list of the available | |
styles. Since Qt 4.1 it is also possible to specify a custom dash | |
pattern using the setDashPattern() function which implicitly | |
converts the style of the pen to Qt::CustomDashLine. | |
\note This function resets the dash offset to zero. | |
\sa style(), {QPen#Pen Style}{Pen Style} | |
*/ | |
void QPen::setStyle(Qt::PenStyle s) | |
{ | |
if (d->style == s) | |
return; | |
detach(); | |
d->style = s; | |
QPenData *dd = static_cast<QPenData *>(d); | |
dd->dashPattern.clear(); | |
dd->dashOffset = 0; | |
} | |
/*! | |
Returns the dash pattern of this pen. | |
\sa style(), isSolid() | |
*/ | |
QVector<qreal> QPen::dashPattern() const | |
{ | |
QPenData *dd = static_cast<QPenData *>(d); | |
if (d->style == Qt::SolidLine || d->style == Qt::NoPen) { | |
return QVector<qreal>(); | |
} else if (dd->dashPattern.isEmpty()) { | |
const qreal space = 2; | |
const qreal dot = 1; | |
const qreal dash = 4; | |
switch (d->style) { | |
case Qt::DashLine: | |
dd->dashPattern << dash << space; | |
break; | |
case Qt::DotLine: | |
dd->dashPattern << dot << space; | |
break; | |
case Qt::DashDotLine: | |
dd->dashPattern << dash << space << dot << space; | |
break; | |
case Qt::DashDotDotLine: | |
dd->dashPattern << dash << space << dot << space << dot << space; | |
break; | |
default: | |
break; | |
} | |
} | |
return dd->dashPattern; | |
} | |
/*! | |
Sets the dash pattern for this pen to the given \a pattern. This | |
implicitly converts the style of the pen to Qt::CustomDashLine. | |
The pattern must be specified as an even number of positive entries | |
where the entries 1, 3, 5... are the dashes and 2, 4, 6... are the | |
spaces. For example: | |
\table 100% | |
\row | |
\o \inlineimage qpen-custom.png | |
\o | |
\snippet doc/src/snippets/code/src_gui_painting_qpen.cpp 3 | |
\endtable | |
The dash pattern is specified in units of the pens width; e.g. a | |
dash of length 5 in width 10 is 50 pixels long. Note that a pen | |
with zero width is equivalent to a cosmetic pen with a width of 1 | |
pixel. | |
Each dash is also subject to cap styles so a dash of 1 with square | |
cap set will extend 0.5 pixels out in each direction resulting in | |
a total width of 2. | |
Note that the default cap style is Qt::SquareCap, meaning that a | |
square line end covers the end point and extends beyond it by half | |
the line width. | |
\sa setStyle(), dashPattern(), setCapStyle(), setCosmetic() | |
*/ | |
void QPen::setDashPattern(const QVector<qreal> &pattern) | |
{ | |
if (pattern.isEmpty()) | |
return; | |
detach(); | |
QPenData *dd = static_cast<QPenData *>(d); | |
dd->dashPattern = pattern; | |
d->style = Qt::CustomDashLine; | |
if ((dd->dashPattern.size() % 2) == 1) { | |
qWarning("QPen::setDashPattern: Pattern not of even length"); | |
dd->dashPattern << 1; | |
} | |
} | |
/*! | |
Returns the dash offset for the pen. | |
\sa setDashOffset() | |
*/ | |
qreal QPen::dashOffset() const | |
{ | |
QPenData *dd = static_cast<QPenData *>(d); | |
return dd->dashOffset; | |
} | |
/*! | |
Sets the dash offset (the starting point on the dash pattern) for this pen | |
to the \a offset specified. The offset is measured in terms of the units used | |
to specify the dash pattern. | |
\table | |
\row \o \inlineimage qpen-dashpattern.png | |
\o For example, a pattern where each stroke is four units long, followed by a gap | |
of two units, will begin with the stroke when drawn as a line. | |
However, if the dash offset is set to 4.0, any line drawn will begin with the gap. | |
Values of the offset up to 4.0 will cause part of the stroke to be drawn first, | |
and values of the offset between 4.0 and 6.0 will cause the line to begin with | |
part of the gap. | |
\endtable | |
\note This implicitly converts the style of the pen to Qt::CustomDashLine. | |
*/ | |
void QPen::setDashOffset(qreal offset) | |
{ | |
if (qFuzzyCompare(offset, static_cast<QPenData *>(d)->dashOffset)) | |
return; | |
detach(); | |
QPenData *dd = static_cast<QPenData *>(d); | |
dd->dashOffset = offset; | |
if (d->style != Qt::CustomDashLine) { | |
dd->dashPattern = dashPattern(); | |
d->style = Qt::CustomDashLine; | |
} | |
} | |
/*! | |
Returns the miter limit of the pen. The miter limit is only | |
relevant when the join style is set to Qt::MiterJoin. | |
\sa setMiterLimit(), {QPen#Join Style}{Join Style} | |
*/ | |
qreal QPen::miterLimit() const | |
{ | |
const QPenData *dd = static_cast<QPenData *>(d); | |
return dd->miterLimit; | |
} | |
/*! | |
Sets the miter limit of this pen to the given \a limit. | |
\image qpen-miterlimit.png | |
The miter limit describes how far a miter join can extend from the | |
join point. This is used to reduce artifacts between line joins | |
where the lines are close to parallel. | |
This value does only have effect when the pen style is set to | |
Qt::MiterJoin. The value is specified in units of the pen's width, | |
e.g. a miter limit of 5 in width 10 is 50 pixels long. The default | |
miter limit is 2, i.e. twice the pen width in pixels. | |
\sa miterLimit(), setJoinStyle(), {QPen#Join Style}{Join Style} | |
*/ | |
void QPen::setMiterLimit(qreal limit) | |
{ | |
detach(); | |
QPenData *dd = static_cast<QPenData *>(d); | |
dd->miterLimit = limit; | |
} | |
/*! | |
\fn qreal QPen::width() const | |
Returns the pen width with integer precision. | |
\sa setWidth(), widthF() | |
*/ | |
int QPen::width() const | |
{ | |
return qRound(d->width); | |
} | |
/*! | |
\fn qreal QPen::widthF() const | |
Returns the pen width with floating point precision. | |
\sa setWidthF() width() | |
*/ | |
qreal QPen::widthF() const | |
{ | |
return d->width; | |
} | |
/*! | |
\fn QPen::setWidth(int width) | |
Sets the pen width to the given \a width in pixels with integer | |
precision. | |
A line width of zero indicates a cosmetic pen. This means that the | |
pen width is always drawn one pixel wide, independent of the \l | |
{QPainter#Coordinate Transformations}{transformation} set on the | |
painter. | |
Setting a pen width with a negative value is not supported. | |
\sa setWidthF(), width() | |
*/ | |
void QPen::setWidth(int width) | |
{ | |
if (width < 0) | |
qWarning("QPen::setWidth: Setting a pen width with a negative value is not defined"); | |
if ((qreal)width == d->width) | |
return; | |
detach(); | |
d->width = width; | |
} | |
/*! | |
Sets the pen width to the given \a width in pixels with floating point | |
precision. | |
A line width of zero indicates a cosmetic pen. This means that the | |
pen width is always drawn one pixel wide, independent of the \l | |
{QPainter#Coordinate Transformations}{transformation} on the | |
painter. | |
Setting a pen width with a negative value is not supported. | |
\sa setWidth() widthF() | |
*/ | |
void QPen::setWidthF(qreal width) | |
{ | |
if (width < 0.f) | |
qWarning("QPen::setWidthF: Setting a pen width with a negative value is not defined"); | |
if (qAbs(d->width - width) < 0.00000001f) | |
return; | |
detach(); | |
d->width = width; | |
} | |
/*! | |
Returns the pen's cap style. | |
\sa setCapStyle(), {QPen#Cap Style}{Cap Style} | |
*/ | |
Qt::PenCapStyle QPen::capStyle() const | |
{ | |
return d->capStyle; | |
} | |
/*! | |
\fn void QPen::setCapStyle(Qt::PenCapStyle style) | |
Sets the pen's cap style to the given \a style. The default value | |
is Qt::SquareCap. | |
\sa capStyle(), {QPen#Cap Style}{Cap Style} | |
*/ | |
void QPen::setCapStyle(Qt::PenCapStyle c) | |
{ | |
if (d->capStyle == c) | |
return; | |
detach(); | |
d->capStyle = c; | |
} | |
/*! | |
Returns the pen's join style. | |
\sa setJoinStyle(), {QPen#Join Style}{Join Style} | |
*/ | |
Qt::PenJoinStyle QPen::joinStyle() const | |
{ | |
return d->joinStyle; | |
} | |
/*! | |
\fn void QPen::setJoinStyle(Qt::PenJoinStyle style) | |
Sets the pen's join style to the given \a style. The default value | |
is Qt::BevelJoin. | |
\sa joinStyle(), {QPen#Join Style}{Join Style} | |
*/ | |
void QPen::setJoinStyle(Qt::PenJoinStyle j) | |
{ | |
if (d->joinStyle == j) | |
return; | |
detach(); | |
d->joinStyle = j; | |
} | |
/*! | |
\fn const QColor &QPen::color() const | |
Returns the color of this pen's brush. | |
\sa brush(), setColor() | |
*/ | |
QColor QPen::color() const | |
{ | |
return d->brush.color(); | |
} | |
/*! | |
\fn void QPen::setColor(const QColor &color) | |
Sets the color of this pen's brush to the given \a color. | |
\sa setBrush(), color() | |
*/ | |
void QPen::setColor(const QColor &c) | |
{ | |
detach(); | |
d->brush = QBrush(c); | |
} | |
/*! | |
Returns the brush used to fill strokes generated with this pen. | |
*/ | |
QBrush QPen::brush() const | |
{ | |
return d->brush; | |
} | |
/*! | |
Sets the brush used to fill strokes generated with this pen to the given | |
\a brush. | |
\sa brush(), setColor() | |
*/ | |
void QPen::setBrush(const QBrush &brush) | |
{ | |
detach(); | |
d->brush = brush; | |
} | |
/*! | |
Returns true if the pen has a solid fill, otherwise false. | |
\sa style(), dashPattern() | |
*/ | |
bool QPen::isSolid() const | |
{ | |
return d->brush.style() == Qt::SolidPattern; | |
} | |
/*! | |
Returns true if the pen is cosmetic; otherwise returns false. | |
Cosmetic pens are used to draw strokes that have a constant width | |
regardless of any transformations applied to the QPainter they are | |
used with. Drawing a shape with a cosmetic pen ensures that its | |
outline will have the same thickness at different scale factors. | |
A zero width pen is cosmetic by default; pens with a non-zero width | |
are non-cosmetic. | |
\sa setCosmetic(), widthF() | |
*/ | |
bool QPen::isCosmetic() const | |
{ | |
QPenData *dd = static_cast<QPenData *>(d); | |
return (dd->cosmetic == true) || d->width == 0; | |
} | |
/*! | |
Sets this pen to cosmetic or non-cosmetic, depending on the value of | |
\a cosmetic. | |
\sa isCosmetic() | |
*/ | |
void QPen::setCosmetic(bool cosmetic) | |
{ | |
detach(); | |
QPenData *dd = static_cast<QPenData *>(d); | |
dd->cosmetic = cosmetic; | |
} | |
/*! | |
\fn bool QPen::operator!=(const QPen &pen) const | |
Returns true if the pen is different from the given \a pen; | |
otherwise false. Two pens are different if they have different | |
styles, widths or colors. | |
\sa operator==() | |
*/ | |
/*! | |
\fn bool QPen::operator==(const QPen &pen) const | |
Returns true if the pen is equal to the given \a pen; otherwise | |
false. Two pens are equal if they have equal styles, widths and | |
colors. | |
\sa operator!=() | |
*/ | |
bool QPen::operator==(const QPen &p) const | |
{ | |
QPenData *dd = static_cast<QPenData *>(d); | |
QPenData *pdd = static_cast<QPenData *>(p.d); | |
return (p.d == d) | |
|| (p.d->style == d->style | |
&& p.d->capStyle == d->capStyle | |
&& p.d->joinStyle == d->joinStyle | |
&& p.d->width == d->width | |
&& pdd->miterLimit == dd->miterLimit | |
&& (d->style != Qt::CustomDashLine | |
|| (qFuzzyCompare(pdd->dashOffset, dd->dashOffset) && | |
pdd->dashPattern == dd->dashPattern)) | |
&& p.d->brush == d->brush | |
&& pdd->cosmetic == dd->cosmetic); | |
} | |
/*! | |
\fn bool QPen::isDetached() | |
\internal | |
*/ | |
bool QPen::isDetached() | |
{ | |
return d->ref == 1; | |
} | |
/***************************************************************************** | |
QPen stream functions | |
*****************************************************************************/ | |
#ifndef QT_NO_DATASTREAM | |
/*! | |
\fn QDataStream &operator<<(QDataStream &stream, const QPen &pen) | |
\relates QPen | |
Writes the given \a pen to the given \a stream and returns a reference to | |
the \a stream. | |
\sa {Serializing Qt Data Types} | |
*/ | |
QDataStream &operator<<(QDataStream &s, const QPen &p) | |
{ | |
QPenData *dd = static_cast<QPenData *>(p.d); | |
if (s.version() < 3) { | |
s << (quint8)p.style(); | |
} else if (s.version() < QDataStream::Qt_4_3) { | |
s << (quint8)(p.style() | p.capStyle() | p.joinStyle()); | |
} else { | |
s << (quint16)(p.style() | p.capStyle() | p.joinStyle()); | |
s << (bool)(dd->cosmetic); | |
} | |
if (s.version() < 7) { | |
s << (quint8)p.width(); | |
s << p.color(); | |
} else { | |
s << double(p.widthF()); | |
s << p.brush(); | |
s << double(p.miterLimit()); | |
if (sizeof(qreal) == sizeof(double)) { | |
s << p.dashPattern(); | |
} else { | |
// ensure that we write doubles here instead of streaming the pattern | |
// directly; otherwise, platforms that redefine qreal might generate | |
// data that cannot be read on other platforms. | |
QVector<qreal> pattern = p.dashPattern(); | |
s << quint32(pattern.size()); | |
for (int i = 0; i < pattern.size(); ++i) | |
s << double(pattern.at(i)); | |
} | |
if (s.version() >= 9) | |
s << double(p.dashOffset()); | |
} | |
return s; | |
} | |
/*! | |
\fn QDataStream &operator>>(QDataStream &stream, QPen &pen) | |
\relates QPen | |
Reads a pen from the given \a stream into the given \a pen and | |
returns a reference to the \a stream. | |
\sa {Serializing Qt Data Types} | |
*/ | |
QDataStream &operator>>(QDataStream &s, QPen &p) | |
{ | |
quint16 style; | |
quint8 width8 = 0; | |
double width = 0; | |
QColor color; | |
QBrush brush; | |
double miterLimit = 2; | |
QVector<qreal> dashPattern; | |
double dashOffset = 0; | |
bool cosmetic = false; | |
if (s.version() < QDataStream::Qt_4_3) { | |
quint8 style8; | |
s >> style8; | |
style = style8; | |
} else { | |
s >> style; | |
s >> cosmetic; | |
} | |
if (s.version() < 7) { | |
s >> width8; | |
s >> color; | |
brush = color; | |
width = width8; | |
} else { | |
s >> width; | |
s >> brush; | |
s >> miterLimit; | |
if (sizeof(qreal) == sizeof(double)) { | |
s >> dashPattern; | |
} else { | |
quint32 numDashes; | |
s >> numDashes; | |
double dash; | |
for (quint32 i = 0; i < numDashes; ++i) { | |
s >> dash; | |
dashPattern << dash; | |
} | |
} | |
if (s.version() >= 9) | |
s >> dashOffset; | |
} | |
p.detach(); | |
QPenData *dd = static_cast<QPenData *>(p.d); | |
dd->width = width; | |
dd->brush = brush; | |
dd->style = Qt::PenStyle(style & Qt::MPenStyle); | |
dd->capStyle = Qt::PenCapStyle(style & Qt::MPenCapStyle); | |
dd->joinStyle = Qt::PenJoinStyle(style & Qt::MPenJoinStyle); | |
dd->dashPattern = dashPattern; | |
dd->miterLimit = miterLimit; | |
dd->dashOffset = dashOffset; | |
dd->cosmetic = cosmetic; | |
return s; | |
} | |
#endif //QT_NO_DATASTREAM | |
#ifndef QT_NO_DEBUG_STREAM | |
QDebug operator<<(QDebug dbg, const QPen &p) | |
{ | |
#ifndef Q_BROKEN_DEBUG_STREAM | |
const char *PEN_STYLES[] = { | |
"NoPen", | |
"SolidLine", | |
"DashLine", | |
"DotLine", | |
"DashDotLine", | |
"DashDotDotLine", | |
"CustomDashLine" | |
}; | |
dbg.nospace() << "QPen(" << p.width() << ',' << p.brush() | |
<< ',' << PEN_STYLES[p.style()] << ',' << int(p.capStyle()) | |
<< ',' << int(p.joinStyle()) << ',' << p.dashPattern() | |
<< ',' << p.dashOffset() | |
<< ',' << p.miterLimit() << ')'; | |
return dbg.space(); | |
#else | |
qWarning("This compiler doesn't support streaming QPen to QDebug"); | |
return dbg; | |
Q_UNUSED(p); | |
#endif | |
} | |
#endif | |
/*! | |
\fn DataPtr &QPen::data_ptr() | |
\internal | |
*/ | |
/*! | |
\typedef QPen::DataPtr | |
\internal | |
*/ | |
QT_END_NAMESPACE | |
#undef QT_COMPILING_QPEN |