/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt SVG 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 "qsvgstyle_p.h"

#include "qsvgfont_p.h"
#include "qsvggraphics_p.h"
#include "qsvgnode_p.h"
#include "qsvgtinydocument_p.h"

#include "qpainter.h"
#include "qpair.h"
#include "qcolor.h"
#include "qdebug.h"
#include "qmath.h"
#include "qnumeric.h"

QT_BEGIN_NAMESPACE

QSvgExtraStates::QSvgExtraStates()
    : fillOpacity(1.0)
    , strokeOpacity(1.0)
    , svgFont(0)
    , textAnchor(Qt::AlignLeft)
    , fontWeight(400)
    , fillRule(Qt::WindingFill)
    , strokeDashOffset(0)
    , vectorEffect(false)
{
}

QSvgStyleProperty::~QSvgStyleProperty()
{
}

void QSvgFillStyleProperty::apply(QPainter *, const QSvgNode *, QSvgExtraStates &)
{
    Q_ASSERT(!"This should not be called!");
}

void QSvgFillStyleProperty::revert(QPainter *, QSvgExtraStates &)
{
    Q_ASSERT(!"This should not be called!");
}


QSvgQualityStyle::QSvgQualityStyle(int color)
{
    Q_UNUSED(color);
}
void QSvgQualityStyle::apply(QPainter *, const QSvgNode *, QSvgExtraStates &)
{

}
void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &)
{

}

QSvgFillStyle::QSvgFillStyle()
    : m_style(0)
    , m_fillRule(Qt::WindingFill)
    , m_oldFillRule(Qt::WindingFill)
    , m_fillOpacity(1.0)
    , m_oldFillOpacity(0)
    , m_gradientResolved(1)
    , m_fillRuleSet(0)
    , m_fillOpacitySet(0)
    , m_fillSet(0)
{
}

void QSvgFillStyle::setFillRule(Qt::FillRule f)
{
    m_fillRuleSet = 1;
    m_fillRule = f;
}

void QSvgFillStyle::setFillOpacity(qreal opacity)
{
    m_fillOpacitySet = 1;
    m_fillOpacity = opacity;
}

void QSvgFillStyle::setFillStyle(QSvgFillStyleProperty* style)
{
    m_style = style;
    m_fillSet = 1;
}

void QSvgFillStyle::setBrush(QBrush brush)
{
    m_fill = std::move(brush);
    m_style = 0;
    m_fillSet = 1;
}

void QSvgFillStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &states)
{
    m_oldFill = p->brush();
    m_oldFillRule = states.fillRule;
    m_oldFillOpacity = states.fillOpacity;

    if (m_fillRuleSet)
        states.fillRule = m_fillRule;
    if (m_fillSet) {
        if (m_style)
            p->setBrush(m_style->brush(p, states));
        else
            p->setBrush(m_fill);
    }
    if (m_fillOpacitySet)
        states.fillOpacity = m_fillOpacity;
}

void QSvgFillStyle::revert(QPainter *p, QSvgExtraStates &states)
{
    if (m_fillOpacitySet)
        states.fillOpacity = m_oldFillOpacity;
    if (m_fillSet)
        p->setBrush(m_oldFill);
    if (m_fillRuleSet)
        states.fillRule = m_oldFillRule;
}

QSvgViewportFillStyle::QSvgViewportFillStyle(const QBrush &brush)
    : m_viewportFill(brush)
{
}

void QSvgViewportFillStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &)
{
    m_oldFill = p->brush();
    p->setBrush(m_viewportFill);
}

void QSvgViewportFillStyle::revert(QPainter *p, QSvgExtraStates &)
{
    p->setBrush(m_oldFill);
}

QSvgFontStyle::QSvgFontStyle(QSvgFont *font, QSvgTinyDocument *doc)
    : m_svgFont(font)
    , m_doc(doc)
    , m_familySet(0)
    , m_sizeSet(0)
    , m_styleSet(0)
    , m_variantSet(0)
    , m_weightSet(0)
    , m_textAnchorSet(0)
{
}

QSvgFontStyle::QSvgFontStyle()
    : m_svgFont(0)
    , m_doc(0)
    , m_familySet(0)
    , m_sizeSet(0)
    , m_styleSet(0)
    , m_variantSet(0)
    , m_weightSet(0)
    , m_textAnchorSet(0)
{
}

