summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-06-17 13:28:57 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-06-17 13:29:56 +0200
commitf33a29a8dbe03cbe9e59f9e5124f15e90b6336fc (patch)
tree09ba56a3338604358e53c7a33c35d29dc32860a6 /src
parent3864601f76e0b212ec69ad64409d939fd021fbd2 (diff)
parent5c298ef5bea0930b68263ba84194250dbb9d26a9 (diff)
downloadqtsvg-f33a29a8dbe03cbe9e59f9e5124f15e90b6336fc.tar.gz
Merge remote-tracking branch 'origin/wip/qt6' into wip/cmake
Change-Id: Icb0da709c1cb8d2bdc2f33edfe656b7821cb148a
Diffstat (limited to 'src')
-rw-r--r--src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp2
-rw-r--r--src/svg/qsvggenerator.cpp54
-rw-r--r--src/svg/qsvggraphics.cpp33
-rw-r--r--src/svg/qsvggraphics_p.h5
-rw-r--r--src/svg/qsvghandler.cpp57
-rw-r--r--src/svg/qsvgstyle.cpp11
-rw-r--r--src/svg/qsvgstyle_p.h1
-rw-r--r--src/svg/qsvgtinydocument.cpp50
-rw-r--r--src/svg/qsvgtinydocument_p.h5
9 files changed, 144 insertions, 74 deletions
diff --git a/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp b/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp
index e23dd9a..09064e3 100644
--- a/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp
+++ b/src/plugins/iconengines/svgiconengine/qsvgiconengine.cpp
@@ -197,7 +197,7 @@ QPixmap QSvgIconEngine::pixmap(const QSize &size, QIcon::Mode mode,
QPixmap pm;
QString pmckey(d->pmcKey(size, mode, state));
- if (QPixmapCache::find(pmckey, pm))
+ if (QPixmapCache::find(pmckey, &pm))
return pm;
if (d->addedPixmaps) {
diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp
index 07f8d74..360b02b 100644
--- a/src/svg/qsvggenerator.cpp
+++ b/src/svg/qsvggenerator.cpp
@@ -227,10 +227,10 @@ public:
QString rct(QStringLiteral("<rect x=\"%1\" y=\"%2\" width=\"%3\" height=\"%4\" />"));
QTextStream str(&d_func()->defs, QIODevice::Append);
str << "<mask id=\"" << maskId << "\" x=\"0\" y=\"0\" width=\"8\" height=\"8\" "
- << "stroke=\"none\" fill=\"#ffffff\" patternUnits=\"userSpaceOnUse\" >" << endl;
+ << "stroke=\"none\" fill=\"#ffffff\" patternUnits=\"userSpaceOnUse\" >" << Qt::endl;
for (QRect r : reg)
- str << rct.arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height()) << endl;
- str << QStringLiteral("</mask>") << endl << endl;
+ str << rct.arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height()) << Qt::endl;
+ str << QStringLiteral("</mask>") << Qt::endl << Qt::endl;
d_func()->savedPatternMasks.append(maskId);
}
return maskId;
@@ -243,9 +243,9 @@ public:
QString maskId = savePatternMask(brush.style());
QString geo(QStringLiteral("x=\"0\" y=\"0\" width=\"8\" height=\"8\""));
QTextStream str(&d_func()->defs, QIODevice::Append);
- str << QString(QStringLiteral("<pattern id=\"%1\" %2 patternUnits=\"userSpaceOnUse\" >")).arg(patternId, geo) << endl;
- str << QString(QStringLiteral("<rect %1 stroke=\"none\" fill=\"%2\" mask=\"url(#%3);\" />")).arg(geo, color, maskId) << endl;
- str << QStringLiteral("</pattern>") << endl << endl;
+ str << QString(QStringLiteral("<pattern id=\"%1\" %2 patternUnits=\"userSpaceOnUse\" >")).arg(patternId, geo) << Qt::endl;
+ str << QString(QStringLiteral("<rect %1 stroke=\"none\" fill=\"%2\" mask=\"url(#%3);\" />")).arg(geo, color, maskId) << Qt::endl;
+ str << QStringLiteral("</pattern>") << Qt::endl << Qt::endl;
d_func()->savedPatternBrushes.append(patternId);
}
return patternId;
@@ -266,7 +266,7 @@ public:
str << QLatin1String("id=\"") << d_func()->generateGradientName() << QLatin1String("\">\n");
saveGradientStops(str, g);
- str << QLatin1String("</linearGradient>") <<endl;
+ str << QLatin1String("</linearGradient>") <<Qt::endl;
}
void saveRadialGradientBrush(const QGradient *g)
{
@@ -283,7 +283,7 @@ public:
}
str << QLatin1String("id=\"") <<d_func()->generateGradientName()<< QLatin1String("\">\n");
saveGradientStops(str, g);
- str << QLatin1String("</radialGradient>") << endl;
+ str << QLatin1String("</radialGradient>") << Qt::endl;
}
void saveConicalGradientBrush(const QGradient *)
{
@@ -544,7 +544,7 @@ public:
"font-size=\"" << d->attributes.font_size << "\" "
"font-weight=\"" << d->attributes.font_weight << "\" "
"font-style=\"" << d->attributes.font_style << "\" "
- << endl;
+ << Qt::endl;
}
};
@@ -892,29 +892,29 @@ bool QSvgPaintEngine::begin(QPaintDevice *)
d->stream = new QTextStream(&d->header);
// stream out the header...
- *d->stream << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" << endl << "<svg";
+ *d->stream << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" << Qt::endl << "<svg";
if (d->size.isValid()) {
qreal wmm = d->size.width() * 25.4 / d->resolution;
qreal hmm = d->size.height() * 25.4 / d->resolution;
- *d->stream << " width=\"" << wmm << "mm\" height=\"" << hmm << "mm\"" << endl;
+ *d->stream << " width=\"" << wmm << "mm\" height=\"" << hmm << "mm\"" << Qt::endl;
}
if (d->viewBox.isValid()) {
*d->stream << " viewBox=\"" << d->viewBox.left() << ' ' << d->viewBox.top();
- *d->stream << ' ' << d->viewBox.width() << ' ' << d->viewBox.height() << '\"' << endl;
+ *d->stream << ' ' << d->viewBox.width() << ' ' << d->viewBox.height() << '\"' << Qt::endl;
}
*d->stream << " xmlns=\"http://www.w3.org/2000/svg\""
" xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
- " version=\"1.2\" baseProfile=\"tiny\">" << endl;
+ " version=\"1.2\" baseProfile=\"tiny\">" << Qt::endl;
if (!d->attributes.document_title.isEmpty()) {
- *d->stream << "<title>" << d->attributes.document_title << "</title>" << endl;
+ *d->stream << "<title>" << d->attributes.document_title << "</title>" << Qt::endl;
}
if (!d->attributes.document_description.isEmpty()) {
- *d->stream << "<desc>" << d->attributes.document_description << "</desc>" << endl;
+ *d->stream << "<desc>" << d->attributes.document_description << "</desc>" << Qt::endl;
}
d->stream->setString(&d->defs);
@@ -924,7 +924,7 @@ bool QSvgPaintEngine::begin(QPaintDevice *)
// Start the initial graphics state...
*d->stream << "<g ";
generateQtDefaults();
- *d->stream << endl;
+ *d->stream << Qt::endl;
return true;
}
@@ -945,10 +945,10 @@ bool QSvgPaintEngine::end()
*d->stream << d->defs;
*d->stream << d->body;
if (d->afterFirstUpdate)
- *d->stream << "</g>" << endl; // close the updateState
+ *d->stream << "</g>" << Qt::endl; // close the updateState
- *d->stream << "</g>" << endl // close the Qt defaults
- << "</svg>" << endl;
+ *d->stream << "</g>" << Qt::endl // close the Qt defaults
+ << "</svg>" << Qt::endl;
delete d->stream;
@@ -1009,13 +1009,13 @@ void QSvgPaintEngine::updateState(const QPaintEngineState &state)
}
if (flags & QPaintEngine::DirtyTransform) {
- d->matrix = state.matrix();
+ d->matrix = state.transform().toAffine();
*d->stream << "transform=\"matrix(" << d->matrix.m11() << ','
<< d->matrix.m12() << ','
<< d->matrix.m21() << ',' << d->matrix.m22() << ','
<< d->matrix.dx() << ',' << d->matrix.dy()
<< ")\""
- << endl;
+ << Qt::endl;
}
if (flags & QPaintEngine::DirtyFont) {
@@ -1027,7 +1027,7 @@ void QSvgPaintEngine::updateState(const QPaintEngineState &state)
stream() << "opacity=\""<<state.opacity()<<"\" ";
}
- *d->stream << '>' << endl;
+ *d->stream << '>' << Qt::endl;
d->afterFirstUpdate = true;
}
@@ -1046,7 +1046,7 @@ void QSvgPaintEngine::drawEllipse(const QRectF &r)
*d->stream << "\" r=\"" << r.width() / qreal(2.0);
else
*d->stream << "\" rx=\"" << r.width() / qreal(2.0) << "\" ry=\"" << r.height() / qreal(2.0);
- *d->stream << "\"/>" << endl;
+ *d->stream << "\"/>" << Qt::endl;
}
void QSvgPaintEngine::drawPath(const QPainterPath &p)
@@ -1090,7 +1090,7 @@ void QSvgPaintEngine::drawPath(const QPainterPath &p)
}
}
- *d->stream << "\"/>" << endl;
+ *d->stream << "\"/>" << Qt::endl;
}
void QSvgPaintEngine::drawPolygon(const QPointF *points, int pointCount,
@@ -1112,7 +1112,7 @@ void QSvgPaintEngine::drawPolygon(const QPointF *points, int pointCount,
const QPointF &pt = points[i];
stream() << pt.x() << ',' << pt.y() << ' ';
}
- stream() << "\" />" <<endl;
+ stream() << "\" />" <<Qt::endl;
} else {
path.closeSubpath();
drawPath(path);
@@ -1130,7 +1130,7 @@ void QSvgPaintEngine::drawRects(const QRectF *rects, int rectCount)
*d->stream << " vector-effect=\"non-scaling-stroke\"";
*d->stream << " x=\"" << rect.x() << "\" y=\"" << rect.y()
<< "\" width=\"" << rect.width() << "\" height=\"" << rect.height()
- << "\"/>" << endl;
+ << "\"/>" << Qt::endl;
}
}
@@ -1155,7 +1155,7 @@ void QSvgPaintEngine::drawTextItem(const QPointF &pt, const QTextItem &textItem)
*d->stream << " >"
<< s.toHtmlEscaped()
<< "</text>"
- << endl;
+ << Qt::endl;
}
QT_END_NAMESPACE
diff --git a/src/svg/qsvggraphics.cpp b/src/svg/qsvggraphics.cpp
index 5b273af..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>
@@ -121,14 +122,14 @@ void QSvgArc::draw(QPainter *p, QSvgExtraStates &states)
}
QSvgImage::QSvgImage(QSvgNode *parent, const QImage &image,
- const QRect &bounds)
+ const QRectF &bounds)
: QSvgNode(parent), m_image(image),
m_bounds(bounds)
{
- if (m_bounds.width() == 0)
- m_bounds.setWidth(m_image.width());
- if (m_bounds.height() == 0)
- m_bounds.setHeight(m_image.height());
+ if (m_bounds.width() == 0.0)
+ m_bounds.setWidth(static_cast<qreal>(m_image.width()));
+ if (m_bounds.height() == 0.0)
+ m_bounds.setHeight(static_cast<qreal>(m_image.height()));
}
void QSvgImage::draw(QPainter *p, QSvgExtraStates &states)
@@ -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 6e5b9d6..8488b33 100644
--- a/src/svg/qsvggraphics_p.h
+++ b/src/svg/qsvggraphics_p.h
@@ -104,13 +104,13 @@ class Q_SVG_PRIVATE_EXPORT QSvgImage : public QSvgNode
{
public:
QSvgImage(QSvgNode *parent, const QImage &image,
- const QRect &bounds);
+ const QRectF &bounds);
void draw(QPainter *p, QSvgExtraStates &states) override;
Type type() const override;
QRectF bounds(QPainter *p, QSvgExtraStates &states) const override;
private:
QImage m_image;
- QRect m_bounds;
+ QRectF m_bounds;
};
class Q_SVG_PRIVATE_EXPORT QSvgLine : public QSvgNode
@@ -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 0468bbe..fe79977 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -774,21 +774,31 @@ static QVector<qreal> parsePercentageList(const QChar *&str)
static QString idFromUrl(const QString &url)
{
+ // The form is url(<IRI>), where IRI can be
+ // just an ID on #<id> form.
QString::const_iterator itr = url.constBegin();
QString::const_iterator end = url.constEnd();
+ QString id;
while (itr != end && (*itr).isSpace())
++itr;
if (itr != end && (*itr) == QLatin1Char('('))
++itr;
+ else
+ return QString();
while (itr != end && (*itr).isSpace())
++itr;
- if (itr != end && (*itr) == QLatin1Char('#'))
+ if (itr != end && (*itr) == QLatin1Char('#')) {
+ id += *itr;
++itr;
- QString id;
+ } else {
+ return QString();
+ }
while (itr != end && (*itr) != QLatin1Char(')')) {
id += *itr;
++itr;
}
+ if (itr == end || (*itr) != QLatin1Char(')'))
+ return QString();
return id;
}
@@ -1596,7 +1606,7 @@ static bool parsePathDataFast(const QStringRef &dataStr, QPainterPath &path)
const QChar *end = str + dataStr.size();
while (str != end) {
- while (str->isSpace())
+ while (str->isSpace() && (str + 1) != end)
++str;
QChar pathElem = *str;
++str;
@@ -2605,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,
@@ -2792,10 +2802,10 @@ static QSvgNode *createImageNode(QSvgNode *parent,
QSvgNode *img = new QSvgImage(parent,
image,
- QRect(int(nx),
- int(ny),
- int(nwidth),
- int(nheight)));
+ QRectF(nx,
+ ny,
+ nwidth,
+ nheight));
return img;
}
@@ -3709,14 +3719,20 @@ bool QSvgHandler::startElement(const QString &localName,
}
break;
default:
+ const QByteArray msg = QByteArrayLiteral("Could not add child element to parent element because the types are incorrect.");
+ qCWarning(lcSvgHandler, "%s", prefixMessage(msg, xml).constData());
+ delete node;
+ node = 0;
break;
}
}
- parseCoreNode(node, attributes);
+ if (node) {
+ parseCoreNode(node, attributes);
#ifndef QT_NO_CSSPARSER
- cssStyleLookup(node, this, m_selector);
+ cssStyleLookup(node, this, m_selector);
#endif
- parseStyle(node, attributes, this);
+ parseStyle(node, attributes, this);
+ }
} else if (FactoryMethod method = findGraphicsFactory(localName)) {
//rendering element
Q_ASSERT(!m_nodes.isEmpty());
@@ -3728,6 +3744,13 @@ bool QSvgHandler::startElement(const QString &localName,
case QSvgNode::DEFS:
case QSvgNode::SWITCH:
{
+ if (node->type() == QSvgNode::TSPAN) {
+ const QByteArray msg = QByteArrayLiteral("\'tspan\' element in wrong context.");
+ qCWarning(lcSvgHandler, "%s", prefixMessage(msg, xml).constData());
+ delete node;
+ node = 0;
+ break;
+ }
QSvgStructureNode *group =
static_cast<QSvgStructureNode*>(m_nodes.top());
group->addChild(node, someId(attributes));
diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp
index 5448797..b934f94 100644
--- a/src/svg/qsvgstyle.cpp
+++ b/src/svg/qsvgstyle.cpp
@@ -942,13 +942,20 @@ void QSvgGradientStyle::setStopLink(const QString &link, QSvgTinyDocument *doc)
void QSvgGradientStyle::resolveStops()
{
+ QStringList visited;
+ resolveStops_helper(&visited);
+}
+
+void QSvgGradientStyle::resolveStops_helper(QStringList *visited)
+{
if (!m_link.isEmpty() && m_doc) {
QSvgStyleProperty *prop = m_doc->styleProperty(m_link);
- if (prop && prop != this) {
+ if (prop && !visited->contains(m_link)) {
+ visited->append(m_link);
if (prop->type() == QSvgStyleProperty::GRADIENT) {
QSvgGradientStyle *st =
static_cast<QSvgGradientStyle*>(prop);
- st->resolveStops();
+ st->resolveStops_helper(visited);
m_gradient->setStops(st->qgradient()->stops());
m_gradientStopsSet = st->gradientStopsSet();
}
diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h
index 916c9fa..39aa690 100644
--- a/src/svg/qsvgstyle_p.h
+++ b/src/svg/qsvgstyle_p.h
@@ -577,6 +577,7 @@ public:
void setStopLink(const QString &link, QSvgTinyDocument *doc);
QString stopLink() const { return m_link; }
void resolveStops();
+ void resolveStops_helper(QStringList *visited);
void setMatrix(const QMatrix &matrix);
QMatrix qmatrix() const
diff --git a/src/svg/qsvgtinydocument.cpp b/src/svg/qsvgtinydocument.cpp
index 15351bd..77aafb4 100644
--- a/src/svg/qsvgtinydocument.cpp
+++ b/src/svg/qsvgtinydocument.cpp
@@ -187,6 +187,7 @@ QSvgTinyDocument * QSvgTinyDocument::load(const QString &fileName)
} else {
qCWarning(lcSvgHandler, "Cannot read file '%s', because: %s (line %d)",
qPrintable(fileName), qPrintable(handler.errorString()), handler.lineNumber());
+ delete handler.document();
}
return doc;
}
@@ -207,6 +208,8 @@ QSvgTinyDocument * QSvgTinyDocument::load(const QByteArray &contents)
if (handler.ok()) {
doc = handler.document();
doc->m_animationDuration = handler.animationDuration();
+ } else {
+ delete handler.document();
}
return doc;
}
@@ -219,6 +222,8 @@ QSvgTinyDocument * QSvgTinyDocument::load(QXmlStreamReader *contents)
if (handler.ok()) {
doc = handler.document();
doc->m_animationDuration = handler.animationDuration();
+ } else {
+ delete handler.document();
}
return doc;
}
@@ -334,6 +339,7 @@ void QSvgTinyDocument::setHeight(int len, bool percent)
void QSvgTinyDocument::setViewBox(const QRectF &rect)
{
m_viewBox = rect;
+ m_implicitViewBox = false;
}
void QSvgTinyDocument::addSvgFont(QSvgFont *font)
@@ -358,7 +364,10 @@ QSvgNode *QSvgTinyDocument::namedNode(const QString &id) const
void QSvgTinyDocument::addNamedStyle(const QString &id, QSvgFillStyleProperty *style)
{
- m_namedStyles.insert(id, style);
+ if (!m_namedStyles.contains(id))
+ m_namedStyles.insert(id, style);
+ else
+ qCWarning(lcSvgHandler) << "Duplicate unique style id:" << id;
}
QSvgFillStyleProperty *QSvgTinyDocument::namedStyle(const QString &id) const
@@ -412,14 +421,35 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
source = viewBox();
if (source != target && !source.isNull()) {
- QTransform transform;
- transform.scale(target.width() / source.width(),
- target.height() / source.height());
- QRectF c2 = transform.mapRect(source);
- p->translate(target.x() - c2.x(),
- target.y() - c2.y());
- p->scale(target.width() / source.width(),
- target.height() / source.height());
+ if (m_implicitViewBox) {
+ QTransform transform;
+ transform.scale(target.width() / source.width(),
+ target.height() / source.height());
+ QRectF c2 = transform.mapRect(source);
+ p->translate(target.x() - c2.x(),
+ target.y() - c2.y());
+ p->scale(target.width() / source.width(),
+ target.height() / source.height());
+ } else {
+ // Code path used when a view box is specified and we're not rendering a specific element by id
+ // but the entire document. This attempts to emulate the default values of the <preserveAspectRatio>
+ // tag that's implicitly defined when <viewbox> is used.
+
+ // Apply the view box translation if specified.
+ p->translate(target.x() - source.x(),
+ target.y() - source.y());
+
+ // Scale the view box into the view port (target) by preserve the aspect ratio.
+ QSizeF viewBoxSize = source.size();
+ viewBoxSize.scale(target.width(), target.height(), Qt::KeepAspectRatio);
+
+ // Center the view box in the view port
+ p->translate((target.width() - viewBoxSize.width()) / 2,
+ (target.height() - viewBoxSize.height()) / 2);
+
+ p->scale(viewBoxSize.width() / source.width(),
+ viewBoxSize.height() / source.height());
+ }
}
}
@@ -455,7 +485,7 @@ QMatrix QSvgTinyDocument::matrixForElement(const QString &id) const
t *= node->m_style.transform->qtransform();
node = node->parent();
}
-
+
return t.toAffine();
}
diff --git a/src/svg/qsvgtinydocument_p.h b/src/svg/qsvgtinydocument_p.h
index aa51751..5f5d06b 100644
--- a/src/svg/qsvgtinydocument_p.h
+++ b/src/svg/qsvgtinydocument_p.h
@@ -125,6 +125,7 @@ private:
bool m_widthPercent;
bool m_heightPercent;
+ mutable bool m_implicitViewBox = true;
mutable QRectF m_viewBox;
QHash<QString, QSvgRefCounter<QSvgFont> > m_fonts;
@@ -173,8 +174,10 @@ inline bool QSvgTinyDocument::heightPercent() const
inline QRectF QSvgTinyDocument::viewBox() const
{
- if (m_viewBox.isNull())
+ if (m_viewBox.isNull()) {
m_viewBox = transformedBounds();
+ m_implicitViewBox = true;
+ }
return m_viewBox;
}