summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-11-16 03:01:30 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-11-16 03:01:30 +0100
commit64841de96485d5dfd7c24c052626bff6a953bca3 (patch)
treef65badaf28508cff0e27990ce8d3ed9ece8a9baf
parentf35b26751c7320868e56c3fbe1b5d5d7a55ed239 (diff)
parente489a325769d295ee3b3948d98f5d07814dffd97 (diff)
downloadqtsvg-64841de96485d5dfd7c24c052626bff6a953bca3.tar.gz
Merge remote-tracking branch 'origin/5.14' into 5.15
Change-Id: I6d5d6b486fbd7d0d9324937e24edff2890f02bdf
-rw-r--r--src/svg/qsvgtinydocument.cpp14
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp39
-rw-r--r--tests/libfuzzer/svg/qsvgrenderer/render/main.cpp2
3 files changed, 46 insertions, 9 deletions
diff --git a/src/svg/qsvgtinydocument.cpp b/src/svg/qsvgtinydocument.cpp
index 3143ad2..56960bf 100644
--- a/src/svg/qsvgtinydocument.cpp
+++ b/src/svg/qsvgtinydocument.cpp
@@ -338,7 +338,7 @@ void QSvgTinyDocument::setHeight(int len, bool percent)
void QSvgTinyDocument::setViewBox(const QRectF &rect)
{
m_viewBox = rect;
- m_implicitViewBox = false;
+ m_implicitViewBox = rect.isNull();
}
void QSvgTinyDocument::addSvgFont(QSvgFont *font)
@@ -420,7 +420,9 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
source = viewBox();
if (source != target && !source.isNull()) {
- if (m_implicitViewBox) {
+ if (m_implicitViewBox || !sourceRect.isNull()) {
+ // Code path used when no view box is set, or when an explicit source size is given which
+ // overrides it (which is the case when we're rendering only a specific element by id).
QTransform transform;
transform.scale(target.width() / source.width(),
target.height() / source.height());
@@ -434,10 +436,6 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
// 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);
@@ -448,6 +446,10 @@ void QSvgTinyDocument::mapSourceToTarget(QPainter *p, const QRectF &targetRect,
p->scale(viewBoxSize.width() / source.width(),
viewBoxSize.height() / source.height());
+
+ // Apply the view box translation if specified.
+ p->translate(target.x() - source.x(),
+ target.y() - source.y());
}
}
}
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index cf19213..309c646 100644
--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
@@ -59,6 +59,7 @@ private slots:
void testStrokeWidth();
void testMapViewBoxToTarget();
void testRenderElement();
+ void testRenderElementToBounds();
void constructorQXmlStreamReader() const;
void loadQXmlStreamReader() const;
void nestedQXmlStreamReader() const;
@@ -269,14 +270,13 @@ void tst_QSvgRenderer::testMapViewBoxToTarget()
}
{ // Viewport and viewBox specified -> scale 500x500 square to 1000x750 while preserving aspect ratio gives 750x750
- // however the box is centered at 375, 250
data = "<svg width=\"1000\" height=\"750\" viewBox=\"-250 -250 500 500\"><g><rect x=\"0\" y=\"0\" width=\"500\" height=\"500\" /></g></svg>";
QPicture picture;
QPainter painter(&picture);
QSvgRenderer rend(data);
rend.render(&painter);
painter.end();
- QCOMPARE(picture.boundingRect(), QRect(375, 250, 750, 750));
+ QCOMPARE(picture.boundingRect(), QRect(500, 375, 750, 750));
}
}
@@ -337,6 +337,41 @@ void tst_QSvgRenderer::testRenderElement()
}
+void tst_QSvgRenderer::testRenderElementToBounds()
+{
+ // QTBUG-79933
+ QImage reference(400, 200, QImage::Format_ARGB32);
+ {
+ reference.fill(Qt::transparent);
+ QPainter p(&reference);
+ p.fillRect( 0, 0, 200, 100, Qt::blue);
+ p.fillRect(200, 100, 200, 100, Qt::blue);
+ p.fillRect( 0, 0, 100, 50, Qt::red);
+ p.fillRect(100, 50, 100, 50, Qt::red);
+ p.fillRect(200, 100, 100, 50, Qt::red);
+ p.fillRect(300, 150, 100, 50, Qt::red);
+ }
+
+ QImage rendering(400, 200, QImage::Format_ARGB32);
+ {
+ const char *const src =
+ "<svg viewBox=\"0 0 100 100\">" // Presence of a viewBox triggered QTBUG-79933
+ "<path id=\"el1\" d=\"M 80,10 H 0 V 0 h 40 v 20 h 40 z\" fill=\"red\" />"
+ "<path id=\"el2\" d=\"M 90,100 V 20 h 10 V 60 H 80 v 40 z\" fill=\"blue\" />"
+ "</svg>";
+ const QByteArray data(src);
+ QSvgRenderer rend(data);
+ rendering.fill(Qt::transparent);
+ QPainter p(&rendering);
+ rend.render(&p, "el1", QRectF( 0, 0, 200, 100));
+ rend.render(&p, "el2", QRectF( 0, 0, 200, 100));
+ rend.render(&p, "el1", QRectF(200, 100, 200, 100));
+ rend.render(&p, "el2", QRectF(200, 100, 200, 100));
+ }
+
+ QCOMPARE(reference, rendering);
+}
+
void tst_QSvgRenderer::constructorQXmlStreamReader() const
{
const QByteArray data(src);
diff --git a/tests/libfuzzer/svg/qsvgrenderer/render/main.cpp b/tests/libfuzzer/svg/qsvgrenderer/render/main.cpp
index 0197115..2439e52 100644
--- a/tests/libfuzzer/svg/qsvgrenderer/render/main.cpp
+++ b/tests/libfuzzer/svg/qsvgrenderer/render/main.cpp
@@ -36,7 +36,7 @@ extern "C" int LLVMFuzzerTestOneInput(const char *Data, size_t Size) {
static QApplication a(c, nullptr);
static QImage image(377, 233, QImage::Format_RGB32);
static QPainter painter(&image);
- QSvgRenderer renderer(QByteArray(Data, Size));
+ QSvgRenderer renderer(QByteArray::fromRawData(Data, Size));
renderer.render(&painter);
return 0;
}