int QSvgFontStyle::SVGToQtWeight(int weight) {
    switch (weight) {
    case 100:
    case 200:
        return QFont::Light;
    case 300:
    case 400:
        return QFont::Normal;
    case 500:
    case 600:
        return QFont::DemiBold;
    case 700:
    case 800:
        return QFont::Bold;
    case 900:
        return QFont::Black;
    }
    return QFont::Normal;
}

void QSvgFontStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &states)
{
    m_oldQFont = p->font();
    m_oldSvgFont = states.svgFont;
    m_oldTextAnchor = states.textAnchor;
    m_oldWeight = states.fontWeight;

    if (m_textAnchorSet)
        states.textAnchor = m_textAnchor;

    QFont font = m_oldQFont;
    if (m_familySet) {
        states.svgFont = m_svgFont;
        font.setFamilies(m_qfont.families());
    }

    if (m_sizeSet)
        font.setPointSizeF(m_qfont.pointSizeF());

    if (m_styleSet)
        font.setStyle(m_qfont.style());

    if (m_variantSet)
        font.setCapitalization(m_qfont.capitalization());

    if (m_weightSet) {
        if (m_weight == BOLDER) {
            states.fontWeight = qMin(states.fontWeight + 100, 900);
        } else if (m_weight == LIGHTER) {
            states.fontWeight = qMax(states.fontWeight - 100, 100);
        } else {
            states.fontWeight = m_weight;
        }
        font.setWeight(SVGToQtWeight(states.fontWeight));
    }

    p->setFont(font);
}

void QSvgFontStyle::revert(QPainter *p, QSvgExtraStates &states)
{
    p->setFont(m_oldQFont);
    states.svgFont = m_oldSvgFont;
    states.textAnchor = m_oldTextAnchor;
    states.fontWeight = m_oldWeight;
}

QSvgStrokeStyle::QSvgStrokeStyle()
    : m_strokeOpacity(1.0)
    , m_oldStrokeOpacity(0.0)
    , m_strokeDashOffset(0)
    , m_oldStrokeDashOffset(0)
    , m_style(0)
    , m_gradientResolved(1)
    , m_vectorEffect(0)
    , m_oldVectorEffect(0)
    , m_strokeSet(0)
    , m_strokeDashArraySet(0)
    , m_strokeDashOffsetSet(0)
    , m_strokeLineCapSet(0)
    , m_strokeLineJoinSet(0)
    , m_strokeMiterLimitSet(0)
    , m_strokeOpacitySet(0)
    , m_strokeWidthSet(0)
    , m_vectorEffectSet(0)
{
}

void QSvgStrokeStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &states)
{
    m_oldStroke = p->pen();
    m_oldStrokeOpacity = states.strokeOpacity;
    m_oldStrokeDashOffset = states.strokeDashOffset;
    m_oldVectorEffect = states.vectorEffect;

    QPen pen = p->pen();

    qreal oldWidth = pen.widthF();
    qreal width = m_stroke.widthF();
    if (oldWidth == 0)
        oldWidth = 1;
    if (width == 0)
        width = 1;
    qreal scale = oldWidth / width;

    if (m_strokeOpacitySet)
        states.strokeOpacity = m_strokeOpacity;

    if (m_vectorEffectSet)
        states.vectorEffect = m_vectorEffect;

    if (m_strokeSet) {
        if (m_style)
            pen.setBrush(m_style->brush(p, states));
        else
            pen.setBrush(m_stroke.brush());
    }

    if (m_strokeWidthSet)
        pen.setWidthF(m_stroke.widthF());

    bool setDashOffsetNeeded = false;

    if (m_strokeDashOffsetSet) {
        states.strokeDashOffset = m_strokeDashOffset;
        setDashOffsetNeeded = true;
    }

    if (m_strokeDashArraySet) {
        if (m_stroke.style() == Qt::SolidLine) {
            pen.setStyle(Qt::SolidLine);
        } else if (m_strokeWidthSet || oldWidth == 1) {
            // If both width and dash array was set, the dash array is already scaled correctly.
            pen.setDashPattern(m_stroke.dashPattern());
            setDashOffsetNeeded = true;
        } else {
            // If dash array was set, but not the width, the dash array has to be scaled with respect to the old width.
            QVector<qreal> dashes = m_stroke.dashPattern();
            for (int i = 0; i < dashes.size(); ++i)
                dashes[i] /= oldWidth;
            pen.setDashPattern(dashes);
            setDashOffsetNeeded = true;
        }
    } else if (m_strokeWidthSet && pen.style() != Qt::SolidLine && scale != 1) {
        // If the width was set, but not the dash array, the old dash array must be scaled with respect to the new width.
        QVector<qreal> dashes = pen.dashPattern();
        for (int i = 0; i < dashes.size(); ++i)
            dashes[i] *= scale;
        pen.setDashPattern(dashes);
        setDashOffsetNeeded = true;
    }

    if (m_strokeLineCapSet)
        pen.setCapStyle(m_stroke.capStyle());
    if (m_strokeLineJoinSet)
        pen.setJoinStyle(m_stroke.joinStyle());
    if (m_strokeMiterLimitSet)
        pen.setMiterLimit(m_stroke.miterLimit());

    // You can have dash offset on solid strokes in SVG files, but not in Qt.
    // QPen::setDashOffset() will set the pen style to Qt::CustomDashLine,
    // so don't call the method if the pen is solid.
    if (setDashOffsetNeeded && pen.style() != Qt::SolidLine) {
        qreal currentWidth = pen.widthF();
        if (currentWidth == 0)
            currentWidth = 1;
        pen.setDashOffset(states.strokeDashOffset / currentWidth);
    }

    pen.setCosmetic(states.vectorEffect);

    p->setPen(pen);
}

