Merge branch 'explicit-image-from-xpm'

Make wxImage ctor from XPM data explicit to avoid surprising behaviour.

See https://github.com/wxWidgets/wxWidgets/pull/2332

Closes #19149.
This commit is contained in:
Vadim Zeitlin
2021-04-20 00:19:24 +01:00
19 changed files with 150 additions and 15 deletions

View File

@@ -183,6 +183,9 @@ Changes in behaviour which may result in build errors
- wxGridEvent methods GetRow() and GetCol() are no longer virtual.
- wxImage constructor from XPM data is now explicit, write "wxImage(xpmData)"
instead of just "xpmData" if you really need to use it.
3.1.6: (released 2021-06-??)
----------------------------

View File

@@ -11,6 +11,7 @@
#define _WX_DFB_CURSOR_H_
class WXDLLIMPEXP_FWD_CORE wxBitmap;
class WXDLLIMPEXP_FWD_CORE wxImage;
//-----------------------------------------------------------------------------
// wxCursor
@@ -24,6 +25,10 @@ public:
#if WXWIN_COMPATIBILITY_2_8
wxCursor(int id) { InitFromStock((wxStockCursor)id); }
#endif
#if wxUSE_IMAGE
wxCursor(const wxImage& image);
wxCursor(const char* const* xpmData);
#endif // wxUSE_IMAGE
wxCursor(const wxString& name,
wxBitmapType type = wxCURSOR_DEFAULT_TYPE,
int hotSpotX = 0, int hotSpotY = 0);

View File

@@ -25,10 +25,11 @@ public:
#endif
#if wxUSE_IMAGE
wxCursor( const wxImage & image );
wxCursor(const char* const* xpmData);
#endif // wxUSE_IMAGE
wxCursor(const wxString& name,
wxBitmapType type = wxCURSOR_DEFAULT_TYPE,
int hotSpotX = 0, int hotSpotY = 0);
#endif
wxCursor( const char bits[], int width, int height,
int hotSpotX = -1, int hotSpotY = -1,
const char maskBits[] = NULL,

View File

@@ -310,7 +310,7 @@ public:
{ LoadFile( name, type, index ); }
wxImage( const wxString& name, const wxString& mimetype, int index = -1 )
{ LoadFile( name, mimetype, index ); }
wxImage( const char* const* xpmData )
explicit wxImage( const char* const* xpmData )
{ Create(xpmData); }
#if wxUSE_STREAMS

View File

@@ -32,6 +32,7 @@ public:
#if wxUSE_IMAGE
wxCursor(const wxImage& image);
wxCursor(const char* const* xpmData);
#endif
wxCursor(wxStockCursor id) { InitFromStock(id); }
@@ -52,6 +53,10 @@ protected:
private:
void InitFromStock(wxStockCursor);
#if wxUSE_IMAGE
void InitFromImage(const wxImage& image);
#endif
void Create(const char bits[], int width, int height,
int hotSpotX = -1, int hotSpotY = -1,
const char maskBits[] = NULL);

View File

@@ -19,7 +19,10 @@ class WXDLLIMPEXP_CORE wxCursor : public wxCursorBase
public:
// constructors
wxCursor();
#if wxUSE_IMAGE
wxCursor(const wxImage& image);
wxCursor(const char* const* xpmData);
#endif // wxUSE_IMAGE
wxCursor(const wxString& name,
wxBitmapType type = wxCURSOR_DEFAULT_TYPE,
int hotSpotX = 0, int hotSpotY = 0);
@@ -42,6 +45,10 @@ protected:
virtual wxGDIImageRefData *CreateData() const wxOVERRIDE;
private:
#if wxUSE_IMAGE
void InitFromImage(const wxImage& image);
#endif // wxUSE_IMAGE
wxDECLARE_DYNAMIC_CLASS(wxCursor);
};

View File

@@ -19,7 +19,10 @@ class WXDLLIMPEXP_CORE wxCursor : public wxCursorBase
public:
wxCursor();
#if wxUSE_IMAGE
wxCursor(const wxImage & image) ;
wxCursor(const char* const* xpmData);
#endif // wxUSE_IMAGE
wxCursor(const wxString& name,
wxBitmapType type = wxCURSOR_DEFAULT_TYPE,
int hotSpotX = 0, int hotSpotY = 0);
@@ -42,7 +45,9 @@ protected:
private:
void InitFromStock(wxStockCursor);
void CreateFromImage(const wxImage & image) ;
#if wxUSE_IMAGE
void InitFromImage(const wxImage & image) ;
#endif // wxUSE_IMAGE
wxDECLARE_DYNAMIC_CLASS(wxCursor);
};

