aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickvectorimage
Commit message (Collapse)AuthorAgeFilesLines
* doc: Remove references to Lottie VectorImage backend being TPEskil Abrahamsen Blomfeldt3 days1-5/+4
| | | | | | | | Lottietoqml and the corresponding VectorImage backend are no longer in tech preview in Qt 6.11. Change-Id: I73647ff0d1df263b314b0535d988823b44afa34b Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* qml generator: add functionality for animated (morphing) pathsEirik Aavitsland6 days7-9/+219
| | | | | | | | | | | | | | | | | Add a new Path item to the Helpers module: pathInterpolated, that holds a list of paths (specified as svg path texts) and has a settable interpolation factor property. Based on the value factor, the resulting path will be an interpolation between path #n and path#n+1, where n is the integer part of the factor. The fractional part determines the interpolation weight between the two. Replace the static QPainterPath in PathNodeInfo with an animated property holding QPainterPath values. During generation, if the property is found to be animated, a PathInterpolated item is generated instead of a static PathSvg item. Change-Id: Ic061005e135cbde1bd88ab1ac7c9e7840f55c232 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* VectorImage: Add support for offset path animationsEskil Abrahamsen Blomfeldt11 days5-1/+256
| | | | | | | | | This implements the offset path animation in SVG by mapping it to the PathInterpolator in Qt Quick. Task-number: QTBUG-140751 Change-Id: Ib05e32b8e5190213744c38cc2fc1ca85ef1feaac Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* Put QQuickVectorImage helper classes in namespaceEskil Abrahamsen Blomfeldt13 days2-0/+7
| | | | | | | | Avoid polluting the global namespace with these generic names. Pick-to: 6.10 Change-Id: I9126bea529789795323f1d7696f9c5490036e862 Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* qml generator: extend masking functionalityEirik Aavitsland2025-11-054-4/+12
| | | | | | | | Add support for alpha and inverted mask modes Task-number: QTBUG-137913 Change-Id: I86a58d860733abee2158788ff74ce36eef42c770 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* vectorimage: Fix transforms with constant animationsEskil Abrahamsen Blomfeldt2025-10-312-1/+22
| | | | | | | | | | | | | | | | | If an item has a "constant animation", i.e. an animation which set the transform, but which is the same for its full duration, we skip generating animations. However, these animations may be set to replace previous transforms (the default transform for instance). We add an optional branch which does this programmatically in the case where we do not generate the animations themselves. This change also defines animations that start at an offset as non-constant, since these should not be applied immediately and therefore need a PauseAnimation. Change-Id: I270b89c31093ac6e882a56f321f3fef487939038 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: Implement symbol supportEskil Abrahamsen Blomfeldt2025-10-294-3/+65
| | | | | | | | | | | This implements support for the <symbol> tag, which is like a definition node, but which defines its own coordinate system (viewbox) to make it more reusable. Fixes: QTBUG-121539 Change-Id: I5fef5ad264511bc72ff40e66cfd0c6091812b015 Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Support masked items with transformsEskil Abrahamsen Blomfeldt2025-10-221-5/+18
| | | | | | | | | | | | | | | | | | When we get the bounds for our masked item, we need the bounds of the actual shape it contains. This means we want to apply all styles except the transform, since the transform will be applied to the ShaderEffect item later on. All the other styles might affect the content bounds. We could perhaps solve this by adding a contentBounds() to QSvgNode, which returns the bounds untransformed, but for now we just apply the inverted transform to the rect afterwards to cancel the effect. This of course means that if you set a degenerate transform on the item, it will not work correctly, but that implies that you are scaling one of the axes by 0, so this is theoretical corner case. Fixes: QTBUG-141168 Change-Id: I3221e599cf4bfe48733173ecb13e28058066b19c Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* QML generator: Avoid creating empty animationsEirik Aavitsland2025-10-171-1/+8
| | | | | | | | | | | | | | | | | When generating qml for an animated transform, we check for each property if the value actually changes, and if not, we generate just constant property assignment instead of an item to be animated. If it turns out that the whole transform is constant, we would still generate the animation block, but it would contain no actual value animations. This is both redundant, and would cause a warning message if the whole generated scene was paused ("setPaused() cannot be used when animation isn't running"). Fix by only generating the animation block if any of the transform property values is non-constant. Change-Id: Iec9c7b580ab6245c46d6de8693f8c83a170d5049 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* VectorImage: Fix offset transformation of use nodesEskil Abrahamsen Blomfeldt2025-10-163-4/+10
| | | | | | | | | | | | | | | | | | | Instead of just using transform property itself for this, the <use> node in SVG has an additional offset property which is documented to be a "final offset transformation". We would previously apply this as the x and y coordinates of the item in the generated Qt Quick code, which works when there is no other transform on the item (or the only transform is another translation). But since the x and y is applied before the other transforms, if we scale, rotate, etc. the coordinate system, then we would get the wrong position. Pick-to: 6.10 Change-Id: I72b05439c06619231cfc5d4ba5a639e06d7aa184 Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: add missing includeSamuli Piippo2025-10-091-0/+1
| | | | | | | | | | | Amend f4dc2cf06bb816a0cf75e9b7e01bfdb6c3b1e16d and include for QSet to fix: | src/quickvectorimage/generator/qquickqmlgenerator_p.h:159:19: error: field ‘m_generatedIds’ has incomplete type ‘QSet<QString>’ | 159 | QSet<QString> m_generatedIds; | | ^~~~~~~~~~~~~~ Change-Id: I492ace0646810290fe144f5620741e248e22fe18 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* QML Generator: Fix transform reference and improve layer handlingEirik Aavitsland2025-10-082-16/+9
| | | | | | | | | | | | | | | The recent mask commit mistakenly removed the generation of (layer) transform references; this commit adds that back. That commit also moved the generation of ids to the visitors. Hence we can simplify the transform reference handling by just relating to those ids, and drop the special layer number handling. As a driveby, improve flexibility by replacing the hardcoded "LayerItem" with a settable customItemType input field. Change-Id: I694a7f5b274e8e114ea9a59f5331954a3e94b290 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* VectorImage: Support basic masksEskil Abrahamsen Blomfeldt2025-09-3010-99/+490
| | | | | | | | | | | | | | | | This implements support for SVG masks with the default content unit type. The alternative "object bounding box" content unit type is still not supported as it would need additional logic to replicate the mask per masked item. With this change, the parser has to provide a unique ID for each node, so that references to masks can be resolved by the parser. This involves some complexity in the SVG parser to avoid name collisions for use nodes, switch nodes, etc. Task-number: QTBUG-121537 Change-Id: If9f47f364f8682ab6021e7f6277c480c3f075297 Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* VectorImage: Don't depend on implicit QMap includeFabian Kosmale2025-09-181-0/+1
| | | | | | Change-Id: I84881eca74ebd0876deafedc7498dc3cafdc6474 Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Fix Android deployment of VectorImage pluginsEskil Abrahamsen Blomfeldt2025-09-171-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | When selecting which files to automatically bundle in an Android package, we look at the dependencies of the app and try to infer which libraries are needed. For plugins, which specific ones will be loaded is determined at runtime, so we include any category of plugin that is used by one or more of the application's dependencies. This is done by setting the PLUGIN_TYPES of the module. If the application depends on this module, it will then include all plugins of said type. For instance, Qt Gui includes all "imageformats". For vectorimageformats, we had put this dependency on the VectorImage import, but since this is loaded at runtime, the deployment tool was not able to determine the dependency on it. We instead make it a dependency of Qt Quick instead. VectorImage is technically a part of Qt Quick and any app depending on it may want to load vector image formats. Task-number: QTBUG-140187 Pick-to: 6.10 Change-Id: I2ab42a6c23710a97936ae39ace47b19411e2c6a8 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
* vectorimage: Add dependency on QtQuick.ShapesEskil Abrahamsen Blomfeldt2025-09-171-0/+1
| | | | | | | | | | | | The generated code may (and will) depend on QtQuick.Shapes, but this cannot be determined by the Android deploy tool without some help. This adds a dependency on that module so that you don't have to manually add it to your own QML code. Pick-to: 6.10 Task-number: QTBUG-140187 Change-Id: Id888407345d3c1932d3200d540aa7d2b56ef228f Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Add ShapePath.cosmeticStrokeShawn Rutledge2025-09-121-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QSvgRenderer already obeys the QPen::isCosmetic() setting. Now we add a ShapePath.cosmeticStroke property and try to support cosmetic stroking both with SVG and with Shapes, in all renderers. The curve renderer now starts with skinny triangles: each segment's end vertices are passed to the vertex shader with their original positions, and the shader uses the normal and the stroke width to expand the stroke triangles outwards as needed. We always add triangles for end caps, regardless whether they are square or round. We get rid of addBevelTriangle and fix bevels, square caps and miters: All three of these cases are done by drawing lines adjusted to the right direction within the respective triangles. And to avoid seeing rounded ends at any reasonable zoom level, we need the line equation coefficients to take the line very far outside the actual triangles. Square caps are really square: we render line segments in those three triangles, not extensions of the adjacent curve or line. Miters are also rendered as straight tangent lines. The bevel's triangle is very short when the join is an acute angle, and almost as tall as the full stroke width when the join is very obtuse. But when the triangle is short, we need to diminish the stroke width rendered in the fragment shader so that the center of the stroke falls on the inner corner of that triangle, and the edge of the stroke is rendered along the outer bevel edge rather than trying to go outside. That's achieved by multiplying the stroke width by the cosine of half the total angle, AKA the dot product. That is now in the normalExt.z vertex attribute. Normals (normalExt.xy) can be premultiplied rather than normalized: in fact some of them already have length > 1. In qsgbatchrenderer, Renderer::prepareAlphaBatches() breaks batches when overlaps occur. Now that we stroke lines with vertices that represent them as zero-width lines (and thus Element.bounds has the same x or y coordinates on both corners), we must consider lines right on top of each other to be overlapping: e.g. the stacks of horizontal (dashed) line segments in paint-stroke-202-t.svg must be in separate batches. At the time QQuickShape::updatePaintNode() is called, the available transform node (from UpdatePaintNodeData or an individual node's parent which is a transform node) does not contain the scaling factor that we need to allow for the stroke width to be adjusted for cosmetic stroking. But in QQuickShapePrivate::sync(), windowToItemTransform() is known, and from bde55ad574ac84440e2cdc9c1122a344bb1cb67a we have a precedent in QSGCurveStrokeMaterialShader::updateUniformData() for using the square root of the matrix determinant as a scaling approximation (ok when the scaling is uniform). QQuickShapeSoftwareRenderer::setNode() was already adjusting a path's bounding rect by its stroke width, and we need a multiplicative factor there to account for cosmetic stroking, to avoid excessive clipping in the software renderer. So now we have another use for the triangulationScale that was introduced in bcfcaeb87be783d8c329b0bc96323f1c9863982d. When QQShapeGenericRenderer is used (rendererType == GeometryRenderer), and any ShapePath has cosmeticStroke, we need it to re-triangulate whenever scale changes. QQuickShapeGenericRenderer::triangulateStroke() calls QTriangulatingStroker::setInvScale(1 / triangulationScale), and QTriangulatingStroker::process() multiplies its m_width by the inverse scale that was set (since 2009). So this tells us that the intended meaning of triangulationScale is the inverse of the factor by which we multiply the pen width. And when QQShapeGenericRenderer is in use, and there are cosmetic strokes, QQuickShape::itemChange triggers re-triangulation on changes in scale. When setting the QQuickShapeCurveRenderer::DebugWireframe debug visualization flag, we need to repeat the vertex shader calculations to expand the "skinny" triangles according to stroke width, just as we do with the actual stroking vertices. For now customTriangulator2 remains as legacy code, to be removed later on. It's poorly named, and returns a list of TriangleData which need to be iterated afterwards ("fix it in post"), looking up the QQuadPath::Element again in that second loop, which can go wrong when a path contains a move command. (For example, it could calculate a bevel between the end-tangent of one subpath and the start-tangent of the next.) customTriangulator2() was called from only one place, processStroke(), to which addStrokeTriangleCallback() is given: so the new way is to just call the callback directly as soon as we've calculated each triangle. Because we are not iterating again afterwards, the switch(type) is not needed in that case, and we no longer need TriangleData::type, except for supporting customTriangulator2(). [ChangeLog][QtQuick][Shapes] ShapePath now has a cosmeticStroke property which causes strokeWidth to be constant despite scaling. Set the environment variable QT_QUICKSHAPES_STROKE_EXPANDING to 1 to enable an experimental method of expanding strokes in the vertex shader, minimizing the need to re-triangulate when strokeWidth changes. Task-number: QTBUG-124638 Change-Id: I4eac0ddcd6f623b79bc70c766ff116f4b77736cb Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* QML generator: optimize by sharing custom easing curve objectsEirik Aavitsland2025-09-062-3/+14
| | | | | | | | | | | | | Real world cases will commonly have only a few different easing curves that are used many times. Instead of creating many copies of identical custom easing curves, created shared ones at the top level and just refer to those. Pick-to: 6.10 Task-number: QTBUG-139594 Change-Id: I6e91d3b3435cece58158fa595f391ca04176140b Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* QML generator: minor optimization of transformsEirik Aavitsland2025-09-061-3/+8
| | | | | | | | | Just a basic translation is a pretty common transform in real world samples. No need to trigger a full matrix4x4 multiplication for that. Pick-to: 6.10 Change-Id: Iab84da5dd2983b0da55cbe081b84692b20053fee Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* QML generator: Skip generating invisible path itemsEirik Aavitsland2025-08-211-1/+3
| | | | | | | | | | This was already done for the fill-only and stroke-only cases. This patch adds it for the fill-and-stroke case. This shaves another few percents off the size of some of the test files. Pick-to: 6.10 Change-Id: I354b3df6c9fe073d61a83d87eda7f4b4abd9f3da Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* QML generator: improve detection of constant animationsEirik Aavitsland2025-08-181-1/+5
| | | | | | | | | | It can happen that also animations with more than 2 registered frames turn out to have a constant value, and thus can be simplified. Improve the detection function to cover also such cases. Pick-to: 6.10 Change-Id: I7f95e0371be6d36bcebff01a99ffa0cd226b54ef Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* QML generator: lighten produced qml by skipping constant animationsEirik Aavitsland2025-08-142-15/+59
| | | | | | | | | | | | | | | | | | In animated transforms, it is common that only 1-2 of the properties (scale/translate/rotate/anchor) are actually animated, while the rest have constant, and often default, values. To lighten the generated qml code somewhat, this patch skips generating Animation items for constant value properties. In particular, it skips animating the center/origin point of rotations when not needed. And for properties with constant default values, the entire Transform object is skipped. Depending on the inpu, this saves 10-50% of the size of the generated qml, and correspondingly saves loading time and processing load. Fixes: QTBUG-139076 Pick-to: 6.10 Change-Id: I151164b63356b0fd3b15cfcdc8d163f835d46fde Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* vectorimage: Use ScriptAction instead of zero duration animationEskil Abrahamsen Blomfeldt2025-07-312-107/+135
| | | | | | | | | Using a zero duration animation is a bit hacky and there's no need for it. Instead we just set the value direction in a script. Pick-to: 6.10 Change-Id: Ia23f8aadc73a2aed3e1dd9521d160adb0fa6399e Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* doc: Expand VectorImage docs to include information about LottieEskil Abrahamsen Blomfeldt2025-07-301-6/+18
| | | | | | | | | | | There is now a plugin in the Qt Lottie repository which VectorImage will use if the assumeTrustedSource property is set to true. This needs to also be documented in VectorImage. Pick-to: 6.10 Change-Id: Id5f07842631a0794fef47bb29487cb08f398faa1 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Implement support for easingEskil Abrahamsen Blomfeldt2025-07-283-3/+31
| | | | | | | | | | | | | This allows the parser to provide easing information per frame in the form of a bezier curve. This should allow specifying any of the typical bezier curves, although mapping the default ones to enums at one point in the future may make sense as an optimization. Pick-to: 6.10 Task-number: QTBUG-135695 Change-Id: I5bff5ccce33fb3b6300a87f5ea8c52d2cf8ded7e Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Add internal enabler for getting parent item of vectorimage generatorEskil Abrahamsen Blomfeldt2025-06-261-0/+5
| | | | | | | | | This will be used by the Lottie plugin for accessing the hierarchy of items after they have been generated. Pick-to: 6.10 Change-Id: I623fd3d80e42e43f17c28f0e52effae16b8ba633 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Add private plugin architecture to VectorImageEskil Abrahamsen Blomfeldt2025-06-196-57/+122
| | | | | | | | | | | | This will allow us to load Lottie files by creating a plugin in the Lottie module. The plugins are currently only queried if the opt-in "trusted content" flag is set. Pick-to: 6.10 Fixes: QTBUG-135266 Change-Id: I4901636e41f3bb73a78cbceb312f6cad9e96c5d2 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* Work around component name clash for multiple VectorImagesEirik Aavitsland2025-06-013-27/+35
| | | | | | | | | | | | | | The qml generator would create a child component to group the animation properties. This now causes qml engine failures if there are multiple VectorImage items. Work around by dropping the grouping component and just place the animation properties in the top level item directly if the QML generator is going to be used from VectorImage. Change-Id: I77ac9029093f3259aef9357c056da42f09974763 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Add assumeTrustedSource property to VectorImageEskil Abrahamsen Blomfeldt2025-05-307-5/+52
| | | | | | | | | Certain checks and restrictions are in effect by default on the SVG parser. This introduces a way for disabling these in the VectorImage, when it is used with trusted content. Change-Id: I7a11c7276a01ae9eb128ed0afb2a04c38fe90c7a Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: Prepare for separate helpers import for non-svg formatsEirik Aavitsland2025-05-285-107/+16
| | | | | | | | In particular, remove the Layer helper item, which will be added to a qtlottie helpers import instead. Change-Id: I9df98fc5bd983dd13822b62655e65f7f1093f4ca Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* qquicktransformgroup: change transitive include to an explicit oneFabian Kosmale2025-05-221-0/+1
| | | | | Change-Id: I702ddfa549a7fadee423628f576dfff4083448a7 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Android: fix comparison of different signed integersRami Potinkara2025-05-201-1/+1
| | | | | | | | | | This patch fixes the comparison of different signed integers on Android x86 architecture. Fix introduces q20::cmp_greater_equal to be used. Fixes: QTBUG-136969 Change-Id: I6ec17c3604b82266cfd7a68f7f5505360b6a65c6 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
* Avoid redundant property Animation stepsEirik Aavitsland2025-05-201-97/+111
| | | | | | | | | Animation steps that do not actually modify the property value are replaced with just a PauseAnimation. Significantly reduces the number of lines in the output. Change-Id: I281acb123e664ed21e63c5a94ac65dc30e4de1fa Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Support replace animationsEskil Abrahamsen Blomfeldt2025-05-196-175/+414
| | | | | | | | | | | | | SVG has a feature where a set of animations on the transform can be set to either replace or append to previous animations, but only while the animation set is active. In order to support this, we introduce a helper class called TransformGroup which can contain a set of parallel animations and have them override the others. Change-Id: I28be7d120527b1f2d1e3dbf5c5de94094c766363 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: Support transform referencesEirik Aavitsland2025-05-165-27/+157
| | | | | | | | | | | | The Lottie file format has a feature where a layer can have the transform of another layer (including any transform set on one of its ancestors) as its base. This means that we need a specialized helper type that collects the transforms of its ancestors and exposes the combination so that it can be referenced from a different part of the generated QML. Change-Id: I20b72cb9b9af2834f40f391ecb8df7bb0c5e1958 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Support items that are visible for specific durationsEskil Abrahamsen Blomfeldt2025-05-162-20/+36
| | | | | | | | | This is a feature in Lottie, where layers pop into existence and pop out later on. We do this by animating the visibility of the item. Change-Id: Ieebab4e84f9254976b0de9759a1f0f4c8026210e Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Add API to VectorImage for controlling animationsEskil Abrahamsen Blomfeldt2025-05-146-29/+214
| | | | | | | | | | | | | | | | | | | | | A lot of animations will just be a single time line that you is intended to be controlled from the outside (and formats like Lottie does not support anything beyond this), so we need some API to match the general Animation API so that you can restart, pause/resume and change the number of times an animation loops. We do this by adding a group of properties called "animations" that can be used to control all the animations in the document at once. We generate this both in the QML file from *toqml and also in VectorImage itself. [ChangeLog][QtQuickVectorImage] Added some API to the VectorImage for looping, stopping, pausing and resuming animations. Fixes: QTBUG-135265 Change-Id: Id372c00110d165d02db357ce77eb1dec504cffb8 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Add path trimming to quick vector graphics generatorsEirik Aavitsland2025-05-132-0/+22
| | | | | Change-Id: I8364e33cb2bffd528e73c1fd1e46fa8b3663e951 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Support fill-opacity and stroke-opacity in VectorImageEskil Abrahamsen Blomfeldt2025-04-307-9/+232
| | | | | | | | | | | | | | | | | | | | The alpha value of the fill and stroke colors can be animated separately in SVG. In order to support this, we introduce a specialized ColorOpacityAnimation type in a Helpers library which only overwrites the alpha channel of the target property. This requires an extra hook in the animation frame work which allows us to get the current value of the property. It should have minimal impact on any existing code, but may have additional use cases later, when we implement support for additive color animations for instance. Since the interpolator API in QVariantAnimation is public API, we add a secondary, private API for this. If we see use for it in the future, this could mature to a public API as well. Fixes: QTBUG-135322 Change-Id: I803f4e64c41e9d6dc355f2468233661885aa7f15 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Adapt to refactor of transform anims in Qt SvgEskil Abrahamsen Blomfeldt2025-04-292-42/+88
| | | | | | | | | In order to correctly support transformation order, we needed a refactor in Qt Svg. We need to adapt to this and apply the animations in the correct order in Qt Quick. Change-Id: I38e323f95b7edc26fd8d78ebd98778c3da1adbea Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* QQuickItemGenerator: Add missing includes/forward declarationsFabian Kosmale2025-04-162-0/+2
| | | | | Change-Id: I957b800ce4fca00f846ae5c567e84b72b6fc0401 Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* qml: remove unused headerZhao Yuhang2025-04-131-1/+0
| | | | | | | These headers don't use std::pair at all. Change-Id: I1c5c5974949ada2e05151e238884ce4f12156b5f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Port away from QPairZhao Yuhang2025-04-123-3/+3
| | | | | | | | QPair is just an alias of std::pair anyway. Task-number: QTBUG-115841 Change-Id: I26fc90adcc775aac9955ad57304af914dc4ed48f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Implement item generator via QML generatorEskil Abrahamsen Blomfeldt2025-04-115-715/+62
| | | | | | | | | | | | | | | | | We were spending time doing the same implementation twice, since the item generator and QML generator were two separate code paths. We also risked having bugs which only occurred in one of the code paths. This may at some point be a valid optimization, but during development it is premature. The parsing of the QML is a one-time cost when loading the SVG and this is an acceptable cost for now. Optimizations can come later when we have a more stable state. Fixes: QTBUG-135269 Change-Id: I649a89d7a2e18ef1c0213658dc106f2cc1194841 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* QQuickAnimatedProperty: Add missing includeFabian Kosmale2025-04-101-0/+1
| | | | | Change-Id: I35a01ad834ad701be8c99334dc4ee5063eac0ce8 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Port transform animations to animated property systemEskil Abrahamsen Blomfeldt2025-04-107-498/+386
| | | | | | | | | | | | | | | Move away from the complex attempt at creating a single animation out of the key frames and instead pass each animation into Qt Quick. While this will fix some things, it may also regress for some cases of overlapping conflicting animations since we now just depend on the Qt Quick behavior there. If we see the need to support these cases, then we probably need a special ParallelAnimation type that allows modifying how the changes are applied based on which animations are active. Change-Id: I0c0ff867cd5917b19318ebe241a1ab8a9c1c8156 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Animate opacity propertyEskil Abrahamsen Blomfeldt2025-04-104-22/+18
| | | | | | | | Use the new generalized animations to implement support for opacity animations. Change-Id: Id758942d383f71b08ffc514fa5341e13194deaca Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* Change the way we do color animationsEskil Abrahamsen Blomfeldt2025-04-049-201/+378
| | | | | | | | | | | | | | | | | | | | | | | | We need a generalized way of doing animations to simplify adding animations for other properties. In order to be as expressive as possible we need to just pass the animation info on to the generator and let it handle it. If there are multiple animations affecting the same property at the same time, we just instantiate them in Qt Quick and let its engine handle the conflict. This means that the only way to implement special SMIL conflict behavior such as add/replace is to create specialized animation classes in Qt Quick. We can do this at a later stage if it becomes a priority. The main use case of having multiple animations affecting a property at different times should be covered by this implementation, it should be easy to expand to new types, and it should be easy to add stuff like easing curves to it. Change-Id: I927ea2cef214a300ae8fae3f76ee87fb5d505b3d Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* vectorimage: Fix possible QML error with miterlimitEskil Abrahamsen Blomfeldt2025-04-041-2/+2
| | | | | | | | | | | | | The miterLimit in Qt Quick Shapes is an int, so if we generate fractional numbers in the QML file, that will lead to a parser error. This was reproducible by running svgtoqml on paint-stroke-07-t.svg. Pick-to: 6.8 6.9 Change-Id: Ia03cbba7f70f687dc93ac20b86314dae1fbc30d3 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* vectorimage: Fix identical gradient stops in qml generatorEskil Abrahamsen Blomfeldt2025-04-041-2/+4
| | | | | | | | | | | | | | | | | | | | | | In SVG, two subsequent identical gradient stops means a hard transition to the color of the second at that position. However, this is not the case in Qt and because of the way we sort the gradient stops, the order of the two identical stops will be wrong. This is addressed by adding an epsilon to identical stops in Qt Svg, but the epsilon is FLT_EPSILON, which is around 1e-7. The default output precision for doubles in Qt is 6, so when storing the numbers to file, the epsilon would be lost, the two positions would be considered identical and the reordering would happen. This caused a visual error when running svgtoqml on the paint-grad-16-t.svg test. Pick-to: 6.8 6.9 Change-Id: I857958512c3de7dc843a705893b4c2d7d2a36fd4 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>