void QSvgStrokeStyle::revert(QPainter *p, QSvgExtraStates &states)
{
    p->setPen(m_oldStroke);
    states.strokeOpacity = m_oldStrokeOpacity;
    states.strokeDashOffset = m_oldStrokeDashOffset;
    states.vectorEffect = m_oldVectorEffect;
}

void QSvgStrokeStyle::setDashArray(const QVector<qreal> &dashes)
{
    if (m_strokeWidthSet) {
        QVector<qreal> d = dashes;
        qreal w = m_stroke.widthF();
        if (w != 0 && w != 1) {
            for (int i = 0; i < d.size(); ++i)
                d[i] /= w;
        }
        m_stroke.setDashPattern(d);
    } else {
        m_stroke.setDashPattern(dashes);
    }
    m_strokeDashArraySet = 1;
}

QSvgSolidColorStyle::QSvgSolidColorStyle(const QColor &color)
    : m_solidColor(color)
{
}

QSvgGradientStyle::QSvgGradientStyle(QGradient *grad)
    : m_gradient(grad), m_gradientStopsSet(false)
{
}

QBrush QSvgGradientStyle::brush(QPainter *, QSvgExtraStates &)
{
    if (!m_link.isEmpty()) {
        resolveStops();
    }

    // If the gradient is marked as empty, insert transparent black
    if (!m_gradientStopsSet) {
        m_gradient->setStops(QGradientStops() << QGradientStop(0.0, QColor(0, 0, 0, 0)));
        m_gradientStopsSet = true;
    }

    QBrush b(*m_gradient);

    if (!m_transform.isIdentity())
        b.setTransform(m_transform);

    return b;
}


void QSvgGradientStyle::setTransform(const QTransform &transform)
{
    m_transform = transform;
}

QSvgTransformStyle::QSvgTransformStyle(const QTransform &trans)
    : m_transform(trans)
{
}

void QSvgTransformStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &)
{
    m_oldWorldTransform = p->worldTransform();
    p->setWorldTransform(m_transform, true);
}

void QSvgTransformStyle::revert(QPainter *p, QSvgExtraStates &)
{
    p->setWorldTransform(m_oldWorldTransform, false /* don't combine */);
}

QSvgStyleProperty::Type QSvgQualityStyle::type() const
{
    return QUALITY;
}

QSvgStyleProperty::Type QSvgFillStyle::type() const
{
    return FILL;
}

QSvgStyleProperty::Type QSvgViewportFillStyle::type() const
{
    return VIEWPORT_FILL;
}

QSvgStyleProperty::Type QSvgFontStyle::type() const
{
    return FONT;
}

QSvgStyleProperty::Type QSvgStrokeStyle::type() const
{
    return STROKE;
}

QSvgStyleProperty::Type QSvgSolidColorStyle::type() const
{
    return SOLID_COLOR;
}

QSvgStyleProperty::Type QSvgGradientStyle::type() const
{
    return GRADIENT;
}

QSvgStyleProperty::Type QSvgTransformStyle::type() const
{
    return TRANSFORM;
}


QSvgCompOpStyle::QSvgCompOpStyle(QPainter::CompositionMode mode)
    : m_mode(mode)
{

}

void QSvgCompOpStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &)
{
    m_oldMode = p->compositionMode();
    p->setCompositionMode(m_mode);
}

