QPainter: fix assert when drawing bitmaps at very near to .5 coord
The code assumed that the rounding of a floating point value, and the rounding of the sum of that value and an integer, would always snap in the same direction. But because of accuracy limits (independently of the rounding function employed), that is not always the case for fractions very near to .5. Fixes: QTBUG-122451 Pick-to: 6.6 6.5 6.2 5.15 Change-Id: I0825d42e6be7f6e3397760a5e9be5dddca42dcdc Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> (cherry picked from commit a43d86fe1c0bc9d352f67c134a9ee5f754aea5e6) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
d251de904a
commit
824d293601
@ -3397,16 +3397,18 @@ void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSp
|
|||||||
// Boundaries
|
// Boundaries
|
||||||
int w = image.width();
|
int w = image.width();
|
||||||
int h = image.height();
|
int h = image.height();
|
||||||
int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height());
|
int px = qRound(pos.x());
|
||||||
int ymin = qMax(qRound(pos.y()), 0);
|
int py = qRound(pos.y());
|
||||||
int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width());
|
int ymax = qMin(py + h, d->rasterBuffer->height());
|
||||||
int xmin = qMax(qRound(pos.x()), 0);
|
int ymin = qMax(py, 0);
|
||||||
|
int xmax = qMin(px + w, d->rasterBuffer->width());
|
||||||
|
int xmin = qMax(px, 0);
|
||||||
|
|
||||||
int x_offset = xmin - qRound(pos.x());
|
int x_offset = xmin - px;
|
||||||
|
|
||||||
QImage::Format format = image.format();
|
QImage::Format format = image.format();
|
||||||
for (int y = ymin; y < ymax; ++y) {
|
for (int y = ymin; y < ymax; ++y) {
|
||||||
const uchar *src = image.scanLine(y - qRound(pos.y()));
|
const uchar *src = image.scanLine(y - py);
|
||||||
if (format == QImage::Format_MonoLSB) {
|
if (format == QImage::Format_MonoLSB) {
|
||||||
for (int x = 0; x < xmax - xmin; ++x) {
|
for (int x = 0; x < xmax - xmin; ++x) {
|
||||||
int src_x = x + x_offset;
|
int src_x = x + x_offset;
|
||||||
|
@ -61,6 +61,7 @@ private slots:
|
|||||||
#endif
|
#endif
|
||||||
void drawPixmapFragments();
|
void drawPixmapFragments();
|
||||||
void drawPixmapNegativeScale();
|
void drawPixmapNegativeScale();
|
||||||
|
void drawPixmapRounding();
|
||||||
|
|
||||||
void drawLine_data();
|
void drawLine_data();
|
||||||
void drawLine();
|
void drawLine();
|
||||||
@ -747,6 +748,16 @@ void tst_QPainter::drawPixmapNegativeScale()
|
|||||||
QVERIFY(resultImage.pixel(12, 8) == qRgba(0, 0, 0, 255)); // and right strip is now black
|
QVERIFY(resultImage.pixel(12, 8) == qRgba(0, 0, 0, 255)); // and right strip is now black
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QPainter::drawPixmapRounding()
|
||||||
|
{
|
||||||
|
// Just test that we don't assert
|
||||||
|
QBitmap bm(8, 8);
|
||||||
|
QImage out(64, 64, QImage::Format_RGB32);
|
||||||
|
QPainter p(&out);
|
||||||
|
qreal y = 26.499999999999996;
|
||||||
|
p.drawPixmap(QPointF(0, y), bm);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QPainter::drawLine_data()
|
void tst_QPainter::drawLine_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<QLine>("line");
|
QTest::addColumn<QLine>("line");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user