Merge branch 'getsubbitmap-fixes'

Assorted fixes to wxBitmap::GetSubBitmap().

See #24010.
This commit is contained in:
Vadim Zeitlin 2023-11-03 00:49:50 +01:00
commit 71c25b4de7
4 changed files with 78 additions and 39 deletions

View file

@ -1062,7 +1062,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect& r) const
const wxBitmapRefData* bmpData = M_BMPDATA;
#ifdef __WXGTK3__
const double s = bmpData->m_scaleFactor;
const wxRect rect(int(r.x * s), int(r.y * s), int(r.width * s), int(r.height * s));
const wxRect rect(wxRound(r.x * s), wxRound(r.y * s), wxRound(r.width * s), wxRound(r.height * s));
#else
const wxRect& rect = r;
#endif

View file

@ -1142,15 +1142,20 @@ wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect ) const
wxBitmap wxBitmap::GetSubBitmapOfHDC( const wxRect& rect, WXHDC hdc ) const
{
wxCHECK_MSG( IsOk() &&
(rect.x >= 0) && (rect.y >= 0) &&
wxCHECK_MSG( IsOk(), wxNullBitmap, wxT("invalid bitmap") );
wxCHECK_MSG( (rect.x >= 0) && (rect.y >= 0) &&
(rect.x+rect.width <= GetWidth()) &&
(rect.y+rect.height <= GetHeight()),
wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
wxNullBitmap, wxT("invalid bitmap region") );
wxBitmap ret( rect.width, rect.height, GetDepth() );
wxASSERT_MSG( ret.IsOk(), wxT("GetSubBitmap error") );
// For consistency with the other ports, preserve this bitmap scale factor
// for the returned bitmap, even if it's not really used in wxMSW.
ret.SetScaleFactor(GetScaleFactor());
// handle alpha channel, if any
if (HasAlpha())
ret.UseAlpha();

View file

@ -964,11 +964,12 @@ WXImage wxBitmap::OSXGetImage() const
wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
{
wxCHECK_MSG( IsOk() &&
(rect.x >= 0) && (rect.y >= 0) &&
(rect.x+rect.width <= GetWidth()) &&
(rect.y+rect.height <= GetHeight()),
wxNullBitmap, wxT("invalid bitmap or bitmap region") );
wxCHECK_MSG( IsOk(), wxNullBitmap, wxT("invalid bitmap") );
wxCHECK_MSG((rect.x >= 0) && (rect.y >= 0) &&
(rect.x+rect.width <= GetLogicalWidth()) &&
(rect.y+rect.height <= GetLogicalHeight()),
wxNullBitmap, wxT("invalid bitmap region") );
wxBitmap ret;
double scale = GetScaleFactor();

View file

@ -1705,36 +1705,6 @@ TEST_CASE("Bitmap::DC", "[bitmap][dc]")
#endif // wxUSE_SVG
}
#if defined(wxHAS_DPI_INDEPENDENT_PIXELS) || defined(__WXMSW__)
TEST_CASE("Bitmap::ScaleFactor", "[bitmap][dc][scale]")
{
// Create a bitmap with scale factor != 1.
wxBitmap bmp;
bmp.CreateWithDIPSize(8, 8, 2);
REQUIRE( bmp.GetScaleFactor() == 2 );
CHECK( bmp.GetSize() == wxSize(16, 16) );
// wxMemoryDC should use the same scale factor as the bitmap.
wxMemoryDC dc(bmp);
CHECK( dc.GetContentScaleFactor() == 2 );
// A bitmap "compatible" with this DC should also use the same scale factor.
wxBitmap bmp2(4, 4, dc);
CHECK( bmp2.GetScaleFactor() == 2 );
CHECK( bmp2.GetSize() == wxSize(8, 8) );
// A compatible bitmap created from wxImage and this DC should also inherit
// the same scale factor, but its size should be still the same as that of
// the image.
wxImage img(16, 16);
wxBitmap bmp3(img, dc);
CHECK( bmp3.GetScaleFactor() == 2 );
CHECK( bmp3.GetSize() == wxSize(16, 16) );
}
#endif // ports with scaled bitmaps support
#if wxUSE_GRAPHICS_CONTEXT
inline void DrawScaledBmp(wxBitmap& bmp, float scale, wxGraphicsRenderer* renderer)
@ -1827,3 +1797,66 @@ TEST_CASE("GC::DrawBitmap", "[bitmap][drawbitmap]")
#endif //wxUSE_GRAPHICS_CONTEXT
#endif //wxHAS_RAW_BITMAP
#if defined(wxHAS_DPI_INDEPENDENT_PIXELS) || defined(__WXMSW__)
TEST_CASE("Bitmap::ScaleFactor", "[bitmap][dc][scale]")
{
// Create a bitmap with scale factor != 1.
wxBitmap bmp;
bmp.CreateWithDIPSize(8, 8, 2);
REQUIRE( bmp.GetScaleFactor() == 2 );
CHECK( bmp.GetSize() == wxSize(16, 16) );
// wxMemoryDC should use the same scale factor as the bitmap.
wxMemoryDC dc(bmp);
CHECK( dc.GetContentScaleFactor() == 2 );
// A bitmap "compatible" with this DC should also use the same scale factor.
wxBitmap bmp2(4, 4, dc);
CHECK( bmp2.GetScaleFactor() == 2 );
CHECK( bmp2.GetSize() == wxSize(8, 8) );
// A compatible bitmap created from wxImage and this DC should also inherit
// the same scale factor, but its size should be still the same as that of
// the image.
wxImage img(16, 16);
wxBitmap bmp3(img, dc);
CHECK( bmp3.GetScaleFactor() == 2 );
CHECK( bmp3.GetSize() == wxSize(16, 16) );
}
TEST_CASE("wxBitmap::GetSubBitmap", "[bitmap]")
{
// Make the logical size odd to test correct rounding.
const double scale = 1.5;
const wxSize sizeLog(15, 15);
const wxSize sizePhy(23, 23);
// Prepare the main bitmap.
wxBitmap bmp;
bmp.CreateWithDIPSize(sizeLog, scale);
CHECK( bmp.GetDIPSize() == sizeLog );
CHECK( bmp.GetSize() == sizePhy );
CHECK( bmp.GetScaleFactor() == scale );
// Extracting sub-bitmap of the entire bitmap size should return the bitmap
// of the same size.
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
const wxRect rectAll(wxPoint(0, 0), sizeLog);
#else
const wxRect rectAll(wxPoint(0, 0), sizePhy);
#endif
const wxBitmap sub = bmp.GetSubBitmap(rectAll);
CHECK( sub.GetDIPSize() == sizeLog );
CHECK( sub.GetSize() == sizePhy );
CHECK( sub.GetScaleFactor() == scale );
// Using incorrect bounds should assert.
wxRect rectInvalid = rectAll;
rectInvalid.Offset(1, 0);
WX_ASSERT_FAILS_WITH_ASSERT( bmp.GetSubBitmap(rectInvalid) );
}
#endif // ports with scaled bitmaps support