aboutsummaryrefslogtreecommitdiffstats
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-12-09 15:25:14 +0800
commit361d4bdf548cae2c56d681f550b185bbad7e3ba8 (patch)
treef0376a544b1c255c5793592466ed9851d97edab0
parenta3759ce6aa208a7b59d7f22247935c17c5fb9ad3 (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 Change-Id: I250a041f87c0270d67af191168f7bcfbf6237925 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> (cherry picked from commit 649151bdcc4c2e747224d4405d3b6bb13525161d) Reviewed-by: Paul Wicking <paul.wicking@qt.io>
-rw-r--r--src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc2
-rw-r--r--src/quickcontrols2/imagine/impl/qquickninepatchimage.cpp44
2 files changed, 45 insertions, 1 deletions
diff --git a/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc b/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc
index f6fe5a970a..36297e9080 100644
--- a/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc
+++ b/src/quickcontrols2/doc/src/includes/qquickimaginestyle.qdocinc
@@ -53,5 +53,7 @@
\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.
\endtable
//! [env]
diff --git a/src/quickcontrols2/imagine/impl/qquickninepatchimage.cpp b/src/quickcontrols2/imagine/impl/qquickninepatchimage.cpp
index 33de94f3d5..7d0790240d 100644
--- a/src/quickcontrols2/imagine/impl/qquickninepatchimage.cpp
+++ b/src/quickcontrols2/imagine/impl/qquickninepatchimage.cpp
@@ -87,6 +87,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();
@@ -207,6 +210,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;
@@ -215,12 +243,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;
}
}
@@ -228,6 +260,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())
@@ -332,6 +370,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
@@ -465,6 +505,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;
}