summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Portale <alessandro.portale@qt.io>2019-11-12 22:10:34 +0100
committerEirik Aavitsland <eirik.aavitsland@qt.io>2019-11-14 08:14:02 +0000
commite489a325769d295ee3b3948d98f5d07814dffd97 (patch)
tree40934f17f3367c5785662e1e92946342295d0d37
parentbeb0d74195ddc642524fe1f5a2d65d944527d1b5 (diff)
downloadqtsvg-e489a325769d295ee3b3948d98f5d07814dffd97.tar.gz
Re-fix scaling when rendering a specific element by id
This is a modification of 14fa4591eb34a35cf3d485fd901e3f1e2caa7770 That patch corrected the handling of the view box when rendering an entire SVG document. However, contrary to intention stated in the comment of that patch, it turns out that the new viewbox handling code path can be taken also for the case of rendering only a single element by id. Instead, we want to keep the original behavior where the element's origin bounds are transformed to fit into the user requested target bounds, allowing non-proportional scaling. Since the render-single-element case is easily and uniqely identifiable by the sourceRect parameter being non-null, just add an explicit check for that to the code path branching. Done-with: Eirik Aavitsland <eirik.aavitsland@qt.io> Fixes: QTBUG-79933 Change-Id: I64a35bbb193db22c33670b48ea165a91df8e719e Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/svg/qsvgtinydocument.cpp4
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp36
2 files changed, 39 insertions, 1 deletions
diff --git a/src/svg/qsvgtinydocument.cpp b/src/svg/qsvgtinydocument.cpp
index a2bf1c7..56960bf 100644
--- a/src/svg/qsvgtinydocument.cpp
+++ b/src/svg/qsvgtinydocument.cpp
@@ -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());
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index eb3ecba..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;
@@ -336,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);