diff options
-rw-r--r-- | src/svg/qsvghandler.cpp | 47 | ||||
-rw-r--r-- | src/svg/qsvgstyle.cpp | 4 | ||||
-rw-r--r-- | src/svg/qsvgstyle_p.h | 34 | ||||
-rw-r--r-- | tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 16 |
4 files changed, 91 insertions, 10 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 9486512..345dcf3 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -639,17 +639,22 @@ static void parseBrush(QSvgNode *node, f = Qt::OddEvenFill; if (value.startsWith(QLatin1String("url"))) { value = value.remove(0, 3); + QSvgFillStyle *prop = new QSvgFillStyle(0); QSvgStyleProperty *style = styleFromUrl(node, value); if (style) { - QSvgFillStyle *prop = new QSvgFillStyle(style); - if (!opacity.isEmpty()) { - qreal clampedOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); - prop->setFillOpacity(clampedOpacity); - } - node->appendStyleProperty(prop, myId); + prop->setFillStyle(style); } else { - qWarning("Couldn't resolve property: %s", qPrintable(idFromUrl(value))); + QString id = idFromUrl(value); + prop->setGradientId(id); + prop->setGradientResolved(false); + } + if (!opacity.isEmpty()) { + qreal clampedOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); + prop->setFillOpacity(clampedOpacity); } + if (!fillRule.isEmpty()) + prop->setFillRule(f); + node->appendStyleProperty(prop,myId); } else if (value != QLatin1String("none")) { QColor color; if (constructColor(value, opacity, color, handler)) { @@ -3580,8 +3585,34 @@ bool QSvgHandler::endElement(const QStringRef &localName) node->popFormat(); } - if (node == Graphics) + if (node == Graphics) { + // Iterate through the m_renderers to resolve any unresolved gradients. + QSvgNode* curNode = static_cast<QSvgNode*>(m_nodes.top()); + if (curNode->type() == QSvgNode::DOC || + curNode->type() == QSvgNode::G || + curNode->type() == QSvgNode::DEFS || + curNode->type() == QSvgNode::SWITCH) { + QSvgStructureNode* structureNode = static_cast<QSvgStructureNode*>(curNode); + QList<QSvgNode*> ren = structureNode->renderers(); + QList<QSvgNode*>::iterator itr = ren.begin(); + while (itr != ren.end()) { + QSvgNode *eleNode = *itr++; + QSvgFillStyle *prop = static_cast<QSvgFillStyle*>(eleNode->styleProperty(QSvgStyleProperty::FILL)); + if (prop && !(prop->isGradientResolved())) { + QString id = prop->getGradientId(); + QSvgStyleProperty *style = structureNode->scopeStyle(id); + if (style) { + prop->setFillStyle(style); + } else { + qWarning("Couldn't resolve property : %s",qPrintable(id)); + prop->setBrush(QBrush(Qt::NoBrush)); + } + } + } + } m_nodes.pop(); + } + else if (m_style && !m_skipNodes.isEmpty() && m_skipNodes.top() != Style) m_style = 0; diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index 9d46649..fec6231 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -81,12 +81,12 @@ void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &) } QSvgFillStyle::QSvgFillStyle(const QBrush &brush) - : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false) + : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true) { } QSvgFillStyle::QSvgFillStyle(QSvgStyleProperty *style) - : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false) + : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false), m_gradientResolved (true) { } diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h index 4bbc6cf..e65b6f5 100644 --- a/src/svg/qsvgstyle_p.h +++ b/src/svg/qsvgstyle_p.h @@ -229,6 +229,38 @@ public: { return m_fill; } + + void setGradientId(const QString &Id) + { + m_gradientId = Id; + } + + QString getGradientId() const + { + return m_gradientId; + } + + + void setGradientResolved(bool resolved) + { + m_gradientResolved = resolved; + } + + bool isGradientResolved() const + { + return m_gradientResolved; + } + + void setFillStyle(QSvgStyleProperty* style) + { + m_style = style; + } + + void setBrush(QBrush brush) + { + m_fill = brush; + } + private: // fill v v 'inherit' | <Paint.datatype> // fill-opacity v v 'inherit' | <OpacityValue.datatype> @@ -241,6 +273,8 @@ private: bool m_fillOpacitySet; qreal m_fillOpacity; qreal m_oldOpacity; + QString m_gradientId; + bool m_gradientResolved; }; class QSvgViewportFillStyle : public QSvgStyleProperty diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index c7bfee8..820bcba 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -75,6 +75,7 @@ private slots: void stylePropagation() const; void matrixForElement() const; void gradientStops() const; + void gradientRefs(); void fillRule(); void opacity(); void paths(); @@ -535,7 +536,10 @@ void tst_QSvgRenderer::gradientStops() const QCOMPARE(image, refImage); } +} +void tst_QSvgRenderer::gradientRefs() +{ const char *svgs[] = { "<svg>" "<defs>" @@ -567,6 +571,17 @@ void tst_QSvgRenderer::gradientStops() const "</linearGradient>" "</defs>" "<rect fill=\"url(#gradient)\" height=\"8\" width=\"256\" x=\"0\" y=\"0\"/>" + "</svg>", + "<svg>" + "<rect fill=\"url(#gradient)\" height=\"8\" width=\"256\" x=\"0\" y=\"0\"/>" + "<defs>" + "<linearGradient id=\"gradient0\">" + "<stop offset=\"0\" stop-color=\"red\" stop-opacity=\"0\"/>" + "<stop offset=\"1\" stop-color=\"blue\"/>" + "</linearGradient>" + "<linearGradient id=\"gradient\" xlink:href=\"#gradient0\">" + "</linearGradient>" + "</defs>" "</svg>" }; for (int i = 0 ; i < sizeof(svgs) / sizeof(svgs[0]) ; ++i) @@ -591,6 +606,7 @@ void tst_QSvgRenderer::gradientStops() const } } + #ifndef QT_NO_COMPRESS void tst_QSvgRenderer::testGzLoading() { |