VectorImage: Add support for gradient/fill transforms
Handle the SVG gradientTransform and patternTransform attributes. Fixes: QTBUG-121661 Pick-to: 6.8 Change-Id: I79d85ebfef46527e2909440aaca94c975bf21a47 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Reviewed-by: Hatem ElKharashy <hatem.elkharashy@qt.io>
This commit is contained in:
parent
ab359c11e1
commit
10637de078
|
@ -161,6 +161,8 @@ void QQuickItemGenerator::outputShapePath(const PathNodeInfo &info, const QPaint
|
|||
shapePath->setFillColor(info.fillColor);
|
||||
|
||||
shapePath->setFillRule(fillRule);
|
||||
if (!info.fillTransform.isIdentity())
|
||||
shapePath->setFillTransform(info.fillTransform);
|
||||
|
||||
QString svgPathString = painterPath ? QQuickVectorImageGenerator::Utils::toSvgString(*painterPath) : QQuickVectorImageGenerator::Utils::toSvgString(*quadPath);
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ struct PathNodeInfo : NodeInfo
|
|||
QColor fillColor;
|
||||
StrokeStyle strokeStyle;
|
||||
QGradient grad;
|
||||
QTransform fillTransform;
|
||||
};
|
||||
|
||||
struct TextNodeInfo : NodeInfo
|
||||
|
|
|
@ -80,17 +80,9 @@ void QQuickQmlGenerator::generateNodeBase(const NodeInfo &info)
|
|||
} else if (info.transform.type() == QTransform::TxScale && !x && !y) {
|
||||
stream() << "transform: Scale { xScale: " << sx << "; yScale: " << sy << " }";
|
||||
} else {
|
||||
const QMatrix4x4 m(info.transform);
|
||||
{
|
||||
stream() << "transform: [ Matrix4x4 { matrix: Qt.matrix4x4 (";
|
||||
m_indentLevel += 3;
|
||||
const auto *data = m.data();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
stream() << data[i] << ", " << data[i+4] << ", " << data[i+8] << ", " << data[i+12] << ", ";
|
||||
}
|
||||
stream() << ") } ]";
|
||||
m_indentLevel -= 3;
|
||||
}
|
||||
stream() << "transform: Matrix4x4 { matrix: ";
|
||||
generateTransform(info.transform);
|
||||
stream(SameLine) << " }";
|
||||
}
|
||||
}
|
||||
if (!info.isDefaultOpacity) {
|
||||
|
@ -222,6 +214,28 @@ void QQuickQmlGenerator::generateGradient(const QGradient *grad, const QRectF &b
|
|||
}
|
||||
}
|
||||
|
||||
void QQuickQmlGenerator::generateTransform(const QTransform &xf)
|
||||
{
|
||||
if (xf.isAffine()) {
|
||||
stream(SameLine) << "PlanarTransform.fromAffineMatrix("
|
||||
<< xf.m11() << ", " << xf.m12() << ", "
|
||||
<< xf.m21() << ", " << xf.m22() << ", "
|
||||
<< xf.dx() << ", " << xf.dy() << ")";
|
||||
} else {
|
||||
QMatrix4x4 m(xf);
|
||||
stream(SameLine) << "Qt.matrix4x4(";
|
||||
m_indentLevel += 3;
|
||||
const auto *data = m.data();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
stream() << data[i] << ", " << data[i+4] << ", " << data[i+8] << ", " << data[i+12];
|
||||
if (i < 3)
|
||||
stream(SameLine) << ", ";
|
||||
}
|
||||
stream(SameLine) << ")";
|
||||
m_indentLevel -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
void QQuickQmlGenerator::outputShapePath(const PathNodeInfo &info, const QPainterPath *painterPath, const QQuadPath *quadPath, QQuickVectorImageGenerator::PathSelector pathSelector, const QRectF &boundingRect)
|
||||
{
|
||||
Q_UNUSED(pathSelector)
|
||||
|
@ -275,6 +289,18 @@ void QQuickQmlGenerator::outputShapePath(const PathNodeInfo &info, const QPainte
|
|||
} else {
|
||||
stream() << "fillColor: \"" << info.fillColor.name(QColor::HexArgb) << "\"";
|
||||
}
|
||||
|
||||
if (!info.fillTransform.isIdentity()) {
|
||||
const QTransform &xf = info.fillTransform;
|
||||
stream() << "fillTransform: ";
|
||||
if (info.fillTransform.type() == QTransform::TxTranslate)
|
||||
stream(SameLine) << "PlanarTransform.fromTranslate(" << xf.dx() << ", " << xf.dy() << ")";
|
||||
else if (info.fillTransform.type() == QTransform::TxScale && !xf.dx() && !xf.dy())
|
||||
stream(SameLine) << "PlanarTransform.fromScale(" << xf.m11() << ", " << xf.m22() << ")";
|
||||
else
|
||||
generateTransform(xf);
|
||||
}
|
||||
|
||||
if (fillRule == QQuickShapePath::WindingFill)
|
||||
stream() << "fillRule: ShapePath.WindingFill";
|
||||
else
|
||||
|
|
|
@ -78,6 +78,7 @@ protected:
|
|||
|
||||
private:
|
||||
void generateGradient(const QGradient *grad, const QRectF &boundingRect);
|
||||
void generateTransform(const QTransform &xf);
|
||||
|
||||
QStringView indent();
|
||||
enum StreamFlags { NoFlags = 0x0, SameLine = 0x1 };
|
||||
|
|
|
@ -81,6 +81,11 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
QTransform currentFillTransform() const
|
||||
{
|
||||
return m_dummyPainter.brush().transform();
|
||||
}
|
||||
|
||||
QColor currentStrokeColor() const
|
||||
{
|
||||
if (m_dummyPainter.pen().brush().style() == Qt::NoBrush ||
|
||||
|
@ -606,6 +611,8 @@ void QSvgVisitorImpl::visitTextNode(const QSvgText *node)
|
|||
if (info.grad.type() == QGradient::NoGradient && styleResolver->currentFillGradient() != nullptr)
|
||||
info.grad = styleResolver->applyOpacityToGradient(*styleResolver->currentFillGradient(), styleResolver->currentFillOpacity());
|
||||
|
||||
info.fillTransform = styleResolver->currentFillTransform();
|
||||
|
||||
m_generator->generatePath(info);
|
||||
};
|
||||
|
||||
|
@ -819,6 +826,7 @@ void QSvgVisitorImpl::handlePathNode(const QSvgNode *node, const QPainterPath &p
|
|||
info.strokeStyle.color = styleResolver->currentStrokeColor();
|
||||
if (styleResolver->currentFillGradient() != nullptr)
|
||||
info.grad = styleResolver->applyOpacityToGradient(*styleResolver->currentFillGradient(), styleResolver->currentFillOpacity());
|
||||
info.fillTransform = styleResolver->currentFillTransform();
|
||||
|
||||
m_generator->generatePath(info);
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<svg viewBox="0 0 380 800" xmlns="http://www.w3.org/2000/svg">
|
||||
<radialGradient
|
||||
id="gradient1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="100"
|
||||
cy="100"
|
||||
r="100"
|
||||
fx="100"
|
||||
fy="100"
|
||||
gradientTransform="translate(100 0)">
|
||||
<stop offset="0%" stop-color="darkblue" />
|
||||
<stop offset="50%" stop-color="skyblue" />
|
||||
<stop offset="100%" stop-color="darkblue" />
|
||||
</radialGradient>
|
||||
<radialGradient
|
||||
id="gradient2"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="100"
|
||||
cy="100"
|
||||
r="100"
|
||||
fx="100"
|
||||
fy="100"
|
||||
gradientTransform="scale(2 1)">
|
||||
<stop offset="0%" stop-color="darkblue" />
|
||||
<stop offset="50%" stop-color="skyblue" />
|
||||
<stop offset="100%" stop-color="darkblue" />
|
||||
</radialGradient>
|
||||
<radialGradient
|
||||
id="gradient3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cx="100"
|
||||
cy="100"
|
||||
r="100"
|
||||
fx="100"
|
||||
fy="100"
|
||||
gradientTransform="skewX(40)">
|
||||
<stop offset="0%" stop-color="darkblue" />
|
||||
<stop offset="50%" stop-color="skyblue" />
|
||||
<stop offset="100%" stop-color="darkblue" />
|
||||
</radialGradient>
|
||||
|
||||
<rect x="0" y="0" width="300" height="100" fill="url(#gradient1)" />
|
||||
<text font-size="124" x="0" y="200" stroke="black" fill="url(#gradient1)">XLAT</text>
|
||||
|
||||
<g transform="translate(0 250)">
|
||||
<rect x="0" y="0" width="300" height="100" fill="url(#gradient2)" />
|
||||
<text font-size="124" x="0" y="200" stroke="black" fill="url(#gradient2)">SCAL</text>
|
||||
</g>
|
||||
|
||||
<g transform="translate(0 500)">
|
||||
<rect x="0" y="0" width="300" height="100" fill="url(#gradient3)" />
|
||||
<text font-size="124" x="0" y="200" stroke="black" fill="url(#gradient3)">SKEW</text>
|
||||
</g>
|
||||
|
||||
<!--
|
||||
<g font-family="Arial" font-size="92" transform="translate(50 0)">
|
||||
<text x="0" y="100" stroke="black" fill="url(#gradient1)">TEST</text>
|
||||
</g>
|
||||
-->
|
||||
</svg>
|
||||
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,25 @@
|
|||
import QtQuick
|
||||
import QtQuick.VectorImage
|
||||
|
||||
Rectangle {
|
||||
id: topLevelItem
|
||||
width: 800
|
||||
height: 800
|
||||
|
||||
ListModel {
|
||||
id: renderers
|
||||
ListElement { renderer: VectorImage.GeometryRenderer }
|
||||
ListElement { renderer: VectorImage.CurveRenderer }
|
||||
}
|
||||
|
||||
Row {
|
||||
Repeater {
|
||||
model: renderers
|
||||
|
||||
VectorImage {
|
||||
source: "../shared/svg/gradientxform.svg"
|
||||
preferredRendererType: renderer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue