Add wxBitmap::CreateWithLogicalSize()

This function should be used instead of CreateWithDIPSize() in portable
code, the latter is currently often used to do what this function is
doing, but this only works correctly in wxOSX and wxGTK3 but not wxMSW.
This commit is contained in:
Vadim Zeitlin 2024-01-09 02:58:10 +01:00
parent 8967bed190
commit 9cc5e5d276
5 changed files with 88 additions and 0 deletions

View file

@ -178,6 +178,11 @@ 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;
// DIP size and logical size are the same thing for ports using scaling,
// i.e. where physical and logical sizes are different (e.g. wxGTK and
// wxOSX), but we want to have both sets of functions to use them in the
// ports where physical and logical sizes are the same (wxMSW).
bool CreateWithDIPSize(const wxSize& sz,
double scale,
int depth = wxBITMAP_SCREEN_DEPTH)
@ -187,6 +192,15 @@ public:
int depth = wxBITMAP_SCREEN_DEPTH)
{ return DoCreate(wxSize(width, height), scale, depth); }
bool CreateWithLogicalSize(const wxSize& sz,
double scale,
int depth = wxBITMAP_SCREEN_DEPTH)
{ return DoCreate(sz, scale, depth); }
bool CreateWithLogicalSize(int width, int height,
double scale,
int depth = wxBITMAP_SCREEN_DEPTH)
{ return DoCreate(wxSize(width, height), scale, depth); }
virtual int GetHeight() const = 0;
virtual int GetWidth() const = 0;
virtual int GetDepth() const = 0;

View file

@ -157,6 +157,14 @@ public:
int depth = wxBITMAP_SCREEN_DEPTH)
{ return CreateWithDIPSize(wxSize(width, height), scale, depth); }
bool CreateWithLogicalSize(const wxSize& sz,
double scale,
int depth = wxBITMAP_SCREEN_DEPTH);
bool CreateWithLogicalSize(int width, int height,
double scale,
int depth = wxBITMAP_SCREEN_DEPTH)
{ return CreateWithLogicalSize(wxSize(width, height), scale, depth); }
virtual bool LoadFile(const wxString& name, wxBitmapType type = wxBITMAP_DEFAULT_TYPE);
virtual bool SaveFile(const wxString& name, wxBitmapType type, const wxPalette *cmap = nullptr) const;

View file

@ -494,6 +494,10 @@ public:
Create a bitmap specifying its size in DPI-independent pixels and the
scale factor to use.
This should be used when the bitmap size is fixed (e.g. at
compile-time) and not if it comes from wxWindow::GetSize() or other
similar functions -- use CreateWithLogicalSize() in the latter case.
The physical size of the bitmap is obtained by multiplying the given
@a size by @a scale and rounding it to the closest integer.
@ -524,6 +528,43 @@ public:
double scale,
int depth = wxBITMAP_SCREEN_DEPTH);
/**
Create a bitmap specifying its size in logical pixels and the scale
factor to use.
This should be typically used when creating bitmaps associated to a
window area, e.g. to create a bitmap covering the entire window the
@a size parameter should be wxWindow::GetClientSize() and @a scale
should be the wxWindow::GetDPIScaleFactor().
The physical size of the bitmap created by this function depends on the
platform and will be the same as @a size on the platforms for which
`wxHAS_DPI_INDEPENDENT_PIXELS` is not defined (e.g. wxMSW) or @a size
multiplied by @a scale for those where it is (e.g. wxGTK3 and wxOSX).
In other words, this function is the same as CreateWithDIPSize() if
`wxHAS_DPI_INDEPENDENT_PIXELS` is defined, but not otherwise.
@param size
The size of the bitmap in logical pixels. Both width and
height must be strictly positive.
@param scale
Scale factor used by the bitmap, see SetScaleFactor().
@param depth
The number of bits used to represent each bitmap pixel.
@return @true if the creation was successful.
@since 3.3.0
*/
bool CreateWithLogicalSize(const wxSize& size,
double scale,
int depth = wxBITMAP_SCREEN_DEPTH);
/// @overload
bool CreateWithLogicalSize(int width, int height,
double scale,
int depth = wxBITMAP_SCREEN_DEPTH);
/**
Create a bitmap with a scale factor.

View file

@ -775,6 +775,17 @@ bool wxBitmap::CreateWithDIPSize(const wxSize& size, double scale, int depth)
return true;
}
bool
wxBitmap::CreateWithLogicalSize(const wxSize& size, double scale, int depth)
{
if ( !Create(size, depth) )
return false;
GetBitmapData()->m_scaleFactor = scale;
return true;
}
bool wxBitmap::DoCreate(int w, int h, int d, WXHDC hdc)
{
UnRef();

View file

@ -1848,6 +1848,20 @@ TEST_CASE("Bitmap::ScaleFactor", "[bitmap][dc][scale]")
wxBitmap bmp3(img, dc);
CHECK( bmp3.GetScaleFactor() == 2 );
CHECK( bmp3.GetSize() == wxSize(16, 16) );
// And another way to create a bitmap with specified scale factor.
const wxSize sizeLog(10, 10);
wxBitmap bmp4;
bmp4.CreateWithLogicalSize(sizeLog, 2);
CHECK( bmp4.GetScaleFactor() == 2 );
CHECK( bmp4.GetLogicalSize() == sizeLog );
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
CHECK( bmp4.GetSize() == 2*sizeLog );
#else
CHECK( bmp4.GetSize() == sizeLog );
#endif
}
TEST_CASE("wxBitmap::GetSubBitmap", "[bitmap]")