diff options
Diffstat (limited to 'src/svg/qsvghandler.cpp')
-rw-r--r-- | src/svg/qsvghandler.cpp | 86 |
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()) { |