[graphics/krita] libs/ui/tool: Refractor canvas and reference image preview painting
Emmet O'Neill <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 089f875a83fb5565be16052090c093f3f25e70f5 by Emmet O'Neill, on behalf of Le Tien Dat.
Committed on 13/08/2026 at 23:16.
Pushed by emmetoneill into branch 'master'.
Refractor canvas and reference image preview painting
M +68 -58 libs/ui/tool/KisAsyncColorSamplerHelper.cpp
M +4 -0 libs/ui/tool/KisAsyncColorSamplerHelper.h
https://invent.kde.org/graphics/krita/-/commit/089f875a83fb5565be16052090c093f3f25e70f5
diff --git a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
index 67906023ccb..a9e9c4d9c01 100644
--- a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
+++ b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
@@ -70,7 +70,7 @@ struct KisAsyncColorSamplerHelper::Private
bool circlePreviewExtraCircles {true};
qreal circleZoomPreviewScale {2};
QRectF previewDocRect;
- QPainterPath cacheInnerPath;
+ QPainterPath cacheCircleInnerClip;
QColor currentColor;
QColor baseColor;
@@ -521,7 +521,7 @@ void KisAsyncColorSamplerHelper::paintCircle(QPainter &gc,
QPainterPath innerPath;
innerPath.addPath(innerEllipse);
- m_d->cacheInnerPath = innerPath;
+ m_d->cacheCircleInnerClip = innerPath;
if (m_d->circlePreviewThickness < 0.5 && m_d->circlePreviewExtraCircles) {
qreal extraMargin = 0.1*m_d->circlePreviewThickness*innerRect.width(); // looks better
@@ -540,82 +540,92 @@ void KisAsyncColorSamplerHelper::paintCircle(QPainter &gc,
// TODO: Check why zoom still show after leaving canvas
cachePainter.setPen(Qt::NoPen);
cachePainter.setCompositionMode(QPainter::CompositionMode_Clear);
- cachePainter.drawPath(tf.map(m_d->cacheInnerPath));
+ cachePainter.drawPath(tf.map(m_d->cacheCircleInnerClip));
+ bool didDrawRefImage = false;
+
+ paintCircleCanvasPreview(cachePainter, cacheRect, tf.map(m_d->cacheCircleInnerClip));
+
+ // 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->cacheCircleInnerClip));
+ }
+
+ gc.drawPixmap(viewRectF.toRect(), m_d->cache);
+
+ gc.restore();
+}
+
+void KisAsyncColorSamplerHelper::paintCircleCanvasPreview(QPainter &gc, const QRectF &viewRectF, const QPainterPath &clip) {
QRectF sampleDocRectF = m_d->previewDocRect;
- sampleDocRectF.setHeight(sampleDocRectF.height() / m_d->circleZoomPreviewScale);
- sampleDocRectF.setWidth(sampleDocRectF.width() / m_d->circleZoomPreviewScale);
+ sampleDocRectF.setSize(sampleDocRectF.size() / m_d->circleZoomPreviewScale);
sampleDocRectF.moveCenter(m_d->previewDocRect.center());
+
QRectF canvasSampleRectF = m_d->canvas->image()->documentToPixel(sampleDocRectF);
- dbgUI << "View rect: " << viewRectF;
dbgUI << "Preview doc rect: " << m_d->previewDocRect;
dbgUI << "Sample doc rect: " << sampleDocRectF;
dbgUI << "Canvas sample rect: " << canvasSampleRectF;
dbgUI << "Sample doc point: " << sampleDocRectF.center();
- QImage cacheCanvasImage;
- bool sampledRefImage = false;
+ // Copy a piece of canvas image with size = (previewDocRect size) / (zoom preview scale)
+ QImage canvasPreview = m_d->canvas->image()->convertToQImage(canvasSampleRectF.toRect(), nullptr);
+ gc.setCompositionMode(QPainter::CompositionMode_SourceOver);
+
+ gc.setClipPath(clip);
+ // QtDoc: 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
+ // drawImage will scale it up that many times, thus achieving the zoom effect
+ gc.drawImage(viewRectF, canvasPreview);
+
+ gc.setClipPath(QPainterPath(), Qt::NoClip);
+}
+
+void KisAsyncColorSamplerHelper::paintCircleReferenceImagePreview(QPainter &gc, const QRectF &viewRectF, const QPainterPath &clip) {
+ gc.setCompositionMode(QPainter::CompositionMode_SourceOver);
// Check if doc coord is on canvas or reference image
KisDocument *doc = m_d->canvas->viewManager()->document();
- if (doc) {
- KisReferenceImagesLayerSP refLayer = doc->referenceImagesLayer();
- if (refLayer) {
- for(int i=0;i<refLayer->referenceImages().count();i++) {
- KisReferenceImage *refImage = refLayer->referenceImages().at(i);
- QPolygonF outline = refImage->outline().toFillPolygon().translated(refImage->position());
- if (outline.containsPoint(sampleDocRectF.center(), Qt::OddEvenFill)) {
- dbgUI << "Sampling on reference image no " << i;
- // TODO: Figure out how to convert shape coordinate to pixel coordinate
- // Just need to divide by scale. How to find the scale though
- QImage image = refImage->getImage();
- qreal xScale = refImage->boundingRect().width() / image.width();
- qreal yScale = refImage->boundingRect().height() / image.height();
- QRectF refRectF = refImage->documentToShape(sampleDocRectF);
- dbgUI << "Shape coordinate: " << refRectF;
- dbgUI << "Image scaling: " << refImage->transformation().m11();
- QPointF topLeft = refRectF.topLeft();
- topLeft.setX(topLeft.x() / xScale);
- topLeft.setY(topLeft.y() / yScale);
- QPointF bottomRight = refRectF.bottomRight();
- bottomRight.setX(bottomRight.x() / xScale);
- bottomRight.setY(bottomRight.y() / yScale);
-
- dbgUI << "Shape pixel coordinate: " << QRectF(topLeft, bottomRight);
-
- cacheCanvasImage = refImage->getImage().copy(QRectF(topLeft, bottomRight).toRect());
- sampledRefImage = true;
- }
- }
- }
- }
+ if (!doc) return;
+ KisReferenceImagesLayerSP refLayer = doc->referenceImagesLayer();
+ if (!refLayer) return;
- if (!sampledRefImage)
- // Copy a piece of canvas image with size = (previewDocRect size) / (zoom preview scale)
- cacheCanvasImage = m_d->canvas->image()->convertToQImage(canvasSampleRectF.toRect(), nullptr);
+ QRectF sampleDocRectF = m_d->previewDocRect;
+ sampleDocRectF.setSize(sampleDocRectF.size() / m_d->circleZoomPreviewScale);
+ sampleDocRectF.moveCenter(m_d->previewDocRect.center());
- cachePainter.setClipPath(tf.map(m_d->cacheInnerPath));
- cachePainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ for(int i=0;i<refLayer->referenceImages().count();i++) {
+ KisReferenceImage *refImage = refLayer->referenceImages().at(i);
+ QPolygonF outline = refImage->outline().toFillPolygon().translated(refImage->position());
+ if (!outline.containsPoint(sampleDocRectF.center(), Qt::OddEvenFill)) continue;
- // QtDoc: 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
- // drawImage will scale it up that many times, thus achieving the zoom effect
- cachePainter.drawImage(cacheRect, cacheCanvasImage);
+ dbgUI << "Sampling on reference image no " << i;
- cachePainter.setClipPath(QPainterPath(), Qt::NoClip);
+ QImage image = refImage->getImage();
+ qreal xScale = refImage->boundingRect().width() / image.width();
+ qreal yScale = refImage->boundingRect().height() / image.height();
+ QRectF refRectF = refImage->documentToShape(sampleDocRectF);
- // 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));
- }
+ dbgUI << "Shape coordinate: " << refRectF;
+ dbgUI << "Image scaling: " << refImage->transformation().m11();
- gc.drawPixmap(viewRectF.toRect(), m_d->cache);
+ QPointF topLeft = refRectF.topLeft();
+ topLeft.setX(topLeft.x() / xScale);
+ topLeft.setY(topLeft.y() / yScale);
+ QPointF bottomRight = refRectF.bottomRight();
+ bottomRight.setX(bottomRight.x() / xScale);
+ bottomRight.setY(bottomRight.y() / yScale);
- gc.restore();
+ dbgUI << "Shape pixel coordinate: " << QRectF(topLeft, bottomRight);
+
+ QImage refPreview = refImage->getImage().copy(QRectF(topLeft, bottomRight).toRect());
+ refPreview.convertTo(QImage::Format_ARGB32);
+
+ gc.drawImage(viewRectF, refPreview);
+ }
}
void KisAsyncColorSamplerHelper::slotAddSamplingJob(const QPointF &docPoint)
diff --git a/libs/ui/tool/KisAsyncColorSamplerHelper.h b/libs/ui/tool/KisAsyncColorSamplerHelper.h
index 1a7d3c1e8d5..88d680ad581 100644
--- a/libs/ui/tool/KisAsyncColorSamplerHelper.h
+++ b/libs/ui/tool/KisAsyncColorSamplerHelper.h
@@ -15,6 +15,7 @@
#include "kis_types.h"
class QPainter;
+class QPainterPath;
class KoViewConverter;
class KisStrokesFacade;
class KisCanvas2;
@@ -80,6 +81,9 @@ private:
void paintRectangle(QPainter &gc, const QRectF &viewRectF, const QColor ¤tColor, const QColor &baseColor);
void paintCircle(QPainter &gc, const QRectF &viewRectF, const QColor ¤tColor, const QColor &baseColor);
+ void paintCircleCanvasPreview(QPainter &gc, const QRectF &viewRectF, const QPainterPath &clip);
+ void paintCircleReferenceImagePreview(QPainter &gc, const QRectF &viewRectF, const QPainterPath &clip);
+
struct Private;
QScopedPointer<Private> m_d;
};