Fix scale factor confusion in wxMac wxBitmap implementation
Merge ctors from (width, height) and (width, height, scale) into a single one because the former really should be just a special case of the latter for scale == 1 but, surprisingly and confusingly it wasn't, because the latter also multiplied the size by scale, meaning that width and height parameters had different meanings. This resulted in at least 3 bugs when using scale factors different from 1: first, copying bitmaps wasn't done correctly because as wxBitmapRefData copy ctor incorrectly scaled its size by scale again. And second, creating bitmap from wxImage whose size wasn't divisible by scale not just didn't work correctly but crashed when accessing memory outside of the image because (unnecessarily) dividing and multiplying the image size by scale wasn't idempotent. Finally, even for the images of even size (assuming scale factor of 2), bitmaps created from them used incorrect width and height, corresponding to the half of the image dimensions, instead of the same ones, as they're supposed to be (the scaled dimensions are supposed to be returned by GetScale{Width,Height} methods). Closes #17505.
This commit is contained in:
@@ -49,8 +49,7 @@ class WXDLLEXPORT wxBitmapRefData: public wxGDIRefData
|
||||
friend class WXDLLIMPEXP_FWD_CORE wxIcon;
|
||||
friend class WXDLLIMPEXP_FWD_CORE wxCursor;
|
||||
public:
|
||||
wxBitmapRefData(int width , int height , int depth, double logicalscale);
|
||||
wxBitmapRefData(int width , int height , int depth);
|
||||
wxBitmapRefData(int width , int height , int depth, double logicalscale = 1.0);
|
||||
wxBitmapRefData(CGContextRef context);
|
||||
wxBitmapRefData(CGImageRef image, double scale);
|
||||
wxBitmapRefData();
|
||||
@@ -106,8 +105,7 @@ public:
|
||||
|
||||
int GetBytesPerRow() const { return m_bytesPerRow; }
|
||||
private :
|
||||
bool Create(int width , int height , int depth);
|
||||
bool Create(int width , int height , int depth, double logicalScale);
|
||||
bool Create(int width , int height , int depth, double logicalscale);
|
||||
bool Create( CGImageRef image, double scale );
|
||||
bool Create( CGContextRef bitmapcontext);
|
||||
void Init();
|
||||
@@ -269,13 +267,7 @@ wxBitmapRefData::wxBitmapRefData()
|
||||
Init() ;
|
||||
}
|
||||
|
||||
wxBitmapRefData::wxBitmapRefData( int w , int h , int d )
|
||||
{
|
||||
Init() ;
|
||||
Create( w , h , d ) ;
|
||||
}
|
||||
|
||||
wxBitmapRefData::wxBitmapRefData(int w , int h , int d, double logicalscale)
|
||||
wxBitmapRefData::wxBitmapRefData( int w , int h , int d , double logicalscale)
|
||||
{
|
||||
Init() ;
|
||||
Create( w , h , d, logicalscale ) ;
|
||||
@@ -370,11 +362,12 @@ bool wxBitmapRefData::Create(CGContextRef context)
|
||||
return m_ok ;
|
||||
}
|
||||
|
||||
bool wxBitmapRefData::Create( int w , int h , int d )
|
||||
bool wxBitmapRefData::Create( int w , int h , int d, double logicalscale )
|
||||
{
|
||||
m_width = wxMax(1, w);
|
||||
m_height = wxMax(1, h);
|
||||
m_depth = d ;
|
||||
m_scaleFactor = logicalscale;
|
||||
m_hBitmap = NULL ;
|
||||
|
||||
m_bytesPerRow = GetBestBytesPerRow( m_width * 4 ) ;
|
||||
@@ -395,12 +388,6 @@ bool wxBitmapRefData::Create( int w , int h , int d )
|
||||
return m_ok ;
|
||||
}
|
||||
|
||||
bool wxBitmapRefData::Create( int w , int h , int d, double logicalScale )
|
||||
{
|
||||
m_scaleFactor = logicalScale;
|
||||
return Create(w*logicalScale,h*logicalScale,d);
|
||||
}
|
||||
|
||||
void wxBitmapRefData::UseAlpha( bool use )
|
||||
{
|
||||
if ( m_hasAlpha == use )
|
||||
@@ -1125,7 +1112,7 @@ bool wxBitmap::CreateScaled(int w, int h, int d, double logicalScale)
|
||||
if ( d < 0 )
|
||||
d = wxDisplayDepth() ;
|
||||
|
||||
m_refData = new wxBitmapRefData( w , h , d, logicalScale );
|
||||
m_refData = new wxBitmapRefData( w*logicalScale , h*logicalScale , d, logicalScale );
|
||||
|
||||
return M_BITMAPDATA->IsOk() ;
|
||||
}
|
||||
@@ -1220,7 +1207,7 @@ wxBitmap::wxBitmap(const wxImage& image, int depth, double scale)
|
||||
|
||||
wxBitmapRefData* bitmapRefData;
|
||||
|
||||
m_refData = bitmapRefData = new wxBitmapRefData( width/scale, height/scale, depth, scale) ;
|
||||
m_refData = bitmapRefData = new wxBitmapRefData( width, height, depth, scale) ;
|
||||
|
||||
if ( bitmapRefData->IsOk())
|
||||
{
|
||||
|
Reference in New Issue
Block a user