Revision control
++ // Copyright (C) 2024 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++ /*!
++ \title Vector Image Example
++ \example vectorimage
++ \image qml-vectorimage-example.png {3x3 grid comparing Image,
++ VectorImage, and svgtoqml rendering of hearts at different scales}
++ \brief A Qt Quick example demonstrating the differences of \l{Qt SVG}, VectorImage and \l{svgtoqml}.
++ \ingroup qtquickexamples
++ \examplecategory {Graphics}
++
++ There are several different ways you can include two-dimensional vector graphics in your
++ Qt application. This example focuses on the \c{SVG} format and how this can be used with Qt.
++ As a baseline, Qt supports the static features of the \c{SVG Tiny 1.2} profile. In addition,
++ \l{Qt SVG} optionally supports some features from the full profile, but those are not used in
++ this example.
++
++ The example shows a grid of 3x3 cells, each containing the same vector image of a heart. The
++ heart image is provided as an \c{SVG} file with the example.
++
++ In the grid, each row shows the image at a different scale factor (1x, 2.5x and 4x
++ respectively).
++
++ Each column represents a different way to render the vector graphics in Qt. The left-most column
++ is an \l{Image} component, the center column is a \l{VectorImage} component and the right-most
++ column is a pregenerated \c{QML} representation created using the \l{svgtoqml} tool.
++
++ Each method of rendering the vector graphics has its own benefits and drawbacks, and caters to
++ different use cases. To make an informed decision about which one to use, it can be useful to
++ understand the details of how they differ.
++
++ \section1 The \l{Image} component and \l{Qt SVG}
++
++ When you use the \l{Image} element and set an \c{SVG} file as source, this will invoke the
++ image format plugin in \l{Qt SVG}. The plugin will parse the \c{SVG} file, rasterize it using
++ the software rasterizer in \l{QPainter} and then provide it to Qt Quick as a pixmap image. This
++ is equivalent to using the \l{QSvgRenderer} class to draw the image.
++
++ \snippet vectorimage/Main.qml image
++
++ Since the vector image is rasterized at a specific size, any transformation we apply to the
++ \l{Image} will be applied to the \e{rasterized image}. This can result in pixelation artifacts
++ and uneven curves.
++
++ Loading a vector image through \l{Image} works best if you request the image at the exact size
++ that you intend to display. When the \l{Image} is displayed at a 1x scale in the top-most row,
++ it looks identical to the others, but at higher scale factors it starts to look fuzzy.
++
++ If the image will ever only be displayed with a single size, then this will typically be the
++ most performant option. There is a start-up cost for rasterizing the image at the specified
++ size, but after this, the cost of copying the data onto the screen is very low.
++
++ But as the image is requested at multiple different sizes, the start-up cost will grow, as will
++ the accumulated memory consumption. Animated zooms of the image can often get too expensive to
++ run at full frame rate on lower end devices. These are the use cases for which \l{VectorImage}
++ and \l{svgtoqml} should be considered.
++
++ \section1 The \l{VectorImage} component
++
++ As an alternative to \l{Image}, Qt provides the \l{VectorImage} component. This converts the
++ \c{SVG} image to a vector graphics representation in Qt Quick, and rasterization happens on
++ demand, on the graphics HW, as it is rendered to the screen.
++
++ \snippet vectorimage/Main.qml vectorimage
++
++ Since the image is not pre-rasterized, we can apply transformations to it without losing
++ fidelity to the original shapes. Note that the example uses the \c{VectorImage.CurveRenderer}
++ renderer type. This is recommended for use cases where the image will be transformed and
++ antialiasing is needed.
++
++ This means that we can display the image at any size and even animate the scale of the image,
++ and all the work will be done by the graphics hardware. However, when the \l{VectorImage} is
++ rendered onto the screen, it will come at a slightly higher cost than rendering an \l{Image}.
++ This is because the rasterization of curves happens every time the component is rendered and
++ not ahead of time.
++
++ Therefore, \l{VectorImage} is most suitable for vector graphics where the size will change
++ frequently. It can also be suitable when the destination size of the image is very large and
++ memory consumption is a concern. When using \l{Image}, the full rasterized image has to be
++ stored in graphics memory. Thus, the memory consumption will scale with the size of the image.
++ The memory consumed by \l{VectorImage} will be the same, regardless of the destination size it
++ is rendered at.
++
++ \section1 The \l{svgtoqml} tool
++
++ The \l{VectorImage} component parses the \c{SVG} file and builds up an equivalent scene of
++ Qt Quick items at run-time.
++
++ If the \c{SVG} is part of the application assets, then some of the work can be done ahead of
++ time instead, by using the \l{svgtoqml} tool. This tool produces the same scene as
++ \l{VectorImage}, but instead of building it at run-time, it creates a \c{QML} file which can
++ be included in the application project.
++
++ In this example, the \c{heart.svg} file is converted to \c{Heart.qml} automatically during
++ the build.
++
++ \snippet vectorimage/CMakeLists.txt svgtoqml
++
++ This component can be instantiated in the scene like any other Qt Quick item.
++
++ \snippet vectorimage/Main.qml svgtoqml
++
++ By using this approach, we do not need to parse the \c{SVG} file every time the application
++ is started. In addition, the \c{svgtoqml} tool can optimize and analyze the shapes, in order to
++ provide the renderer with hints that will further speed up its run-time processing.
++
++ The \l{svgtoqml} tool should be considered for the same use cases as \l{VectorImage} and should
++ be preferred whenever the \c{SVG} file is available as an asset when the application is built
++ and is not provided by the end-user of the application.
++ */