Fix GetSubBitmap() returned value size when rounding is required

When using non-integer scale factor, we need to round the result of the
multiplication by it instead of truncating it for consistency with the
behaviour of wxBitmap::CreateWithDIPSize() and the other places where we
do this, including wxOSX version of this function.

Add a simple unit test checking that this works correctly (it would fail
with wxGTK before).
This commit is contained in:
Vadim Zeitlin 2023-10-29 00:50:40 +02:00
parent 4048542d54
commit 2cf77c2596
2 changed files with 29 additions and 1 deletions

View file

@ -1062,7 +1062,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect& r) const
const wxBitmapRefData* bmpData = M_BMPDATA;
#ifdef __WXGTK3__
const double s = bmpData->m_scaleFactor;
const wxRect rect(int(r.x * s), int(r.y * s), int(r.width * s), int(r.height * s));
const wxRect rect(wxRound(r.x * s), wxRound(r.y * s), wxRound(r.width * s), wxRound(r.height * s));
#else
const wxRect& rect = r;
#endif

View file

@ -1826,4 +1826,32 @@ TEST_CASE("Bitmap::ScaleFactor", "[bitmap][dc][scale]")
CHECK( bmp3.GetSize() == wxSize(16, 16) );
}
TEST_CASE("wxBitmap::GetSubBitmap", "[bitmap]")
{
// Make the logical size odd to test correct rounding.
const double scale = 1.5;
const wxSize sizeLog(15, 15);
const wxSize sizePhy(23, 23);
// Prepare the main bitmap.
wxBitmap bmp;
bmp.CreateWithDIPSize(sizeLog, scale);
CHECK( bmp.GetDIPSize() == sizeLog );
CHECK( bmp.GetSize() == sizePhy );
CHECK( bmp.GetScaleFactor() == scale );
// Extracting sub-bitmap of the entire bitmap size should return the bitmap
// of the same size.
#if wxHAS_DPI_INDEPENDENT_PIXELS
const wxRect rectAll(wxPoint(0, 0), sizeLog);
#else
const wxRect rectAll(wxPoint(0, 0), sizePhy);
#endif
const wxBitmap sub = bmp.GetSubBitmap(rectAll);
CHECK( sub.GetDIPSize() == sizeLog );
CHECK( sub.GetSize() == sizePhy );
CHECK( sub.GetScaleFactor() == scale );
}
#endif // ports with scaled bitmaps support