native scaling support for bitmap

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74287 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor 2013-06-25 14:02:11 +00:00
parent a85ccd79fd
commit f8bfebfcb8
2 changed files with 60 additions and 10 deletions

View File

@ -135,6 +135,12 @@ public:
bool Create( CGImageRef image );
bool Create( WX_NSImage image );
// Create a bitmap compatible with the given DC, inheriting its magnification factor
bool Create(int width, int height, const wxDC& dc);
// Create a bitmap with a scale factor, width and height are multiplied with that factor
bool CreateScaled(int logwidth, int logheight, int depth, double logicalScale);
// virtual bool Create( WXHICON icon) ;
virtual bool LoadFile(const wxString& name, wxBitmapType type = wxBITMAP_DEFAULT_TYPE);
virtual bool SaveFile(const wxString& name, wxBitmapType type, const wxPalette *cmap = NULL) const;
@ -197,6 +203,7 @@ public:
void *BeginRawAccess() ;
void EndRawAccess() ;
double GetScaleFactor() const;
protected:
virtual wxGDIRefData *CreateGDIRefData() const;
virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const;

View File

@ -56,6 +56,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(CGImageRef image);
wxBitmapRefData();
@ -75,7 +76,7 @@ public:
int GetWidth() const { return m_width; }
int GetHeight() const { return m_height; }
int GetDepth() const { return m_depth; }
double GetScaleFactor() const { return m_scaleFactor; }
void *GetRawAccess() const;
void *BeginRawAccess();
void EndRawAccess();
@ -109,6 +110,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( CGImageRef image );
void Init();
@ -127,6 +129,7 @@ public:
#endif
CGContextRef m_hBitmap;
double m_scaleFactor;
};
@ -242,12 +245,13 @@ void wxBitmapRefData::Init()
m_rawAccessCount = 0 ;
m_hasAlpha = false;
m_scaleFactor = 1.0;
}
wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData &tocopy) : wxGDIRefData()
{
Init();
Create(tocopy.m_width, tocopy.m_height, tocopy.m_depth);
Create(tocopy.m_width, tocopy.m_height, tocopy.m_depth, tocopy.m_scaleFactor);
if (tocopy.m_bitmapMask)
m_bitmapMask = new wxMask(*tocopy.m_bitmapMask);
@ -271,6 +275,12 @@ wxBitmapRefData::wxBitmapRefData( int w , int h , int d )
Create( w , h , d ) ;
}
wxBitmapRefData::wxBitmapRefData(int w , int h , int d, double logicalscale)
{
Init() ;
Create( w , h , d, logicalscale ) ;
}
wxBitmapRefData::wxBitmapRefData(CGImageRef image)
{
Init();
@ -336,13 +346,19 @@ bool wxBitmapRefData::Create( int w , int h , int d )
m_hBitmap = CGBitmapContextCreate((char*) data, m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), kCGImageAlphaNoneSkipFirst );
wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ;
CGContextTranslateCTM( m_hBitmap, 0, m_height );
CGContextScaleCTM( m_hBitmap, 1, -1 );
CGContextScaleCTM( m_hBitmap, 1*m_scaleFactor, -1*m_scaleFactor );
} /* data != NULL */
m_ok = ( m_hBitmap != NULL ) ;
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 )
@ -354,7 +370,7 @@ void wxBitmapRefData::UseAlpha( bool use )
m_hBitmap = CGBitmapContextCreate((char*) m_memBuf.GetData(), m_width, m_height, 8, m_bytesPerRow, wxMacGetGenericRGBColorSpace(), m_hasAlpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst );
wxASSERT_MSG( m_hBitmap , wxT("Unable to create CGBitmapContext context") ) ;
CGContextTranslateCTM( m_hBitmap, 0, m_height );
CGContextScaleCTM( m_hBitmap, 1, -1 );
CGContextScaleCTM( m_hBitmap, 1*m_scaleFactor, -1*m_scaleFactor );
}
void *wxBitmapRefData::GetRawAccess() const
@ -939,9 +955,9 @@ wxBitmap::wxBitmap(const void* data, wxBitmapType type, int width, int height, i
(void) Create(data, type, width, height, depth);
}
wxBitmap::wxBitmap(int width, int height, const wxDC& WXUNUSED(dc))
wxBitmap::wxBitmap(int width, int height, const wxDC& dc)
{
(void) Create(width, height);
(void)Create(width, height, dc);
}
wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
@ -1046,11 +1062,13 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
(rect.y+rect.height <= GetHeight()),
wxNullBitmap, wxT("invalid bitmap or bitmap region") );
wxBitmap ret( rect.width, rect.height, GetDepth() );
wxBitmap ret;
double scale = GetScaleFactor();
ret.CreateScaled( rect.width, rect.height, GetDepth(), scale );
wxASSERT_MSG( ret.IsOk(), wxT("GetSubBitmap error") );
int destwidth = rect.width ;
int destheight = rect.height ;
int destwidth = rect.width*scale ;
int destheight = rect.height*scale ;
{
unsigned char *sourcedata = (unsigned char*) GetRawAccess() ;
@ -1061,7 +1079,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
{
int sourcelinesize = GetBitmapData()->GetBytesPerRow() ;
int destlinesize = ret.GetBitmapData()->GetBytesPerRow() ;
unsigned char *source = sourcedata + rect.x * 4 + rect.y * sourcelinesize ;
unsigned char *source = sourcedata + int(rect.x * scale * 4 + rect.y *scale * sourcelinesize) ;
unsigned char *dest = destdata ;
for (int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize)
@ -1118,6 +1136,24 @@ bool wxBitmap::Create(int w, int h, int d)
return M_BITMAPDATA->IsOk() ;
}
bool wxBitmap::Create(int w, int h, const wxDC& dc)
{
double factor = dc.GetContentScaleFactor();
return CreateScaled(w,h,wxBITMAP_SCREEN_DEPTH, factor);
}
bool wxBitmap::CreateScaled(int w, int h, int d, double logicalScale)
{
UnRef();
if ( d < 0 )
d = wxDisplayDepth() ;
m_refData = new wxBitmapRefData( w , h , d, logicalScale );
return M_BITMAPDATA->IsOk() ;
}
bool wxBitmap::Create(CGImageRef image)
{
UnRef();
@ -1397,6 +1433,13 @@ int wxBitmap::GetWidth() const
return M_BITMAPDATA->GetWidth() ;
}
double wxBitmap::GetScaleFactor() const
{
wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );
return M_BITMAPDATA->GetScaleFactor() ;
}
int wxBitmap::GetDepth() const
{
wxCHECK_MSG( IsOk(), -1, wxT("invalid bitmap") );