diff options
-rw-r--r-- | src/svg/qsvggraphics.cpp | 23 | ||||
-rw-r--r-- | src/svg/qsvggraphics_p.h | 1 | ||||
-rw-r--r-- | src/svg/qsvghandler.cpp | 14 | ||||
-rw-r--r-- | tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp | 10 |
4 files changed, 32 insertions, 16 deletions
diff --git a/src/svg/qsvggraphics.cpp b/src/svg/qsvggraphics.cpp index 12f2349..bcd2452 100644 --- a/src/svg/qsvggraphics.cpp +++ b/src/svg/qsvggraphics.cpp @@ -41,11 +41,12 @@ #include "qsvgfont_p.h" -#include "qpainter.h" -#include "qtextdocument.h" -#include "qabstracttextdocumentlayout.h" -#include "qtextcursor.h" -#include "qdebug.h" +#include <qabstracttextdocumentlayout.h> +#include <qdebug.h> +#include <qpainter.h> +#include <qscopedvaluerollback.h> +#include <qtextcursor.h> +#include <qtextdocument.h> #include <math.h> #include <limits.h> @@ -458,14 +459,14 @@ void QSvgText::addText(const QString &text) } QSvgUse::QSvgUse(const QPointF &start, QSvgNode *parent, QSvgNode *node) - : QSvgNode(parent), m_link(node), m_start(start) + : QSvgNode(parent), m_link(node), m_start(start), m_recursing(false) { } void QSvgUse::draw(QPainter *p, QSvgExtraStates &states) { - if (Q_UNLIKELY(!m_link || isDescendantOf(m_link))) + if (Q_UNLIKELY(!m_link || isDescendantOf(m_link) || m_recursing)) return; applyStyle(p, states); @@ -473,7 +474,10 @@ void QSvgUse::draw(QPainter *p, QSvgExtraStates &states) if (!m_start.isNull()) { p->translate(m_start); } - m_link->draw(p, states); + { + QScopedValueRollback<bool> guard(m_recursing, true); + m_link->draw(p, states); + } if (!m_start.isNull()) { p->translate(-m_start); } @@ -556,7 +560,8 @@ QSvgNode::Type QSvgVideo::type() const QRectF QSvgUse::bounds(QPainter *p, QSvgExtraStates &states) const { QRectF bounds; - if (Q_LIKELY(m_link && !isDescendantOf(m_link))) { + if (Q_LIKELY(m_link && !isDescendantOf(m_link) && !m_recursing)) { + QScopedValueRollback<bool> guard(m_recursing, true); p->translate(m_start); bounds = m_link->transformedBounds(p, states); p->translate(-m_start); diff --git a/src/svg/qsvggraphics_p.h b/src/svg/qsvggraphics_p.h index 1138d1a..8488b33 100644 --- a/src/svg/qsvggraphics_p.h +++ b/src/svg/qsvggraphics_p.h @@ -251,6 +251,7 @@ private: QSvgNode *m_link; QPointF m_start; QString m_linkId; + mutable bool m_recursing; }; class QSvgVideo : public QSvgNode diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index d30cf9f..fe79977 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -2615,17 +2615,17 @@ static QSvgStyleProperty *createFontNode(QSvgNode *parent, parent = parent->parent(); } - if (parent) { + if (parent && !myId.isEmpty()) { QSvgTinyDocument *doc = static_cast<QSvgTinyDocument*>(parent); - QSvgFont *font = new QSvgFont(horizAdvX); - font->setFamilyName(myId); - if (!font->familyName().isEmpty()) { - if (!doc->svgFont(font->familyName())) - doc->addSvgFont(font); + QSvgFont *font = doc->svgFont(myId); + if (!font) { + font = new QSvgFont(horizAdvX); + font->setFamilyName(myId); + doc->addSvgFont(font); } return new QSvgFontStyle(font, doc); } - return 0; + return nullptr; } static bool parseFontFaceNode(QSvgStyleProperty *parent, diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp index aa07554..e0646f2 100644 --- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp +++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp @@ -1423,6 +1423,16 @@ void tst_QSvgRenderer::testUseElement() " <circle fill=\"#a6ce39\" cx=\"0\" cy=\"0\" r=\"33\" />" " </g>" " </defs>" + "</svg>", + // 17 - Indirect self referral + "<svg>" + " <defs>" + " <g id=\"g0\">" + " <g id=\"g1\"><use href=\"#g2\"/></g>" + " <g id=\"g2\"><use href=\"#g1\"/></g>" + " </g>" + " </defs>" + " <use xlink:href=\"#g0\" fill=\"black\"/>" "</svg>" }; |