View File

@@ -22,10 +22,11 @@ public:
#endif
#if wxUSE_IMAGE
wxCursor( const wxImage & image );
wxCursor(const char* const* xpmData);
#endif // wxUSE_IMAGE
wxCursor(const wxString& name,
wxBitmapType type = wxCURSOR_DEFAULT_TYPE,
int hotSpotX = 0, int hotSpotY = 0);
#endif
virtual wxPoint GetHotSpot() const wxOVERRIDE;
QCursor &GetHandle() const;

View File

@@ -29,6 +29,7 @@ public:
#endif
#if wxUSE_IMAGE
wxCursor( const wxImage & image );
wxCursor(const char* const* xpmData);
#endif
wxCursor(const wxString& name,

View File

@@ -190,6 +190,17 @@ public:
*/
wxCursor(const wxImage& image);
/**
Constructs a cursor from XPM data.
In versions of wxWidgets until 3.1.6 constructing wxCursor from XPM
data implicitly used wxImage constructor from XPM data and wxCursor
constructor from wxImage. Since 3.1.6 this constructor overload is
available to allow constructing wxCursor from XPM to still work, even
though wxImage constructor from XPM is now @c explicit.
*/
wxCursor(const char* const* xpmData);
/**
Copy constructor, uses @ref overview_refcount "reference counting".

View File

@@ -611,8 +611,10 @@ public:
@beginWxPerlOnly
Not supported by wxPerl.
@endWxPerlOnly
This constructor has become @c explicit in wxWidgets 3.1.6.
*/
wxImage(const char* const* xpmData);
explicit wxImage(const char* const* xpmData);
/**
Creates an image from a file.

View File

@@ -53,6 +53,20 @@ void wxCursor::InitFromStock(wxStockCursor cursorId)
#warning "FIXME -- implement the cursor as bitmaps (that's what DFB uses)"
}
#if wxUSE_IMAGE
wxCursor::wxCursor(const wxImage& image)
{
#warning "FIXME"
}
wxCursor::wxCursor(const char* const* xpmData)
{
#warning "FIXME"
}
#endif // wxUSE_IMAGE
wxCursor::wxCursor(const wxString& cursor_file,
wxBitmapType type,
int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY))

View File

@@ -72,11 +72,11 @@ wxCursor::wxCursor()
{
}
#if wxUSE_IMAGE
wxCursor::wxCursor(const wxString& cursor_file,
wxBitmapType type,
int hotSpotX, int hotSpotY)
{
#if wxUSE_IMAGE
wxImage img;
if (!img.LoadFile(cursor_file, type))
return;
@@ -88,13 +88,20 @@ wxCursor::wxCursor(const wxString& cursor_file,
img.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, hotSpotY);
InitFromImage(img);
#endif // wxUSE_IMAGE
}
#if wxUSE_IMAGE
wxCursor::wxCursor(const wxImage& img)
{
InitFromImage(img);
}
#endif
wxCursor::wxCursor(const char* const* xpmData)
{
InitFromImage(wxImage(xpmData));
}
#endif // wxUSE_IMAGE
wxCursor::wxCursor(const char bits[], int width, int height,
int hotSpotX, int hotSpotY,

View File

@@ -93,7 +93,7 @@ wxCursor::wxCursor()
}
#if wxUSE_IMAGE
wxCursor::wxCursor(const wxImage & image)
void wxCursor::InitFromImage(const wxImage & image)
{
unsigned char * rgbBits = image.GetData();
int w = image.GetWidth() ;
@@ -174,6 +174,16 @@ wxCursor::wxCursor(const wxImage & image)
delete[] bits;
delete[] maskBits;
}
wxCursor::wxCursor(const wxImage& image)
{
InitFromImage(image);
}
wxCursor::wxCursor(const char* const* xpmData)
{
InitFromImage(wxImage(xpmData));
}
#endif
void wxCursor::Create(const char bits[], int width, int height,

View File

@@ -153,6 +153,16 @@ wxCursor::wxCursor()
#if wxUSE_IMAGE
wxCursor::wxCursor(const wxImage& image)
{
InitFromImage(image);
}
wxCursor::wxCursor(const char* const* xpmData)
{
InitFromImage(wxImage(xpmData));
}
void wxCursor::InitFromImage(const wxImage& image)
{
// image has to be of the standard cursor size, otherwise we won't be able
// to create it

View File

@@ -225,13 +225,18 @@ wxCursor::wxCursor()
{
}
#if wxUSE_IMAGE
wxCursor::wxCursor( const wxImage &image )
{
#if wxUSE_IMAGE
CreateFromImage( image ) ;
#endif
InitFromImage( image ) ;
}
wxCursor::wxCursor(const char* const* xpmData)
{
InitFromImage( wxImage(xpmData) ) ;
}
#endif // wxUSE_IMAGE
wxGDIRefData *wxCursor::CreateGDIRefData() const
{
return new wxCursorRefData;
@@ -249,7 +254,7 @@ WXHCURSOR wxCursor::GetHCURSOR() const
#if wxUSE_IMAGE
void wxCursor::CreateFromImage(const wxImage & image)
void wxCursor::InitFromImage(const wxImage & image)
{
m_refData = new wxCursorRefData;
int hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X);
@@ -287,7 +292,7 @@ wxCursor::wxCursor(const wxString& cursor_file, wxBitmapType flags, int hotSpotX
image.SetOption( wxIMAGE_OPTION_CUR_HOTSPOT_Y, hotSpotY ) ;
m_refData->DecRef() ;
m_refData = NULL ;
CreateFromImage( image ) ;
InitFromImage( image ) ;
}
#endif
}

View File

@@ -59,11 +59,11 @@ public:
wxIMPLEMENT_DYNAMIC_CLASS(wxCursor, wxGDIObject);
#if wxUSE_IMAGE
wxCursor::wxCursor(const wxString& cursor_file,
wxBitmapType type,
int hotSpotX, int hotSpotY)
{
#if wxUSE_IMAGE
wxImage img;
if (!img.LoadFile(cursor_file, type))
return;
@@ -75,13 +75,20 @@ wxCursor::wxCursor(const wxString& cursor_file,
img.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, hotSpotY);
InitFromImage(img);
#endif // wxUSE_IMAGE
}
#if wxUSE_IMAGE
wxCursor::wxCursor(const wxImage& img)
{
InitFromImage(img);
}
#endif
wxCursor::wxCursor(const char* const* xpmData)
{
InitFromImage(wxImage(xpmData));
}
#endif // wxUSE_IMAGE
wxPoint wxCursor::GetHotSpot() const
{

View File

@@ -140,6 +140,11 @@ wxCursor::wxCursor( const wxImage & WXUNUSED(image) )
{
wxFAIL_MSG( wxT("wxCursor creation from wxImage not yet implemented") );
}
wxCursor::wxCursor(const char* const* WXUNUSED(xpmData))
{
wxFAIL_MSG( wxT("wxCursor creation from XPM not yet implemented") );
}
#endif
wxCursor::~wxCursor()

View File

@@ -21,6 +21,8 @@
#include "wx/anidecod.h" // wxImageArray
#include "wx/bitmap.h"
#include "wx/cursor.h"
#include "wx/icon.h"
#include "wx/palette.h"
#include "wx/url.h"
#include "wx/log.h"
@@ -2164,6 +2166,40 @@ TEST_CASE("wxImage::InitAlpha", "[image][initalpha]")
}
}
TEST_CASE("wxImage::XPM", "[image][xpm]")
{
static const char * dummy_xpm[] = {
"16 16 2 1",
"@ c Black",
" c None",
"@ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @ ",
" @"
};
wxImage image(dummy_xpm);
CHECK( image.IsOk() );
// The goal here is mostly just to check that this code compiles, i.e. that
// creating all these classes from XPM works.
CHECK( wxBitmap(dummy_xpm).IsOk() );
CHECK( wxCursor(dummy_xpm).IsOk() );
CHECK( wxIcon(dummy_xpm).IsOk() );
}
/*
TODO: add lots of more tests to wxImage functions
*/