Add devicePixelRatio metric to QPaintDevice.
Previously QPainter computed the devicePixelRatio based on the physical and logical dpi, and expected that the ratio between them would be either 1x or 2x. This was problematic for paint devices like printers where the physical dpi can be much higher than the logical dpi, and also for QScreen where the physical dpi would have to be defined as a multiple of the logical dpi. Add QPaintDevice::PdmDevicePixelRatio and QPaintDevice:: devicePixelRatio() getter and implement it for the QPaintDevice subclasses. Use it when calculating the highdpi scale transform in qpainter.cpp and when scaling the clip rect in qwidget.cpp. Remove physical dpi scaling for QImage, QPixmap and QOpenGLPaintDevice, reverting to the old behavior. Change-Id: I6c97510613196d4536ff39d08e9750b8782283d4 Reviewed-by: Samuel Rødal <samuel.rodal@digia.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
This commit is contained in:
parent
1f3a67e870
commit
cea58f4b77
@ -4994,12 +4994,17 @@ int QImage::metric(PaintDeviceMetric metric) const
|
||||
break;
|
||||
|
||||
case PdmPhysicalDpiX:
|
||||
return qRound(d->dpmx * 0.0254 * d->devicePixelRatio);
|
||||
return qRound(d->dpmx * 0.0254);
|
||||
break;
|
||||
|
||||
case PdmPhysicalDpiY:
|
||||
return qRound(d->dpmy * 0.0254 * d->devicePixelRatio);
|
||||
return qRound(d->dpmy * 0.0254);
|
||||
break;
|
||||
|
||||
case PdmDevicePixelRatio:
|
||||
return d->devicePixelRatio;
|
||||
break;
|
||||
|
||||
default:
|
||||
qWarning("QImage::metric(): Unhandled metric type %d", metric);
|
||||
break;
|
||||
|
@ -956,6 +956,9 @@ int QPicture::metric(PaintDeviceMetric m) const
|
||||
case PdmDepth:
|
||||
val = 24;
|
||||
break;
|
||||
case PdmDevicePixelRatio:
|
||||
val = 1;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
qWarning("QPicture::metric: Invalid metric command");
|
||||
|
@ -120,6 +120,8 @@ int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) con
|
||||
case QPaintDevice::PdmDpiY: // fall-through
|
||||
case QPaintDevice::PdmPhysicalDpiY:
|
||||
return qt_defaultDpiY();
|
||||
case QPaintDevice::PdmDevicePixelRatio:
|
||||
return 1;
|
||||
default:
|
||||
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
|
||||
break;
|
||||
|
@ -278,11 +278,13 @@ int QRasterPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
|
||||
case QPaintDevice::PdmDpiX:
|
||||
return qt_defaultDpiX();
|
||||
case QPaintDevice::PdmPhysicalDpiX:
|
||||
return qt_defaultDpiX() * image.devicePixelRatio();
|
||||
return qt_defaultDpiX();
|
||||
case QPaintDevice::PdmDpiY:
|
||||
return qt_defaultDpiX();
|
||||
case QPaintDevice::PdmPhysicalDpiY:
|
||||
return qt_defaultDpiY() * image.devicePixelRatio();
|
||||
return qt_defaultDpiY();
|
||||
case QPaintDevice::PdmDevicePixelRatio:
|
||||
return image.devicePixelRatio();
|
||||
default:
|
||||
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
|
||||
break;
|
||||
|
@ -282,9 +282,11 @@ int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
|
||||
case PdmDpiY:
|
||||
return qRound(d_ptr->dpmy * 0.0254);
|
||||
case PdmPhysicalDpiX:
|
||||
return qRound(d_ptr->dpmx * 0.0254 * d_ptr->devicePixelRatio);
|
||||
return qRound(d_ptr->dpmx * 0.0254);
|
||||
case PdmPhysicalDpiY:
|
||||
return qRound(d_ptr->dpmy * 0.0254 * d_ptr->devicePixelRatio);
|
||||
return qRound(d_ptr->dpmy * 0.0254);
|
||||
case PdmDevicePixelRatio:
|
||||
return 1;
|
||||
default:
|
||||
qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric);
|
||||
return 0;
|
||||
|
@ -95,6 +95,8 @@ int QPaintDevice::metric(PaintDeviceMetric m) const
|
||||
} else if (m == PdmNumColors) {
|
||||
// FIXME: does this need to be a real value?
|
||||
return 256;
|
||||
} else if (m == PdmDevicePixelRatio) {
|
||||
return 1;
|
||||
} else {
|
||||
qDebug("Unrecognised metric %d!",m);
|
||||
return 0;
|
||||
|
@ -65,7 +65,8 @@ public:
|
||||
PdmDpiX,
|
||||
PdmDpiY,
|
||||
PdmPhysicalDpiX,
|
||||
PdmPhysicalDpiY
|
||||
PdmPhysicalDpiY,
|
||||
PdmDevicePixelRatio
|
||||
};
|
||||
|
||||
virtual ~QPaintDevice();
|
||||
@ -82,6 +83,7 @@ public:
|
||||
int logicalDpiY() const { return metric(PdmDpiY); }
|
||||
int physicalDpiX() const { return metric(PdmPhysicalDpiX); }
|
||||
int physicalDpiY() const { return metric(PdmPhysicalDpiY); }
|
||||
int devicePixelRatio() const { return metric(PdmDevicePixelRatio); }
|
||||
int colorCount() const { return metric(PdmNumColors); }
|
||||
int depth() const { return metric(PdmDepth); }
|
||||
|
||||
|
@ -114,6 +114,10 @@
|
||||
\value PdmPhysicalDpiY The vertical resolution of the device in
|
||||
dots per inch. See also physicalDpiY().
|
||||
|
||||
\value PdmDevicePixelRatio The device pixel ratio for device. Common
|
||||
values are 1 for normal-dpi displays and 2 for high-dpi "retina"
|
||||
displays.
|
||||
|
||||
\sa metric()
|
||||
*/
|
||||
|
||||
@ -273,3 +277,12 @@
|
||||
|
||||
\sa physicalDpiX(), logicalDpiY()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn int QPaintDevice::devicePixelRatio() const
|
||||
|
||||
Returns the device pixel ratio for device.
|
||||
|
||||
Common values are 1 for normal-dpi displays and 2 for high-dpi
|
||||
"retina" displays.
|
||||
*/
|
||||
|
@ -225,17 +225,24 @@ QTransform QPainterPrivate::viewTransform() const
|
||||
return QTransform();
|
||||
}
|
||||
|
||||
int QPainterPrivate::effectiveDevicePixelRatio() const
|
||||
{
|
||||
// Limited feature introduction for Qt 5.0.0, remove ifdef in a later release.
|
||||
#ifdef Q_OS_MAC
|
||||
// Special cases for devices that does not support PdmDevicePixelRatio go here:
|
||||
if (device->devType() == QInternal::Printer)
|
||||
return 1;
|
||||
|
||||
return qMax(1, device->metric(QPaintDevice::PdmDevicePixelRatio));
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
QTransform QPainterPrivate::hidpiScaleTransform() const
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
// Limited feature introduction for Qt 5.0.0, remove ifdef in a later release.
|
||||
if (device->devType() == QInternal::Printer || device->physicalDpiX() == 0 || device->logicalDpiX() == 0)
|
||||
return QTransform();
|
||||
const qreal deviceScale = (device->physicalDpiX() / device->logicalDpiX());
|
||||
if (deviceScale > 1.0)
|
||||
return QTransform::fromScale(deviceScale, deviceScale);
|
||||
#endif
|
||||
return QTransform();
|
||||
int devicePixelRatio = effectiveDevicePixelRatio();
|
||||
return QTransform::fromScale(devicePixelRatio, devicePixelRatio);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1837,14 +1844,7 @@ bool QPainter::begin(QPaintDevice *pd)
|
||||
|
||||
Q_ASSERT(d->engine->isActive());
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
// Limited feature introduction for Qt 5.0.0, remove ifdef in a later release.
|
||||
const bool isHighDpi = (pd->devType() == QInternal::Printer || d->device->physicalDpiX() == 0 || d->device->logicalDpiX() == 0) ?
|
||||
false : (d->device->physicalDpiX() / d->device->logicalDpiX() > 1);
|
||||
#else
|
||||
const bool isHighDpi = false;
|
||||
#endif
|
||||
if (!d->state->redirectionMatrix.isIdentity() || isHighDpi)
|
||||
if (!d->state->redirectionMatrix.isIdentity() || d->effectiveDevicePixelRatio() > 1)
|
||||
d->updateMatrix();
|
||||
|
||||
Q_ASSERT(d->engine->isActive());
|
||||
|
@ -249,6 +249,7 @@ public:
|
||||
}
|
||||
|
||||
QTransform viewTransform() const;
|
||||
int effectiveDevicePixelRatio() const;
|
||||
QTransform hidpiScaleTransform() const;
|
||||
static bool attachPainterPrivate(QPainter *q, QPaintDevice *pdev);
|
||||
void detachPainterPrivate(QPainter *q);
|
||||
|
@ -1455,6 +1455,9 @@ int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
|
||||
case QPaintDevice::PdmDepth:
|
||||
val = 32;
|
||||
break;
|
||||
case QPaintDevice::PdmDevicePixelRatio:
|
||||
val = 1;
|
||||
break;
|
||||
default:
|
||||
qWarning("QPdfWriter::metric: Invalid metric command");
|
||||
return 0;
|
||||
|
@ -1232,6 +1232,9 @@ int QGLFramebufferObject::metric(PaintDeviceMetric metric) const
|
||||
case PdmPhysicalDpiY:
|
||||
return qRound(dpmy * 0.0254);
|
||||
|
||||
case QPaintDevice::PdmDevicePixelRatio:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric);
|
||||
break;
|
||||
|
@ -67,6 +67,8 @@ int QGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
|
||||
const QGLFormat f = format();
|
||||
return f.redBufferSize() + f.greenBufferSize() + f.blueBufferSize() + f.alphaBufferSize();
|
||||
}
|
||||
case PdmDevicePixelRatio:
|
||||
return 1;
|
||||
default:
|
||||
qWarning("QGLPaintDevice::metric() - metric %d not known", metric);
|
||||
return 0;
|
||||
|
@ -462,6 +462,9 @@ int QGLPixelBuffer::metric(PaintDeviceMetric metric) const
|
||||
case PdmPhysicalDpiY:
|
||||
return qRound(dpmy * 0.0254);
|
||||
|
||||
case QPaintDevice::PdmDevicePixelRatio:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
qWarning("QGLPixelBuffer::metric(), Unhandled metric type: %d\n", metric);
|
||||
break;
|
||||
|
@ -364,6 +364,9 @@ int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
|
||||
case QPaintDevice::PdmDepth:
|
||||
val = 24;
|
||||
break;
|
||||
case QPaintDevice::PdmDevicePixelRatio:
|
||||
val = 1;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
qWarning("QPrinter::metric: Invalid metric command");
|
||||
|
@ -1811,9 +1811,8 @@ void QWidgetPrivate::setSystemClip(QPaintDevice *paintDevice, const QRegion ®
|
||||
// it has been tested.
|
||||
QPaintEngine *paintEngine = paintDevice->paintEngine();
|
||||
#ifdef Q_OS_MAC
|
||||
const qreal devicePixelRatio = (paintDevice->physicalDpiX() == 0 || paintDevice->logicalDpiX() == 0) ?
|
||||
1.0 : (paintDevice->physicalDpiX() / paintDevice->logicalDpiX());
|
||||
QTransform scaleTransform;
|
||||
const qreal devicePixelRatio = paintDevice->devicePixelRatio();
|
||||
scaleTransform.scale(devicePixelRatio, devicePixelRatio);
|
||||
paintEngine->d_func()->systemClip = scaleTransform.map(region);
|
||||
#else
|
||||
|
@ -836,6 +836,8 @@ int QWidget::metric(PaintDeviceMetric m) const
|
||||
return qRound(screen->physicalDotsPerInchX());
|
||||
} else if (m == PdmPhysicalDpiY) {
|
||||
return qRound(screen->physicalDotsPerInchY());
|
||||
} else if (m == PdmDevicePixelRatio) {
|
||||
return screen->devicePixelRatio();
|
||||
} else {
|
||||
val = QPaintDevice::metric(m);// XXX
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user