mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-09-26 09:56:32 +08:00
Fix scale computation in wxBitmapBundle for some bitmap sizes
GetNextAvailableScale() returned wrong result when the bitmap size was not exactly divisible by the scale, but this didn't matter for square bitmaps because multiplying the default size by the not quite correct scale still rounded to the correct size. This was not the case for non-square bitmaps, however, as all our computations use only bitmap height and dividing bitmap width by the exact scale and multiplying it by the scale computed from the scaled and unscaled height values could result in a value different from the initial one, as shown by the newly added unit test, which failed before this commit. Fix this by computing the ratio of the bitmap to the base one and then multiplying this ratio by the bitmap scale. Closes #24433.
This commit is contained in:
+15
-1
@@ -248,7 +248,21 @@ double wxBitmapBundleImplSet::GetNextAvailableScale(size_t& i) const
|
||||
if ( entry.generated )
|
||||
continue;
|
||||
|
||||
return static_cast<double>(entry.bitmap.GetSize().y) / GetDefaultSize().y;
|
||||
const wxBitmap& bitmap = entry.bitmap;
|
||||
|
||||
// Determining the scale is not as simple as just dividing the bitmap
|
||||
// height by the bundle height, because this could give us a scale
|
||||
// different from the one actually used by the bitmap: e.g. the size of
|
||||
// a bundle constructed from a single 16x16 bitmap using 1.5 scale
|
||||
// would be 11x11 and 16/11 != 1.5 that we want.
|
||||
//
|
||||
// So instead compute the ratio of the bitmap size in DIPs to the
|
||||
// bundle size, which uses the same rounding, and then multiply it by
|
||||
// the scale factor of the bitmap to get the real scale.
|
||||
const double ratio =
|
||||
static_cast<double>(bitmap.GetDIPSize().y) / GetDefaultSize().y;
|
||||
|
||||
return ratio * bitmap.GetScaleFactor();
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
|
||||
@@ -313,6 +313,14 @@ TEST_CASE("BitmapBundle::GetPreferredSize", "[bmpbundle]")
|
||||
CHECK_THAT( BitmapAtScale(b, 4.25), SameAs(4.0, 2.0) );
|
||||
CHECK_THAT( BitmapAtScale(b, 4.50), SameAs(4.5, 1.5) );
|
||||
CHECK_THAT( BitmapAtScale(b, 5 ), SameAs(5.0, 1.0) );
|
||||
|
||||
|
||||
// Another check to detect that the scale is computed correctly even when
|
||||
// rounding is involved.
|
||||
wxBitmap nonSquare(wxSize(51, 41));
|
||||
nonSquare.SetScaleFactor(1.5);
|
||||
b = wxBitmapBundle::FromBitmap(nonSquare);
|
||||
CHECK( b.GetPreferredBitmapSizeAtScale(1.5) == nonSquare.GetSize() );
|
||||
}
|
||||
|
||||
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
|
||||
|
||||
Reference in New Issue
Block a user