Fix using bitmaps of different dimensions in wxWithImages

Although this is not ideal, it may still happen and sometimes can even
give acceptable results, e.g. using (16, 32) and (24) bitmap bundles
can actuall works nicely enough at x2 scaling if 16px bitmaps are
upscaled by the factor of 3.

To make this work, request the explicit physical bitmap size and
override its scale factor to ensure the resulting bitmap has the correct
logical size.
This commit is contained in:
Vadim Zeitlin 2023-11-07 00:19:25 +01:00
parent baa56732fc
commit 7aef620715

View file

@ -129,10 +129,10 @@ public:
return m_imageList;
}
// Return logical bitmap size that should be used for all images.
// Return physical bitmap size that should be used for all images.
//
// Returns (0, 0) if we don't have any images.
wxSize GetImageLogicalSize(const wxWindow* window) const
wxSize GetImageSize(const wxWindow* window) const
{
wxSize size;
@ -145,7 +145,15 @@ public:
else if ( !m_images.empty() )
size = wxBitmapBundle::GetConsensusSizeFor(window, m_images);
return window->FromPhys(size);
return size;
}
// Return logical bitmap size that should be used for all images.
//
// Returns (0, 0) if we don't have any images.
wxSize GetImageLogicalSize(const wxWindow* window) const
{
return window->FromPhys(GetImageSize(window));
}
// Return logical size of the image to use or (0, 0) if there are none.
@ -190,7 +198,23 @@ public:
{
if ( !m_images.empty() )
{
bitmap = m_images.at(iconIndex).GetBitmapFor(window);
// Note that it's not enough to just use GetBitmapFor() here to
// choose the bitmap of the size most appropriate for the window
// DPI as we need it to be of the same size as the other images
// used in the same control, so we have to use fixed size here.
const wxSize size = GetImageSize(window);
bitmap = m_images.at(iconIndex).GetBitmap(size);
// We also may need to adjust the scale factor to ensure that
// this bitmap takes the same space as all the others, as
// GetBitmap() may set it wrong in this case.
const wxSize logicalSize = window->FromPhys(size);
if ( bitmap.GetLogicalSize() != logicalSize )
{
bitmap.SetScaleFactor(size.y / logicalSize.y);
}
}
else if ( m_imageList )
{