aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@qt.io>2022-11-02 09:32:43 +0800
committerMitch Curtis <mitch.curtis@qt.io>2022-11-08 14:05:15 +0800
commit649151bdcc4c2e747224d4405d3b6bb13525161d (patch)
tree0cae3e78ab0d6d7a558ad58bcb449e4d964417bd /src
parente3d601b6ba76aba0bdc55cae773c2eb435c46bf7 (diff)
QQuickNinePatchImage: fix aliasing by respecting the smooth property
When scaling with fractional values, aliasing can occur. Use the same approach as BorderImage and respect the smooth property of NinePatchImage. This property comes from QQuickImageBase, which sets it to true by default. We change QQuickNinePatchImage's default value for it to false, but this can be overridden by setting QT_QUICK_CONTROLS_IMAGINE_SMOOTH to 1. As NinePatchImage is not public API, and users would have to set the smooth property on every image (where some items contain multiple NinePatchImages), it's better to have one place to set this for all controls. [ChangeLog][Controls] The Imagine style now supports smooth scaling for 9-patch images when the QT_QUICK_CONTROLS_IMAGINE_SMOOTH environment variable is set to 1. Fixes: QTBUG-107989 Pick-to: 6.2 6.4 Change-Id: I250a041f87c0270d67af191168f7bcfbf6237925 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc3
-rw-r--r--src/quickcontrols2impl/qquickninepatchimage.cpp44
2 files changed, 46 insertions, 1 deletions
diff --git a/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc b/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc
index f6fe5a970a..411c6c1088 100644
--- a/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc
+++ b/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc
@@ -53,5 +53,8 @@
\note Due to a technical limitation, the path should not be named
\e "imagine" if it is relative to the \c qtquickcontrols2.conf file.
+ \li \c QT_QUICK_CONTROLS_IMAGINE_SMOOTH
+ \li Set to \c 1 to enable smooth scaling for 9-patch images.
+ This environment variable was added in Qt 6.5.
\endtable
//! [env]
diff --git a/src/quickcontrols2impl/qquickninepatchimage.cpp b/src/quickcontrols2impl/qquickninepatchimage.cpp
index 48a892f812..3f8a9e03e9 100644
--- a/src/quickcontrols2impl/qquickninepatchimage.cpp
+++ b/src/quickcontrols2impl/qquickninepatchimage.cpp
@@ -54,6 +54,9 @@ QList<qreal> QQuickNinePatchData::coordsForSize(qreal size) const
return coords;
}
+/*
+ Adds the 0 index coordinate if appropriate, and the one at "size".
+*/
void QQuickNinePatchData::fill(const QList<qreal> &coords, qreal size)
{
data.clear();
@@ -174,6 +177,31 @@ public:
QQuickNinePatchData yDivs;
};
+/*
+ Examines each pixel in a horizontal or vertical (if offset is equal to the image's width)
+ line, storing the start and end index ("coordinate") of each 9-patch line.
+
+ For instance, in the 7x3 (9x5 actual size) 9-patch image below, which has no horizontal
+ stretchable area, it would return {}:
+
+ +-----+
+ | |
+ +-----+
+
+ If indices 3 to 5 were marked, it would return {2, 5}:
+
+ xxx
+ +-----+
+ | |
+ +-----+
+
+ If indices 3 and 5 were marked, it would store {0, 2, 3, 4, 5, 7}:
+
+ x x
+ +-----+
+ | |
+ +-----+
+*/
static QList<qreal> readCoords(const QRgb *data, int from, int count, int offset, QRgb color)
{
int p1 = -1;
@@ -182,12 +210,16 @@ static QList<qreal> readCoords(const QRgb *data, int from, int count, int offset
int p2 = from + i * offset;
if (data[p2] == color) {
// colored pixel
- if (p1 == -1)
+ if (p1 == -1) {
+ // This is the start of a 9-patch line.
p1 = i;
+ }
} else {
// empty pixel
if (p1 != -1) {
+ // This is the end of a 9-patch line; add the start and end indices as coordinates...
coords << p1 << i;
+ // ... and reset p1 so that we can search for the next one.
p1 = -1;
}
}
@@ -195,6 +227,12 @@ static QList<qreal> readCoords(const QRgb *data, int from, int count, int offset
return coords;
}
+/*
+ Called whenever a 9-patch image is set as the image's source.
+
+ Reads the 9-patch lines from the source image and sets the
+ inset and padding properties accordingly.
+*/
void QQuickNinePatchImagePrivate::updatePatches()
{
if (ninePatch.isNull())
@@ -299,6 +337,8 @@ void QQuickNinePatchImagePrivate::updateInsets(const QList<qreal> &horizontal, c
QQuickNinePatchImage::QQuickNinePatchImage(QQuickItem *parent)
: QQuickImage(*(new QQuickNinePatchImagePrivate), parent)
{
+ Q_D(QQuickNinePatchImage);
+ d->smooth = qEnvironmentVariableIntValue("QT_QUICK_CONTROLS_IMAGINE_SMOOTH");
}
qreal QQuickNinePatchImage::topPadding() const
@@ -432,6 +472,8 @@ QSGNode *QQuickNinePatchImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNode
QSGTexture *texture = window()->createTextureFromImage(image);
patchNode->initialize(texture, sz * d->devicePixelRatio, image.size(), d->xDivs, d->yDivs, d->devicePixelRatio);
+ auto patchNodeMaterial = static_cast<QSGTextureMaterial *>(patchNode->material());
+ patchNodeMaterial->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
return patchNode;
}