summaryrefslogtreecommitdiff
path: root/src/svg/qsvghandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/svg/qsvghandler.cpp')
-rw-r--r--src/svg/qsvghandler.cpp86
1 files changed, 59 insertions, 27 deletions
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index fe07d0e..5242ffe 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -59,6 +59,7 @@
#include "qdebug.h"
#include "qmath.h"
#include "qnumeric.h"
+#include <qregularexpression.h>
#include "qvarlengtharray.h"
#include "private/qmath_p.h"
@@ -2865,7 +2866,7 @@ static void parseBaseGradient(QSvgNode *node,
}
if (units.isEmpty() || units == QLatin1String("objectBoundingBox")) {
- grad->setCoordinateMode(QGradient::ObjectBoundingMode);
+ grad->setCoordinateMode(QGradient::ObjectMode);
}
}
@@ -3358,29 +3359,30 @@ static QSvgNode *createUseNode(QSvgNode *parent,
}
if (group) {
+ QPointF pt;
+ if (!xStr.isNull() || !yStr.isNull()) {
+ QSvgHandler::LengthType type;
+ qreal nx = parseLength(xStr, type, handler);
+ nx = convertToPixels(nx, true, type);
+
+ qreal ny = parseLength(yStr, type, handler);
+ ny = convertToPixels(ny, true, type);
+ pt = QPointF(nx, ny);
+ }
+
QSvgNode *link = group->scopeNode(linkId);
if (link) {
if (parent->isDescendantOf(link))
qCWarning(lcSvgHandler, "link #%s is recursive!", qPrintable(linkId));
- QPointF pt;
- if (!xStr.isNull() || !yStr.isNull()) {
- QSvgHandler::LengthType type;
- qreal nx = parseLength(xStr, type, handler);
- nx = convertToPixels(nx, true, type);
-
- qreal ny = parseLength(yStr, type, handler);
- ny = convertToPixels(ny, true, type);
- pt = QPointF(nx, ny);
- }
- //delay link resolving till the first draw call on
- //use nodes, link 2might have not been created yet
- QSvgUse *node = new QSvgUse(pt, parent, link);
- return node;
+ return new QSvgUse(pt, parent, link);
}
+
+ //delay link resolving, link might have not been created yet
+ return new QSvgUse(pt, parent, linkId);
}
- qCWarning(lcSvgHandler, "link %s hasn't been detected!", qPrintable(linkId));
+ qCWarning(lcSvgHandler, "<use> element %s in wrong context!", qPrintable(linkId));
return 0;
}
@@ -3646,6 +3648,7 @@ void QSvgHandler::parse()
}
}
resolveGradients(m_doc);
+ resolveNodes();
}
bool QSvgHandler::startElement(const QString &localName,
@@ -3750,6 +3753,9 @@ bool QSvgHandler::startElement(const QString &localName,
static_cast<QSvgText *>(node)->setWhitespaceMode(m_whitespaceMode.top());
} else if (node->type() == QSvgNode::TSPAN) {
static_cast<QSvgTspan *>(node)->setWhitespaceMode(m_whitespaceMode.top());
+ } else if (node->type() == QSvgNode::USE) {
+ if (!static_cast<QSvgUse *>(node)->isResolved())
+ m_resolveNodes.append(node);
}
}
}
@@ -3852,6 +3858,33 @@ void QSvgHandler::resolveGradients(QSvgNode *node)
}
}
+void QSvgHandler::resolveNodes()
+{
+ for (QSvgNode *node : qAsConst(m_resolveNodes)) {
+ if (!node || !node->parent() || node->type() != QSvgNode::USE)
+ continue;
+ QSvgUse *useNode = static_cast<QSvgUse *>(node);
+ if (useNode->isResolved())
+ continue;
+ QSvgNode::Type t = useNode->parent()->type();
+ if (!(t == QSvgNode::DOC || t == QSvgNode::DEFS || t == QSvgNode::G || t == QSvgNode::SWITCH))
+ continue;
+
+ QSvgStructureNode *group = static_cast<QSvgStructureNode *>(useNode->parent());
+ QSvgNode *link = group->scopeNode(useNode->linkId());
+ if (!link) {
+ qCWarning(lcSvgHandler, "link #%s is undefined!", qPrintable(useNode->linkId()));
+ continue;
+ }
+
+ if (useNode->parent()->isDescendantOf(link))
+ qCWarning(lcSvgHandler, "link #%s is recursive!", qPrintable(useNode->linkId()));
+
+ useNode->setLink(link);
+ }
+ m_resolveNodes.clear();
+}
+
bool QSvgHandler::characters(const QStringRef &str)
{
#ifndef QT_NO_CSSPARSER
@@ -3948,24 +3981,23 @@ bool QSvgHandler::processingInstruction(const QString &target, const QString &da
Q_UNUSED(data)
#else
if (target == QLatin1String("xml-stylesheet")) {
- QRegExp rx(QLatin1String("type=\\\"(.+)\\\""));
- rx.setMinimal(true);
+ QRegularExpression rx(QLatin1String("type=\\\"(.+)\\\""),
+ QRegularExpression::InvertedGreedinessOption);
+ QRegularExpressionMatchIterator iter = rx.globalMatch(data);
bool isCss = false;
- int pos = 0;
- while ((pos = rx.indexIn(data, pos)) != -1) {
- QString type = rx.cap(1);
+ while (iter.hasNext()) {
+ QRegularExpressionMatch match = iter.next();
+ QString type = match.captured(1);
if (type.toLower() == QLatin1String("text/css")) {
isCss = true;
}
- pos += rx.matchedLength();
}
if (isCss) {
- QRegExp rx(QLatin1String("href=\\\"(.+)\\\""));
- rx.setMinimal(true);
- pos = 0;
- pos = rx.indexIn(data, pos);
- QString addr = rx.cap(1);
+ QRegularExpression rx(QLatin1String("href=\\\"(.+)\\\""),
+ QRegularExpression::InvertedGreedinessOption);
+ QRegularExpressionMatch match = rx.match(data);
+ QString addr = match.captured(1);
QFileInfo fi(addr);
//qDebug()<<"External CSS file "<<fi.absoluteFilePath()<<fi.exists();
if (fi.exists()) {