diff --git a/src/ksaneviewer.cpp b/src/ksaneviewer.cpp --- a/src/ksaneviewer.cpp +++ b/src/ksaneviewer.cpp @@ -47,6 +47,11 @@ namespace KSaneIface { +static inline QRectF fromNative(const QRectF &rect, qreal dpr) +{ + return QRectF(rect.topLeft() / dpr, rect.size() / dpr); +} + struct KSaneViewer::Private { QGraphicsScene *scene; SelectionItem *selection; @@ -84,10 +89,12 @@ // Init the scene d->scene = new QGraphicsScene(this); - d->scene->setSceneRect(0, 0, img->width(), img->height()); + const auto dpr = img->devicePixelRatio(); + d->scene->setSceneRect(fromNative(QRectF(QPointF(0, 0), img->size()), dpr)); setScene(d->scene); d->selection = new SelectionItem(QRectF()); + d->selection->setDevicePixelRatio(dpr); d->selection->setZValue(10); d->selection->setSaved(false); d->selection->setMaxRight(img->width()); @@ -156,7 +163,10 @@ void KSaneViewer::drawBackground(QPainter *painter, const QRectF &rect) { painter->fillRect(rect, QColor(0x70, 0x70, 0x70)); - painter->drawImage(rect, *d->img, rect); + QRectF r = rect & sceneRect(); + const qreal dpr = d->img->devicePixelRatio(); + QRectF srcRect = QRectF(r.topLeft() * dpr, r.size() * dpr); + painter->drawImage(r, *d->img, srcRect); } // ------------------------------------------------------------------------ @@ -181,9 +191,11 @@ // clear zoom setMatrix(QMatrix()); - d->scene->setSceneRect(0, 0, img->width(), img->height()); + const auto dpr = img->devicePixelRatio(); + d->scene->setSceneRect(fromNative(QRectF(QPointF(0, 0), img->size()), dpr)); d->selection->setMaxRight(img->width()); d->selection->setMaxBottom(img->height()); + d->selection->setDevicePixelRatio(dpr); d->img = img; } @@ -304,37 +316,38 @@ void KSaneViewer::setHighlightArea(float tl_x, float tl_y, float br_x, float br_y) { QRectF rect; + const auto dpr = d->img->devicePixelRatio(); // Left reason for rect: setCoords(x1,y1,x2,y2) != setRect(x1,x2, width, height) rect.setCoords(0, 0, tl_x * d->img->width(), d->img->height()); - d->hideLeft->setRect(rect); + d->hideLeft->setRect(fromNative(rect, dpr)); // Right rect.setCoords(br_x * d->img->width(), 0, d->img->width(), d->img->height()); - d->hideRight->setRect(rect); + d->hideRight->setRect(fromNative(rect, dpr)); // Top rect.setCoords(tl_x * d->img->width(), 0, br_x * d->img->width(), tl_y * d->img->height()); - d->hideTop->setRect(rect); + d->hideTop->setRect(fromNative(rect, dpr)); // Bottom rect.setCoords(tl_x * d->img->width(), br_y * d->img->height(), br_x * d->img->width(), d->img->height()); - d->hideBottom->setRect(rect); + d->hideBottom->setRect(fromNative(rect, dpr)); // hide area rect.setCoords(tl_x * d->img->width(), tl_y * d->img->height(), br_x * d->img->width(), br_y * d->img->height()); - d->hideArea->setRect(rect); + d->hideArea->setRect(fromNative(rect, dpr)); d->hideLeft->show(); d->hideRight->show(); @@ -370,30 +383,31 @@ { if (d->selection->isVisible()) { QRectF rect; + const auto dpr = d->img->devicePixelRatio(); // Left rect.setCoords(0, 0, d->selection->rect().left(), d->img->height()); - d->hideLeft->setRect(rect); + d->hideLeft->setRect(fromNative(rect, dpr)); // Right rect.setCoords(d->selection->rect().right(), 0, d->img->width(), d->img->height()); - d->hideRight->setRect(rect); + d->hideRight->setRect(fromNative(rect, dpr)); // Top rect.setCoords(d->selection->rect().left(), 0, d->selection->rect().right(), d->selection->rect().top()); - d->hideTop->setRect(rect); + d->hideTop->setRect(fromNative(rect, dpr)); // Bottom rect.setCoords(d->selection->rect().left(), d->selection->rect().bottom(), d->selection->rect().right(), d->img->height()); - d->hideBottom->setRect(rect); + d->hideBottom->setRect(fromNative(rect, dpr)); d->hideLeft->show(); d->hideRight->show(); @@ -542,7 +556,7 @@ if (e->button() == Qt::LeftButton) { d->m_left_last_x = e->x(); d->m_left_last_y = e->y(); - QPointF scenePoint = mapToScene(e->pos()); + QPointF scenePoint = mapToScene(e->pos()) * d->selection->devicePixelRatio(); d->lastSPoint = scenePoint; if (e->modifiers() != Qt::ControlModifier) { if (!d->selection->isVisible()) { @@ -571,7 +585,7 @@ clearActiveSelection(); } - QPointF scenePoint = mapToScene(e->pos()); + QPointF scenePoint = mapToScene(e->pos()) * d->selection->devicePixelRatio(); for (int i = 0; i < d->selectionList.size(); i++) { if (d->selectionList[i]->intersects(scenePoint) == SelectionItem::AddRemove) { d->scene->removeItem(d->selectionList[i]); @@ -588,6 +602,7 @@ if (!removed && (d->selection->intersects(scenePoint) == SelectionItem::AddRemove)) { // add the current selection SelectionItem *tmp = new SelectionItem(d->selection->rect()); + tmp->setDevicePixelRatio(d->img->devicePixelRatio()); d->selectionList.push_back(tmp); d->selectionList.back()->setSaved(true); d->selectionList.back()->saveZoom(transform().m11()); @@ -619,7 +634,7 @@ // ------------------------------------------------------------------------ void KSaneViewer::mouseMoveEvent(QMouseEvent *e) { - QPointF scenePoint = mapToScene(e->pos()); + QPointF scenePoint = mapToScene(e->pos()) * d->selection->devicePixelRatio(); if (e->buttons()&Qt::LeftButton) { if (e->modifiers() == Qt::ControlModifier) { @@ -928,6 +943,7 @@ float selArea = (float)(wSelEnd - wSelStart) * (float)(hSelEnd - hSelStart); if (selArea > (area * MIN_AREA_SIZE)) { SelectionItem *tmp = new SelectionItem(QRect(QPoint(x1, y1), QPoint(x2, y2))); + tmp->setDevicePixelRatio(d->img->devicePixelRatio()); d->selectionList.push_back(tmp); d->selectionList.back()->setSaved(true); d->selectionList.back()->saveZoom(transform().m11()); diff --git a/src/ksanewidget_p.cpp b/src/ksanewidget_p.cpp --- a/src/ksanewidget_p.cpp +++ b/src/ksanewidget_p.cpp @@ -715,7 +715,9 @@ x = (int)(SCALED_PREVIEW_MAX_SIDE / ratio); } - m_previewImg = QImage(x, y, QImage::Format_RGB32); + const qreal dpr = q->devicePixelRatioF(); + m_previewImg = QImage(QSize(x, y) * dpr, QImage::Format_RGB32); + m_previewImg.setDevicePixelRatio(dpr); m_previewImg.fill(0xFFFFFFFF); // set the new image diff --git a/src/selectionitem.h b/src/selectionitem.h --- a/src/selectionitem.h +++ b/src/selectionitem.h @@ -65,6 +65,9 @@ QPointF fixTranslation( QPointF dp); QRectF rect(); + qreal devicePixelRatio() const; + void setDevicePixelRatio(qreal dpr); + public: // Graphics Item methods QRectF boundingRect() const override; diff --git a/src/selectionitem.cpp b/src/selectionitem.cpp --- a/src/selectionitem.cpp +++ b/src/selectionitem.cpp @@ -54,6 +54,7 @@ qreal invZoom; qreal selMargin; QRectF addRemRect; + qreal devicePixelRatio; }; SelectionItem::SelectionItem(const QRectF &rect) : QGraphicsItem(), d(new Private) @@ -79,6 +80,8 @@ d->selMargin = selMargin; d->addRemRect = QRectF(0, 0, 0, 0); + + d->devicePixelRatio = 1.0; } SelectionItem::~SelectionItem() @@ -97,7 +100,7 @@ qreal margin = addRemMargin * d->invZoom; QPointF pMargin = addRemMarginPoint * d->invZoom; - d->addRemRect = QRectF(d->rect.center() - pMargin, QSizeF(margin * 2.0, margin * 2.0)); + d->addRemRect = QRectF(d->rect.center() / d->devicePixelRatio - pMargin, QSizeF(margin * 2.0, margin * 2.0)); d->penAddRemFg.setWidthF(3.0 * d->invZoom); } @@ -193,10 +196,7 @@ update(); } - if ((point.x() > d->addRemRect.left()) && - (point.x() < d->addRemRect.right()) && - (point.y() > d->addRemRect.top()) && - (point.y() < d->addRemRect.bottom())) { + if (d->addRemRect.contains(point / d->devicePixelRatio)) { return AddRemove; } return Move; @@ -225,7 +225,7 @@ // calculate the add/remove rectangle qreal margin = addRemMargin * d->invZoom; QPointF pMargin = addRemMarginPoint * d->invZoom; - d->addRemRect = QRectF(d->rect.center() - pMargin, QSizeF(margin * 2, margin * 2)); + d->addRemRect = QRectF(d->rect.center() / d->devicePixelRatio - pMargin, QSizeF(margin * 2, margin * 2)); } QPointF SelectionItem::fixTranslation(QPointF dp) @@ -250,46 +250,45 @@ return d->rect; } -QRectF SelectionItem::boundingRect() const +qreal SelectionItem::devicePixelRatio() const { - QRectF tmp(d->rect.topLeft() - boundMargin, d->rect.bottomRight() + boundMargin); - if (tmp.top() > d->addRemRect.top()) { - tmp.setTop(d->addRemRect.top()); - } - if (tmp.left() > d->addRemRect.left()) { - tmp.setLeft(d->addRemRect.left()); - } - - if (tmp.bottom() < d->addRemRect.bottom()) { - tmp.setBottom(d->addRemRect.bottom()); - } + return d->devicePixelRatio; +} - if (tmp.right() < d->addRemRect.right()) { - tmp.setRight(d->addRemRect.right()); - } +void SelectionItem::setDevicePixelRatio(qreal dpr) +{ + d->devicePixelRatio = dpr; +} - return tmp; +QRectF SelectionItem::boundingRect() const +{ + const auto dpr = d->devicePixelRatio; + QRectF tmp(d->rect.topLeft() / dpr - boundMargin, d->rect.bottomRight() / dpr + boundMargin); + return tmp.united(d->addRemRect); } void SelectionItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { + const auto dpr = d->devicePixelRatio; + QRectF rect(d->rect.topLeft() / dpr, d->rect.size() / dpr); + painter->setPen(d->penDark); - painter->drawRect(d->rect); + painter->drawRect(rect); painter->setPen(d->penLight); - painter->drawRect(d->rect); + painter->drawRect(rect); if (d->showAddRem) { painter->fillRect(d->addRemRect, QBrush(Qt::white)); - QLineF minus(d->addRemRect.left() + 3 * d->invZoom, d->rect.center().y(), - d->addRemRect.right() - 3 * d->invZoom, d->rect.center().y()); + QLineF minus(d->addRemRect.left() + 3 * d->invZoom, d->addRemRect.center().y(), + d->addRemRect.right() - 3 * d->invZoom, d->addRemRect.center().y()); painter->setPen(d->penAddRemFg); painter->drawLine(minus); if (!d->isSaved) { - QLineF plus(d->rect.center().x(), d->addRemRect.top() + 3 * d->invZoom, - d->rect.center().x(), d->addRemRect.bottom() - 3 * d->invZoom); + QLineF plus(d->addRemRect.center().x(), d->addRemRect.top() + 3 * d->invZoom, + d->addRemRect.center().x(), d->addRemRect.bottom() - 3 * d->invZoom); painter->drawLine(plus); } }