X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7aabb2acd3db901fcb74b5eef6e62dd95d807d4d..6ac23e25b85468c7885f6ab43ca0a45f6458af2e:/src/mac/carbon/bitmap.cpp?ds=inline diff --git a/src/mac/carbon/bitmap.cpp b/src/mac/carbon/bitmap.cpp index 7cd5989cde..0359fd6090 100644 --- a/src/mac/carbon/bitmap.cpp +++ b/src/mac/carbon/bitmap.cpp @@ -39,10 +39,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject ) #include "wx/dcmemory.h" // Implementation Notes -// -------------------- +// -------------------- // -// we are always working with a 32 bit deep pixel buffer -// under QuickDraw its alpha parts are going to be ignored in the GWorld, +// we are always working with a 32 bit deep pixel buffer +// under QuickDraw its alpha parts are going to be ignored in the GWorld, // therefore we have a separate GWorld there for blitting the mask in // under Quartz then content is transformed into a CGImageRef representing the same data @@ -61,18 +61,18 @@ void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bi wxBitmapRefData * bmap = bitmap.GetBitmapData() ; if ( bmap == NULL ) return ; - + if ( ( bmap->HasNativeSize() && forceType == 0 ) || forceType == kControlContentIconRef ) { wxBitmap scaleBmp ; - + wxBitmapRefData* bmp = bmap ; - + if ( !bmap->HasNativeSize() ) { // as PICT conversion will only result in a 16x16 icon, let's attempt - // a few scales for better results - + // a few scales for better results + int w = bitmap.GetWidth() ; int h = bitmap.GetHeight() ; int sz = wxMax( w , h ) ; @@ -82,7 +82,7 @@ void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bi bmp = scaleBmp.GetBitmapData() ; } } - + info->contentType = kControlContentIconRef ; info->u.iconRef = bmp->GetIconRef() ; AcquireIconRef( info->u.iconRef ) ; @@ -108,6 +108,10 @@ void wxMacReleaseBitmapButton( ControlButtonContentInfo*info ) { ReleaseIconRef( info->u.iconRef ) ; } + else if ( info->contentType == kControlNoContent ) + { + // there's no bitmap at all, fall through silently + } else if ( info->contentType == kControlContentPictHandle ) { // owned by the bitmap, no release here @@ -142,7 +146,7 @@ void wxBitmapRefData::Init() m_pictHandle = NULL ; m_hBitmap = NULL ; m_hMaskBitmap = NULL; - m_maskBytesPerRow = NULL ; + m_maskBytesPerRow = 0 ; m_rawAccessCount = 0 ; m_hasAlpha = false; @@ -153,16 +157,16 @@ wxBitmapRefData::wxBitmapRefData() Init() ; } -wxBitmapRefData::wxBitmapRefData( int w , int h , int d ) +wxBitmapRefData::wxBitmapRefData( int w , int h , int d ) { Init() ; Create( w , h , d ) ; } -bool wxBitmapRefData::Create( int w , int h , int d ) +bool wxBitmapRefData::Create( int w , int h , int d ) { m_width = w ; - m_height = h ; + m_height = h ; m_depth = d ; m_bytesPerRow = w * 4 ; @@ -174,18 +178,18 @@ bool wxBitmapRefData::Create( int w , int h , int d ) m_hBitmap = NULL ; Rect rect = { 0 , 0 , m_height , m_width } ; verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 , - (char*) data , m_bytesPerRow ) ) ; + (char*) data , m_bytesPerRow ) ) ; wxASSERT_MSG( m_hBitmap , wxT("Unable to create GWorld context") ) ; m_ok = ( m_hBitmap != NULL ) ; - return m_ok ; + return m_ok ; } void wxBitmapRefData::UseAlpha( bool use ) { if ( m_hasAlpha == use ) return ; - + m_hasAlpha = use ; if ( m_hasAlpha ) { @@ -198,7 +202,7 @@ void wxBitmapRefData::UseAlpha( bool use ) wxASSERT( m_hMaskBitmap == NULL ) ; Rect rect = { 0 , 0 , height , width } ; verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hMaskBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 , - (char*) data , m_maskBytesPerRow ) ) ; + (char*) data , m_maskBytesPerRow ) ) ; wxASSERT_MSG( m_hMaskBitmap , wxT("Unable to create GWorld context for alpha mask") ) ; m_maskMemBuf.UngetWriteBuf(size) ; #if !wxMAC_USE_CORE_GRAPHICS @@ -219,14 +223,14 @@ void *wxBitmapRefData::GetRawAccess() const return m_memBuf.GetData() ; } -void *wxBitmapRefData::BeginRawAccess() +void *wxBitmapRefData::BeginRawAccess() { wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ) ; wxASSERT( m_rawAccessCount == 0 ) ; ++m_rawAccessCount ; // we must destroy an existing cached image, as // the bitmap data may change now - wxASSERT_MSG( m_pictHandle == NULL && m_iconRef == NULL , + wxASSERT_MSG( m_pictHandle == NULL && m_iconRef == NULL , wxT("Currently, modifing bitmaps that are used in controls already is not supported") ) ; #if wxMAC_USE_CORE_GRAPHICS if ( m_cgImageRef ) @@ -253,7 +257,7 @@ bool wxBitmapRefData::HasNativeSize() int w = GetWidth() ; int h = GetHeight() ; int sz = wxMax( w , h ) ; - + if ( sz == 128 || sz == 48 || sz == 32 || sz == 16 ) return true ; return false ; @@ -264,17 +268,22 @@ IconRef wxBitmapRefData::GetIconRef() if ( m_iconRef == NULL ) { // Create Icon Family Handle - + IconFamilyHandle iconFamily = NULL ; - + +#ifdef WORDS_BIGENDIAN iconFamily = (IconFamilyHandle) NewHandle(8) ; (**iconFamily).resourceType = kIconFamilyType ; (**iconFamily).resourceSize = sizeof(OSType) + sizeof(Size); - +#else + // test this solution on big endian as well + iconFamily = (IconFamilyHandle) NewHandle(0) ; +#endif + int w = GetWidth() ; int h = GetHeight() ; int sz = wxMax( w , h ) ; - + OSType dataType = 0 ; OSType maskType = 0 ; @@ -303,7 +312,7 @@ IconRef wxBitmapRefData::GetIconRef() { // setup the header properly - Handle data = NULL ; + Handle data = NULL ; Handle maskdata = NULL ; unsigned char * maskptr = NULL ; unsigned char * ptr = NULL ; @@ -311,13 +320,13 @@ IconRef wxBitmapRefData::GetIconRef() size_t masksize ; size = sz * sz * 4 ; - data = NewHandle( size) ; + data = NewHandle( size) ; HLock( data ) ; ptr = (unsigned char*) *data ; memset( ptr , 0, size ) ; masksize = sz * sz ; - maskdata = NewHandle( masksize ) ; + maskdata = NewHandle( masksize ) ; HLock( maskdata ) ; maskptr = (unsigned char*) *maskdata ; memset( maskptr , 0 , masksize ) ; @@ -336,12 +345,12 @@ IconRef wxBitmapRefData::GetIconRef() unsigned char r = *source ++ ; unsigned char g = *source ++ ; unsigned char b = *source ++ ; - + *dest++ = 0 ; *dest++ = r ; *dest++ = g ; *dest++ = b ; - + if ( mask ) *maskdest++ = *masksource++ ; else if ( hasAlpha ) @@ -350,7 +359,7 @@ IconRef wxBitmapRefData::GetIconRef() *maskdest++ = 0xFF ; } } - + OSStatus err = SetIconFamilyData( iconFamily, dataType , data ) ; wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ; @@ -366,16 +375,16 @@ IconRef wxBitmapRefData::GetIconRef() PicHandle pic = GetPictHandle() ; SetIconFamilyData( iconFamily, 'PICT' , (Handle) pic ) ; } - + // transform into IconRef - - static int iconCounter = 2 ; + + static int iconCounter = 2 ; #ifdef __WXDEBUG__ - OSStatus err = + OSStatus err = #endif RegisterIconRefFromIconFamily( 'WXNG' , (OSType) iconCounter, iconFamily, &m_iconRef ) ; wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ; - // we have to retain a reference, as Unregister will decrement it + // we have to retain a reference, as Unregister will decrement it AcquireIconRef( m_iconRef ) ; UnregisterIconRef( 'WXNG' , (OSType) iconCounter ) ; DisposeHandle( (Handle) iconFamily ) ; @@ -394,7 +403,7 @@ PicHandle wxBitmapRefData::GetPictHandle() GWorldPtr mask = NULL ; int height = GetHeight() ; int width = GetWidth() ; - + Rect rect = { 0 , 0 , height , width } ; GetGWorld( &origPort , &origDev ) ; @@ -431,7 +440,7 @@ PicHandle wxBitmapRefData::GetPictHandle() Rect portRect ; GetPortBounds( wp , &portRect ) ; m_pictHandle = OpenPicture(&portRect); - + if(m_pictHandle) { RGBColor white = { 0xffff ,0xffff , 0xffff } ; @@ -479,7 +488,7 @@ CGImageRef wxBitmapRefData::CGImageCreate() const int h = m_height ; CGImageAlphaInfo alphaInfo = kCGImageAlphaNoneSkipFirst ; wxMemoryBuffer* membuf = NULL ; - + if ( m_bitmapMask ) { membuf = new wxMemoryBuffer( imageSize ) ; @@ -511,13 +520,13 @@ CGImageRef wxBitmapRefData::CGImageCreate() const membuf = new wxMemoryBuffer( m_memBuf ) ; } CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace(); - CGDataProviderRef dataProvider = - CGDataProviderCreateWithData( membuf , (const void *)membuf->GetData() , imageSize, - wxMacMemoryBufferReleaseProc ); - image = - ::CGImageCreate( w, h, 8 , 32 , 4 * m_width , colorSpace, alphaInfo , - dataProvider, NULL , false , kCGRenderingIntentDefault ); - CGDataProviderRelease( dataProvider); + CGDataProviderRef dataProvider = + CGDataProviderCreateWithData( membuf , (const void *)membuf->GetData() , imageSize, + wxMacMemoryBufferReleaseProc ); + image = + ::CGImageCreate( w, h, 8 , 32 , 4 * m_width , colorSpace, alphaInfo , + dataProvider, NULL , false , kCGRenderingIntentDefault ); + CGDataProviderRelease( dataProvider); } else { @@ -529,7 +538,7 @@ CGImageRef wxBitmapRefData::CGImageCreate() const // we keep it for later use m_cgImageRef = image ; CGImageRetain( image ) ; - } + } return image ; } #endif @@ -541,7 +550,7 @@ GWorldPtr wxBitmapRefData::GetHBITMAP(GWorldPtr* mask) const { *mask = NULL ; if ( m_bitmapMask ) - *mask = (GWorldPtr) m_bitmapMask->GetHBITMAP() ; + *mask = (GWorldPtr) m_bitmapMask->GetHBITMAP() ; else if ( m_hasAlpha ) { #if !wxMAC_USE_CORE_GRAPHICS @@ -558,16 +567,16 @@ GWorldPtr wxBitmapRefData::GetHBITMAP(GWorldPtr* mask) const return m_hBitmap ; } -void wxBitmapRefData::UpdateAlphaMask() const +void wxBitmapRefData::UpdateAlphaMask() const { if ( m_hasAlpha ) { unsigned char *sourcemask = (unsigned char *) GetRawAccess() ; unsigned char *destalphabase = (unsigned char *) m_maskMemBuf.GetData() ; - + int h = GetHeight() ; int w = GetWidth() ; - + for ( int y = 0 ; y < h ; ++y , destalphabase += m_maskBytesPerRow ) { unsigned char* destalpha = destalphabase ; @@ -642,10 +651,10 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon) IconFamilyHandle iconFamily = NULL ; Handle imagehandle = NewHandle(0) ; Handle maskhandle = NewHandle(0) ; - + OSType maskType = 0; OSType dataType = 0; - IconSelectorValue selector = 0 ; + IconSelectorValue selector = 0 ; if ( w == 128 ) { dataType = kThumbnail32BitData ; @@ -673,12 +682,12 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon) OSStatus err = ( IconRefToIconFamily( MAC_WXHICON(icon.GetHICON()) , selector , &iconFamily ) ) ; - + err =( GetIconFamilyData( iconFamily , dataType , imagehandle ) ) ; err =( GetIconFamilyData( iconFamily , maskType , maskhandle ) ) ; size_t imagehandlesize = GetHandleSize( imagehandle ) ; size_t maskhandlesize = GetHandleSize( maskhandle ) ; - + if ( imagehandlesize != 0 && maskhandlesize != 0 ) { wxASSERT( GetHandleSize( imagehandle ) == w * 4 * h ) ; @@ -686,7 +695,7 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon) UseAlpha() ; unsigned char *source = (unsigned char *) *imagehandle ; unsigned char *sourcemask = (unsigned char *) *maskhandle ; - + unsigned char* destination = (unsigned char*) BeginRawAccess() ; for ( int y = 0 ; y < h ; ++y ) { @@ -702,13 +711,14 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon) EndRawAccess() ; DisposeHandle( imagehandle ) ; DisposeHandle( maskhandle ) ; + created = true ; } DisposeHandle( (Handle) iconFamily ) ; - + } - + if ( !created ) - { + { wxMemoryDC dc ; dc.SelectObject( *this ) ; dc.DrawIcon( icon , 0 , 0 ) ; @@ -799,7 +809,7 @@ void* wxBitmap::GetRawAccess() const return M_BITMAPDATA->GetRawAccess() ; } -void* wxBitmap::BeginRawAccess() +void* wxBitmap::BeginRawAccess() { wxCHECK_MSG( Ok() , NULL , wxT("invalid bitmap") ) ; return M_BITMAPDATA->BeginRawAccess() ; @@ -814,14 +824,14 @@ void wxBitmap::EndRawAccess() bool wxBitmap::CreateFromXpm(const char **bits) { #if wxUSE_IMAGE - wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") ) + wxCHECK_MSG( bits != NULL, false, wxT("invalid bitmap data") ) wxXPMDecoder decoder; wxImage img = decoder.ReadData(bits); - wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid bitmap data") ) + wxCHECK_MSG( img.Ok(), false, wxT("invalid bitmap data") ) *this = wxBitmap(img); - return TRUE; + return true; #else - return FALSE; + return false; #endif } @@ -862,7 +872,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const } } ret.EndRawAccess() ; - + if ( M_BITMAPDATA->m_bitmapMask ) { wxMemoryBuffer maskbuf ; @@ -938,7 +948,7 @@ bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int if ( handler == NULL ) { wxLogWarning(wxT("no bitmap handler for type %d defined."), type); - return FALSE; + return false; } return handler->Create(this, data, type, width, height, depth); @@ -954,12 +964,12 @@ wxBitmap::wxBitmap(const wxImage& image, int depth) int width = image.GetWidth(); int height = image.GetHeight(); - m_refData = new wxBitmapRefData( width , height , depth ) ;; + m_refData = new wxBitmapRefData( width , height , depth ) ; // Create picture bool hasAlpha = false ; - + if ( image.HasMask() ) { // takes precedence, don't mix with alpha info @@ -968,10 +978,10 @@ wxBitmap::wxBitmap(const wxImage& image, int depth) { hasAlpha = image.HasAlpha() ; } - + if ( hasAlpha ) UseAlpha() ; - + unsigned char* destination = (unsigned char*) BeginRawAccess() ; register unsigned char* data = image.GetData(); @@ -1049,7 +1059,7 @@ wxImage wxBitmap::ConvertToImage() const alpha = image.GetAlpha() ; } int index = 0; - + // The following masking algorithm is the same as well in msw/gtk: // the colour used as transparent one in wxImage and the one it is // replaced with when it really occurs in the bitmap @@ -1072,15 +1082,12 @@ wxImage wxBitmap::ConvertToImage() const { if ( *maskp++ == 0 ) { - if ( r == MASK_RED && g == MASK_GREEN && b == MASK_BLUE ) - b = MASK_BLUE_REPLACEMENT ; - else - { - r = MASK_RED ; - g = MASK_GREEN ; - b = MASK_BLUE ; - } + r = MASK_RED ; + g = MASK_GREEN ; + b = MASK_BLUE ; } + else if ( r == MASK_RED && g == MASK_GREEN && b == MASK_BLUE ) + b = MASK_BLUE_REPLACEMENT ; } else if ( hasAlpha ) *alpha++ = a ; @@ -1102,22 +1109,24 @@ wxImage wxBitmap::ConvertToImage() const bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const { + bool success = false; wxBitmapHandler *handler = FindHandler(type); if ( handler ) { - return handler->SaveFile(this, filename, type, palette); + success = handler->SaveFile(this, filename, type, palette); } else { #if wxUSE_IMAGE wxImage image = ConvertToImage(); - return image.SaveFile(filename, type); + success = image.SaveFile(filename, type); +#else + wxLogWarning(wxT("no bitmap handler for type %d defined."), type); #endif } - wxLogWarning(wxT("no bitmap handler for type %d defined."), type); - return false; + return success; } bool wxBitmap::Ok() const @@ -1282,7 +1291,7 @@ wxMask::~wxMask() } } -void wxMask::Init() +void wxMask::Init() { m_width = m_height = m_bytesPerRow = 0 ; m_maskBitmap = NULL ; @@ -1296,7 +1305,7 @@ void *wxMask::GetRawAccess() const // this can be a k8IndexedGrayPixelFormat GWorld, because it never stores other values than black or white // so no rainbox colors will be created by QD when blitting -void wxMask::RealizeNative() +void wxMask::RealizeNative() { if ( m_maskBitmap ) { @@ -1305,7 +1314,7 @@ void wxMask::RealizeNative() } Rect rect = { 0 , 0 , m_height , m_width } ; verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_maskBitmap , k8IndexedGrayPixelFormat , &rect , NULL , NULL , 0 , - (char*) m_memBuf.GetData() , m_bytesPerRow ) ) ; + (char*) m_memBuf.GetData() , m_bytesPerRow ) ) ; } // Create a mask from a mono bitmap (copies the bitmap). @@ -1347,7 +1356,7 @@ bool wxMask::Create(const wxBitmap& bitmap) } m_memBuf.UngetWriteBuf( size ) ; RealizeNative() ; - return TRUE; + return true; } // Create a mask from a bitmap and a colour indicating @@ -1379,7 +1388,7 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) } m_memBuf.UngetWriteBuf( size ) ; RealizeNative() ; - return TRUE; + return true; } WXHBITMAP wxMask::GetHBITMAP() const @@ -1397,18 +1406,18 @@ wxBitmapHandler::~wxBitmapHandler() bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth) { - return FALSE; + return false; } bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags, int desiredWidth, int desiredHeight) { - return FALSE; + return false; } bool wxBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette) { - return FALSE; + return false; } // ---------------------------------------------------------------------------- @@ -1449,10 +1458,10 @@ bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, lo dc.SelectObject( *bitmap ) ; mf.Play( &dc ) ; dc.SelectObject( wxNullBitmap ) ; - return TRUE ; + return true ; } #endif //wxUSE_METAFILE - return FALSE ; + return false ; }