[graphics/krita] libs/ui/tool: Refresh zoom preview without invalidate cached color ring everytime

Emmet O'Neill <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit c8150ddd84e38d88e9406888999b26422af94136 by Emmet O'Neill, on behalf of Le Tien Dat.
Committed on 13/08/2026 at 23:16.
Pushed by emmetoneill into branch 'master'.

Refresh zoom preview without invalidate cached color ring everytime

M  +53   -52   libs/ui/tool/KisAsyncColorSamplerHelper.cpp

https://invent.kde.org/graphics/krita/-/commit/c8150ddd84e38d88e9406888999b26422af94136

diff --git a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
index 0965c3cdbc2..39bb2e00b51 100644
--- a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
+++ b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
@@ -70,7 +70,7 @@ struct KisAsyncColorSamplerHelper::Private
     bool circlePreviewExtraCircles {true};
     QRectF previewDocRect;
     QPointF docPoint;
-    QImage cacheCanvasImage;
+    QPainterPath cacheInnerPath;
 
     QColor currentColor;
     QColor baseColor;
@@ -455,39 +455,40 @@ void KisAsyncColorSamplerHelper::paintCircle(QPainter &gc,
         canvasRotationAngle = -canvasRotationAngle;
     }
 
-    bool needsDualColor = currentColor != baseColor;
-    if (true || needsNewCache || (needsDualColor && !qFuzzyCompare(m_d->cacheRotation, canvasRotationAngle))) {
-        m_d->cacheRotation = canvasRotationAngle;
+    QPainter cachePainter(&m_d->cache);
+    cachePainter.setRenderHint(QPainter::Antialiasing);
 
-        QPainter cachePainter(&m_d->cache);
-        cachePainter.setRenderHint(QPainter::Antialiasing);
-
-        QColor backgroundColor = colorWithAlpha(m_d->backgroundColor, OPACITY_OPAQUE_U8 / 2 + 1);
-        qreal penWidth = m_d->circlePreviewDiameter > 100 ? (2.0 * dpr) : (1.0 * dpr);
-        QPen pen = QPen(backgroundColor, penWidth);
-        if (m_d->circlePreviewOutlineEnabled) {
-            cachePainter.setPen(pen);
-        } else {
-            cachePainter.setPen(Qt::NoPen);
-        }
+    QColor backgroundColor = colorWithAlpha(m_d->backgroundColor, OPACITY_OPAQUE_U8 / 2 + 1);
+    qreal penWidth = m_d->circlePreviewDiameter > 100 ? (2.0 * dpr) : (1.0 * dpr);
+    QPen pen = QPen(backgroundColor, penWidth);
+    if (m_d->circlePreviewOutlineEnabled) {
+        cachePainter.setPen(pen);
+    } else {
+        cachePainter.setPen(Qt::NoPen);
+    }
 
-        QRectF cacheRect = m_d->cache.rect();
-        QRectF outerRect = cacheRect.marginsRemoved(QMarginsF(penWidth, penWidth, penWidth, penWidth));
+    QRectF cacheRect = m_d->cache.rect();
 
-        QTransform tf;
+    // The color sampler preview is an outline and those rotate along
+    // with the canvas. That's undesirable for the sampler preview
+    // though, so we calculate the transformation to counter the rotation here
+    QPointF cacheCenter = cacheRect.center();
+    QTransform tf;
+    tf.translate(cacheCenter.x(), cacheCenter.y());
+    tf.rotate(-canvasRotationAngle);
+    tf.translate(-cacheCenter.x(), -cacheCenter.y());
 
-        QPointF cacheCenter = cacheRect.center();
-        tf.translate(cacheCenter.x(), cacheCenter.y());
-        tf.rotate(-canvasRotationAngle);
-        tf.translate(-cacheCenter.x(), -cacheCenter.y());
+    bool needsDualColor = currentColor != baseColor;
+    if (needsNewCache || (needsDualColor && !qFuzzyCompare(m_d->cacheRotation, canvasRotationAngle))) {
+        m_d->cacheRotation = canvasRotationAngle;
 
+        QRectF outerRect = cacheRect.marginsRemoved(QMarginsF(penWidth, penWidth, penWidth, penWidth));
 
         if (needsDualColor) {
             // The color sampler preview is an outline and those rotate along
             // with the canvas. That's undesirable for the sampler preview
             // though, so we un-rotate its contents here accordingly.
 
-
             QPainterPath clipPath;
             clipPath.addPolygon(tf.map(QPolygonF(QRectF(0, 0, cacheRect.width(), cacheRect.height() / 2.0 + 1.0))));
             cachePainter.setClipPath(clipPath);
@@ -520,6 +521,7 @@ void KisAsyncColorSamplerHelper::paintCircle(QPainter &gc,
         QPainterPath innerPath;
         innerPath.addPath(innerEllipse);
 
+        m_d->cacheInnerPath = innerPath;
 
         if (m_d->circlePreviewThickness < 0.5 && m_d->circlePreviewExtraCircles) {
             qreal extraMargin = 0.1*m_d->circlePreviewThickness*innerRect.width(); // looks better
@@ -532,37 +534,36 @@ void KisAsyncColorSamplerHelper::paintCircle(QPainter &gc,
 
             innerPath = innerPath.intersected(innerEllipse);
         }
+    }
 
-        // cachePainter.setPen(Qt::NoPen);
-        // cachePainter.setCompositionMode(QPainter::CompositionMode_Clear);
-        // cachePainter.drawPath(tf.map(innerPath));
-
-        if (true) {
-            dbgUI << "View rect: " << viewRectF;
-            QRectF docRectF = m_d->converter().viewToDocument(viewRectF);
-            QRectF docSampleRectF = QRectF(m_d->docPoint.x() - docRectF.width()/4, m_d->docPoint.y() - docRectF.height()/4, docRectF.width()/2, docRectF.height()/2);
-            QRectF canvasSampleRectF = m_d->canvas->image()->documentToPixel(docSampleRectF);
-            dbgUI << "Doc point: " << m_d->docPoint;
-            dbgUI << "Doc view rect: " << docRectF;
-            dbgUI << "Canvas point: " << canvasSampleRectF.topLeft();
-
-            m_d->cacheCanvasImage = m_d->canvas->image()->convertToQImage(canvasSampleRectF.toRect(), nullptr);
-
-            cachePainter.setClipPath(tf.map(innerPath));
-            // cachePainter.setBrush(Qt::GlobalColor::cyan);
-            cachePainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
-            cachePainter.drawImage(cacheRect, m_d->cacheCanvasImage);
-
-            cachePainter.setClipPath(QPainterPath(), Qt::NoClip);
-        }
-
-        if (m_d->circlePreviewOutlineEnabled) {
-            cachePainter.setBrush(Qt::transparent);
-            cachePainter.setPen(pen);
-            cachePainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
-            cachePainter.drawPath(tf.map(innerPath));
-        }
+    dbgUI << "View rect: " << viewRectF;
+    QRectF docRectF = m_d->converter().viewToDocument(viewRectF);
+    QRectF docSampleRectF = QRectF(m_d->docPoint.x() - docRectF.width()/4, m_d->docPoint.y() - docRectF.height()/4, docRectF.width()/2, docRectF.height()/2);
+    QRectF canvasSampleRectF = m_d->canvas->image()->documentToPixel(docSampleRectF);
+    dbgUI << "Doc point: " << m_d->docPoint;
+    dbgUI << "Doc view rect: " << docRectF;
+    dbgUI << "Canvas point: " << canvasSampleRectF.topLeft();
+    // Copy a piece of canvas image with size = (cacheRect document size) / (zoom preview scale)
+    QImage cacheCanvasImage = m_d->canvas->image()->convertToQImage(canvasSampleRectF.toRect(), nullptr);
+
+    cachePainter.setClipPath(tf.map(m_d->cacheInnerPath));
+    cachePainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+
+    // QtDoc: Note: The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
+    // Since the piece of canvas is (zoom preview scale) times smaller than cacheRect
+    // Draw image will scale it up that many times, thus achieving the zoom effect
+    cachePainter.drawImage(cacheRect, cacheCanvasImage);
+
+    cachePainter.setClipPath(QPainterPath(), Qt::NoClip);
+
+    // Draw inner circle outline if enabled
+    if (m_d->circlePreviewOutlineEnabled) {
+        cachePainter.setBrush(Qt::transparent);
+        cachePainter.setPen(pen);
+        cachePainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+        cachePainter.drawPath(tf.map(m_d->cacheInnerPath));
     }
+
     gc.drawPixmap(viewRectF.toRect(), m_d->cache);
 
     gc.restore();
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.