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]")