From f8bfebfcb88bf7d1457e74d2c6fe2e001ed2d546 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 25 Jun 2013 14:02:11 +0000 Subject: [PATCH 1/1] native scaling support for bitmap git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74287 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/osx/bitmap.h | 7 +++++ src/osx/core/bitmap.cpp | 63 ++++++++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/include/wx/osx/bitmap.h b/include/wx/osx/bitmap.h index 736e325376..d9ec58f7bf 100644 --- a/include/wx/osx/bitmap.h +++ b/include/wx/osx/bitmap.h @@ -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; diff --git a/src/osx/core/bitmap.cpp b/src/osx/core/bitmap.cpp index da236465dd..f1f1821a38 100644 --- a/src/osx/core/bitmap.cpp +++ b/src/osx/core/bitmap.cpp @@ -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") ); -- 2.47.2