[graphics/krita] libs/ui: Show last valid preview when cache miss to avoid flickering or painting giberish. Zoom factor limit increase to 50x
Emmet O'Neill <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit d027f69b8f4bc4290ccf12ad88778c9450923af6 by Emmet O'Neill, on behalf of Dat Le.
Committed on 13/08/2026 at 23:16.
Pushed by emmetoneill into branch 'master'.
Show last valid preview when cache miss to avoid flickering or painting giberish. Zoom factor limit increase to 50x
From KA feature request, the author seems to like crude pixel grid. So let's allow extreme zoom factor
M +1 -1 libs/ui/dialogs/kis_dlg_preferences.cc
M +10 -5 libs/ui/tool/KisAsyncColorSamplerHelper.cpp
M +1 -1 libs/ui/tool/KisAsyncColorSamplerHelper.h
https://invent.kde.org/graphics/krita/-/commit/d027f69b8f4bc4290ccf12ad88778c9450923af6
diff --git a/libs/ui/dialogs/kis_dlg_preferences.cc b/libs/ui/dialogs/kis_dlg_preferences.cc
index f060c1259f2..28b5b585511 100644
--- a/libs/ui/dialogs/kis_dlg_preferences.cc
+++ b/libs/ui/dialogs/kis_dlg_preferences.cc
@@ -331,7 +331,7 @@ GeneralTab::GeneralTab(QWidget *_parent, const char *_name)
m_grpColorSamplerZoomPreview->setChecked(cfg.colorSamplerZoomPreviewEnabled());
- m_ssbColorSamplerZoomPreviewScale->setRange(1, 20);
+ m_ssbColorSamplerZoomPreviewScale->setRange(1, 50);
m_ssbColorSamplerZoomPreviewScale->setSingleStep(1);
m_ssbColorSamplerZoomPreviewScale->setValue(cfg.colorSamplerZoomPreviewScale());
diff --git a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
index 795ae913e0b..2248a24ac66 100644
--- a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
+++ b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
@@ -83,6 +83,7 @@ struct KisAsyncColorSamplerHelper::Private
QPainterPath cacheCrosshairPath;
int cacheCirclePreviewDiameter;
bool canvasPreviewFetchingStarted {false};
+ QRect oldCanvasPixelRect;
QColor currentColor;
QColor baseColor;
@@ -412,6 +413,8 @@ void KisAsyncColorSamplerHelper::deactivate()
// Reset the cached zoom preview image and rect
m_d->cacheCanvasPreviewImage = QImage();
m_d->cacheCanvasPreviewRect = QRect();
+ m_d->canvasPreviewFetchingStarted = false;
+ m_d->oldCanvasPixelRect = QRect();
m_d->isActive = false;
@@ -696,7 +699,7 @@ void KisAsyncColorSamplerHelper::paintCircleCrosshair(QPainter &gc, const QRectF
{
QColor crosshairColor = Qt::black;
// TODO: Check back with Wolthera about the sRGB param
- qreal luminance = KisPaintingTweaks::luminosityCoarse(currentColor, true);
+ qreal luminance = KisPaintingTweaks::luminosityCoarse(currentColor);
if (luminance < 0.5) crosshairColor = Qt::white;
gc.save();
@@ -727,7 +730,7 @@ QImage KisAsyncColorSamplerHelper::cacheCanvasImage(QRect &canvasPixelRect) {
if (m_d->cacheCanvasPreviewRect.isEmpty() || !m_d->cacheCanvasPreviewRect.contains(canvasPixelRect)) {
// Cache an area larger than the needed preview area to avoid rapid small dynamic allocations
- // And also avoid frequent preview delay from fetching canvas image asynchronously repeatedly
+ // And also avoid frequent preview delay from repeatedly fetching canvas image asynchronously
qreal cacheScale = 4;
QRect cacheCanvasRect = canvasPixelRect;
@@ -744,13 +747,15 @@ QImage KisAsyncColorSamplerHelper::cacheCanvasImage(QRect &canvasPixelRect) {
if (!m_d->canvasPreviewFetchingStarted) {
m_d->canvasPreviewFetchingStarted = true;
m_d->strokesFacade()->addJob(m_d->strokeId,
- new KisColorSamplerStrokeStrategy::GenerateCanvasZoomPreviewData(canvasImage, cacheCanvasRect, canvasImage->profile()));
+ new KisColorSamplerStrokeStrategy::GenerateCanvasZoomPreviewData(canvasImage, cacheCanvasRect, canvasImage->colorSpace()->profile()));
}
- // Instead of returning an empty QImage and cause painful flickering
- // Just return old cache, it's not really noticeable normally. In extreme cases, we have a cool lazy loading effect :D
+ // Return the last valid canvas preview while we wait to fetch new canvas cache async
+ if (!m_d->oldCanvasPixelRect.isNull()) canvasPixelRect = m_d->oldCanvasPixelRect;
+ return m_d->cacheCanvasPreviewImage;
}
canvasPixelRect.translate(-m_d->cacheCanvasPreviewRect.topLeft());
+ m_d->oldCanvasPixelRect = canvasPixelRect;
return m_d->cacheCanvasPreviewImage;
}
diff --git a/libs/ui/tool/KisAsyncColorSamplerHelper.h b/libs/ui/tool/KisAsyncColorSamplerHelper.h
index 13a955f24c3..074489ba649 100644
--- a/libs/ui/tool/KisAsyncColorSamplerHelper.h
+++ b/libs/ui/tool/KisAsyncColorSamplerHelper.h
@@ -88,7 +88,7 @@ private:
bool paintCircleCanvasPreview(QPainter &gc, const QRectF &viewRectF, const QRectF &zoomDocRectF, const QPainterPath &clip);
void paintCircleReferenceImagePreview(QPainter &gc, const QRectF &viewRectF, const QRectF &zoomDocRectF, const QPainterPath &clip);
- // Returns a QImage that should either contain the canvasPixelRectF, or the whole canvas if canvasPixelRectF > canvas size.
+ // Returns a QImage that should either contain the canvasPixelRect + caching, or the whole canvas if canvasPixelRect + caching > canvas size.
// Also modify the input rect to point to the same position relative to the returned image
QImage cacheCanvasImage(QRect &canvasPixelRect);