Add HiDPI support

Authored by volkov on Apr 25 2019, 12:44 PM.

Diff Detail

No Linters Available
No Unit Test Coverage
Build Status
Buildable 11338
Build 11356: arc lint + arc unit
volkov requested review of this revision.Apr 25 2019, 12:44 PM
volkov created this revision.
ngraham added a subscriber: ngraham.

The KSane library is not a framework.

davidedmundson added inline comments.

I don't understand this bit.

What does m_previewImg's devicePixelRatio have to do with anything if we're only now about to create m_previewImg?

It looks more like this needs a fix in m_previewViewer

volkov added inline comments.Apr 25 2019, 2:50 PM

Ah, yes, it's needless, thanks.

volkov updated this revision to Diff 56974.Apr 25 2019, 2:51 PM

removed needless image scaling

sars added a comment.Apr 25 2019, 6:51 PM

Now I must show my ignorance... why do we need this devicePixelRatio in ksanevewer/selectionitem?

When setting and reading the scan areas we are using ratios of maximum....

volkov added a comment.EditedApr 26 2019, 11:28 AM

Qt supports a high DPI mode where the main coordinate system is virtualized and made independent of the display pixel density.
Geometry is now specified in device independent pixels. This includes widget and item geometry, event geometry, desktop, window and screen
geometry, and animation velocities. Rendered output is in device pixels, which corresponds to the display resolution. The ratio between the
device independent and device pixel coordinate systems is the devicePixelRatio.

High resolution versions of pixmaps have a device pixel ratio value larger than 1 (see QImageReader, QPixmap::devicePixelRatio()). Should it
match the value of the underlying QPaintDevice, it is drawn directly onto the device with no additional transformation applied.

This is for example the case when drawing a QPixmap of 64x64 pixels size with a device pixel ratio of 2 onto a high DPI screen which also has
a device pixel ratio of 2. Note that the pixmap is then effectively 32x32 pixels in user space.

We want to draw scanned images without highdpi scaling by Qt, so we set devicePixelRatio for them,
and thus the size of the scanned image is in device pixels. SelectionItem was modified to keep its
geometry also in device pixels to avoid extra changes in ksaneviewer.cpp. For consistency the same
should be done for "hide" items to avoid transforms such as "d->hideLeft->setRect(fromNative(rect, dpr));",
but it requires to create a separate class for them.

You can test the change without HiDPI monitor by setting env var QT_SCALE_FACTOR=2

volkov updated this revision to Diff 57030.Apr 26 2019, 12:35 PM

rebase on extracted HideRectItem

volkov updated this revision to Diff 57036.Apr 26 2019, 1:00 PM

leave a single commit

sars accepted this revision.Apr 28 2019, 7:36 PM

I do not have strong opinion about the with of the line, it just hit me that it might become a bit narrow...


override and same for setRect() ?


Do we want to divide the width of the selection-item border also? might it not become a bit narrow?

This revision is now accepted and ready to land.Apr 28 2019, 7:36 PM
volkov added inline comments.Apr 29 2019, 10:31 AM

They are not virtual...
Maybe public inheritance is not a good choice here.


Qt scales width of a pen by devicePixelRatio, and this is the inverse transform to make it again 1 pixel.


use pen->setWidth(0) instead;

A line width of zero indicates a cosmetic pen. This means that the pen width is always drawn one pixel wide, independent of the transformation set on the painter.

volkov updated this revision to Diff 57175.Apr 29 2019, 12:06 PM

use precise coordinates for selections + use cosmetic pens

volkov marked an inline comment as done.Apr 29 2019, 12:07 PM
davidedmundson accepted this revision.Apr 29 2019, 12:07 PM
volkov updated this revision to Diff 57176.Apr 29 2019, 12:23 PM

emulate missing QGraphicsView::mapToScene(const QPointF &) by using QPainterPath wrapper

volkov closed this revision.Apr 29 2019, 1:13 PM