summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/svg/qsvghandler.cpp47
-rw-r--r--src/svg/qsvgstyle.cpp4
-rw-r--r--src/svg/qsvgstyle_p.h34
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp16
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()
{