aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickvectorimage
Commit message (Collapse)AuthorAgeFilesLines
* VectorImage: Support CSS easing curvesHatem ElKharashy33 hours2-1/+43
| | | | | | | | | | | | Supports linear and any cubic bezier based easing curves supported by Qt Svg. For the current time being, whenever the easing curve is set to a step function in Qt Svg, we revert to the default value which is the "ease" keyword in CSS. Pick-to: 6.11 Task-number: QTBUG-142333 Change-Id: Ifb6b3a2dfe955b5a247399e201efe0d7877bf235 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Docs: fix various linksVolker Hilsheimer37 hours1-3/+4
| | | | | | | | | Use the correct syntax for the scope of the link target for Qt Quick types. Pick-to: 6.11 Change-Id: Ica96c1b736a9b8ddd29a63c21d6a7094bd598ed8 Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
* VectorImage: Fix compilation after Qt Svg changesHatem ElKharashy4 days2-7/+7
| | | | | | | | | | Qt Svg has renamed QSvgTinyDocument to QSvgDocument. The name now better reflects the implementation and the required changes in Vector Image are done in this commit. Pick-to: 6.11 Change-Id: Ib558cc622b325575e24c9028d98134e4321416f7 Reviewed-by: Robert Löhning <robert.loehning@qt.io>
* VectorImage: Parse contents in separate QML contextEskil Abrahamsen Blomfeldt7 days2-1/+5
| | | | | | | | | The generated QML does not need access to the VectorImage's context, since it is self-contained. Pick-to: 6.10 6.11 Change-Id: I61b12aaf5c3abcfe4c21057a28f46f9d85c2054a Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: Escape quotes in font familiesEskil Abrahamsen Blomfeldt8 days2-5/+10
| | | | | | | | | | | | Loading SVG files that use font families with quotes will produce invalid output that does not parse correctly. When outputting the font family, we have to escape the quotes first. In addition, any character in the font family has to be valid HTML when we output it into a style tag. Pick-to: 6.8 6.10 6.11 Change-Id: If25b3cfd3a537d7f7c8c65045deece1ad02b43c3 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: Sanitize source string used in outputEskil Abrahamsen Blomfeldt8 days1-3/+22
| | | | | | | | | | | | | Source string is used as object name in output, so we sanitize it to make sure it does not contain illegal characters. SVG already mandates a limited character set here, but rather than trust the parser we sanitize before passing to the generator like the Lottie visitor does. Fixes: QTBUG-142556 Pick-to: 6.8 6.10 6.11 Change-Id: I0684e726ab69a0735dcb5f91369b090d58a90b7b Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: Add dependency on QtQuick.EffectsEskil Abrahamsen Blomfeldt12 days1-1/+1
| | | | | | | | | | | | | | This amends 39ec01eec2b5262cb60f5c266d5f4107aae7e415. On Android, we need to ensure implicit imports are known to the tools. When adding support for the blur effect, we also added an implicit dependency on MultiEffect, but since no one told the deployment tool, we would get a test failure when loading files. Fixes: QTBUG-142472 Change-Id: Ic2f91c9fce94a90ca05314827edb77b7f9cdec4a Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: Fix compilation after qtsvg's ligature handling fixRobert Löhning12 days1-7/+15
| | | | | | | | | | | While qtsvg now supports ligatures of multiple characters the existing code here does not yet. Fixing that is out of scope for this patch. It's only meant to keep the code working the way it did before. Pick-to: 6.10 Change-Id: Ie62d3b3d5764a6bcb3d75e6594a8729652c0dcf4 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
* Add support for feMergeEskil Abrahamsen Blomfeldt12 days6-7/+123
| | | | | | | | We support merging up to 8 effects for now. Task-number: QTBUG-121541 Change-Id: Ic60400f054700e4ff44452870770b2175834dd85 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: Post processing effect chainingEskil Abrahamsen Blomfeldt12 days8-58/+661
| | | | | | | | | | This introduces chaining post-processing effects, and the feComposite and feBlend nodes to allow compositing these. Task-number: QTBUG-121541 Change-Id: Ib2aa99139869814a575a2bf9d9e6319b31828285 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* VectorImage: Add support for more filtersEskil Abrahamsen Blomfeldt12 days5-53/+311
| | | | | | | | | | | | | | | | | | This adds support for the feColorMatrix, feOffset and feFlood filters. We also need to change how we calculate the bounds of post-processed items to use the internal bounds. Basically, we need the bounds of the children of the item + the item itself before the node's transform is applied. This is because the bounding box is axis aligned, so we cannot get the original rectangle back just by applying the inverse transform in the case of e.g. rotations. Task-number: QTBUG-121541 Change-Id: I7a8863bef4397df4043c854256dca312b91f888a Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* VectorImage: fix creation of easingCurve typeHatem ElKharashy12 days1-2/+2
| | | | | | | | | | commit : 1f51dc291c0763453f6a3230c8eb79a28892870f introduced a way to share custom easing curve objects among different animations. However, the easingCurve type was not constructed properly leading to the animation falling back to linear easing. Change-Id: I5a0ce2bd513ba2c24f9554a46547c479f2a2d021 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Traverse certain tags inside <defs>Eskil Abrahamsen Blomfeldt13 days2-1/+48
| | | | | | | | | | | | | | | | We currently skip <defs> tags because any shape in there will be re-traversed later when the <use> tag is handled. But the <defs> may also contain non-graphical elements such as <filter> and <mask>. Long term, we should update our approach to <defs> by using the Component mechanism in QML. For now, we make a special case for <defs> tags to ensure that we traverse generate content for masks and filters even if they are declared inside a <defs>. Fixes: QTBUG-123991 Task-number: QTBUG-121541 Change-Id: I5f6e10962383528d3bc8fbe21ced2d79e557d8e5 Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* VectorImage: Fix opacity on individual shapesEskil Abrahamsen Blomfeldt2025-12-021-0/+3
| | | | | | | | | | | | | When shapes are combined into a single Shape object, the opacity information is lost. Similarly to how we handle non-default transforms on the shapes, we make sure the shapes with opacities are never combined with others. In principle, we could combine shapes with the same opacity, but for simplicity we just split them up at least until we see a strong need. Pick-to: 6.10 Change-Id: I2c8a444f9b38fc8cf66728d80b1a724f24469630 Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
* VectorImage: Implement support for gaussian blurEskil Abrahamsen Blomfeldt2025-12-026-49/+322
| | | | | | | | | | | | | | | | | This introduces support for the gaussian blur filter using the MultiEffect as an approximation. The approximation is not going to look perfect, but will perform better than doing an actual gaussian blur on the contents. Since the objective here is runtime performance, this is a reasonable trade-off. In order to make this work correctly with masks, we also refactor the mask code and now use ShaderEffectSources instead of layers in order to have full control. Task-number: QTBUG-121541 Change-Id: Idb1574a2f4d03311ab787fb4a6476b6c604c88b2 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* VectorImage: Fix opacity on masked itemsEskil Abrahamsen Blomfeldt2025-12-021-3/+6
| | | | | | | | | If the masked item has opacity != 1, we have to set this on the shader effect that applies the mask, not on the input item to the mask, same as transforms and animations. Change-Id: I87d937f51e7d1913f313968eb3cfee2855336de5 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* doc: Remove references to Lottie VectorImage backend being TPEskil Abrahamsen Blomfeldt2025-11-291-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 Aavitsland2025-11-267-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 Blomfeldt2025-11-215-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 Blomfeldt2025-11-192-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>