Commit 9d95d8d5 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Fix canvas scale in HiDPI mode

Qt has a bit complicated way to deal with openGL widget
in scaled HiDPI mode. The openGL widget's framebuffer is
stored in hardware pixels (physical coordinates), but before
calling paintGL, Qt sets manual scaling with glOrtho that
makes this FBO look as if it is stored in logical pixels.

This patch basically takes it into account by setting
a correct physical resolution in
KisZoomManager::updateScreenResolution(). It has one non-
trivial consequence. Now, when setting zoom to 100% and
having pixel aspect mode activated, Flake coordinate system
does **not** have 100% zoom, because it is measured in
logical coordinates, but not in physical ones, which are
bigger.

BUG:360541
Fixes T2299
parent 83a05fff
......@@ -2658,7 +2658,7 @@ void KisMainWindow::moveEvent(QMoveEvent *e)
const int newScreen = qApp->desktop()->screenNumber(e->pos());
if (oldScreen != newScreen) {
KisConfigNotifier::instance()->notifyConfigChanged();
emit screenChanged();
}
}
......
......@@ -226,6 +226,9 @@ Q_SIGNALS:
void guiLoadingFinished();
/// emitted when the window is migrated among different screens
void screenChanged();
public Q_SLOTS:
/**
......
......@@ -251,6 +251,7 @@ KisView::KisView(KisDocument *document, KoCanvasResourceProvider *resourceManage
d->paintingAssistantsDecoration->setVisible(true);
d->showFloatingMessage = cfg.showCanvasMessages();
d->zoomManager.updateScreenResolution(this);
}
KisView::~KisView()
......@@ -758,6 +759,11 @@ bool KisView::queryClose()
}
void KisView::slotScreenChanged()
{
d->zoomManager.updateScreenResolution(this);
}
void KisView::resetImageSizeAndScroll(bool changeCentering,
const QPointF &oldImageStillPoint,
const QPointF &newImageStillPoint)
......@@ -983,6 +989,7 @@ void KisView::slotLoadingFinished()
}
setCurrentNode(activeNode);
connect(d->viewManager->mainWindow(), SIGNAL(screenChanged()), SLOT(slotScreenChanged()));
zoomManager()->updateImageBoundsSnapping();
}
......
......@@ -247,6 +247,8 @@ public Q_SLOTS:
bool queryClose();
void slotScreenChanged();
private Q_SLOTS:
void slotImageNodeAdded(KisNodeSP node);
void slotContinueAddNode(KisNodeSP newActiveNode);
......
......@@ -198,6 +198,7 @@ KisCanvas2::KisCanvas2(KisCoordinatesConverter *coordConverter, KoCanvasResource
*/
m_d->bootstrapLodBlocked = true;
connect(view->mainWindow(), SIGNAL(guiLoadingFinished()), SLOT(bootstrapFinished()));
connect(view->mainWindow(), SIGNAL(screenChanged()), SLOT(slotConfigChanged()));
KisImageConfig config(false);
......
......@@ -30,7 +30,12 @@
struct KisCoordinatesConverter::Private {
Private():
isXAxisMirrored(false), isYAxisMirrored(false), rotationAngle(0.0) { }
isXAxisMirrored(false),
isYAxisMirrored(false),
rotationAngle(0.0),
devicePixelRatio(1.0)
{
}
KisImageWSP image;
......@@ -38,6 +43,7 @@ struct KisCoordinatesConverter::Private {
bool isYAxisMirrored;
qreal rotationAngle;
QSizeF canvasWidgetSize;
qreal devicePixelRatio;
QPointF documentOffset;
QTransform flakeToWidget;
......@@ -150,6 +156,11 @@ void KisCoordinatesConverter::setCanvasWidgetSize(QSize size)
recalculateTransformations();
}
void KisCoordinatesConverter::setDevicePixelRatio(qreal value)
{
m_d->devicePixelRatio = value;
}
void KisCoordinatesConverter::setImage(KisImageWSP image)
{
m_d->image = image;
......@@ -444,3 +455,10 @@ void KisCoordinatesConverter::imageScale(qreal *scaleX, qreal *scaleY) const
*scaleX = zoomX / resX;
*scaleY = zoomY / resY;
}
void KisCoordinatesConverter::imagePhysicalScale(qreal *scaleX, qreal *scaleY) const
{
imageScale(scaleX, scaleY);
*scaleX *= m_d->devicePixelRatio;
*scaleY *= m_d->devicePixelRatio;
}
......@@ -60,6 +60,7 @@ public:
~KisCoordinatesConverter() override;
void setCanvasWidgetSize(QSize size);
void setDevicePixelRatio(qreal value);
void setImage(KisImageWSP image);
void setDocumentOffset(const QPoint &offset);
......@@ -147,6 +148,7 @@ public:
QPointF widgetCenterPoint() const;
void imageScale(qreal *scaleX, qreal *scaleY) const;
void imagePhysicalScale(qreal *scaleX, qreal *scaleY) const;
private:
friend class KisZoomAndPanTest;
......
......@@ -79,6 +79,9 @@ KisZoomManager::KisZoomManager(QPointer<KisView> view, KoZoomHandler * zoomHandl
, m_verticalRuler(0)
, m_zoomAction(0)
, m_zoomActionWidget(0)
, m_physicalDpiX(72.0)
, m_physicalDpiY(72.0)
, m_devicePixelRatio(1.0)
{
}
......@@ -89,6 +92,27 @@ KisZoomManager::~KisZoomManager()
}
}
void KisZoomManager::updateScreenResolution(QWidget *parentWidget)
{
if (qFuzzyCompare(parentWidget->physicalDpiX(), m_physicalDpiX) &&
qFuzzyCompare(parentWidget->physicalDpiY(), m_physicalDpiY) &&
qFuzzyCompare(parentWidget->devicePixelRatio(), m_devicePixelRatio)) {
return;
}
m_physicalDpiX = parentWidget->physicalDpiX();
m_physicalDpiY = parentWidget->physicalDpiY();
m_devicePixelRatio = parentWidget->devicePixelRatio();
KisCoordinatesConverter *converter =
dynamic_cast<KisCoordinatesConverter*>(m_zoomHandler);
converter->setDevicePixelRatio(m_devicePixelRatio);
changeAspectMode(m_aspectMode);
}
void KisZoomManager::setup(KActionCollection * actionCollection)
{
......@@ -336,17 +360,20 @@ void KisZoomManager::changeAspectMode(bool aspectMode)
{
KisImageWSP image = m_view->image();
KoZoomMode::Mode newMode = KoZoomMode::ZOOM_CONSTANT;
qreal newZoom = m_zoomHandler->zoom();
const KoZoomMode::Mode newMode = KoZoomMode::ZOOM_CONSTANT;
const qreal newZoom = m_zoomHandler->zoom();
const qreal resolutionX =
aspectMode ? image->xRes() / m_devicePixelRatio : POINT_TO_INCH(m_physicalDpiX);
qreal resolutionX = aspectMode ? image->xRes() : POINT_TO_INCH(static_cast<qreal>(KoDpi::dpiX()));
qreal resolutionY = aspectMode ? image->yRes() : POINT_TO_INCH(static_cast<qreal>(KoDpi::dpiY()));
const qreal resolutionY =
aspectMode ? image->yRes() / m_devicePixelRatio : POINT_TO_INCH(m_physicalDpiY);
m_aspectMode = aspectMode;
m_zoomController->setZoom(newMode, newZoom, resolutionX, resolutionY);
m_view->canvasBase()->notifyZoomChanged();
}
void KisZoomManager::pageOffsetChanged()
{
QRectF widgetRect = m_view->canvasBase()->coordinatesConverter()->imageRectInWidgetPixels();
......
......@@ -55,6 +55,8 @@ public:
KisZoomManager(QPointer<KisView> view, KoZoomHandler*, KoCanvasController *);
~KisZoomManager() override;
void updateScreenResolution(QWidget *parentWidget);
void setup(KActionCollection * actionCollection);
void updateGUI();
KoZoomController * zoomController() const {
......@@ -100,6 +102,10 @@ private:
QPointer<QWidget> m_zoomActionWidget;
QPoint m_rulersOffset;
KisSignalAutoConnectionsStore m_mouseTrackingConnections;
qreal m_physicalDpiX;
qreal m_physicalDpiY;
qreal m_devicePixelRatio;
bool m_aspectMode;
};
......
......@@ -657,7 +657,8 @@ void KisOpenGLCanvas2::drawImage()
}
qreal scaleX, scaleY;
converter->imageScale(&scaleX, &scaleY);
converter->imagePhysicalScale(&scaleX, &scaleY);
d->displayShader->setUniformValue(d->displayShader->location(Uniform::ViewportScale), (GLfloat) scaleX);
d->displayShader->setUniformValue(d->displayShader->location(Uniform::TexelSize), (GLfloat) d->openGLImageTextures->texelSize());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment