summaryrefslogtreecommitdiff
path: root/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp')
-rw-r--r--tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp140
1 files changed, 102 insertions, 38 deletions
diff --git a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
index ea23d2d..7e4a5ae 100644
--- a/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
+++ b/tests/auto/qsvgrenderer/tst_qsvgrenderer.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <QtTest/QtTest>
@@ -74,6 +49,7 @@ private slots:
void fillRule();
void opacity();
void paths();
+ void paths2();
void displayMode();
void strokeInherit();
void testFillInheritance();
@@ -85,6 +61,9 @@ private slots:
void oss_fuzz_23731();
void oss_fuzz_24131();
void oss_fuzz_24738();
+ void imageRendering();
+ void illegalAnimateTransform_data();
+ void illegalAnimateTransform();
#ifndef QT_NO_COMPRESS
void testGzLoading();
@@ -522,14 +501,17 @@ static qreal transformNorm(const QTransform &m)
+ m.m33() * m.m33());
}
-static bool diffIsSmallEnough(double diff, double norm)
+template<typename T>
+static inline bool diffIsSmallEnough(T diff, T norm)
{
- return diff <= 1e-12 * norm;
-}
-
-static inline bool diffIsSmallEnough(float diff, float norm)
-{
- return diff <= 1e-5 * norm;
+ static_assert(std::is_same_v<T, double> || std::is_same_v<T, float>);
+ T sigma = []{
+ if constexpr (std::is_same_v<T, double>)
+ return 1e-12;
+ else
+ return 1e-5;
+ }();
+ return diff <= sigma * norm;
}
static void compareTransforms(const QTransform &m1, const QTransform &m2)
@@ -594,6 +576,8 @@ void tst_QSvgRenderer::boundsOnElement() const
"<use x=\"0\" y=\"0\" transform=\"rotate(45)\" xlink:href=\"#baconost\"/>"
"</g>"
"</g>"
+ "<text id=\"textA\" x=\"50\" y=\"100\">Lorem ipsum</text>"
+ "<text id=\"textB\" transform=\"matrix(1 0 0 1 50 100)\">Lorem ipsum</text>"
"</svg>");
qreal sqrt2 = qSqrt(2);
@@ -605,6 +589,10 @@ void tst_QSvgRenderer::boundsOnElement() const
QCOMPARE(renderer.boundsOnElement(QLatin1String("baconost")), QRectF(-10 * sqrt2, -10 * sqrt2, 20 * sqrt2, 20 * sqrt2));
QCOMPARE(renderer.boundsOnElement(QLatin1String("hapaa")), QRectF(-13, -9, 22, 22));
QCOMPARE(renderer.boundsOnElement(QLatin1String("prim")), QRectF(-10 * sqrt2 - 3, -10 * sqrt2 + 1, 20 * sqrt2, 20 * sqrt2));
+
+ QRectF textBoundsA = renderer.boundsOnElement(QLatin1String("textA"));
+ QVERIFY(!textBoundsA.isEmpty());
+ QCOMPARE(renderer.boundsOnElement(QLatin1String("textB")), textBoundsA);
}
void tst_QSvgRenderer::gradientStops() const
@@ -798,13 +786,13 @@ void tst_QSvgRenderer::recursiveRefs()
#ifndef QT_NO_COMPRESS
void tst_QSvgRenderer::testGzLoading()
{
- QSvgRenderer renderer(QLatin1String(SRCDIR "heart.svgz"));
+ QSvgRenderer renderer(QFINDTESTDATA("heart.svgz"));
QVERIFY(renderer.isValid());
QSvgRenderer resourceRenderer(QLatin1String(":/heart.svgz"));
QVERIFY(resourceRenderer.isValid());
- QFile largeFileGz(SRCDIR "large.svgz");
+ QFile largeFileGz(QFINDTESTDATA("large.svgz"));
largeFileGz.open(QIODevice::ReadOnly);
QByteArray data = largeFileGz.readAll();
QSvgRenderer autoDetectGzData(data);
@@ -826,9 +814,9 @@ void tst_QSvgRenderer::testGzHelper_data()
QTest::newRow("small") << QByteArray::fromHex(QByteArray("1f8b08005819934800034b"
"cbcfe70200a865327e04000000")) << QByteArray("foo\n");
- QFile largeFileGz("large.svgz");
+ QFile largeFileGz(QFINDTESTDATA("large.svgz"));
largeFileGz.open(QIODevice::ReadOnly);
- QFile largeFile("large.svg");
+ QFile largeFile(QFINDTESTDATA("large.svg"));
largeFile.open(QIODevice::ReadOnly);
QTest::newRow("large") << largeFileGz.readAll() << largeFile.readAll();
@@ -1047,6 +1035,19 @@ void tst_QSvgRenderer::paths()
}
}
+void tst_QSvgRenderer::paths2()
+{
+ const char *svg =
+ "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\">"
+ "<path d=\"M 3 8 A 5 5 0 1013 8\" id=\"path1\"/>"
+ "</svg>";
+
+ QByteArray data(svg);
+ QSvgRenderer renderer(data);
+ QVERIFY(renderer.isValid());
+ QCOMPARE(renderer.boundsOnElement(QLatin1String("path1")).toRect(), QRect(3, 8, 10, 5));
+}
+
void tst_QSvgRenderer::displayMode()
{
static const char *svgs[] = {
@@ -1632,5 +1633,68 @@ void tst_QSvgRenderer::oss_fuzz_24738()
QSvgRenderer().load(QByteArray("<svg><path d=\"a 2 1e-212.....\">"));
}
+QByteArray image_data_url(QImage &image) {
+ QByteArray data;
+ QBuffer buffer(&data);
+ buffer.open(QBuffer::ReadWrite);
+ image.save(&buffer, "PNG");
+ buffer.close();
+ QByteArray url("data:image/png;base64,");
+ url.append(data.toBase64());
+ return url;
+}
+
+void tst_QSvgRenderer::imageRendering() {
+ QImage img(2, 2, QImage::Format_ARGB32_Premultiplied);
+ img.fill(Qt::green);
+ img.setPixel(0, 0, qRgb(255, 0, 0));
+ img.setPixel(1, 1, qRgb(255, 0, 0));
+ QByteArray imgurl(image_data_url(img));
+ QString svgtemplate(
+ "<svg><g transform='scale(2, 2)'>"
+ "<image image-rendering='%1' xlink:href='%2' width='2' height='2' />"
+ "</g></svg>"
+ );
+ const char *cases[] = {"optimizeQuality", "optimizeSpeed"};
+ for (auto ir: cases) {
+ QString svg = svgtemplate.arg(QLatin1String(ir)).arg(QLatin1String(imgurl));
+ QImage img1(4, 4, QImage::Format_ARGB32);
+ QPainter p1;
+ p1.begin(&img1);
+ QSvgRenderer renderer(svg.toLatin1());
+ Q_ASSERT(renderer.isValid());
+ renderer.render(&p1);
+ p1.end();
+
+ QImage img2(4, 4, QImage::Format_ARGB32);
+ QPainter p2(&img2);
+ p2.scale(2, 2);
+ if (QLatin1String(ir) == QLatin1String("optimizeSpeed"))
+ p2.setRenderHint(QPainter::SmoothPixmapTransform, false);
+ else if (QLatin1String(ir) == QLatin1String("optimizeQuality"))
+ p2.setRenderHint(QPainter::SmoothPixmapTransform, true);
+ p2.drawImage(0, 0, img);
+ p2.end();
+ QCOMPARE(img1, img2);
+ }
+}
+
+void tst_QSvgRenderer::illegalAnimateTransform_data()
+{
+ QTest::addColumn<QByteArray>("svg");
+
+ QTest::newRow("case1") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"8,0,5,0\">");
+ QTest::newRow("case2") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" values=\"1,2\">");
+ QTest::newRow("case3") << QByteArray("<svg><animateTransform type=\"rotate\" begin=\"1\" dur=\"2\" from=\".. 5 2\" to=\"f\">");
+ QTest::newRow("case4") << QByteArray("<svg><animateTransform type=\"scale\" begin=\"1\" dur=\"2\" by=\"--,..\">");
+}
+
+void tst_QSvgRenderer::illegalAnimateTransform()
+{
+ QFETCH(QByteArray, svg);
+ QSvgRenderer renderer;
+ QVERIFY(!renderer.load(svg)); // also shouldn't assert
+}
+
QTEST_MAIN(tst_QSvgRenderer)
#include "tst_qsvgrenderer.moc"