mirror of
https://invent.kde.org/graphics/okular
synced 2024-10-02 14:14:10 +00:00
Fixed issue with occasional mis-sized tile
It turns out that there were two issues at play here: rounding errors meant that pixmaps were almost never the same size as pagePainter thought the tiles should be, and the tile-is-the-size-it-should-be code path was broken (but only hit in rare cases, seemingly at random). To help with rounding errors in the future, I added a geometryF function to NormalizedRect that returns a QRectF. In general, device-independent-pixel points/rects should be floating point, and device-pixel rects should be integer.
This commit is contained in:
parent
521ea660ee
commit
8c61b6a2b4
|
@ -243,6 +243,13 @@ QRect NormalizedRect::roundedGeometry(int xScale, int yScale) const
|
|||
return QRect(l, t, r - l + 1, b - t + 1);
|
||||
}
|
||||
|
||||
QRectF NormalizedRect::geometryF(float xScale, float yScale) const
|
||||
{
|
||||
float l = (left * xScale), t = (top * yScale), r = (right * xScale), b = (bottom * yScale);
|
||||
|
||||
return QRectF(l, t, r - l, b - t);
|
||||
}
|
||||
|
||||
void NormalizedRect::transform(const QTransform &matrix)
|
||||
{
|
||||
QRectF rect(left, top, right - left, bottom - top);
|
||||
|
|
|
@ -282,6 +282,11 @@ public:
|
|||
*/
|
||||
QRect roundedGeometry(int xScale, int yScale) const;
|
||||
|
||||
/**
|
||||
* Same functionality as geometry, but nothing is converted into int.
|
||||
*/
|
||||
QRectF geometryF(float xScale, float yScale) const;
|
||||
|
||||
/**
|
||||
* Returns the normalized bounding rectangle of the normalized rectangle
|
||||
* combined with the @p other normalized rectangle.
|
||||
|
|
|
@ -247,18 +247,18 @@ void PagePainter::paintCroppedPageOnPainter(QPainter *destPainter,
|
|||
QList<Okular::Tile>::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd();
|
||||
while (tIt != tEnd) {
|
||||
const Okular::Tile &tile = *tIt;
|
||||
QRect tileRect = tile.rect().geometry(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft());
|
||||
QRect dTileRect = QRectF(tileRect.x() * dpr, tileRect.y() * dpr, tileRect.width() * dpr, tileRect.height() * dpr).toAlignedRect();
|
||||
QRect limitsInTile = limits & tileRect;
|
||||
QRectF dLimitsInTile = dLimits & dTileRect;
|
||||
QRectF tileRect = tile.rect().geometryF(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft());
|
||||
QRect dTileRect = tile.rect().geometry(dScaledWidth, dScaledHeight).translated(-dScaledCrop.topLeft());
|
||||
QRectF limitsInTile = QRectF(limits) & tileRect;
|
||||
QRect dLimitsInTile = dLimits & dTileRect;
|
||||
|
||||
if (!limitsInTile.isEmpty()) {
|
||||
QPixmap *tilePixmap = tile.pixmap();
|
||||
|
||||
if (tilePixmap->width() == dTileRect.width() && tilePixmap->height() == dTileRect.height()) {
|
||||
destPainter->drawPixmap(limitsInTile.topLeft(), *tilePixmap, dLimitsInTile.translated(-dTileRect.topLeft()));
|
||||
destPainter->drawPixmap(limitsInTile, *tilePixmap, dLimitsInTile.translated(-dTileRect.topLeft()));
|
||||
} else {
|
||||
destPainter->drawPixmap(tileRect, *tilePixmap);
|
||||
destPainter->drawPixmap(tileRect, *tilePixmap, tilePixmap->rect());
|
||||
}
|
||||
}
|
||||
tIt++;
|
||||
|
@ -284,16 +284,16 @@ void PagePainter::paintCroppedPageOnPainter(QPainter *destPainter,
|
|||
QList<Okular::Tile>::const_iterator tIt = tiles.constBegin(), tEnd = tiles.constEnd();
|
||||
while (tIt != tEnd) {
|
||||
const Okular::Tile &tile = *tIt;
|
||||
QRect tileRect = tile.rect().geometry(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft());
|
||||
QRect dTileRect(QRectF(tileRect.x() * dpr, tileRect.y() * dpr, tileRect.width() * dpr, tileRect.height() * dpr).toAlignedRect());
|
||||
QRect limitsInTile = limits & tileRect;
|
||||
QRectF tileRect = tile.rect().geometryF(scaledWidth, scaledHeight).translated(-scaledCrop.topLeft());
|
||||
QRect dTileRect = tile.rect().geometry(dScaledWidth, dScaledHeight).translated(-dScaledCrop.topLeft());
|
||||
QRectF limitsInTile = QRectF(limits) & tileRect;
|
||||
QRect dLimitsInTile = dLimits & dTileRect;
|
||||
|
||||
if (!limitsInTile.isEmpty()) {
|
||||
QPixmap *tilePixmap = tile.pixmap();
|
||||
|
||||
if (tilePixmap->width() == dTileRect.width() && tilePixmap->height() == dTileRect.height()) {
|
||||
p.drawPixmap(limitsInTile.translated(-limits.topLeft()).topLeft(), *tilePixmap, dLimitsInTile.translated(-dTileRect.topLeft()));
|
||||
p.drawPixmap(limitsInTile.translated(-limits.topLeft()), *tilePixmap, dLimitsInTile.translated(-dTileRect.topLeft()));
|
||||
} else {
|
||||
double xScale = tilePixmap->width() / (double)dTileRect.width();
|
||||
double yScale = tilePixmap->height() / (double)dTileRect.height();
|
||||
|
|
Loading…
Reference in a new issue