void QSvgCompOpStyle::revert(QPainter *p, QSvgExtraStates &)
{
    p->setCompositionMode(m_oldMode);
}

QSvgStyleProperty::Type QSvgCompOpStyle::type() const
{
    return COMP_OP;
}

QSvgStyle::~QSvgStyle()
{
}

void QSvgStyle::apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &states)
{
    if (quality) {
        quality->apply(p, node, states);
    }

    if (fill) {
        fill->apply(p, node, states);
    }

    if (viewportFill) {
        viewportFill->apply(p, node, states);
    }

    if (font) {
        font->apply(p, node, states);
    }

    if (stroke) {
        stroke->apply(p, node, states);
    }

    if (transform) {
        transform->apply(p, node, states);
    }

    if (animateColor) {
        animateColor->apply(p, node, states);
    }

    //animated transforms have to be applied
    //_after_ the original object transformations
    if (!animateTransforms.isEmpty()) {
        qreal totalTimeElapsed = node->document()->currentElapsed();
        // Find the last animateTransform with additive="replace", since this will override all
        // previous animateTransforms.
        QList<QSvgRefCounter<QSvgAnimateTransform> >::const_iterator itr = animateTransforms.constEnd();
        do {
            --itr;
            if ((*itr)->animActive(totalTimeElapsed)
                && (*itr)->additiveType() == QSvgAnimateTransform::Replace) {
                // An animateTransform with additive="replace" will replace the transform attribute.
                if (transform)
                    transform->revert(p, states);
                break;
            }
        } while (itr != animateTransforms.constBegin());

        // Apply the animateTransforms after and including the last one with additive="replace".
        for (; itr != animateTransforms.constEnd(); ++itr) {
            if ((*itr)->animActive(totalTimeElapsed))
                (*itr)->apply(p, node, states);
        }
    }

    if (opacity) {
        opacity->apply(p, node, states);
    }

    if (compop) {
        compop->apply(p, node, states);
    }
}

void QSvgStyle::revert(QPainter *p, QSvgExtraStates &states)
{
    if (quality) {
        quality->revert(p, states);
    }

    if (fill) {
        fill->revert(p, states);
    }

    if (viewportFill) {
        viewportFill->revert(p, states);
    }

    if (font) {
        font->revert(p, states);
    }

    if (stroke) {
        stroke->revert(p, states);
    }

    //animated transforms need to be reverted _before_
    //the native transforms
    if (!animateTransforms.isEmpty()) {
        QList<QSvgRefCounter<QSvgAnimateTransform> >::const_iterator itr = animateTransforms.constBegin();
        for (; itr != animateTransforms.constEnd(); ++itr) {
            if ((*itr)->transformApplied()) {
                (*itr)->revert(p, states);
                break;
            }
        }
        for (; itr != animateTransforms.constEnd(); ++itr)
            (*itr)->clearTransformApplied();
    }

    if (transform) {
        transform->revert(p, states);
    }

    if (animateColor) {
        animateColor->revert(p, states);
    }

    if (opacity) {
        opacity->revert(p, states);
    }

    if (compop) {
        compop->revert(p, states);
    }
}

QSvgAnimateTransform::QSvgAnimateTransform(int startMs, int endMs, int byMs )
    : QSvgStyleProperty(),
      m_from(startMs),
      m_totalRunningTime(endMs - startMs),
      m_type(Empty),
      m_additive(Replace),
      m_count(0),
      m_finished(false),
      m_freeze(false),
      m_repeatCount(-1.),
      m_transformApplied(false)
{
    Q_UNUSED(byMs);
}

void QSvgAnimateTransform::setArgs(TransformType type, Additive additive, const QVector<qreal> &args)
{
    m_type = type;
    m_args = args;
    m_additive = additive;
    Q_ASSERT(!(args.count()%3));
    m_count = args.count() / 3;
}

void QSvgAnimateTransform::apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &)
{
    m_oldWorldTransform = p->worldTransform();
    resolveMatrix(node);
    p->setWorldTransform(m_transform, true);
    m_transformApplied = true;
}

void QSvgAnimateTransform::revert(QPainter *p, QSvgExtraStates &)
{
    p->setWorldTransform(m_oldWorldTransform, false /* don't combine */);
    m_transformApplied = false;
}

