Fix drawTiledPixmap() and texture-brush painting with high-DPR images

Although QPainter::drawImage()/drawPixmap() would render images scaled
according to their devicePixelRatio(), that would not happen for
drawTiledPixmap() and when using a textured brush. Implemented here,
in combination with the pending "High-dpi drawTiledPixmap (raster
paint engine)" commit.

[ChangeLog][QtGui] Fix drawTiledPixmap() and texture-brush painting with high-DPR images

Task-number: QTBUG-67248
Change-Id: I037e3f897fa708038a0222d3b0c61c7842d87961
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
This commit is contained in:
Eirik Aavitsland 2018-04-09 12:37:19 +02:00 committed by Simon Hausmann
parent 29b012eb0f
commit bd1fd197ca
6 changed files with 102 additions and 1 deletions

View File

@ -101,6 +101,14 @@ void QEmulationPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
real_engine->fill(path, copy);
return;
}
} else if (style == Qt::TexturePattern) {
qreal dpr = qHasPixmapTexture(brush) ? brush.texture().devicePixelRatioF() : brush.textureImage().devicePixelRatioF();
if (!qFuzzyCompare(dpr, 1.0)) {
QBrush copy = brush;
combineXForm(&copy, QRectF(0, 0, 1.0/dpr, 1.0/dpr));
real_engine->fill(path, copy);
return;
}
}
real_engine->fill(path, brush);

View File

@ -948,6 +948,8 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con
{
QBrush brush(state()->pen.color(), pixmap);
QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y());
if (!qFuzzyCompare(pixmap.devicePixelRatioF(), 1.0))
xform.scale(1.0/pixmap.devicePixelRatioF(), 1.0/pixmap.devicePixelRatioF());
brush.setTransform(xform);
qreal pts[] = { r.x(), r.y(),

View File

@ -190,6 +190,13 @@ void QPainterPrivate::checkEmulation()
if (pg && pg->coordinateMode() > QGradient::LogicalMode)
doEmulation = true;
if (state->brush.style() == Qt::TexturePattern) {
if (qHasPixmapTexture(state->brush))
doEmulation |= !qFuzzyCompare(state->brush.texture().devicePixelRatioF(), 1.0);
else
doEmulation |= !qFuzzyCompare(state->brush.textureImage().devicePixelRatioF(), 1.0);
}
if (doEmulation && extended->flags() & QPaintEngineEx::DoNotEmulate)
return;

View File

@ -561,6 +561,10 @@ void PaintCommands::staticInit()
"^bitmap_load\\s+([\\w.:\\/]*)\\s*([\\w.:\\/]*)$",
"bitmap_load <bitmap filename> <bitmapName>\n - note that the image is stored as a pixmap",
"bitmap_load :/images/bitmap.png myBitmap");
DECL_PAINTCOMMAND("pixmap_setDevicePixelRatio", command_pixmap_setDevicePixelRatio,
"^pixmap_setDevicePixelRatio\\s+([\\w.:\\/]*)\\s+([.0-9]*)$",
"pixmap_setDevicePixelRatio <pixmapName> <dpr>",
"pixmap_setDevicePixelRatio myPixmap 2.0");
DECL_PAINTCOMMAND("image_convertToFormat", command_image_convertToFormat,
"^image_convertToFormat\\s+([\\w.:\\/]*)\\s+([\\w.:\\/]+)\\s+([\\w0-9_]*)$",
"image_convertToFormat <sourceImageName> <destImageName> <image format enum>",
@ -577,6 +581,10 @@ void PaintCommands::staticInit()
"^image_setColorCount\\s+([\\w.:\\/]*)\\s+([0-9]*)$",
"image_setColorCount <imageName> <nbColors>",
"image_setColorCount myImage 128");
DECL_PAINTCOMMAND("image_setDevicePixelRatio", command_image_setDevicePixelRatio,
"^image_setDevicePixelRatio\\s+([\\w.:\\/]*)\\s+([.0-9]*)$",
"image_setDevicePixelRatio <imageName> <dpr>",
"image_setDevicePixelRatio myImage 2.0");
DECL_PAINTCOMMANDSECTION("transformations");
DECL_PAINTCOMMAND("resetMatrix", command_resetMatrix,
@ -1761,7 +1769,9 @@ void PaintCommands::command_setBrush(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QImage img = image_load<QImage>(caps.at(1));
QImage img = m_imageMap[caps.at(1)]; // try cache first
if (img.isNull())
img = image_load<QImage>(caps.at(1));
if (!img.isNull()) { // Assume image brush
if (m_verboseMode)
printf(" -(lance) setBrush(image=%s, width=%d, height=%d)\n",
@ -2132,6 +2142,20 @@ void PaintCommands::command_bitmap_load(QRegularExpressionMatch re)
m_pixmapMap[name] = bm;
}
void PaintCommands::command_pixmap_setDevicePixelRatio(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double dpr = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) pixmap_setDevicePixelRatio(%s), %.1f -> %.1f\n",
qPrintable(name), m_pixmapMap[name].devicePixelRatioF(), dpr);
m_pixmapMap[name].setDevicePixelRatio(dpr);
}
/***************************************************************************************************/
void PaintCommands::command_pixmap_setMask(QRegularExpressionMatch re)
{
@ -2196,6 +2220,21 @@ void PaintCommands::command_image_setColor(QRegularExpressionMatch re)
m_imageMap[name].setColor(index, color.rgba());
}
/***************************************************************************************************/
void PaintCommands::command_image_setDevicePixelRatio(QRegularExpressionMatch re)
{
QStringList caps = re.capturedTexts();
QString name = caps.at(1);
double dpr = convertToDouble(caps.at(2));
if (m_verboseMode)
printf(" -(lance) image_setDevicePixelRatio(%s), %.1f -> %.1f\n",
qPrintable(name), m_imageMap[name].devicePixelRatioF(), dpr);
m_imageMap[name].setDevicePixelRatio(dpr);
}
/***************************************************************************************************/
void PaintCommands::command_abort(QRegularExpressionMatch)
{

View File

@ -229,10 +229,12 @@ private:
void command_pixmap_load(QRegularExpressionMatch re);
void command_pixmap_setMask(QRegularExpressionMatch re);
void command_bitmap_load(QRegularExpressionMatch re);
void command_pixmap_setDevicePixelRatio(QRegularExpressionMatch re);
void command_image_convertToFormat(QRegularExpressionMatch re);
void command_image_load(QRegularExpressionMatch re);
void command_image_setColor(QRegularExpressionMatch re);
void command_image_setColorCount(QRegularExpressionMatch re);
void command_image_setDevicePixelRatio(QRegularExpressionMatch re);
// commands: transformation
void command_resetMatrix(QRegularExpressionMatch re);

View File

@ -0,0 +1,43 @@
setRenderHint Antialiasing true
setRenderHint SmoothPixmapTransform true
image_load sign.png img1
pixmap_load sign.png pix1
begin_block drawIt
save
drawImage img1 20 20 -1 -1
drawRect 17.5 17.5 85 85
setBrush img1
setPen NoPen
drawRect 20 120 120 120
brushRotate 45
drawRect 20 260 120 120
setBrush NoBrush
drawTiledPixmap pix1 20 400 120 120
restore
end_block
save
translate 150 0
rotate -5
repeat_block drawIt
restore
image_setDevicePixelRatio img1 2.0
pixmap_setDevicePixelRatio pix1 2.0
translate 400 0
repeat_block drawIt
save
translate 150 0
rotate -5
repeat_block drawIt
restore