Use non-integer scale that is exact multiple of an available one

Always rounding non-integer scale when upscaling is wrong, as we could
be able to upscale an existing x1.5 image to e.g. 300% DPI scaling with
relatively good results, so only do it if there is no available scale
that exactly divides the requested one.

Add a previously failing unit test which passes now.
This commit is contained in:
Vadim Zeitlin
2022-06-02 01:34:25 +01:00
parent d86c1a8c46
commit 6d5bd15d12
2 changed files with 37 additions and 3 deletions

View File

@@ -711,9 +711,42 @@ wxBitmapBundleImpl::DoGetPreferredSize(double scaleTarget) const
// bitmaps of standard size are scaled when 2x DPI scaling is used.
if ( scaleTarget > 1.5*scaleLast )
{
// However scaling by non-integer scales doesn't work well at all, so
// round it to the closest integer in this case.
scaleBest = wxRound(scaleTarget);
// However scaling by non-integer scales doesn't work well at
// all, so try to find a bitmap that we may rescale by an
// integer factor.
//
// Note that this is similar to GetIndexToUpscale(), but we
// don't want to fall back on the largest bitmap here, so we
// can't reuse it.
//
// Also, while we reenter GetNextAvailableScale() here, it
// doesn't matter because we're not going to continue using it
// in the outer loop any more.
for ( i = 0;; )
{
const double scale = GetNextAvailableScale(i);
if ( scale == 0.0 )
break;
const double factor = scaleTarget / scale;
if ( wxRound(factor) == factor )
{
scaleBest = scaleTarget;
// We don't need to keep going: if there is a bigger
// bitmap which can be scaled using an integer factor
// to the target scale, our GetIndexToUpscale() will
// find it, we don't need to do it here.
break;
}
}
// If none of the bitmaps can be upscaled by an integer factor,
// round the target scale itself, as we can be sure to be able
// to scale at least the base bitmap to it using an integer
// factor then.
if ( scaleBest == 0.0 )
scaleBest = wxRound(scaleTarget);
}
else // Target scale is not much greater than the biggest one we have.
{

View File

@@ -301,6 +301,7 @@ TEST_CASE("BitmapBundle::GetPreferredSize", "[bmpbundle]")
CHECK_THAT( BitmapAtScale(b, 3.33), SameAs(3.0, 1.5) );
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) );
}