void QSvgAnimateTransform::resolveMatrix(const QSvgNode *node)
{
    static const qreal deg2rad = qreal(0.017453292519943295769);
    qreal totalTimeElapsed = node->document()->currentElapsed();
    if (totalTimeElapsed < m_from || m_finished)
        return;

    qreal animationFrame = 0;
    if (m_totalRunningTime != 0) {
        animationFrame = (totalTimeElapsed - m_from) / m_totalRunningTime;

        if (m_repeatCount >= 0 && m_repeatCount < animationFrame) {
            m_finished = true;
            animationFrame = m_repeatCount;
        }
    }

    qreal percentOfAnimation = animationFrame;
    if (percentOfAnimation > 1) {
        percentOfAnimation -= ((int)percentOfAnimation);
    }

    qreal currentPosition = percentOfAnimation * (m_count - 1);
    int endElem   = qCeil(currentPosition);
    int startElem = qMax(endElem - 1, 0);

    switch(m_type)
    {
    case Translate: {
        startElem *= 3;
        endElem   *= 3;
        qreal from1, from2;
        qreal to1, to2;
        from1 = m_args[startElem++];
        from2 = m_args[startElem++];
        to1   = m_args[endElem++];
        to2   = m_args[endElem++];

        qreal transXDiff = (to1-from1) * percentOfAnimation;
        qreal transX = from1 + transXDiff;
        qreal transYDiff = (to2-from2) * percentOfAnimation;
        qreal transY = from2 + transYDiff;
        m_transform = QTransform();
        m_transform.translate(transX, transY);
        break;
    }
    case Scale: {
        startElem *= 3;
        endElem   *= 3;
        qreal from1, from2;
        qreal to1, to2;
        from1 = m_args[startElem++];
        from2 = m_args[startElem++];
        to1   = m_args[endElem++];
        to2   = m_args[endElem++];

        qreal transXDiff = (to1-from1) * percentOfAnimation;
        qreal transX = from1 + transXDiff;
        qreal transYDiff = (to2-from2) * percentOfAnimation;
        qreal transY = from2 + transYDiff;
        if (transY == 0)
            transY = transX;
        m_transform = QTransform();
        m_transform.scale(transX, transY);
        break;
    }
    case Rotate: {
        startElem *= 3;
        endElem   *= 3;
        qreal from1, from2, from3;
        qreal to1, to2, to3;
        from1 = m_args[startElem++];
        from2 = m_args[startElem++];
        from3 = m_args[startElem++];
        to1   = m_args[endElem++];
        to2   = m_args[endElem++];
        to3   = m_args[endElem++];

        qreal rotationDiff = (to1 - from1) * percentOfAnimation;
        //qreal rotation = from1 + rotationDiff;

        qreal transXDiff = (to2-from2) * percentOfAnimation;
        qreal transX = from2 + transXDiff;
        qreal transYDiff = (to3-from3) * percentOfAnimation;
        qreal transY = from3 + transYDiff;
        m_transform = QTransform();
        m_transform.translate(transX, transY);
        m_transform.rotate(rotationDiff);
        m_transform.translate(-transX, -transY);
        break;
    }
    case SkewX: {
        startElem *= 3;
        endElem   *= 3;
        qreal from1;
        qreal to1;
        from1 = m_args[startElem++];
        to1   = m_args[endElem++];

        qreal transXDiff = (to1-from1) * percentOfAnimation;
        qreal transX = from1 + transXDiff;
        m_transform = QTransform();
        m_transform.shear(qTan(transX * deg2rad), 0);
        break;
    }
    case SkewY: {
        startElem *= 3;
        endElem   *= 3;
        qreal from1;
        qreal to1;
        from1 = m_args[startElem++];
        to1   = m_args[endElem++];


        qreal transYDiff = (to1 - from1) * percentOfAnimation;
        qreal transY = from1 + transYDiff;
        m_transform = QTransform();
        m_transform.shear(0, qTan(transY * deg2rad));
        break;
    }
    default:
        break;
    }
}

QSvgStyleProperty::Type QSvgAnimateTransform::type() const
{
    return ANIMATE_TRANSFORM;
}

void QSvgAnimateTransform::setFreeze(bool freeze)
{
    m_freeze = freeze;
}

void QSvgAnimateTransform::setRepeatCount(qreal repeatCount)
{
    m_repeatCount = repeatCount;
}

QSvgAnimateColor::QSvgAnimateColor(int startMs, int endMs, int byMs)
    : QSvgStyleProperty(),
      m_from(startMs),
      m_totalRunningTime(endMs - startMs),
      m_fill(false),
      m_finished(false),
      m_freeze(false),
      m_repeatCount(-1.)
{
    Q_UNUSED(byMs);
}

