From 7b4257b9cda8bbbaf8a6e19068bf60d4b6d69a92 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Oct 2021 23:15:02 +0200 Subject: [PATCH] Respect the scale of the bitmap converted to wxBitmapBundle Use the scaled size, different from the default size, when constructing wxBitmapBundle from an existing wxBitmap to keep the existing code using scaled bitmaps working. Add a unit test checking that this now works as expected under the platforms where scale factor is used. --- src/common/bmpbndl.cpp | 15 +++++++++++++-- tests/graphics/bmpbundle.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/common/bmpbndl.cpp b/src/common/bmpbndl.cpp index f89c3490f4..af6702d08a 100644 --- a/src/common/bmpbndl.cpp +++ b/src/common/bmpbndl.cpp @@ -110,6 +110,11 @@ private: // Note that this vector is never empty. Entries m_entries; + // The size of the bitmap at the default size. + // + // Note that it may be different from the size of the first entry if we + // only have high resolution bitmap and no bitmap for 100% DPI. + wxSize m_sizeDefault; // Common implementation of all ctors. void Init(const wxBitmap* bitmaps, size_t n); @@ -141,6 +146,13 @@ void wxBitmapBundleImplSet::Init(const wxBitmap* bitmaps, size_t n) std::sort(m_entries.begin(), m_entries.end(), BitmapSizeComparator()); + // This is not normally the case, but it could happen that even the + // smallest bitmap has scale factor > 1, so use its scaled size (this can + // notably be the case when there is only a single high resolution bitmap + // provided, e.g. in the code predating wxBitmapBundle introduction but now + // using it due to implicit conversion to it from wxBitmap). + m_sizeDefault = m_entries[0].bitmap.GetScaledSize(); + // Should we check that all bitmaps really have unique sizes here? For now, // don't bother with this, but we might want to do it later if it really // turns out to be a problem in practice. @@ -152,8 +164,7 @@ void wxBitmapBundleImplSet::Init(const wxBitmap* bitmaps, size_t n) wxSize wxBitmapBundleImplSet::GetDefaultSize() const { - // Default size is the size of the smallest bitmap in the bundle. - return m_entries[0].bitmap.GetSize(); + return m_sizeDefault; } wxSize wxBitmapBundleImplSet::GetPreferredSizeAtScale(double scale) const diff --git a/tests/graphics/bmpbundle.cpp b/tests/graphics/bmpbundle.cpp index b14a25148c..b08fafc26a 100644 --- a/tests/graphics/bmpbundle.cpp +++ b/tests/graphics/bmpbundle.cpp @@ -68,6 +68,40 @@ TEST_CASE("BitmapBundle::GetPreferredSize", "[bmpbundle]") CHECK( b.GetPreferredSizeAtScale(3 ) == bigger ); } +#ifdef wxHAS_BITMAP_SCALE_FACTOR + +TEST_CASE("BitmapBundle::Scaled", "[bmpbundle]") +{ + // Adding a bitmap with scale factor > 1 should create the bundle using the + // scaled size as default size. + wxBitmap scaled2x(64, 64); + scaled2x.SetScaleFactor(2); + CHECK( scaled2x.GetScaledSize() == wxSize(32, 32) ); + + wxBitmapBundle b(scaled2x); + CHECK( b.GetDefaultSize() == wxSize(32, 32) ); + + // Retrieving this bitmap back from the bundle should preserve its scale. + scaled2x = b.GetBitmap(wxSize(64, 64)); + CHECK( scaled2x.GetSize() == wxSize(64, 64) ); + CHECK( scaled2x.GetScaleFactor() == 2 ); + + // And retrieving the bitmap from the bundle should set scale factor for it + // even if it hadn't originally been added with it. + b = wxBitmapBundle::FromBitmaps(wxBitmap(32, 32), wxBitmap(64, 64)); + scaled2x = b.GetBitmap(wxSize(64, 64)); + CHECK( scaled2x.GetSize() == wxSize(64, 64) ); + CHECK( scaled2x.GetScaleFactor() == 2 ); + + // Using scaled bitmaps when there is more than one of them is a bad idea + // in general, as only physical size matters, but the default size should + // still be the scaled size of the smallest one. + b = wxBitmapBundle::FromBitmaps(scaled2x, wxBitmap(64, 64)); + CHECK( b.GetDefaultSize() == wxSize(32, 32) ); +} + +#endif // wxHAS_BITMAP_SCALE_FACTOR + #ifdef wxHAS_SVG TEST_CASE("BitmapBundle::FromSVG", "[bmpbundle][svg]")