43struct RelevantCanvasState
47 QPointF viewportOffsetF;
49 std::tuple<qreal,qreal> transformations()
const {
50 return {
zoom, rotation};
53 bool operator==(
const RelevantCanvasState& other)
const {
56 viewportOffsetF == other.viewportOffsetF;
59 bool operator!=(
const RelevantCanvasState& other)
const {
60 return !(*
this == other);
63 static RelevantCanvasState fromCanvasState(
const KisCanvasState &state) {
69#define ceiledSize(sz) QSize(ceil((sz).width()), ceil((sz).height()))
71inline void copyQImageBuffer(uchar* dst,
const uchar* src , qint32 deltaX, qint32 width)
74 memcpy(dst + 4 * deltaX, src, 4 *(width - deltaX) *
sizeof(uchar));
76 memcpy(dst, src - 4 * deltaX, 4 *(width + deltaX) *
sizeof(uchar));
80void copyQImage(qint32 deltaX, qint32 deltaY, QImage* dstImage,
const QImage& srcImage)
82 qint32 height = dstImage->height();
83 qint32 width = dstImage->width();
84 Q_ASSERT(dstImage->width() == srcImage.width() && dstImage->height() == srcImage.height());
86 for (
int y = 0; y < height - deltaY; y ++) {
87 const uchar* src = srcImage.scanLine(y);
88 uchar* dst = dstImage->scanLine(y + deltaY);
92 for (
int y = 0; y < height + deltaY; y ++) {
93 const uchar* src = srcImage.scanLine(y - deltaY);
94 uchar* dst = dstImage->scanLine(y);
164 auto relevantState = RelevantCanvasState::fromCanvasState(state);
185 if (offset.isNull())
return;
187 QPoint alignedOffset = offset.toPoint();
189 if(offset != alignedOffset) {
194 dbgRender <<
"prescaling the entire image because the offset is float";
208 QRect oldViewportRect = newViewportRect.translated(alignedOffset);
210 QRegion updateRegion = newViewportRect;
211 QRect savedArea = newViewportRect & oldViewportRect;
212 if(!savedArea.isEmpty()) {
214 updateRegion -= savedArea;
217 QPainter gc(&newImage);
218 auto rc = updateRegion.begin();
219 while (rc != updateRegion.end()) {
226 Q_FOREACH (
const QRect& rc, patches) {
227 QRect viewportPatch =
276 imageToViewport(ppInfo->dirtyImageRectVar).toAlignedRect();
282 if(!info->dirtyViewportRect().isEmpty())
299 Q_FOREACH (
const QRect& rc, patches) {
304 gc.setCompositionMode(QPainter::CompositionMode_Source);
329 QSizeF minimalSize(qMin(imageRect.width(),
m_d->
canvasSize.width()),
331 QRectF minimalRect(QPointF(0,0), minimalSize);
360 info->dirtyImageRectVar = dirtyImageRect;
371 QRect croppedViewRect = viewportRect.intersected(QRect(QPoint(0, 0),
m_d->
viewportSize));
384 const int borderSize =
BORDER_SIZE(qMax(info->scaleX, info->scaleY));
385 info->imageRect.adjust(-borderSize, -borderSize, borderSize, borderSize);
394 info->borderWidth = 0;
397 dbgRender <<
"smoothBetween100And200Percent" << Qt::endl;
398 info->renderHints = QPainter::SmoothPixmapTransform;
399 info->borderWidth = borderSize;
403 info->renderHints = QPainter::SmoothPixmapTransform;
404 info->borderWidth = borderSize;
408 dbgRender <<
"#####################################";
413 dbgRender <<
"Not aligned rect of the canvas (raw):\t" << croppedViewRect;
414 dbgRender <<
"Update rect in KisImage's pixels:\t" << info->imageRect;
415 dbgRender <<
"Update rect in canvas' pixels:\t" << info->viewportRect;
416 dbgRender <<
"#####################################";
422 gc.setCompositionMode(QPainter::CompositionMode_Source);
428 if (info->imageRect.isEmpty())
return;
437 patch.
drawMe(gc, info->viewportRect, info->renderHints);
bool operator==(const KisRegion &lhs, const KisRegion &rhs)
bool operator!=(const KoID &v1, const KoID &v2)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static KisCanvasState fromConverter(const KisCoordinatesConverter &converter)
static KisConfigNotifier * instance()
void imageScale(qreal *scaleX, qreal *scaleY) const
_Private::Traits< T >::Result viewportToImage(const T &obj) const
_Private::Traits< T >::Result widgetToViewport(const T &obj) const
QRectF imageRectInWidgetPixels() const
_Private::Traits< T >::Result imageToViewport(const T &obj) const
KisDisplayConfig This class keeps track of the color management configuration for image to display....
KoColorConversionTransformation::ConversionFlags conversionFlags
const KoColorProfile * profile
KoColorConversionTransformation::Intent intent
int updatePatchWidth() const
int updatePatchHeight() const
void preScale(const QRectF &dstRect)
void drawMe(QPainter &gc, const QRectF &dstRect, QPainter::RenderHints renderHints)
QRect bounds() const override
void updateScaledImage(KisPPUpdateInfoSP info)
void viewportMoved(const QPointF &offset)
void fillInUpdateInformation(const QRect &viewportRect, KisPPUpdateInfoSP info)
~KisPrescaledProjection() override
void notifyCanvasStateChanged(const KisCanvasState &state)
QImage prescaledQImage() const
void notifyCanvasSizeChanged(const QSize &widgetSize)
void setChannelFlags(const QBitArray &channelFlags)
void slotImageSizeChanged(qint32 w, qint32 h)
KisPPUpdateInfoSP getInitialUpdateInformation(const QRect &dirtyImageRect)
void updateViewportSize()
void recalculateCache(KisUpdateInfoSP info)
void drawUsingBackend(QPainter &gc, KisPPUpdateInfoSP info)
void setDisplayConfig(const KisDisplayConfig &config)
void setImage(KisImageWSP image)
KisUpdateInfoSP updateCache(const QRect &dirtyImageRect)
void setCoordinatesConverter(KisCoordinatesConverter *coordinatesConverter)
void setDisplayFilter(QSharedPointer< KisDisplayFilter > displayFilter)
virtual void setDisplayFilter(QSharedPointer< KisDisplayFilter > displayFilter)=0
virtual KisImagePatch getNearestPatch(KisPPUpdateInfoSP info)=0
virtual void alignSourceRect(QRect &rect, qreal scale)
virtual void recalculateCache(KisPPUpdateInfoSP info)=0
virtual void setChannelFlags(const QBitArray &channelFlags)=0
virtual void updateCache(const QRect &dirtyImageRect)=0
virtual void setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)=0
virtual void setImageSize(qint32 w, qint32 h)=0
virtual void setImage(KisImageWSP image)=0
virtual void drawFromOriginalImage(QPainter &gc, KisPPUpdateInfoSP info)=0
static bool qFuzzyCompare(half p1, half p2)
#define SCALE_LESS_THAN(scX, scY, value)
#define SCALE_MORE_OR_EQUAL_TO(scX, scY, value)
#define BORDER_SIZE(scale)
void copyQImageBuffer(uchar *dst, const uchar *src, qint32 deltaX, qint32 width)
void copyQImage(qint32 deltaX, qint32 deltaY, QImage *dstImage, const QImage &srcImage)
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
QVector< QRect > splitRectIntoPatches(const QRect &rc, const QSize &patchSize)
std::optional< RelevantCanvasState > currentRelevantCanvasState
KisProjectionBackend * projectionBackend
KisCoordinatesConverter * coordinatesConverter