aboutsummaryrefslogtreecommitdiffstats
path: root/tests/manual/svg
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/svg')
-rw-r--r--tests/manual/svg/CMakeLists.txt74
-rw-r--r--tests/manual/svg/QmlGenerator.qml26
-rw-r--r--tests/manual/svg/SvgImage.qml17
-rw-r--r--tests/manual/svg/data/image/1.svg3
-rw-r--r--tests/manual/svg/data/image/2.svg3
-rw-r--r--tests/manual/svg/data/image/3.svg6
-rw-r--r--tests/manual/svg/data/image/data.pngbin0 -> 6901 bytes
-rw-r--r--tests/manual/svg/data/image/qtlogo.pngbin0 -> 6901 bytes
-rw-r--r--tests/manual/svg/data/painting/fill_color.svg7
-rw-r--r--tests/manual/svg/data/painting/fill_gradient.svg15
-rw-r--r--tests/manual/svg/data/painting/fill_stroke.svg3
-rw-r--r--tests/manual/svg/data/painting/stroke_color.svg7
-rw-r--r--tests/manual/svg/data/styling/stroking_capStyle_shapes_1.svg11
-rw-r--r--tests/manual/svg/data/styling/stroking_capStyle_shapes_2.svg12
-rw-r--r--tests/manual/svg/data/styling/stroking_dash.svg10
-rw-r--r--tests/manual/svg/data/styling/stroking_joinStyle_shapes_1.svg12
-rw-r--r--tests/manual/svg/data/styling/stroking_text.svg4
-rw-r--r--tests/manual/svg/data/text/1.svg44
-rw-r--r--tests/manual/svg/data/text/2.svg45
-rw-r--r--tests/manual/svg/data/text/3.svg20
-rw-r--r--tests/manual/svg/data/text/4.svg20
-rw-r--r--tests/manual/svg/data/text/5.svg44
-rw-r--r--tests/manual/svg/main.cpp14
-rw-r--r--tests/manual/svg/mainwindow.cpp142
-rw-r--r--tests/manual/svg/mainwindow.h47
-rw-r--r--tests/manual/svg/mainwindow.ui292
-rw-r--r--tests/manual/svg/svgmanager.cpp96
-rw-r--r--tests/manual/svg/svgmanager.h82
-rw-r--r--tests/manual/svg/svgpainter.cpp81
-rw-r--r--tests/manual/svg/svgpainter.h49
30 files changed, 1186 insertions, 0 deletions
diff --git a/tests/manual/svg/CMakeLists.txt b/tests/manual/svg/CMakeLists.txt
new file mode 100644
index 0000000000..1576c0d741
--- /dev/null
+++ b/tests/manual/svg/CMakeLists.txt
@@ -0,0 +1,74 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.5)
+
+project(svg VERSION 0.1 LANGUAGES CXX)
+
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Quick Qml Svg SvgWidgets QuickWidgets QuickVectorImageGeneratorPrivate)
+find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Quick Qml Svg SvgWidgets QuickWidgets QuickVectorImageGeneratorPrivate)
+
+set(PROJECT_SOURCES
+ main.cpp
+ mainwindow.h mainwindow.cpp
+ mainwindow.ui
+ svgpainter.h svgpainter.cpp
+ svgmanager.h svgmanager.cpp
+)
+
+if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
+ qt_add_executable(svg
+ MANUAL_FINALIZATION
+ ${PROJECT_SOURCES}
+ )
+# Define target properties for Android with Qt 6 as:
+# set_property(TARGET svg APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
+# ${CMAKE_CURRENT_SOURCE_DIR}/android)
+# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
+else()
+ if(ANDROID)
+ add_library(svg SHARED
+ ${PROJECT_SOURCES}
+ )
+# Define properties for Android with Qt 5 after find_package() calls as:
+# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
+ else()
+ add_executable(svg
+ ${PROJECT_SOURCES}
+ )
+ endif()
+endif()
+
+target_link_libraries(svg PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Quick Qt${QT_VERSION_MAJOR}::Qml Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::QuickWidgets Qt${QT_VERSION_MAJOR}::QuickVectorImageGeneratorPrivate Qt${QT_VERSION_MAJOR}::SvgWidgets)
+
+set_target_properties(svg PROPERTIES
+ MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
+ MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
+ MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
+ MACOSX_BUNDLE TRUE
+ WIN32_EXECUTABLE TRUE
+)
+
+install(TARGETS svg
+ BUNDLE DESTINATION .
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+)
+
+qt_add_qml_module(svg
+ VERSION 1.0
+ URI SvgImageTest
+ QML_FILES SvgImage.qml QmlGenerator.qml
+)
+
+
+if(QT_VERSION_MAJOR EQUAL 6)
+ qt_finalize_executable(svg)
+endif()
diff --git a/tests/manual/svg/QmlGenerator.qml b/tests/manual/svg/QmlGenerator.qml
new file mode 100644
index 0000000000..96435ba4f0
--- /dev/null
+++ b/tests/manual/svg/QmlGenerator.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick
+import SvgImageTest
+
+Item {
+ id: item
+ width: childrenRect.width * (SvgManager.scale / 10.0)
+ height: childrenRect.height * (SvgManager.scale / 10.0)
+ scale: SvgManager.scale / 10
+ transformOrigin: Item.TopLeft
+
+ property var dynamicObject: null
+ Connections {
+ target: SvgManager
+ function onCurrentSourceChanged() {
+ if (dynamicObject)
+ dynamicObject.destroy()
+
+ var s = SvgManager.qmlSource
+
+ dynamicObject = Qt.createQmlObject(s, item, "dummy.qml")
+ }
+ }
+}
diff --git a/tests/manual/svg/SvgImage.qml b/tests/manual/svg/SvgImage.qml
new file mode 100644
index 0000000000..ce0bb4ab12
--- /dev/null
+++ b/tests/manual/svg/SvgImage.qml
@@ -0,0 +1,17 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+import QtQuick
+import QtQuick.VectorImage
+import SvgImageTest
+
+Item {
+ width: vectorImage.implicitWidth * (SvgManager.scale / 10.0)
+ height: vectorImage.implicitHeight * (SvgManager.scale / 10.0)
+ scale: SvgManager.scale / 10.0
+ transformOrigin: Item.TopLeft
+ VectorImage {
+ id: vectorImage
+ source: SvgManager.currentSource
+ }
+}
diff --git a/tests/manual/svg/data/image/1.svg b/tests/manual/svg/data/image/1.svg
new file mode 100644
index 0000000000..d5f27450c2
--- /dev/null
+++ b/tests/manual/svg/data/image/1.svg
@@ -0,0 +1,3 @@
+<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
+ <image xlink:href="data.png" height="200" width="200" />
+</svg>
diff --git a/tests/manual/svg/data/image/2.svg b/tests/manual/svg/data/image/2.svg
new file mode 100644
index 0000000000..3f71e5ca23
--- /dev/null
+++ b/tests/manual/svg/data/image/2.svg
@@ -0,0 +1,3 @@
+<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
+ <image xlink:href="qtlogo.png" height="200" width="200" />
+</svg>
diff --git a/tests/manual/svg/data/image/3.svg b/tests/manual/svg/data/image/3.svg
new file mode 100644
index 0000000000..85751587d9
--- /dev/null
+++ b/tests/manual/svg/data/image/3.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg viewBox="0 0 210 297">
+<image width="200" height="200" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAA8CAYAAAGPy61gAAAAAXNSR0IArs4c6QAAAJZlWElmTU0A&#10;KgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgExAAIAAAARAAAAWodp&#10;AAQAAAABAAAAbAAAAAAAAABIAAAAAQAAAEgAAAABQWRvYmUgSW1hZ2VSZWFkeQAAAAOgAQADAAAA&#10;AQABAACgAgAEAAAAAQAAAFSgAwAEAAAAAQAAADwAAAAAm/SbDAAAAAlwSFlzAAALEwAACxMBAJqc&#10;GAAAAi1pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6&#10;bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDYuMC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRm&#10;PSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJk&#10;ZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8v&#10;bnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMu&#10;YWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+QWRvYmUgSW1h&#10;Z2VSZWFkeTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43Mjwv&#10;dGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmll&#10;bnRhdGlvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzI8L3RpZmY6WFJlc29sdXRpb24+&#10;CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpg60/Z&#10;AAAXv0lEQVR4Ae1caZBdxXXuvve+bXaNFhAIJI0EWmZGCEaIJYVLBlxFlkpBbBGXKwRXYkOFwmAW&#10;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&#10;rkJggg==&#10;" id="image1" x="10" y="10" />
+</svg>
diff --git a/tests/manual/svg/data/image/data.png b/tests/manual/svg/data/image/data.png
new file mode 100644
index 0000000000..7b660be3de
--- /dev/null
+++ b/tests/manual/svg/data/image/data.png
Binary files differ
diff --git a/tests/manual/svg/data/image/qtlogo.png b/tests/manual/svg/data/image/qtlogo.png
new file mode 100644
index 0000000000..7b660be3de
--- /dev/null
+++ b/tests/manual/svg/data/image/qtlogo.png
Binary files differ
diff --git a/tests/manual/svg/data/painting/fill_color.svg b/tests/manual/svg/data/painting/fill_color.svg
new file mode 100644
index 0000000000..7772839369
--- /dev/null
+++ b/tests/manual/svg/data/painting/fill_color.svg
@@ -0,0 +1,7 @@
+<svg viewBox="0 0 400 1000" xmlns="http://www.w3.org/2000/svg">
+ <g fill-opacity="0.3">
+ <rect width="300" height="300" fill="red"/>
+ </g>
+ <rect transform="translate(0, 350)" width="300" height="300" fill="red"/>
+ <rect transform="translate(0, 700)" width="300" height="300" fill="transparent" stroke="yellow" stroke-width="5"/>
+</svg>
diff --git a/tests/manual/svg/data/painting/fill_gradient.svg b/tests/manual/svg/data/painting/fill_gradient.svg
new file mode 100644
index 0000000000..5fefb40442
--- /dev/null
+++ b/tests/manual/svg/data/painting/fill_gradient.svg
@@ -0,0 +1,15 @@
+<svg viewBox="0 0 200 400" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <linearGradient id="grad1" x1="0%" x2="100%" y1="0%" y2="0%">
+ <stop offset="0%" stop-color="green" stop-opacity="0.8"/>
+ <stop offset="100%" stop-color="red" stop-opacity="0.8"/>
+ </linearGradient>
+ <linearGradient id="grad2" x1="0%" x2="100%" y1="0%" y2="0%">
+ <stop offset="0%" stop-color="green"/>
+ <stop offset="100%" stop-color="red"/>
+ </linearGradient>
+ </defs>
+ <ellipse cx="100" cy="70" rx="85" ry="55" fill="url(#grad1)"/>
+ <ellipse cx="100" cy="200" rx="85" ry="55" fill="url(#grad2)" fill-opacity="0.8"/>
+ <ellipse cx="100" cy="330" rx="85" ry="55" fill="url(#grad1)" fill-opacity="0.5"/>
+</svg>
diff --git a/tests/manual/svg/data/painting/fill_stroke.svg b/tests/manual/svg/data/painting/fill_stroke.svg
new file mode 100644
index 0000000000..8069faf516
--- /dev/null
+++ b/tests/manual/svg/data/painting/fill_stroke.svg
@@ -0,0 +1,3 @@
+<svg viewBox="0 0 800 800" xmlns="http://www.w3.org/2000/svg">
+ <rect transform="translate(50, 50)" width="400" height="400" fill="green" stroke="black" fill-opacity="0.5" stroke-opacity="0.2" stroke-width="20"/>
+</svg> \ No newline at end of file
diff --git a/tests/manual/svg/data/painting/stroke_color.svg b/tests/manual/svg/data/painting/stroke_color.svg
new file mode 100644
index 0000000000..d77755e1fd
--- /dev/null
+++ b/tests/manual/svg/data/painting/stroke_color.svg
@@ -0,0 +1,7 @@
+<svg viewBox="0 0 400 1000" xmlns="http://www.w3.org/2000/svg">
+ <g stroke-opacity="0.3">
+ <rect transform="translate(25, 25)" width="300" height="300" stroke="red" stroke-width="10"/>
+ </g>
+ <rect transform="translate(25, 350)" width="300" height="300" stroke="red" stroke-width="10"/>
+ <rect transform="translate(25, 700)" width="300" height="300" fill="yellow" stroke="transparent"/>
+</svg>
diff --git a/tests/manual/svg/data/styling/stroking_capStyle_shapes_1.svg b/tests/manual/svg/data/styling/stroking_capStyle_shapes_1.svg
new file mode 100644
index 0000000000..9448fcb527
--- /dev/null
+++ b/tests/manual/svg/data/styling/stroking_capStyle_shapes_1.svg
@@ -0,0 +1,11 @@
+<svg width="900" height="600" viewBox="0 0 90 60" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <g id="capTest">
+ <polyline points="10,10 80,10" fill="none" stroke-width="8" stroke="black"/>
+ <polyline points="10,10 80,10" fill="none" stroke-width="0.5" stroke-linecap="butt" stroke="yellow"/>
+ </g>
+ </defs>
+ <use href="#capTest" stroke-linecap="butt"/>
+ <use href="#capTest" y="20" stroke-linecap="round"/>
+ <use href="#capTest" y=" 40" stroke-linecap="square"/>
+</svg>
diff --git a/tests/manual/svg/data/styling/stroking_capStyle_shapes_2.svg b/tests/manual/svg/data/styling/stroking_capStyle_shapes_2.svg
new file mode 100644
index 0000000000..1d52d2d247
--- /dev/null
+++ b/tests/manual/svg/data/styling/stroking_capStyle_shapes_2.svg
@@ -0,0 +1,12 @@
+<svg width="900" height="300" viewBox="0 0 130 40" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <polyline id="letterz" points="10,10 40,10 10,30 40,30" fill="none" stroke-width="2.5" stroke="black"/>
+ <polyline id="highlight" points="10,10 40,10 10,30 40,30" fill="none" stroke-width="0.1" stroke="yellow"/>
+ </defs>
+ <use href="#letterz" stroke-linecap="butt"/>
+ <use href="#highlight"/>
+ <use href="#letterz" x="40" stroke-linecap="round"/>
+ <use href="#highlight" x="40"/>
+ <use href="#letterz" x=" 80" stroke-linecap="square"/>
+ <use href="#highlight" x="80"/>
+</svg>
diff --git a/tests/manual/svg/data/styling/stroking_dash.svg b/tests/manual/svg/data/styling/stroking_dash.svg
new file mode 100644
index 0000000000..5fdefa4cce
--- /dev/null
+++ b/tests/manual/svg/data/styling/stroking_dash.svg
@@ -0,0 +1,10 @@
+<svg width="460" height="200" viewBox="0 0 30 13" xmlns="http://www.w3.org/2000/svg">
+ <line x1="0" y1="1" x2="30" y2="1" stroke="black" stroke-dashoffset="2"/>
+ <line x1="0" y1="3" x2="30" y2="3" stroke="black" stroke-dasharray="4 2"/>
+<!--positive dashoffset pulls the dashes-->
+ <line x1="0" y1="5" x2="30" y2="5" stroke="black" stroke-dasharray="4 2" stroke-dashoffset="2"/>
+ <line x1="0" y1="7" x2="30" y2="7" stroke="black" stroke-dasharray="4 2" stroke-dashoffset="4"/>
+ <!--negative dashoffset pushs the dashes-->
+ <line x1="0" y1="9" x2="30" y2="9" stroke="black" stroke-dasharray="4 2" stroke-dashoffset="-2"/>
+ <line x1="0" y1="11" x2="30" y2="11" stroke="black" stroke-dasharray="4 2" stroke-dashoffset="-4"/>
+</svg>
diff --git a/tests/manual/svg/data/styling/stroking_joinStyle_shapes_1.svg b/tests/manual/svg/data/styling/stroking_joinStyle_shapes_1.svg
new file mode 100644
index 0000000000..1da775a97e
--- /dev/null
+++ b/tests/manual/svg/data/styling/stroking_joinStyle_shapes_1.svg
@@ -0,0 +1,12 @@
+<svg width="600" height="200" viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
+ <defs>
+ <g id="capTest">
+ <polyline points="1,8 1,2 7,2" fill="none" stroke-width="1" stroke="black"/>
+ <polyline points="1,8 1,2 7,2" fill="none" stroke-width="0.03" stroke="yellow"/>
+ </g>
+ </defs>
+
+ <use href="#capTest" x="1" stroke-linejoin="bevel"/>
+ <use href="#capTest" x="11" stroke-linejoin="round"/>
+ <use href="#capTest" x="21" stroke-linejoin="miter"/>
+</svg>
diff --git a/tests/manual/svg/data/styling/stroking_text.svg b/tests/manual/svg/data/styling/stroking_text.svg
new file mode 100644
index 0000000000..bacc04fff4
--- /dev/null
+++ b/tests/manual/svg/data/styling/stroking_text.svg
@@ -0,0 +1,4 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
+ <text y="70" style="font-size: 80px; font-weight: bold; font-family: sans-serif; stroke-dasharray:5,5; fill: peachpuff; stroke: crimson; stroke-width:4.1px; stroke-linecap: square; stroke-linejoin: bevel;">pizazz</text>
+ <text y="150" style="font-size: 80px; font-weight: bold; font-family: sans-serif; fill: peachpuff; stroke: blue; stroke-width:4.1px; stroke-linecap: square; stroke-linejoin: bevel;">pizazz</text>
+</svg>
diff --git a/tests/manual/svg/data/text/1.svg b/tests/manual/svg/data/text/1.svg
new file mode 100644
index 0000000000..d6fd4905f0
--- /dev/null
+++ b/tests/manual/svg/data/text/1.svg
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="210mm"
+ height="297mm"
+ viewBox="0 0 210 297"
+ version="1.1"
+ id="svg1"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs1">
+ <linearGradient
+ id="linearGradient1">
+ <stop
+ style="stop-color:#ff0000;stop-opacity:1;"
+ offset="0"
+ id="stop1" />
+ <stop
+ style="stop-color:#00ff00;stop-opacity:1;"
+ offset="1"
+ id="stop2" />
+ </linearGradient>
+ <rect
+ x="150.02508"
+ y="181.45326"
+ width="412.12424"
+ height="148.24613"
+ id="rect1" />
+ <linearGradient
+ xlink:href="#linearGradient1"
+ id="linearGradient2"
+ x1="159.13997"
+ y1="232.67492"
+ x2="543.63868"
+ y2="232.67492"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <g id="layer1">
+ <text xml:space="preserve" transform="scale(0.26458333)" id="text1" x="150.02539" y="266.60392" style="font-size:93.3333px;fill:url(#linearGradient2)"><tspan id="tspan3">FOO</tspan><tspan style="font-weight:bold;font-family:Dubai;-inkscape-font-specification:'Dubai Bold'">BAR</tspan></text>
+ </g>
+</svg>
diff --git a/tests/manual/svg/data/text/2.svg b/tests/manual/svg/data/text/2.svg
new file mode 100644
index 0000000000..bf438e7aa0
--- /dev/null
+++ b/tests/manual/svg/data/text/2.svg
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="210mm"
+ height="297mm"
+ viewBox="0 0 210 297"
+ version="1.1"
+ id="svg1"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs1">
+ <linearGradient
+ id="linearGradient1">
+ <stop
+ style="stop-color:#ff0000;stop-opacity:1;"
+ offset="0"
+ id="stop1" />
+ <stop
+ style="stop-color:#00ff00;stop-opacity:1;"
+ offset="1"
+ id="stop2" />
+ </linearGradient>
+ <rect
+ x="150.02508"
+ y="181.45326"
+ width="412.12424"
+ height="148.24613"
+ id="rect1" />
+ <linearGradient
+ xlink:href="#linearGradient1"
+ id="linearGradient2"
+ x1="159.13997"
+ y1="232.67492"
+ x2="543.63868"
+ y2="232.67492"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <g id="layer1">
+ <text xml:space="preserve" transform="scale(0.26458333)" id="text1" x="150.02539" y="266.60392" style="font-size:93.3333px;font-family:Cali;white-space:pre;shape-inside:url(#rect1);display:inline;opacity:0.557377;fill:url(#linearGradient2);stroke-width:1.00157">
+ <tspan>FOO</tspan><tspan style="font-weight:bold;font-family:Dubai;-inkscape-font-specification:'Dubai Bold'">BAR</tspan></text>
+ </g>
+</svg>
diff --git a/tests/manual/svg/data/text/3.svg b/tests/manual/svg/data/text/3.svg
new file mode 100644
index 0000000000..322cfff821
--- /dev/null
+++ b/tests/manual/svg/data/text/3.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="210mm"
+ height="297mm"
+ viewBox="0 0 210 297"
+ version="1.1"
+ id="svg1"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs1">
+ </defs>
+ <g id="layer1">
+ <text xml:space="preserve" transform="scale(0.26458333)" id="text1" x="0" y="100" style="font-size:93.3333px;white-space:pre;shape-inside:url(#rect1);display:inline;opacity:0.557377;fill:#ff0000ff;stroke-width:1.00157">
+ <tspan>FOO</tspan><tspan style="font-weight:bold;font-family:Dubai">BAR</tspan></text>
+ </g>
+</svg>
diff --git a/tests/manual/svg/data/text/4.svg b/tests/manual/svg/data/text/4.svg
new file mode 100644
index 0000000000..d7146dedab
--- /dev/null
+++ b/tests/manual/svg/data/text/4.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="210mm"
+ height="297mm"
+ viewBox="0 0 210 297"
+ version="1.1"
+ id="svg1"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs1">
+ </defs>
+ <g id="layer1">
+ <text xml:space="preserve" transform="scale(0.26458333)" id="text1" x="0" y="100" style="font-size:93.3333px">
+ <tspan style="fill: red">FO</tspan><tspan style="stroke: red">O</tspan><tspan style="font-weight:bold;font-family:Dubai">BAR</tspan></text>
+ </g>
+</svg>
diff --git a/tests/manual/svg/data/text/5.svg b/tests/manual/svg/data/text/5.svg
new file mode 100644
index 0000000000..a63d53e526
--- /dev/null
+++ b/tests/manual/svg/data/text/5.svg
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="210mm"
+ height="297mm"
+ viewBox="0 0 210 297"
+ version="1.1"
+ id="svg1"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs1">
+ <linearGradient
+ id="linearGradient1">
+ <stop
+ style="stop-color:#ff0000;stop-opacity:1;"
+ offset="0"
+ id="stop1" />
+ <stop
+ style="stop-color:#00ff00;stop-opacity:1;"
+ offset="1"
+ id="stop2" />
+ </linearGradient>
+ <rect
+ x="150.02508"
+ y="181.45326"
+ width="412.12424"
+ height="148.24613"
+ id="rect1" />
+ <linearGradient
+ xlink:href="#linearGradient1"
+ id="linearGradient2"
+ x1="159.13997"
+ y1="232.67492"
+ x2="543.63868"
+ y2="232.67492"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <g id="layer1">
+ <text xml:space="preserve" transform="scale(0.26458333)" id="text1" x="150.02539" y="266.60392" style="font-size:93.3333px"><tspan id="tspan3" style="stroke:red">FOO</tspan><tspan style="fill:url(#linearGradient2);font-weight:bold;font-family:Dubai;">BAR</tspan></text>
+ </g>
+</svg>
diff --git a/tests/manual/svg/main.cpp b/tests/manual/svg/main.cpp
new file mode 100644
index 0000000000..d86d7a3793
--- /dev/null
+++ b/tests/manual/svg/main.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "mainwindow.h"
+
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+ return a.exec();
+}
diff --git a/tests/manual/svg/mainwindow.cpp b/tests/manual/svg/mainwindow.cpp
new file mode 100644
index 0000000000..403202514b
--- /dev/null
+++ b/tests/manual/svg/mainwindow.cpp
@@ -0,0 +1,142 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "mainwindow.h"
+#include "./ui_mainwindow.h"
+
+#include "svgmanager.h"
+#include "svgpainter.h"
+
+#include <QFileDialog>
+#include <QSettings>
+#include <QQuickWidget>
+#include <QQmlEngine>
+#include <QSlider>
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ , ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+
+ connect(ui->tbSelectDir, &QToolButton::clicked, this, &MainWindow::selectDirectory);
+ connect(ui->tbNext, &QToolButton::clicked, this, &MainWindow::next);
+ connect(ui->tbPrev, &QToolButton::clicked, this, &MainWindow::previous);
+ m_manager = new SvgManager(this);
+
+ m_imageLabel = new QLabel;
+ m_imageLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ ui->saImage->setWidget(m_imageLabel);
+ ui->saImage->setBackgroundRole(QPalette::Base);
+
+ m_svgPainter = new SvgPainter;
+ ui->saSvgPainter->setWidget(m_svgPainter);
+ ui->saSvgPainter->setBackgroundRole(QPalette::Base);
+
+ m_svgImageWidget = new QQuickWidget;
+ m_svgImageWidget->setSource(QUrl(QStringLiteral("qrc:/SvgImageTest/SvgImage.qml")));
+ m_svgImageWidget->setResizeMode(QQuickWidget::SizeViewToRootObject);
+ m_svgImageWidget->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ ui->saSvgImage->setWidget(m_svgImageWidget);
+
+ m_qmlGeneratorWidget = new QQuickWidget;
+ m_qmlGeneratorWidget->setSource(QUrl(QStringLiteral("qrc:/SvgImageTest/QmlGenerator.qml")));
+ m_qmlGeneratorWidget->setResizeMode(QQuickWidget::SizeViewToRootObject);
+ m_qmlGeneratorWidget->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ ui->saQmlGenerator->setWidget(m_qmlGeneratorWidget);
+
+ connect(m_manager, &SvgManager::currentSourceChanged, this, &MainWindow::updateSources);
+
+ m_settings = new QSettings(QStringLiteral("org.qtproject"), QStringLiteral("svg-test"), this);
+
+ connect(ui->cbCurrentDir, &QComboBox::currentTextChanged, this, &MainWindow::loadDirectory);
+ QStringList list = m_settings->value(QStringLiteral("directories")).toString().split(QLatin1Char(','));
+ setDirList(list);
+
+ connect(ui->hsScale, &QAbstractSlider::valueChanged, m_manager, &SvgManager::setScale);
+ connect(ui->hsScale, &QAbstractSlider::valueChanged, m_svgPainter, &SvgPainter::setScale);
+ connect(ui->hsScale, &QAbstractSlider::valueChanged, this, &MainWindow::setScale);
+ int scale = m_settings->value(QStringLiteral("scale"), 10).toInt();
+ ui->hsScale->setValue(scale);
+}
+
+void MainWindow::loadDirectory(const QString &newDir)
+{
+ m_manager->setCurrentDirectory(newDir);
+}
+
+void MainWindow::setDirList(const QStringList &list)
+{
+ ui->cbCurrentDir->clear();
+ for (QString dirName : list)
+ ui->cbCurrentDir->addItem(dirName);
+
+ m_settings->setValue(QStringLiteral("directories"), list.join(QLatin1Char(',')));
+}
+
+void MainWindow::setScale(const int scale)
+{
+ m_settings->setValue(QStringLiteral("scale"), scale);
+}
+
+void MainWindow::updateCurrentDir(const QString &s)
+{
+ QStringList list;
+ for (int i = 0; i < ui->cbCurrentDir->count(); ++i) {
+ if (ui->cbCurrentDir->itemText(i) != s)
+ list.append(ui->cbCurrentDir->itemText(i));
+ }
+
+ list.prepend(s);
+
+ while (list.size() > 10)
+ list.removeLast();
+
+ setDirList(list);
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::updateSources()
+{
+ m_svgPainter->setSource(m_manager->currentSource());
+
+ QFileInfo info(m_manager->currentSource().toLocalFile());
+ ui->lCurrentFileName->setText(info.baseName());
+
+ QFileInfo pngInfo(info.absolutePath() + QLatin1Char('/') + info.baseName() + QStringLiteral(".png"));
+ if (pngInfo.exists()) {
+ ui->lRefPng->setVisible(true);
+ ui->saImage->setVisible(true);
+ QPixmap pixmap = QPixmap::fromImage(QImage(pngInfo.absoluteFilePath()));
+ m_imageLabel->setPixmap(pixmap);
+ } else {
+ ui->lRefPng->setVisible(false);
+ ui->saImage->setVisible(false);
+ m_imageLabel->clear();
+ }
+}
+
+void MainWindow::selectDirectory()
+{
+ QString s = QFileDialog::getExistingDirectory(this, tr("Select directory"), m_manager->currentDirectory());
+ if (!s.isEmpty()) {
+ updateCurrentDir(s);
+ }
+}
+
+void MainWindow::next()
+{
+ if (m_manager->currentIndex() + 1 < m_manager->sourceCount())
+ m_manager->setCurrentIndex(m_manager->currentIndex() + 1);
+}
+
+void MainWindow::previous()
+{
+ if (m_manager->currentIndex() > 0)
+ m_manager->setCurrentIndex(m_manager->currentIndex() - 1);
+
+}
diff --git a/tests/manual/svg/mainwindow.h b/tests/manual/svg/mainwindow.h
new file mode 100644
index 0000000000..81e4bea113
--- /dev/null
+++ b/tests/manual/svg/mainwindow.h
@@ -0,0 +1,47 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+QT_BEGIN_NAMESPACE
+namespace Ui { class MainWindow; }
+QT_END_NAMESPACE
+
+class SvgPainter;
+class SvgManager;
+class QSettings;
+class QLabel;
+class QQuickWidget;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = nullptr);
+ ~MainWindow();
+
+private slots:
+ void updateSources();
+ void selectDirectory();
+ void next();
+ void previous();
+ void loadDirectory(const QString &newDir);
+
+private:
+ void updateCurrentDir(const QString &newDir);
+ void setDirList(const QStringList &list);
+ void setScale(const int scale);
+
+ Ui::MainWindow *ui;
+ SvgManager *m_manager = nullptr;
+ QSettings *m_settings = nullptr;
+ QLabel *m_imageLabel = nullptr;
+ SvgPainter *m_svgPainter = nullptr;
+ QQuickWidget *m_svgImageWidget = nullptr;
+ QQuickWidget *m_qmlGeneratorWidget = nullptr;
+};
+#endif // MAINWINDOW_H
diff --git a/tests/manual/svg/mainwindow.ui b/tests/manual/svg/mainwindow.ui
new file mode 100644
index 0000000000..ee75f1f49b
--- /dev/null
+++ b/tests/manual/svg/mainwindow.ui
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1107</width>
+ <height>1003</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QVBoxLayout" name="verticalLayout_6">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="vaRefPng">
+ <item>
+ <widget class="QLabel" name="lRefPng">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Reference PNG</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="saImage">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Reference png</string>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>263</width>
+ <height>789</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>QSvgRenderer</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="saSvgPainter">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Reference QPainter</string>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents_4">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>264</width>
+ <height>789</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>VectorImage</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="saSvgImage">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>QML generator</string>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents_2">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>263</width>
+ <height>789</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Qml Generator</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="saQmlGenerator">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>VectorImage</string>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents_3">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>263</width>
+ <height>789</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Directory</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QComboBox" name="cbCurrentDir">
+ <property name="maxCount">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tbSelectDir">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QToolButton" name="tbPrev">
+ <property name="text">
+ <string>⬅️</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="lCurrentFileName">
+ <property name="text">
+ <string>Filename</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tbNext">
+ <property name="font">
+ <font>
+ <family>Segoe UI Emoji</family>
+ </font>
+ </property>
+ <property name="text">
+ <string>➡️</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSlider" name="hsScale">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>10</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1107</width>
+ <height>22</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/svg/svgmanager.cpp b/tests/manual/svg/svgmanager.cpp
new file mode 100644
index 0000000000..b8d49413a5
--- /dev/null
+++ b/tests/manual/svg/svgmanager.cpp
@@ -0,0 +1,96 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "svgmanager.h"
+
+#include <QDir>
+#include <QtQuickVectorImageGenerator/private/qquickqmlgenerator_p.h>
+#include <QTemporaryFile>
+
+SvgManager *SvgManager::g_manager = nullptr;
+
+SvgManager::SvgManager(QObject *parent)
+ : QObject(parent)
+{
+ Q_ASSERT(g_manager == nullptr);
+ g_manager = this;
+ connect(this, &SvgManager::currentIndexChanged, this, &SvgManager::currentSourceChanged, Qt::QueuedConnection);
+}
+
+SvgManager::~SvgManager()
+{
+ Q_ASSERT(g_manager == this);
+ g_manager = nullptr;
+}
+
+void SvgManager::setCurrentIndex(int newCurrentIndex)
+{
+ if (m_currentIndex == newCurrentIndex)
+ return;
+ m_currentIndex = newCurrentIndex;
+ emit currentIndexChanged();
+}
+
+QList<QUrl> SvgManager::sources() const
+{
+ return m_sources;
+}
+
+QString SvgManager::currentDirectory() const
+{
+ return m_currentDirectory;
+}
+
+void SvgManager::setCurrentDirectory(const QString &newCurrentDirectory)
+{
+ if (m_currentDirectory == newCurrentDirectory)
+ return;
+ m_currentDirectory = newCurrentDirectory;
+ emit currentDirectoryChanged();
+
+ m_sources.clear();
+ if (!m_currentDirectory.isEmpty()) {
+ QDir dir(m_currentDirectory);
+ QList<QFileInfo> infos = dir.entryInfoList(QStringList() << QStringLiteral("*.svg"));
+
+ for (const QFileInfo &info : infos)
+ m_sources.append(QUrl::fromLocalFile(info.absoluteFilePath()));
+ }
+ m_currentIndex = m_sources.isEmpty() ? -1 : 0;
+ emit sourcesChanged();
+ emit currentIndexChanged();
+}
+
+QString SvgManager::qmlSource() const
+{
+ QTemporaryFile tempFile;
+ if (tempFile.open()) {
+ QString name = tempFile.fileName();
+ {
+ QQuickQmlGenerator generator(currentSource().toLocalFile(), QQuickVectorImageGenerator::CurveRenderer, tempFile.fileName());
+ generator.setCommentString(QStringLiteral("Generated"));
+ generator.generate();
+ }
+ tempFile.close();
+
+ QFile file(name);
+ if (file.open(QIODevice::ReadOnly))
+ return QString::fromUtf8(file.readAll());
+
+ }
+
+ return QStringLiteral("import QtQuick\nRectangle { width: 100; height: 100; color: \"red\" }");;
+}
+
+qreal SvgManager::scale() const
+{
+ return m_scale;
+}
+
+void SvgManager::setScale(int newScale)
+{
+ if (qFuzzyCompare(m_scale, newScale))
+ return;
+ m_scale = newScale;
+ emit scaleChanged();
+}
diff --git a/tests/manual/svg/svgmanager.h b/tests/manual/svg/svgmanager.h
new file mode 100644
index 0000000000..bdfb20242d
--- /dev/null
+++ b/tests/manual/svg/svgmanager.h
@@ -0,0 +1,82 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef SVGMANAGER_H
+#define SVGMANAGER_H
+
+#include <QObject>
+#include <QUrl>
+#include <QQmlEngine>
+
+class SvgManager : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ QML_SINGLETON
+ Q_PROPERTY(QUrl currentSource READ currentSource NOTIFY currentSourceChanged)
+ Q_PROPERTY(QString qmlSource READ qmlSource NOTIFY currentSourceChanged)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+ Q_PROPERTY(int sourceCount READ sourceCount NOTIFY sourcesChanged)
+ Q_PROPERTY(QString currentDirectory READ currentDirectory WRITE setCurrentDirectory NOTIFY currentDirectoryChanged)
+ Q_PROPERTY(QList<QUrl> sources READ sources NOTIFY sourcesChanged)
+ Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
+public:
+ SvgManager(QObject *parent);
+ ~SvgManager() override;
+
+ static SvgManager *create(QQmlEngine *, QJSEngine *)
+ {
+ return g_manager;
+ }
+
+ QUrl currentSource() const
+ {
+ if (m_currentIndex < 0)
+ return QUrl{};
+
+ return m_sources.at(m_currentIndex);
+ }
+
+ int currentIndex() const
+ {
+ return m_currentIndex;
+ }
+ void setCurrentIndex(int newCurrentIndex);
+
+ int sourceCount() const
+ {
+ return m_sources.size();
+ }
+
+ QList<QUrl> sources() const;
+
+ QString currentDirectory() const;
+ void setCurrentDirectory(const QString &newCurrentDirectory);
+
+ QString qmlSource() const;
+
+ qreal scale() const;
+
+public slots:
+ void setScale(int newScale);
+
+signals:
+ void currentSourceChanged();
+ void currentIndexChanged();
+
+ void sourcesChanged();
+
+ void currentDirectoryChanged();
+
+ void scaleChanged();
+
+private:
+ static SvgManager *g_manager;
+ int m_currentIndex = -1;
+ QList<QUrl> m_sources;
+ QString m_currentDirectory;
+ QString m_qmlSource;
+ qreal m_scale = 10.0;
+};
+
+#endif // SVGMANAGER_H
diff --git a/tests/manual/svg/svgpainter.cpp b/tests/manual/svg/svgpainter.cpp
new file mode 100644
index 0000000000..e040c1d087
--- /dev/null
+++ b/tests/manual/svg/svgpainter.cpp
@@ -0,0 +1,81 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "svgpainter.h"
+#include "svgmanager.h"
+
+#include <QtSvg>
+
+SvgPainter::SvgPainter(QWidget *parent)
+#ifdef SVGWIDGET
+ : QSvgWidget{parent}
+#else
+ : QWidget{parent}
+#endif
+ , m_scale(10)
+{
+#ifndef SVGWIDGET
+ connect(this, SIGNAL(sourceChanged()), this, SLOT(update()));
+#endif
+
+ connect(this, SIGNAL(scaleChanged()), this, SLOT(update()));
+}
+
+QUrl SvgPainter::source() const
+{
+ return m_source;
+}
+
+void SvgPainter::setSource(const QUrl &newSource)
+{
+ if (m_source == newSource)
+ return;
+ m_source = newSource;
+#ifdef SVGWIDGET
+ load(m_source.toLocalFile());
+#endif
+ emit sourceChanged();
+}
+
+qreal SvgPainter::scale() const
+{
+ return m_scale;
+}
+
+void SvgPainter::setScale(const qreal scale)
+{
+ if (m_scale == scale)
+ return;
+ m_scale = scale;
+ emit scaleChanged();
+}
+
+#ifndef SVGWIDGET
+QSize SvgPainter::sizeHint() const
+{
+ return !m_source.isEmpty() ? m_size * m_scale / 10.0 : QSize(1, 1);
+}
+#endif
+
+void SvgPainter::paintEvent(QPaintEvent *event)
+{
+#ifndef SVGWIDGET
+ Q_UNUSED(event)
+ if (!m_source.isEmpty()) {
+ QPainter p(this);
+ p.fillRect(rect(), Qt::white);
+ QSvgRenderer renderer(m_source.toLocalFile());
+
+ renderer.setAspectRatioMode(Qt::KeepAspectRatio);
+ renderer.render(&p);
+ m_size = renderer.defaultSize();
+ setFixedSize(m_size * m_scale / 10.0);
+ }
+#else
+ m_size = renderer()->defaultSize();
+ setFixedSize(m_size * m_scale / 10.0);
+ QSvgWidget::paintEvent(event);
+#endif
+
+}
+
diff --git a/tests/manual/svg/svgpainter.h b/tests/manual/svg/svgpainter.h
new file mode 100644
index 0000000000..5e8a641bd7
--- /dev/null
+++ b/tests/manual/svg/svgpainter.h
@@ -0,0 +1,49 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef SVGPAINTER_H
+#define SVGPAINTER_H
+
+#include <QWidget>
+#include <QUrl>
+#include <QtSvgWidgets/QSvgWidget>
+
+// #define SVGWIDGET
+
+#ifdef SVGWIDGET
+class SvgPainter : public QSvgWidget
+#else
+class SvgPainter : public QWidget
+#endif
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
+public:
+ explicit SvgPainter(QWidget *parent = nullptr);
+
+ QUrl source() const;
+ void setSource(const QUrl &newSource);
+
+ qreal scale() const;
+ void setScale(const qreal scale);
+
+signals:
+ void sourceChanged();
+ void scaleChanged();
+
+
+protected:
+#ifndef SVGWIDGET
+ QSize sizeHint() const override;
+#endif
+ void paintEvent(QPaintEvent *) override;
+
+
+private:
+ QUrl m_source;
+ QSize m_size;
+ qreal m_scale;
+};
+
+#endif // SVGPAINTER_H