diff options
| author | Kwanghyo Park <kwanghyo.park@qt.io> | 2026-09-09 07:11:07 +0300 |
|---|---|---|
| committer | Kwanghyo Park <kwanghyo.park@qt.io> | 2026-09-14 14:27:25 +0000 |
| commit | bd44240ab368f094860b8327673add261510dacc (patch) | |
| tree | 0a63c250ebe34bef77371ddb8e06f5bdd59c3426 | |
| parent | 72baa4b0ad665aba4d527241ddbf305a070fe907 (diff) | |
quickvectorimage: honor bounds references in the item generator
A node can state its bounds as a reference to another node rather than
as a rectangle of its own, but the item generator only read the
rectangle.
Resolve the reference against the bounds the referenced node was given.
Task-number: QTBUG-147743
Change-Id: I943fc4df2a356e9d9764e6eb770f9d95478f8cc3
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
| -rw-r--r-- | src/quickvectorimage/generator/qquickitemgenerator.cpp | 47 | ||||
| -rw-r--r-- | src/quickvectorimage/generator/qquickitemgenerator_p.h | 4 |
2 files changed, 41 insertions, 10 deletions
diff --git a/src/quickvectorimage/generator/qquickitemgenerator.cpp b/src/quickvectorimage/generator/qquickitemgenerator.cpp index 6c5b84d5c5..a06a4a3c20 100644 --- a/src/quickvectorimage/generator/qquickitemgenerator.cpp +++ b/src/quickvectorimage/generator/qquickitemgenerator.cpp @@ -204,10 +204,27 @@ QQuickItem *QQuickItemGenerator::currentItem() const return m_itemStack.isEmpty() ? nullptr : m_itemStack.top(); } -QString QQuickItemGenerator::generateNodeBase(const NodeInfo &info, const QString &idSuffix) +QRectF QQuickItemGenerator::resolveBounds(const NodeInfo &info) const { - Q_UNUSED(idSuffix) + if (!info.bounds.isNull()) + return info.bounds; + + if (info.boundsReferenceId.isEmpty()) + return {}; + return m_bounds.value(info.boundsReferenceId); +} + +void QQuickItemGenerator::registerBounds(const QString &id, const QRectF &bounds) +{ + if (id.isEmpty() || bounds.isNull()) + return; + + m_bounds.insert(id, bounds); +} + +QString QQuickItemGenerator::generateNodeBase(const NodeInfo &info, const QString &idSuffix) +{ static qint64 maxNodes = qEnvironmentVariableIntegerValue("QT_QUICKVECTORIMAGE_MAX_NODES").value_or(10000); if (Q_UNLIKELY(!checkSanityLimit(++m_nodeCounter, maxNodes, "nodes"_L1))) @@ -222,9 +239,11 @@ QString QQuickItemGenerator::generateNodeBase(const NodeInfo &info, const QStrin item->setTransformOrigin(QQuickItem::TopLeft); - if (!info.bounds.isNull()) { - item->setWidth(info.bounds.width()); - item->setHeight(info.bounds.height()); + const QRectF bounds = resolveBounds(info); + if (!bounds.isNull()) { + registerBounds(info.id + idSuffix, bounds); + item->setWidth(bounds.width()); + item->setHeight(bounds.height()); } if (info.filterId.isEmpty() && info.maskId.isEmpty()) { @@ -965,6 +984,10 @@ void QQuickItemGenerator::generateDefsInstantiationNode(const StructureNodeInfo return; } + const QRectF bounds = resolveBounds(info); + registerBounds(info.id, bounds); + registerBounds(info.defsId + "_defs"_L1, bounds); + const qsizetype pendingStart = m_pendingLinkedTransforms.size(); const QHash<QString, QQuickTransformSource *> outerSources = m_transformSourceItems; @@ -1113,9 +1136,11 @@ void QQuickItemGenerator::generateMaskContainer(const MaskNodeInfo &info) popItem(); auto *container = currentItem(); + const bool hasBoundsReference = !info.boundsReferenceId.isEmpty(); + const QRectF maskRect = hasBoundsReference ? resolveBounds(info) : info.maskRect; m_maskDefs[info.id] = { container, - info.maskRect, - info.isMaskRectRelativeCoordinates, + maskRect, + hasBoundsReference ? false : info.isMaskRectRelativeCoordinates, info.isMaskContentRelativeCoordinates, transformer, transformerMatrix }; @@ -1135,8 +1160,9 @@ void QQuickItemGenerator::generateMask(QQuickItem *item, const NodeInfo &info, const qreal w = item->width(); const qreal h = item->height(); + const QRectF resolvedBounds = resolveBounds(info); const QRectF svgBounds = - info.bounds.isNull() ? QRectF(item->x(), item->y(), w, h) : info.bounds; + resolvedBounds.isNull() ? QRectF(item->x(), item->y(), w, h) : resolvedBounds; QRectF svgMaskRect; if (maskDef.isMaskRectRelativeCoordinates) { svgMaskRect = QRectF(maskDef.maskRect.x() * svgBounds.width() + svgBounds.x(), @@ -1256,9 +1282,10 @@ QQuickItem *QQuickItemGenerator::generateFilter(QQuickItem *item, const NodeInfo return nullptr; QQuickItem *parentItem = item->parentItem(); - const QRectF itemBounds = info.bounds.isNull() + const QRectF resolvedBounds = resolveBounds(info); + const QRectF itemBounds = resolvedBounds.isNull() ? QRectF(item->x(), item->y(), item->width(), item->height()) - : info.bounds; + : resolvedBounds; QRectF filterRect = resolveRect(filterInfo.filterRect, filterInfo.csFilterRect, itemBounds); if (filterRect.isEmpty()) diff --git a/src/quickvectorimage/generator/qquickitemgenerator_p.h b/src/quickvectorimage/generator/qquickitemgenerator_p.h index 05bb169a82..6dc90d0609 100644 --- a/src/quickvectorimage/generator/qquickitemgenerator_p.h +++ b/src/quickvectorimage/generator/qquickitemgenerator_p.h @@ -120,6 +120,7 @@ private: QHash<QString, PatternDef> m_patternDefs; QHash<QString, MarkerDef> m_markerDefs; QHash<QString, FilterNodeInfo> m_filterDefs; + QHash<QString, QRectF> m_bounds; QQuickItemSpy *m_topLevelScaleSpy = nullptr; QHash<QString, QQuickTransformSource *> m_transformSourceItems; @@ -128,6 +129,9 @@ private: QStack<bool> m_scopePushed; QMap<std::array<qreal, 4>, QEasingCurve> m_easingCache; + QRectF resolveBounds(const NodeInfo &info) const; + void registerBounds(const QString &id, const QRectF &bounds); + void beginDefsRecord(const QString &id); void endDefsRecord(); void replayDefsRecord(const QString &id); |
