Details
-
Bug
-
Resolution: Fixed
-
P1: Critical
-
6.6, 6.7
-
None
-
-
a5953d20e (dev)
Description
Some fractional scaling factors cause a blank line at the edge of the window. This can look quite jarring.
The core of the issue is reproducible without any platform specific code or windows.
int main(int argc, char *argv[]) { QApplication a(argc, argv); QSize logicalSize(1935, 250); qreal dpr = 1.1; QPixmap pixmap(logicalSize * dpr); pixmap.setDevicePixelRatio(dpr); pixmap.fill(Qt::blue); QPainter painter(&pixmap); QBrush brush(Qt::red); painter.fillRect(QRect(QPoint(0,0), logicalSize), brush); painter.end(); pixmap.save("/tmp/test.png"); }
The result should be a solid red rectangle, but we see a line of blue at the end.
This mimics how QWidget draws it's background, which is where we can see our user-facing issue.
I can confirm the rounding issue comes from
qreal devicePixelRatio() const { return metric(PdmDevicePixelRatioScaled) / devicePixelRatioFScale(); }
static inline qreal devicePixelRatioFScale() { return 0x10000; }
as virtual int metric(PaintDeviceMetric metric) const; reutrns an int and we need a float Qt internally multiplies by a big number and divides back. This introduces a very minor error.
In the example our final X position in device pixels is (1935 * 1.1) 2127.5.
fillRect does not antialias by default unless the QPainter flag is set, so it will cut off on an integer device pixel. If we have the right DPR this renders correctly.
When the device pixel should end on .5 the slightest ever so minor difference in rounding of devicePixelRatio can cause us to paint the pixel wrongly.
Attachments
For Gerrit Dashboard: QTBUG-124342 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
557478,2 | Improve accuracy of QPaintDevice's dpr, avoiding painting artifacts | dev | qt/qtbase | Status: ABANDONED | +2 | +1 |
560069,8 | Add QPaintDevice metric query to get precise fractional DPR value | dev | qt/qtbase | Status: MERGED | +2 | 0 |