From 7aef62071526b9983da7b30fb4655a930560b0b0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 7 Nov 2023 00:19:25 +0100 Subject: [PATCH] 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. --- include/wx/withimages.h | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/include/wx/withimages.h b/include/wx/withimages.h index 97a7c3c123..5c8efd34e2 100644 --- a/include/wx/withimages.h +++ b/include/wx/withimages.h @@ -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 ) {