/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $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
    \inmodule QtGui
    \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 code/src_gui_painting_qpen.cpp 0

    which is equivalent to

    \snippet code/src_gui_painting_qpen.cpp 1

    The default pen is a solid black brush with 1 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
    \li \inlineimage qpen-solid.png
    \li \inlineimage qpen-dash.png
    \li \inlineimage qpen-dot.png
    \row
    \li Qt::SolidLine
    \li Qt::DashLine
    \li Qt::DotLine
    \row
    \li \inlineimage qpen-dashdot.png
    \li \inlineimage qpen-dashdotdot.png
    \li \inlineimage qpen-custom.png
    \row
    \li Qt::DashDotLine
    \li Qt::DashDotDotLine
    \li 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 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
    \li \inlineimage qpen-square.png
    \li \inlineimage qpen-flat.png
    \li \inlineimage qpen-roundcap.png
    \row
    \li Qt::SquareCap
    \li Qt::FlatCap
    \li 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
    \li \inlineimage qpen-bevel.png
    \li \inlineimage qpen-miter.png
    \li \inlineimage qpen-roundjoin.png
    \row
    \li Qt::BevelJoin
    \li Qt::MiterJoin
    \li 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
    \li \inlineimage qpen-demo.png
    \li \b {\l {painting/pathstroke}{The Path Stroking Example}}

    The Path Stroking example 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, {painting/pathstroke}{Path Stroking Example},
        {Scribble Example}
*/

/*!
  \internal
*/
inline QPenPrivate::QPenPrivate(const QBrush &_brush, qreal _width, Qt::PenStyle penStyle,
                                Qt::PenCapStyle _capStyle, Qt::PenJoinStyle _joinStyle, bool _defaultWidth)
    : ref(1), dashOffset(0), miterLimit(2),
      cosmetic(false), defaultWidth(_defaultWidth)
{
    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;

class QPenDataHolder
{
public:
    QPenData *pen;
    QPenDataHolder(const QBrush &brush, qreal width, Qt::PenStyle penStyle,
                   Qt::PenCapStyle penCapStyle, Qt::PenJoinStyle _joinStyle)
        : pen(new QPenData(brush, width, penStyle, penCapStyle, _joinStyle))
    { }
    ~QPenDataHolder()
    {
        if (!pen->ref.deref())
            delete pen;
        pen = nullptr;
    }
};

Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, defaultPenInstance,
                          (Qt::black, 1, Qt::SolidLine, qpen_default_cap, qpen_default_join))
Q_GLOBAL_STATIC_WITH_ARGS(QPenDataHolder, nullPenInstance,
                          (Qt::black, 1, Qt::NoPen, qpen_default_cap, qpen_default_join))

/*!
    Constructs a default black solid line pen with 1 width.
*/

QPen::QPen()
{
    d = defaultPenInstance()->pen;
    d->ref.ref();
}

/*!
    Constructs a black pen with 1 width and the given \a style.

    \sa setStyle()
*/

QPen::QPen(Qt::PenStyle style)
{
    if (style == Qt::NoPen) {
        d = nullPenInstance()->pen;
        d->ref.ref();
    } else {
        d = new QPenData(Qt::black, 1, style, qpen_default_cap, qpen_default_join);
    }
}


/*!
    Constructs a solid line pen with 1 width and the given \a color.

    \sa setBrush(), setColor()
*/

QPen::QPen(const QColor &color)
{
    d = new QPenData(color, 1, 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, false);
}

/*!
    \fn QPen::QPen(const QPen &pen)

    Constructs a pen that is a copy of the given \a pen.
*/

QPen::QPen(const QPen &p) noexcept
{
    d = p.d;
    if (d)
        d->ref.ref();
}


/*!
    \fn QPen::QPen(QPen &&pen)
    \since 5.4

    Constructs a pen that is moved from the given \a pen.

    The moved-from pen can only be assigned to, copied, or
    destroyed. Any other operation (prior to assignment) leads to
    undefined behavior.
*/

/*!
    Destroys the pen.
*/

QPen::~QPen()
{
    if (d && !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.loadRelaxed() == 1)
        return;

    QPenData *x = new QPenData(*static_cast<QPenData *>(d));
    if (!d->ref.deref())
        delete d;
    x->ref.storeRelaxed(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) noexcept
{
    QPen(p).swap(*this);
    return *this;
}

/*!
    \fn QPen &QPen::operator=(QPen &&other)

    Move-assigns \a other to this QPen instance.

    \since 5.2
*/

/*!
    \fn void QPen::swap(QPen &other)
    \since 4.8

    Swaps pen \a other with this pen. This operation is very
    fast and never fails.
*/

/*!
   Returns the pen as a QVariant.
*/
QPen::operator QVariant() const
{
    return QVariant(QMetaType::QPen, 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.reserve(2);
            dd->dashPattern << dash << space;
            break;
        case Qt::DotLine:
            dd->dashPattern.reserve(2);
            dd->dashPattern << dot << space;
            break;
        case Qt::DashDotLine:
            dd->dashPattern.reserve(4);
            dd->dashPattern << dash << space << dot << space;
            break;
        case Qt::DashDotDotLine:
            dd->dashPattern.reserve(6);
            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
    \li \inlineimage qpen-custom.png
    \li
    \snippet 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 \li \inlineimage qpen-dashpattern.png
    \li 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");
        return;
    }
    if (qAbs(d->width - width) < 0.00000001f)
        return;
    detach();
    d->width = width;
    d->defaultWidth = false;
}


/*!
    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 \c true if the pen has a solid fill, otherwise false.

    \sa style(), dashPattern()
*/
bool QPen::isSolid() const
{
    return d->brush.style() == Qt::SolidPattern;
}


/*!
    Returns \c true if the pen is cosmetic; otherwise returns \c 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.

    \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 \c 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 \c 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
            && pdd->defaultWidth == dd->defaultWidth);
}


/*!
    \fn bool QPen::isDetached()

    \internal
*/

bool QPen::isDetached()
{
    return d->ref.loadRelaxed() == 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());
        if (s.version() >= QDataStream::Qt_5_0)
            s << bool(dd->defaultWidth);
    }
    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;
    bool defaultWidth = 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;
            dashPattern.reserve(numDashes);
            for (quint32 i = 0; i < numDashes; ++i) {
                s >> dash;
                dashPattern << dash;
            }
        }
        if (s.version() >= 9)
            s >> dashOffset;
    }

    if (s.version() >= QDataStream::Qt_5_0) {
        s >> defaultWidth;
    } else {
        // best we can do for legacy pens
        defaultWidth = qFuzzyIsNull(width);
    }

    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;
    dd->defaultWidth = defaultWidth;

    return s;
}
#endif //QT_NO_DATASTREAM

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QPen &p)
{
    const char *PEN_STYLES[] = {
        "NoPen",
        "SolidLine",
        "DashLine",
        "DotLine",
        "DashDotLine",
        "DashDotDotLine",
        "CustomDashLine"
    };

    QDebugStateSaver saver(dbg);
    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;
}
#endif

/*!
    \fn DataPtr &QPen::data_ptr()
    \internal
*/

/*!
    \typedef QPen::DataPtr

    \internal
*/

QT_END_NAMESPACE

#undef QT_COMPILING_QPEN
