diff --git a/libs/ui/canvas/kis_image_patch.h b/libs/ui/canvas/kis_image_patch.h --- a/libs/ui/canvas/kis_image_patch.h +++ b/libs/ui/canvas/kis_image_patch.h @@ -56,7 +56,7 @@ * This ensures that we use the QImage smoothscale method, not the QPainter scaling, * which is far inferior. */ - void preScale(const QRectF &dstRect); + void preScale(const QRectF &dstRect, qreal devicePixelRatio); /** * Returns the rect of KisImage covered by the image diff --git a/libs/ui/canvas/kis_image_patch.cpp b/libs/ui/canvas/kis_image_patch.cpp --- a/libs/ui/canvas/kis_image_patch.cpp +++ b/libs/ui/canvas/kis_image_patch.cpp @@ -85,7 +85,7 @@ m_isScaled = false; } -void KisImagePatch::preScale(const QRectF &dstRect) +void KisImagePatch::preScale(const QRectF &dstRect, qreal devicePixelRatio) { if (m_isScaled) return; @@ -93,7 +93,7 @@ qreal scaleY = dstRect.height() / m_interestRect.height(); QSize newImageSize = QSize(ceil(m_image.width() * scaleX), - ceil(m_image.height() * scaleY)); + ceil(m_image.height() * scaleY)) * devicePixelRatio; // Calculating new _aligned_ scale scaleX = qreal(newImageSize.width()) / m_image.width(); scaleY = qreal(newImageSize.height()) / m_image.height(); @@ -104,6 +104,7 @@ scaleRect(m_interestRect, scaleX, scaleY); m_image = m_image.scaled(newImageSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + m_image.setDevicePixelRatio(devicePixelRatio); m_isScaled = true; diff --git a/libs/ui/canvas/kis_prescaled_projection.h b/libs/ui/canvas/kis_prescaled_projection.h --- a/libs/ui/canvas/kis_prescaled_projection.h +++ b/libs/ui/canvas/kis_prescaled_projection.h @@ -103,7 +103,7 @@ * Checks whether it is needed to resize the prescaled image and * updates it. The size is given in canvas widget pixels. */ - void notifyCanvasSizeChanged(const QSize &widgetSize); + void notifyCanvasSizeChanged(const QSize &widgetSize, qreal devicePixelRatio); void notifyZoomChanged(); diff --git a/libs/ui/canvas/kis_prescaled_projection.cpp b/libs/ui/canvas/kis_prescaled_projection.cpp --- a/libs/ui/canvas/kis_prescaled_projection.cpp +++ b/libs/ui/canvas/kis_prescaled_projection.cpp @@ -83,6 +83,7 @@ QSize updatePatchSize; QSize canvasSize; + qreal devicePixelRatio; QSize viewportSize; KisImageWSP image; KisCoordinatesConverter *coordinatesConverter; @@ -139,19 +140,21 @@ if (m_d->prescaledQImage.isNull()) return; if (offset.isNull()) return; - QPoint alignedOffset = offset.toPoint(); + QPointF scaledOffset(offset * m_d->devicePixelRatio); + QPoint alignedOffset = scaledOffset.toPoint(); - if(offset != alignedOffset) { + if(scaledOffset != alignedOffset) { /** - * We can't optimize anything when offset is float :( + * We can't optimize anything when scaledOffset is float :( * Just prescale entire image. */ - dbgRender << "prescaling the entire image because the offset is float"; + dbgRender << "prescaling the entire image because the scaledOffset is float"; preScale(); return; } - QImage newImage = QImage(m_d->viewportSize, QImage::Format_ARGB32); + QImage newImage = QImage(m_d->viewportSize * m_d->devicePixelRatio, QImage::Format_ARGB32); + newImage.setDevicePixelRatio(m_d->devicePixelRatio); newImage.fill(0); /** @@ -287,9 +290,10 @@ m_d->viewportSize = m_d->coordinatesConverter->widgetToViewport(minimalRect).toAlignedRect().size(); if (m_d->prescaledQImage.isNull() || - m_d->prescaledQImage.size() != m_d->viewportSize) { + m_d->prescaledQImage.size() != m_d->viewportSize * m_d->devicePixelRatio) { - m_d->prescaledQImage = QImage(m_d->viewportSize, QImage::Format_ARGB32); + m_d->prescaledQImage = QImage(m_d->viewportSize * m_d->devicePixelRatio, QImage::Format_ARGB32); + m_d->prescaledQImage.setDevicePixelRatio(m_d->devicePixelRatio); m_d->prescaledQImage.fill(0); } } @@ -300,9 +304,10 @@ preScale(); } -void KisPrescaledProjection::notifyCanvasSizeChanged(const QSize &widgetSize) +void KisPrescaledProjection::notifyCanvasSizeChanged(const QSize &widgetSize, qreal devicePixelRatio) { m_d->canvasSize = widgetSize; + m_d->devicePixelRatio = devicePixelRatio; updateViewportSize(); preScale(); } @@ -352,8 +357,8 @@ info->viewportRect = m_d->coordinatesConverter->imageToViewport(info->imageRect); info->borderWidth = 0; - if (SCALE_MORE_OR_EQUAL_TO(info->scaleX, info->scaleY, 1.0)) { - if (SCALE_LESS_THAN(info->scaleX, info->scaleY, 2.0)) { + if (SCALE_MORE_OR_EQUAL_TO(info->scaleX * m_d->devicePixelRatio, info->scaleY * m_d->devicePixelRatio, 1.0)) { + if (SCALE_LESS_THAN(info->scaleX * m_d->devicePixelRatio, info->scaleY * m_d->devicePixelRatio, 2.0)) { dbgRender << "smoothBetween100And200Percent" << endl; info->renderHints = QPainter::SmoothPixmapTransform; info->borderWidth = borderSize; @@ -393,7 +398,7 @@ KisImagePatch patch = m_d->projectionBackend->getNearestPatch(info); // prescale the patch because otherwise we'd scale using QPainter, which gives // a crap result compared to QImage's smoothscale - patch.preScale(info->viewportRect); + patch.preScale(info->viewportRect, m_d->devicePixelRatio); patch.drawMe(gc, info->viewportRect, info->renderHints); } } diff --git a/libs/ui/canvas/kis_qpainter_canvas.cpp b/libs/ui/canvas/kis_qpainter_canvas.cpp --- a/libs/ui/canvas/kis_qpainter_canvas.cpp +++ b/libs/ui/canvas/kis_qpainter_canvas.cpp @@ -150,8 +150,9 @@ QRectF viewportRect = converter->widgetToViewport(updateWidgetRect); gc.setCompositionMode(QPainter::CompositionMode_SourceOver); + QRectF scaledRect(viewportRect.topLeft() * devicePixelRatioF(), viewportRect.size() * devicePixelRatioF()); gc.drawImage(viewportRect, m_d->prescaledProjection->prescaledQImage(), - viewportRect); + scaledRect); } QVariant KisQPainterCanvas::inputMethodQuery(Qt::InputMethodQuery query) const @@ -235,7 +236,7 @@ } coordinatesConverter()->setCanvasWidgetSize(size); - m_d->prescaledProjection->notifyCanvasSizeChanged(size); + m_d->prescaledProjection->notifyCanvasSizeChanged(size, devicePixelRatioF()); } void KisQPainterCanvas::slotConfigChanged()