void QSvgAnimateColor::setArgs(bool fill,
                               const QList<QColor> &colors)
{
    m_fill = fill;
    m_colors = colors;
}

void QSvgAnimateColor::setFreeze(bool freeze)
{
    m_freeze = freeze;
}

void QSvgAnimateColor::setRepeatCount(qreal repeatCount)
{
    m_repeatCount = repeatCount;
}

void QSvgAnimateColor::apply(QPainter *p, const QSvgNode *node, QSvgExtraStates &)
{
    qreal totalTimeElapsed = node->document()->currentElapsed();
    if (totalTimeElapsed < m_from || m_finished)
        return;

    qreal animationFrame = 0;
    if (m_totalRunningTime != 0)
        animationFrame = (totalTimeElapsed - m_from) / m_totalRunningTime;

    if (m_repeatCount >= 0 && m_repeatCount < animationFrame) {
        m_finished = true;
        animationFrame = m_repeatCount;
    }

    qreal percentOfAnimation = animationFrame;
    if (percentOfAnimation > 1) {
        percentOfAnimation -= ((int)percentOfAnimation);
    }

    qreal currentPosition = percentOfAnimation * (m_colors.count() - 1);

    int startElem = qFloor(currentPosition);
    int endElem   = qCeil(currentPosition);
    QColor start = m_colors[startElem];
    QColor end = m_colors[endElem];

    qreal percentOfColorMorph = currentPosition;
    if (percentOfColorMorph > 1) {
        percentOfColorMorph -= ((int)percentOfColorMorph);
    }

    // Interpolate between the two fixed colors start and end
    qreal aDiff = (end.alpha() - start.alpha()) * percentOfColorMorph;
    qreal rDiff = (end.red()   - start.red()) * percentOfColorMorph;
    qreal gDiff = (end.green() - start.green()) * percentOfColorMorph;
    qreal bDiff = (end.blue()  - start.blue()) * percentOfColorMorph;

    int alpha  = int(start.alpha() + aDiff);
    int red    = int(start.red() + rDiff);
    int green  = int(start.green() + gDiff);
    int blue   = int(start.blue() + bDiff);

    QColor color(red, green, blue, alpha);

    if (m_fill) {
        QBrush b = p->brush();
        m_oldBrush = b;
        b.setColor(color);
        p->setBrush(b);
    } else {
        QPen pen = p->pen();
        m_oldPen = pen;
        pen.setColor(color);
        p->setPen(pen);
    }
}

void QSvgAnimateColor::revert(QPainter *p, QSvgExtraStates &)
{
    if (m_fill) {
        p->setBrush(m_oldBrush);
    } else {
        p->setPen(m_oldPen);
    }
}

QSvgStyleProperty::Type QSvgAnimateColor::type() const
{
    return ANIMATE_COLOR;
}

QSvgOpacityStyle::QSvgOpacityStyle(qreal opacity)
    : m_opacity(opacity), m_oldOpacity(0)
{

}

void QSvgOpacityStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &)
{
    m_oldOpacity = p->opacity();
    p->setOpacity(m_opacity * m_oldOpacity);
}

void QSvgOpacityStyle::revert(QPainter *p, QSvgExtraStates &)
{
    p->setOpacity(m_oldOpacity);
}

QSvgStyleProperty::Type QSvgOpacityStyle::type() const
{
    return OPACITY;
}

void QSvgGradientStyle::setStopLink(const QString &link, QSvgTinyDocument *doc)
{
    m_link = link;
    m_doc  = doc;
}

void QSvgGradientStyle::resolveStops()
{
    QStringList visited;
    resolveStops_helper(&visited);
}

void QSvgGradientStyle::resolveStops_helper(QStringList *visited)
{
    if (!m_link.isEmpty() && m_doc) {
        QSvgStyleProperty *prop = m_doc->styleProperty(m_link);
        if (prop && !visited->contains(m_link)) {
            visited->append(m_link);
            if (prop->type() == QSvgStyleProperty::GRADIENT) {
                QSvgGradientStyle *st =
                    static_cast<QSvgGradientStyle*>(prop);
                st->resolveStops_helper(visited);
                m_gradient->setStops(st->qgradient()->stops());
                m_gradientStopsSet = st->gradientStopsSet();
            }
        } else {
            qWarning("Could not resolve property : %s", qPrintable(m_link));
        }
        m_link = QString();
    }
}

QT_END_NAMESPACE
