From 691a11989ee1b9eac2e4410894499d544b55fdba Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 23 Oct 2021 20:55:28 +0200 Subject: [PATCH 1/8] Move wxBitmap::ConvertToDisabled() to respect alphabetic order No real changes, just keep the functions sorted as they're clearly intended to be here. This commit is best viewed with --color-moved git option. --- interface/wx/bitmap.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/interface/wx/bitmap.h b/interface/wx/bitmap.h index 734605e350..da167982f1 100644 --- a/interface/wx/bitmap.h +++ b/interface/wx/bitmap.h @@ -402,6 +402,15 @@ public: */ static void CleanUpHandlers(); + /** + Returns disabled (dimmed) version of the bitmap. + + This method is not available when wxUSE_IMAGE == 0. + + @since 2.9.0 + */ + wxBitmap ConvertToDisabled(unsigned char brightness = 255) const; + /** Creates an image from a platform-dependent bitmap. This preserves mask information so that bitmaps and images can be converted back @@ -577,15 +586,6 @@ public: */ wxSize GetSize() const; - /** - Returns disabled (dimmed) version of the bitmap. - - This method is not available when wxUSE_IMAGE == 0. - - @since 2.9.0 - */ - wxBitmap ConvertToDisabled(unsigned char brightness = 255) const; - /** Gets the width of the bitmap in pixels. From b258d02be35482b3e48f22468646543475e8ca7d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 23 Oct 2021 21:10:50 +0200 Subject: [PATCH 2/8] Document wxBitmap::GetScaleFactor() and related methods These methods were added 8+ years ago but never documented for some reason, finally do it now. --- interface/wx/bitmap.h | 61 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/interface/wx/bitmap.h b/interface/wx/bitmap.h index da167982f1..0456114c2b 100644 --- a/interface/wx/bitmap.h +++ b/interface/wx/bitmap.h @@ -551,7 +551,7 @@ public: /** Gets the height of the bitmap in pixels. - @see GetWidth(), GetSize() + @see GetWidth(), GetSize(), GetScaledHeight() */ virtual int GetHeight() const; @@ -577,19 +577,74 @@ public: */ virtual wxBitmap GetSubBitmap(const wxRect& rect) const; + /** + Returns the scale factor of this bitmap. + + Scale factor is 1 by default, but can be greater to indicate that the + size of bitmap in logical, DPI-independent pixels is smaller than its + actual size in physical pixels. Bitmaps with scale factor greater than + 1 must be used in high DPI to appear sharp on the screen. + + Note that the scale factor is only used in the ports where logical + pixels are not the same as physical ones, such as wxOSX or wxGTK3. + + @see GetScaledWidth(), GetScaledHeight(), GetScaledSize() + + @since 2.9.5 + */ + virtual double GetScaleFactor() const; + + /** + Returns the scaled height of the bitmap. + + See GetScaledSize() for more information. + + @see GetScaledWidth(), GetHeight() + + @since 2.9.5 + */ + virtual double GetScaledHeight() const; + + /** + Returns the scaled size of the bitmap. + + The scaled size of the bitmap is its size in pixels, as returned by + GetSize(), divided by its scale factor, as returned by + GetScaleFactor(), and so is the same as the normal size for bitmaps + with the default scale factor of 1 and always less than the physical + size for the higher resolution bitmaps supposed to be used on high DPI + screens. + + @see GetScaledWidth(), GetScaledHeight(), GetSize() + + @since 2.9.5 + */ + virtual wxSize GetScaledSize() const; + + /** + Returns the scaled width of the bitmap. + + See GetScaledSize() for more information. + + @see GetScaledHeight(), GetWidth() + + @since 2.9.5 + */ + virtual double GetScaledWidth() const; + /** Returns the size of the bitmap in pixels. @since 2.9.0 - @see GetHeight(), GetWidth() + @see GetHeight(), GetWidth(), GetScaledSize() */ wxSize GetSize() const; /** Gets the width of the bitmap in pixels. - @see GetHeight(), GetSize() + @see GetHeight(), GetSize(), GetScaledWidth() */ virtual int GetWidth() const; From c8f76dea8ea92d49123726cd8fb929cd9efdaf39 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 23 Oct 2021 20:24:52 +0100 Subject: [PATCH 3/8] Simplify wxBitmap::GetScaledXXX() in wxMSW The scale factor is always 1 in this port, so don't bother dividing or rounding by it. --- include/wx/msw/bitmap.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index 4d661ff13c..260ec080de 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -187,10 +187,9 @@ public: // support for scaled bitmaps virtual double GetScaleFactor() const { return 1.0; } - virtual double GetScaledWidth() const { return GetWidth() / GetScaleFactor(); } - virtual double GetScaledHeight() const { return GetHeight() / GetScaleFactor(); } - virtual wxSize GetScaledSize() const - { return wxSize(wxRound(GetScaledWidth()), wxRound(GetScaledHeight())); } + virtual double GetScaledWidth() const { return GetWidth(); } + virtual double GetScaledHeight() const { return GetHeight(); } + virtual wxSize GetScaledSize() const { return GetSize(); } // implementation only from now on // ------------------------------- From 2c1f4c002d0b4fc81af9f4e14813a8eb7d132964 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 23 Oct 2021 21:18:37 +0200 Subject: [PATCH 4/8] Add wxBitmap::SetScaleFactor() We need to be able to change the scale factor of the bitmaps returned by wxBitmapBundle::GetBitmap(), so add a function allowing to do this. Also add wxHAS_BITMAP_SCALE_FACTOR allowing to check whether this function actually does something non-trivial and explain in the docs that GetScaleFactor() always returns 1 on the platforms where this symbol is not defined. --- docs/doxygen/mainpages/const_cpp.h | 3 +++ include/wx/bitmap.h | 1 + include/wx/gtk/bitmap.h | 7 +++++- include/wx/msw/bitmap.h | 1 + include/wx/osx/bitmap.h | 3 +++ interface/wx/bitmap.h | 39 +++++++++++++++++++++++++++--- src/gtk/bitmap.cpp | 7 ++++++ src/osx/core/bitmap.cpp | 9 +++++++ 8 files changed, 66 insertions(+), 4 deletions(-) diff --git a/docs/doxygen/mainpages/const_cpp.h b/docs/doxygen/mainpages/const_cpp.h index 0c9fdd9b8b..cf3bacf7ab 100644 --- a/docs/doxygen/mainpages/const_cpp.h +++ b/docs/doxygen/mainpages/const_cpp.h @@ -167,6 +167,9 @@ Currently the following symbols exist: have an efficient (CPU-specific) implementation. Notice that the functions themselves are always available but can be prohibitively slow to use when implemented in a generic way, using a critical section.} +@itemdef{wxHAS_BITMAP_SCALE_FACTOR, Defined in @c wx/bitmap.h if bitmaps + actually use scale factor under the current platform, see + wxBitmap::SetScaleFactor().} @itemdef{wxHAS_BITMAPTOGGLEBUTTON, Defined in @c wx/tglbtn.h if wxBitmapToggleButton class is available in addition to wxToggleButton.} @itemdef{wxHAS_CONFIG_TEMPLATE_RW, Defined if the currently used compiler diff --git a/include/wx/bitmap.h b/include/wx/bitmap.h index e4cb25302f..68e49a03ea 100644 --- a/include/wx/bitmap.h +++ b/include/wx/bitmap.h @@ -188,6 +188,7 @@ public: { return wxSize(GetWidth(), GetHeight()); } // support for scaled bitmaps + virtual void SetScaleFactor(double WXUNUSED(scale)) { } virtual double GetScaleFactor() const { return 1.0; } virtual double GetScaledWidth() const { return GetWidth() / GetScaleFactor(); } virtual double GetScaledHeight() const { return GetHeight() / GetScaleFactor(); } diff --git a/include/wx/gtk/bitmap.h b/include/wx/gtk/bitmap.h index 2f17a24e5c..2a6f9c62f5 100644 --- a/include/wx/gtk/bitmap.h +++ b/include/wx/gtk/bitmap.h @@ -17,6 +17,10 @@ typedef struct _GdkPixbuf GdkPixbuf; class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; class WXDLLIMPEXP_FWD_CORE wxCursor; +#ifdef __WXGTK3__ + #define wxHAS_BITMAP_SCALE_FACTOR +#endif + //----------------------------------------------------------------------------- // wxMask //----------------------------------------------------------------------------- @@ -85,8 +89,9 @@ public: { return Create(sz.GetWidth(), sz.GetHeight(), depth); } bool Create(int width, int height, const wxDC& WXUNUSED(dc)) { return Create(width,height); } -#ifdef __WXGTK3__ +#ifdef wxHAS_BITMAP_SCALE_FACTOR virtual bool CreateScaled(int w, int h, int depth, double scale) wxOVERRIDE; + virtual void SetScaleFactor(double scale) wxOVERRIDE; virtual double GetScaleFactor() const wxOVERRIDE; #endif diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index 260ec080de..9672fc437d 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -186,6 +186,7 @@ public: void ResetAlpha() { UseAlpha(false); } // support for scaled bitmaps + virtual void SetScaleFactor(double WXUNUSED(scale)) { } virtual double GetScaleFactor() const { return 1.0; } virtual double GetScaledWidth() const { return GetWidth(); } virtual double GetScaledHeight() const { return GetHeight(); } diff --git a/include/wx/osx/bitmap.h b/include/wx/osx/bitmap.h index bae0e68537..4f85b77fcb 100644 --- a/include/wx/osx/bitmap.h +++ b/include/wx/osx/bitmap.h @@ -13,6 +13,8 @@ #include "wx/palette.h" +#define wxHAS_BITMAP_SCALE_FACTOR + // Bitmap class WXDLLIMPEXP_FWD_CORE wxBitmap; class wxBitmapRefData ; @@ -239,6 +241,7 @@ public: void EndRawAccess(); #endif + void SetScaleFactor(double scale) wxOVERRIDE; double GetScaleFactor() const wxOVERRIDE; void SetSelectedInto(wxDC *dc); diff --git a/interface/wx/bitmap.h b/interface/wx/bitmap.h index 0456114c2b..c45a34a583 100644 --- a/interface/wx/bitmap.h +++ b/interface/wx/bitmap.h @@ -469,7 +469,7 @@ public: @param depth The number of bits used to represent each bitmap pixel. @param logicalScale - Scale factor used by the bitmap + Scale factor used by the bitmap, see SetScaleFactor(). @return @true if the creation was successful. @@ -586,9 +586,10 @@ public: 1 must be used in high DPI to appear sharp on the screen. Note that the scale factor is only used in the ports where logical - pixels are not the same as physical ones, such as wxOSX or wxGTK3. + pixels are not the same as physical ones, such as wxOSX or wxGTK3, and + this function always returns 1 under the other platforms. - @see GetScaledWidth(), GetScaledHeight(), GetScaledSize() + @see SetScaleFactor(), GetScaledWidth(), GetScaledHeight(), GetScaledSize() @since 2.9.5 */ @@ -796,6 +797,38 @@ public: */ virtual void SetHeight(int height); + /** + Sets the bitmap scale factor. + + This doesn't change the bitmap actual size or its contents, but changes + its scale factor, so that it appears in a smaller size when it is drawn + on screen: e.g. setting @a scale to 2 means that the bitmap will be + twice smaller (in each direction) when drawn on screen in the ports in + which logical and physical pixels differ (i.e. wxOSX and wxGTK3, but + not wxMSW). + + When creating a new bitmap, CreateScaled() can be used to specify the + correct scale factor from the beginning. + + Note that this method exists in all ports, but simply does nothing in + those of them that don't use logical pixel scaling. The preprocessor + symbol @c wxHAS_BITMAP_SCALE_FACTOR can be tested to determine whether + the scale factor is really supported, e.g. + + @code + bitmap.SetScaleFactor(2); + + // In the other ports scale factor is always 1, so the assert would + // fail there. + #ifdef wxHAS_BITMAP_SCALE_FACTOR + wxASSERT( bitmap.GetScaleFactor() == 2 ); + #endif + @endcode + + @since 3.1.6 + */ + virtual void SetScaleFactor(double scale); + /** Sets the mask for this bitmap. diff --git a/src/gtk/bitmap.cpp b/src/gtk/bitmap.cpp index 658480e5ff..c6b229e211 100644 --- a/src/gtk/bitmap.cpp +++ b/src/gtk/bitmap.cpp @@ -1002,6 +1002,13 @@ bool wxBitmap::CreateScaled(int w, int h, int depth, double scale) return true; } +void wxBitmap::SetScaleFactor(double scale) +{ + wxCHECK_RET(m_refData, "invalid bitmap"); + + M_BMPDATA->m_scaleFactor = scale; +} + double wxBitmap::GetScaleFactor() const { wxCHECK_MSG(m_refData, -1, "invalid bitmap"); diff --git a/src/osx/core/bitmap.cpp b/src/osx/core/bitmap.cpp index d7211a50e4..2f82e5d9a2 100644 --- a/src/osx/core/bitmap.cpp +++ b/src/osx/core/bitmap.cpp @@ -75,6 +75,8 @@ public: int GetBytesPerRow() const; bool HasAlpha() const; WXImage GetImage() const; + + void SetScaleFactor(double scale) { m_scaleFactor = scale; } double GetScaleFactor() const { return m_scaleFactor; } const void *GetRawAccess() const; @@ -1389,6 +1391,13 @@ int wxBitmap::GetWidth() const return GetBitmapData()->GetWidth() ; } +void wxBitmap::SetScaleFactor(double scale) +{ + wxCHECK_RET( IsOk(), wxT("invalid bitmap") ); + + return GetBitmapData()->SetScaleFactor(scale) ; +} + double wxBitmap::GetScaleFactor() const { wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") ); From 1056ba19afeb378bfb5fb604f6c9ae65854a56be Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Oct 2021 19:19:29 +0200 Subject: [PATCH 5/8] Move scale factor-related wxBitmap functions out of line This will make it possible to change them later without breaking ABI, which is probably worth paying the price of a function call (assuming the compiler could de-virtualize this call and inline it before). No real changes. --- include/wx/bitmap.h | 14 ++++++-------- include/wx/msw/bitmap.h | 15 +++++++-------- src/common/bmpbase.cpp | 33 +++++++++++++++++++++++++++++++++ src/msw/bitmap.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 16 deletions(-) diff --git a/include/wx/bitmap.h b/include/wx/bitmap.h index 68e49a03ea..6b31c71c37 100644 --- a/include/wx/bitmap.h +++ b/include/wx/bitmap.h @@ -177,8 +177,7 @@ public: virtual bool Create(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH) = 0; virtual bool Create(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH) = 0; - virtual bool CreateScaled(int w, int h, int d, double logicalScale) - { return Create(wxRound(w*logicalScale), wxRound(h*logicalScale), d); } + virtual bool CreateScaled(int w, int h, int d, double logicalScale); virtual int GetHeight() const = 0; virtual int GetWidth() const = 0; @@ -188,12 +187,11 @@ public: { return wxSize(GetWidth(), GetHeight()); } // support for scaled bitmaps - virtual void SetScaleFactor(double WXUNUSED(scale)) { } - virtual double GetScaleFactor() const { return 1.0; } - virtual double GetScaledWidth() const { return GetWidth() / GetScaleFactor(); } - virtual double GetScaledHeight() const { return GetHeight() / GetScaleFactor(); } - virtual wxSize GetScaledSize() const - { return wxSize(wxRound(GetScaledWidth()), wxRound(GetScaledHeight())); } + virtual void SetScaleFactor(double scale); + virtual double GetScaleFactor() const; + virtual double GetScaledWidth() const; + virtual double GetScaledHeight() const; + virtual wxSize GetScaledSize() const; #if wxUSE_IMAGE virtual wxImage ConvertToImage() const = 0; diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index 9672fc437d..21ebdec47f 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -158,8 +158,7 @@ public: virtual bool Create(int width, int height, const wxDC& dc); virtual bool Create(const void* data, wxBitmapType type, int width, int height, int depth = 1); - virtual bool CreateScaled(int w, int h, int d, double logicalScale) - { return Create(wxRound(w*logicalScale), wxRound(h*logicalScale), d); } + virtual bool CreateScaled(int w, int h, int d, double logicalScale); virtual bool LoadFile(const wxString& name, wxBitmapType type = wxBITMAP_DEFAULT_TYPE); virtual bool SaveFile(const wxString& name, wxBitmapType type, const wxPalette *cmap = NULL) const; @@ -185,12 +184,12 @@ public: void UseAlpha(bool use = true); void ResetAlpha() { UseAlpha(false); } - // support for scaled bitmaps - virtual void SetScaleFactor(double WXUNUSED(scale)) { } - virtual double GetScaleFactor() const { return 1.0; } - virtual double GetScaledWidth() const { return GetWidth(); } - virtual double GetScaledHeight() const { return GetHeight(); } - virtual wxSize GetScaledSize() const { return GetSize(); } + // provide stabs of scaled bitmaps functions, they are trivial here + virtual void SetScaleFactor(double scale); + virtual double GetScaleFactor() const; + virtual double GetScaledWidth() const; + virtual double GetScaledHeight() const; + virtual wxSize GetScaledSize() const; // implementation only from now on // ------------------------------- diff --git a/src/common/bmpbase.cpp b/src/common/bmpbase.cpp index 7634981844..1136d1f1d2 100644 --- a/src/common/bmpbase.cpp +++ b/src/common/bmpbase.cpp @@ -196,6 +196,39 @@ public: wxIMPLEMENT_DYNAMIC_CLASS(wxBitmapBaseModule, wxModule); +// ---------------------------------------------------------------------------- +// Trivial implementations of scale-factor related functions +// ---------------------------------------------------------------------------- + +bool wxBitmapBase::CreateScaled(int w, int h, int d, double logicalScale) +{ + return Create(wxRound(w*logicalScale), wxRound(h*logicalScale), d); +} + +void wxBitmapBase::SetScaleFactor(double WXUNUSED(scale)) +{ +} + +double wxBitmapBase::GetScaleFactor() const +{ + return 1.0; +} + +double wxBitmapBase::GetScaledWidth() const +{ + return GetWidth() / GetScaleFactor(); +} + +double wxBitmapBase::GetScaledHeight() const +{ + return GetHeight() / GetScaleFactor(); +} + +wxSize wxBitmapBase::GetScaledSize() const +{ + return wxSize(wxRound(GetScaledWidth()), wxRound(GetScaledHeight())); +} + #endif // wxUSE_BITMAP_BASE // ---------------------------------------------------------------------------- diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 30b2d439a6..c63dd61089 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -745,6 +745,11 @@ bool wxBitmap::Create(int width, int height, const wxDC& dc) return false; } +bool wxBitmap::CreateScaled(int w, int h, int d, double logicalScale) +{ + return Create(wxRound(w*logicalScale), wxRound(h*logicalScale), d); +} + bool wxBitmap::DoCreate(int w, int h, int d, WXHDC hdc) { UnRef(); @@ -1357,6 +1362,39 @@ bool wxBitmap::InitFromHBITMAP(WXHBITMAP bmp, int width, int height, int depth) return IsOk(); } +// ---------------------------------------------------------------------------- +// scale factor-related functions +// ---------------------------------------------------------------------------- + +// Note: currently we don't use scale factor at all and don't even store it +// because this seems useless, but we define these functions out of line here +// and not inline in the header to make it possible to change this later +// without breaking ABI if necessary. + +void wxBitmap::SetScaleFactor(double WXUNUSED(scale)) +{ +} + +double wxBitmap::GetScaleFactor() const +{ + return 1.0; +} + +double wxBitmap::GetScaledWidth() const +{ + return GetWidth(); +} + +double wxBitmap::GetScaledHeight() const +{ + return GetHeight(); +} + +wxSize wxBitmap::GetScaledSize() const +{ + return GetSize(); +} + // ---------------------------------------------------------------------------- // raw bitmap access support // ---------------------------------------------------------------------------- From 8f74ac7deff009d347ee50ff2761785e1bd35bbc Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 23 Oct 2021 21:19:49 +0200 Subject: [PATCH 6/8] Adjust scale of bitmaps returned by wxBitmapBundle::GetBitmap() Bitmaps returned from this function must have the appropriate scale factor, e.g. 2 in standard high DPI case, in order to be drawn at correct size in the ports where logical pixels are different from the physical ones, such as wxOSX and wxGTK3. Notably, this allows wxGenericStaticBitmap to work correctly in high DPI in these ports too. This also allows to undo some of the changes done in 399b0ff9ae (Use wxBitmapBundle instead of bitmap scale factor in wxGtkImage, 2021-10-16) to wxGtkImage code and keep using the same code that had been used before. --- src/common/bmpbndl.cpp | 11 ++++++++++- src/gtk/image_gtk.cpp | 15 ++------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/common/bmpbndl.cpp b/src/common/bmpbndl.cpp index becd229c9c..f89c3490f4 100644 --- a/src/common/bmpbndl.cpp +++ b/src/common/bmpbndl.cpp @@ -384,7 +384,16 @@ wxBitmap wxBitmapBundle::GetBitmap(const wxSize& size) const if ( !m_impl ) return wxBitmap(); - return m_impl->GetBitmap(size == wxDefaultSize ? GetDefaultSize() : size); + const wxSize sizeDef = GetDefaultSize(); + + wxBitmap bmp = m_impl->GetBitmap(size == wxDefaultSize ? sizeDef : size); + + // Ensure that the returned bitmap uses the scale factor such that it takes + // the same space, in logical pixels, as the bitmap in the default size. + if ( size != wxDefaultSize ) + bmp.SetScaleFactor(static_cast(size.y)/sizeDef.y); + + return bmp; } // ============================================================================ diff --git a/src/gtk/image_gtk.cpp b/src/gtk/image_gtk.cpp index 98ef9a8589..518b313f99 100644 --- a/src/gtk/image_gtk.cpp +++ b/src/gtk/image_gtk.cpp @@ -155,24 +155,13 @@ static gboolean wxGtkImageDraw(GtkWidget* widget, GdkEventExpose* event) #endif } - const double scaleFactor = image->m_provider->GetScale(); - GtkAllocation alloc; gtk_widget_get_allocation(widget, &alloc); - int x = (alloc.width - int(bitmap.GetWidth() /scaleFactor)) / 2; - int y = (alloc.height - int(bitmap.GetHeight()/scaleFactor)) / 2; + int x = (alloc.width - int(bitmap.GetScaledWidth() )) / 2; + int y = (alloc.height - int(bitmap.GetScaledHeight())) / 2; #ifdef __WXGTK3__ gtk_render_background(gtk_widget_get_style_context(widget), cr, 0, 0, alloc.width, alloc.height); - - if (!wxIsSameDouble(scaleFactor, 1)) - { - cairo_translate(cr, x, y); - const double scale = 1 / scaleFactor; - cairo_scale(cr, scale, scale); - x = 0; - y = 0; - } bitmap.Draw(cr, x, y); #else x += alloc.x; From 30aad30a0a609b879ea5cb938d66c53955268121 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Oct 2021 23:07:21 +0200 Subject: [PATCH 7/8] Don't create unnecessary vector in wxBitmapBundle::FromBitmap() Just use wxBitmapBundle ctor instead, this is both simpler and more efficient. No real changes. --- include/wx/bmpbndl.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/include/wx/bmpbndl.h b/include/wx/bmpbndl.h index 6609e649a0..e55ba08f44 100644 --- a/include/wx/bmpbndl.h +++ b/include/wx/bmpbndl.h @@ -149,12 +149,7 @@ wxBitmapBundle wxBitmapBundle::FromBitmaps(const wxBitmap& bitmap1, /* static */ inline wxBitmapBundle wxBitmapBundle::FromBitmap(const wxBitmap& bitmap) { - if ( !bitmap.IsOk() ) - return wxBitmapBundle(); - - wxVector bitmaps; - bitmaps.push_back(bitmap); - return FromBitmaps(bitmaps); + return wxBitmapBundle(bitmap); } /* static */ inline From 7b4257b9cda8bbbaf8a6e19068bf60d4b6d69a92 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Oct 2021 23:15:02 +0200 Subject: [PATCH 8/8] 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]")