/////////////////////////////////////////////////////////////////////////////
-// Name: bitmap.cpp
+// Name: src/mac/carbon/bitmap.cpp
// Purpose: wxBitmap
// Author: Stefan Csomor
// Modified by:
#include "wx/wxprec.h"
#include "wx/bitmap.h"
-#include "wx/icon.h"
-#include "wx/log.h"
-#include "wx/image.h"
+
+#ifndef WX_PRECOMP
+ #include "wx/log.h"
+ #include "wx/dcmemory.h"
+ #include "wx/icon.h"
+ #include "wx/image.h"
+#endif
+
#include "wx/metafile.h"
#include "wx/xpmdecod.h"
IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
-IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
#ifdef __DARWIN__
#include <ApplicationServices/ApplicationServices.h>
#endif
#include "wx/mac/uma.h"
-#include "wx/dcmemory.h"
// Implementation Notes
// --------------------
#endif
else
{
+#ifndef __LP64__
info->contentType = kControlContentPictHandle ;
info->u.picture = bmap->GetPictHandle() ;
+#endif
}
}
}
m_hasAlpha = false;
}
+wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData &tocopy)
+{
+ Init();
+ Create(tocopy.m_width, tocopy.m_height, tocopy.m_depth);
+
+ if (tocopy.m_bitmapMask)
+ m_bitmapMask = new wxMask(*tocopy.m_bitmapMask);
+
+ unsigned char* dest = (unsigned char*)GetRawAccess();
+ unsigned char* source = (unsigned char*)tocopy.GetRawAccess();
+ size_t numbytes = tocopy.m_width * tocopy.m_height * 4;
+
+ for (size_t i=0; i<numbytes; i++)
+ {
+ *dest++ = *source++;
+ }
+
+ UseAlpha(tocopy.m_hasAlpha);
+
+ // TODO: Copy palette?
+}
+
wxBitmapRefData::wxBitmapRefData()
{
Init() ;
bool wxBitmapRefData::Create( int w , int h , int d )
{
- m_width = w ;
- m_height = h ;
+ m_width = wxMax(1, w);
+ m_height = wxMax(1, h);
m_depth = d ;
m_bytesPerRow = w * 4 ;
m_hBitmap = NULL ;
Rect rect = { 0 , 0 , m_height , m_width } ;
+#ifndef __LP64__
verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 ,
(char*) data , m_bytesPerRow ) ) ;
wxASSERT_MSG( m_hBitmap , wxT("Unable to create GWorld context") ) ;
-
+#endif
m_ok = ( m_hBitmap != NULL ) ;
return m_ok ;
memset( data , 0 , size ) ;
Rect rect = { 0 , 0 , height , width } ;
+#ifndef __LP64__
verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hMaskBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 ,
(char*) data , m_maskBytesPerRow ) ) ;
wxASSERT_MSG( m_hMaskBitmap , wxT("Unable to create GWorld context for alpha mask") ) ;
+#endif
m_maskMemBuf.UngetWriteBuf(size) ;
#if !wxMAC_USE_CORE_GRAPHICS
}
else
{
+#ifndef __LP64__
DisposeGWorld( m_hMaskBitmap ) ;
+#endif
m_hMaskBitmap = NULL ;
m_maskBytesPerRow = 0 ;
}
*maskdest++ = 0xFF - *masksource++ ;
masksource++ ;
masksource++ ;
+ masksource++ ;
}
else if ( hasAlpha )
*maskdest++ = a ;
PicHandle pic = GetPictHandle() ;
SetIconFamilyData( iconFamily, 'PICT' , (Handle) pic ) ;
}
-
// transform into IconRef
-
+#if defined( __WXMAC_OSX__ ) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
+ // cleaner version existing from 10.3 upwards
+ HLock((Handle) iconFamily);
+ OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &m_iconRef );
+ HUnlock((Handle) iconFamily);
+ wxASSERT_MSG( err == noErr , wxT("Error when constructing icon ref") );
+#else
static int iconCounter = 2 ;
OSStatus err = RegisterIconRefFromIconFamily( 'WXNG' , (OSType) iconCounter, iconFamily, &m_iconRef ) ;
// we have to retain a reference, as Unregister will decrement it
AcquireIconRef( m_iconRef ) ;
UnregisterIconRef( 'WXNG' , (OSType) iconCounter ) ;
- DisposeHandle( (Handle) iconFamily ) ;
++iconCounter ;
+#endif
+ DisposeHandle( (Handle) iconFamily ) ;
}
return m_iconRef ;
{
if ( m_pictHandle == NULL )
{
+#ifndef __LP64__
CGrafPtr origPort = NULL ;
GDHandle origDev = NULL ;
GWorldPtr wp = NULL ;
SetGWorld( origPort , origDev ) ;
if ( clipRgn )
DisposeRgn( clipRgn ) ;
+#endif
}
return m_pictHandle ;
for ( int y = 0 ; y < h ; ++y , sourcemaskstart += maskrowbytes)
{
unsigned char *sourcemask = sourcemaskstart ;
- for ( int x = 0 ; x < w ; ++x , sourcemask+=3 , destalpha += 4 )
+ for ( int x = 0 ; x < w ; ++x , sourcemask += 4 , destalpha += 4 )
{
*destalpha = 0xFF - *sourcemask ;
}
membuf = new wxMemoryBuffer( m_memBuf ) ;
}
-
- CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace();
- CGDataProviderRef dataProvider =
- CGDataProviderCreateWithData(
- membuf , (const void *)membuf->GetData() , imageSize,
- wxMacMemoryBufferReleaseProc );
- image =
+
+ CGDataProviderRef dataProvider = NULL ;
+ if ( m_depth == 1 )
+ {
+ wxMemoryBuffer* maskBuf = new wxMemoryBuffer( m_width * m_height );
+ unsigned char * maskBufData = (unsigned char *) maskBuf->GetData();
+ unsigned char * bufData = (unsigned char *) membuf->GetData() ;
+ // copy one color component
+ for( int i = 0 ; i < m_width * m_height ; ++i )
+ maskBufData[i] = bufData[i*4+3];
+ dataProvider =
+ CGDataProviderCreateWithData(
+ maskBuf , (const void *) maskBufData , m_width * m_height,
+ wxMacMemoryBufferReleaseProc );
+ // as we are now passing the mask buffer to the data provider, we have
+ // to release the membuf ourselves
+ delete membuf ;
+
+ image = ::CGImageMaskCreate( w, h, 8, 8, m_width , dataProvider, NULL, false );
+ }
+ else
+ {
+ CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace();
+ 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
m_iconRef = NULL ;
}
+#ifndef __LP64__
if ( m_pictHandle )
{
KillPicture( m_pictHandle ) ;
DisposeGWorld( MAC_WXHBITMAP(m_hMaskBitmap) ) ;
m_hMaskBitmap = NULL ;
}
-
+#endif
if (m_bitmapMask)
{
delete m_bitmapMask;
(void)Create(w, h, d);
}
-wxBitmap::wxBitmap(void *data, wxBitmapType type, int width, int height, int depth)
+wxBitmap::wxBitmap(const void* data, wxBitmapType type, int width, int height, int depth)
{
(void) Create(data, type, width, height, depth);
}
LoadFile(filename, type);
}
-wxBitmap::wxBitmap(const char **bits)
+wxObjectRefData* wxBitmap::CreateRefData() const
{
- (void) CreateFromXpm(bits);
+ return new wxBitmapRefData;
}
-wxBitmap::wxBitmap(char **bits)
+wxObjectRefData* wxBitmap::CloneRefData(const wxObjectRefData* data) const
{
- (void) CreateFromXpm((const char **)bits);
+ return new wxBitmapRefData(*wx_static_cast(const wxBitmapRefData *, data));
}
void * wxBitmap::GetRawAccess() const
M_BITMAPDATA->EndRawAccess() ;
}
-bool wxBitmap::CreateFromXpm(const char **bits)
-{
-#if wxUSE_IMAGE
- 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") )
-
- *this = wxBitmap(img);
-
- return true;
-#else
-
- return false;
-#endif
-}
-
#ifdef __WXMAC_OSX__
WXCGIMAGEREF wxBitmap::CGImageCreate() const
{
if ( M_BITMAPDATA->m_bitmapMask )
{
wxMemoryBuffer maskbuf ;
- int rowBytes = ( destwidth + 3 ) & 0xFFFFFFC ;
+ int rowBytes = ( destwidth * 4 + 3 ) & 0xFFFFFFC ;
size_t maskbufsize = rowBytes * destheight ;
- int sourcelinesize = M_BITMAPDATA->m_bitmapMask->GetBytesPerRow() ;
+ int sourcelinesize = M_BITMAPDATA->m_bitmapMask->GetBytesPerRow() ;
int destlinesize = rowBytes ;
unsigned char *source = (unsigned char *) M_BITMAPDATA->m_bitmapMask->GetRawAccess() ;
unsigned char *destdata = (unsigned char * ) maskbuf.GetWriteBuf( maskbufsize ) ;
wxASSERT( (source != NULL) && (destdata != NULL) ) ;
- source += rect.x + rect.y * sourcelinesize ;
+ source += rect.x * 4 + rect.y * sourcelinesize ;
unsigned char *dest = destdata ;
for (int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize)
{
- for (int xx = 0; xx < destlinesize; xx++ )
- *(dest+xx) = 0xFF - *(source+xx*3) ;
+ memcpy( dest , source , destlinesize ) ;
}
maskbuf.UngetWriteBuf( maskbufsize ) ;
return false;
}
-bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int depth)
+bool wxBitmap::Create(const void* data, wxBitmapType type, int width, int height, int depth)
{
UnRef();
wxBitmap::wxBitmap(const wxImage& image, int depth)
{
- wxCHECK_RET( image.Ok(), wxT("invalid image") )
+ wxCHECK_RET( image.Ok(), wxT("invalid image") );
// width and height of the device-dependent bitmap
int width = image.GetWidth();
// 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
+ // replaced with when it actually occurs in the bitmap
static const int MASK_RED = 1;
static const int MASK_GREEN = 2;
static const int MASK_BLUE = 3;
for (int xx = 0; xx < width; xx++)
{
color = *((long*) source) ;
+#ifdef WORDS_BIGENDIAN
a = ((color&0xFF000000) >> 24) ;
r = ((color&0x00FF0000) >> 16) ;
g = ((color&0x0000FF00) >> 8) ;
b = (color&0x000000FF);
-
+#else
+ b = ((color&0xFF000000) >> 24) ;
+ g = ((color&0x00FF0000) >> 16) ;
+ r = ((color&0x0000FF00) >> 8) ;
+ a = (color&0x000000FF);
+#endif
if ( hasMask )
{
if ( *maskp++ == 0xFF )
}
else if ( r == MASK_RED && g == MASK_GREEN && b == MASK_BLUE )
b = MASK_BLUE_REPLACEMENT ;
+
+ maskp++ ;
maskp++ ;
maskp++ ;
}
#endif //wxUSE_IMAGE
-bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type,
- const wxPalette *palette) const
+bool wxBitmap::SaveFile( const wxString& filename,
+ wxBitmapType type, const wxPalette *palette ) const
{
bool success = false;
wxBitmapHandler *handler = FindHandler(type);
return success;
}
-bool wxBitmap::Ok() const
+bool wxBitmap::IsOk() const
{
return (M_BITMAPDATA && M_BITMAPDATA->Ok());
}
void wxBitmap::SetWidth(int w)
{
- if (!M_BITMAPDATA)
- m_refData = new wxBitmapRefData;
-
+ AllocExclusive();
M_BITMAPDATA->SetWidth(w);
}
void wxBitmap::SetHeight(int h)
{
- if (!M_BITMAPDATA)
- m_refData = new wxBitmapRefData;
-
+ AllocExclusive();
M_BITMAPDATA->SetHeight(h);
}
void wxBitmap::SetDepth(int d)
{
- if (!M_BITMAPDATA)
- m_refData = new wxBitmapRefData;
-
+ AllocExclusive();
M_BITMAPDATA->SetDepth(d);
}
void wxBitmap::SetOk(bool isOk)
{
- if (!M_BITMAPDATA)
- m_refData = new wxBitmapRefData;
-
+ AllocExclusive();
M_BITMAPDATA->SetOk(isOk);
}
void wxBitmap::SetPalette(const wxPalette& palette)
{
- if (!M_BITMAPDATA)
- m_refData = new wxBitmapRefData;
-
+ AllocExclusive();
M_BITMAPDATA->m_bitmapPalette = palette ;
}
#endif // wxUSE_PALETTE
void wxBitmap::SetMask(wxMask *mask)
{
- if (!M_BITMAPDATA)
- m_refData = new wxBitmapRefData;
-
+ AllocExclusive();
// Remove existing mask if there is one.
delete M_BITMAPDATA->m_bitmapMask;
Init() ;
}
+wxMask::wxMask(const wxMask &tocopy)
+{
+ Init();
+
+ m_bytesPerRow = tocopy.m_bytesPerRow;
+ m_width = tocopy.m_width;
+ m_height = tocopy.m_height;
+
+ size_t size = m_bytesPerRow * m_height;
+ unsigned char* dest = (unsigned char*)m_memBuf.GetWriteBuf( size );
+ unsigned char* source = (unsigned char*)tocopy.m_memBuf.GetData();
+ for (size_t i=0; i<size; i++)
+ {
+ *dest++ = *source++;
+ }
+
+ m_memBuf.UngetWriteBuf( size ) ;
+ RealizeNative() ;
+}
+
// Construct a mask from a bitmap and a colour indicating
// the transparent area
-wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
+wxMask::wxMask( const wxBitmap& bitmap, const wxColour& colour )
{
Init() ;
- Create(bitmap, colour);
+ Create( bitmap, colour );
}
// Construct a mask from a mono bitmap (copies the bitmap).
-wxMask::wxMask(const wxBitmap& bitmap)
+wxMask::wxMask( const wxBitmap& bitmap )
{
Init() ;
- Create(bitmap);
+ Create( bitmap );
}
// Construct a mask from a mono bitmap (copies the bitmap).
+
wxMask::wxMask( const wxMemoryBuffer& data, int width , int height , int bytesPerRow )
{
Init() ;
- Create(data, width , height , bytesPerRow );
+ Create( data, width , height , bytesPerRow );
}
wxMask::~wxMask()
{
+#ifndef __LP64__
if ( m_maskBitmap )
{
- DisposeGWorld( (GWorldPtr) m_maskBitmap ) ;
+ DisposeGWorld( (GWorldPtr)m_maskBitmap ) ;
m_maskBitmap = NULL ;
}
+#endif
}
void wxMask::Init()
return m_memBuf.GetData() ;
}
-// The default ColorTable for k8IndexedGrayPixelFormat in Intel seems to be broken, so we'll use an non-indexed
-// bitmap mask instead, in order to keep the code simple, the change is done for ppc implementations as well
+// The default ColorTable for k8IndexedGrayPixelFormat in Intel appears to be broken, so we'll use an non-indexed
+// bitmap mask instead; in order to keep the code simple, the change applies to PowerPC implementations as well
void wxMask::RealizeNative()
{
+#ifndef __LP64__
if ( m_maskBitmap )
{
- DisposeGWorld( (GWorldPtr) m_maskBitmap ) ;
+ DisposeGWorld( (GWorldPtr)m_maskBitmap ) ;
m_maskBitmap = NULL ;
}
Rect rect = { 0 , 0 , m_height , m_width } ;
- verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_maskBitmap , k24RGBPixelFormat , &rect , NULL , NULL , 0 ,
- (char*) m_memBuf.GetData() , m_bytesPerRow ) ) ;
+ OSStatus err = NewGWorldFromPtr(
+ (GWorldPtr*) &m_maskBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 ,
+ (char*) m_memBuf.GetData() , m_bytesPerRow ) ;
+ verify_noerr( err ) ;
+#endif
}
// Create a mask from a mono bitmap (copies the bitmap).
+
bool wxMask::Create(const wxMemoryBuffer& data,int width , int height , int bytesPerRow)
{
m_memBuf = data ;
{
m_width = bitmap.GetWidth() ;
m_height = bitmap.GetHeight() ;
- m_bytesPerRow = ( m_width * 3 + 3 ) & 0xFFFFFFC ;
+ m_bytesPerRow = ( m_width * 4 + 3 ) & 0xFFFFFFC ;
size_t size = m_bytesPerRow * m_height ;
unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ;
*destdata++ = 0xFF ;
*destdata++ = 0xFF ;
*destdata++ = 0xFF ;
+ *destdata++ = 0xFF ;
}
else
{
*destdata++ = 0x00 ;
*destdata++ = 0x00 ;
*destdata++ = 0x00 ;
+ *destdata++ = 0x00 ;
}
}
}
{
m_width = bitmap.GetWidth() ;
m_height = bitmap.GetHeight() ;
- m_bytesPerRow = ( m_width * 3 + 3 ) & 0xFFFFFFC ;
+ m_bytesPerRow = ( m_width * 4 + 3 ) & 0xFFFFFFC ;
size_t size = m_bytesPerRow * m_height ;
unsigned char * destdatabase = (unsigned char*) m_memBuf.GetWriteBuf( size ) ;
g = *srcdata++ ;
b = *srcdata++ ;
- if ( colour == wxColour( r , g , b) )
+ if ( colour == wxColour( r , g , b ) )
{
*destdata++ = 0xFF ;
*destdata++ = 0xFF ;
*destdata++ = 0xFF ;
+ *destdata++ = 0xFF ;
}
else
{
*destdata++ = 0x00 ;
*destdata++ = 0x00 ;
*destdata++ = 0x00 ;
+ *destdata++ = 0x00 ;
}
}
}
// wxBitmapHandler
// ----------------------------------------------------------------------------
-wxBitmapHandler::~wxBitmapHandler()
-{
-}
-
-bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
-{
- return false;
-}
-
-bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
- int desiredWidth, int desiredHeight)
-{
- return false;
-}
-
-bool wxBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
-{
- return false;
-}
+IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandler, wxBitmapHandlerBase)
// ----------------------------------------------------------------------------
// Standard Handlers
virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
int desiredWidth, int desiredHeight);
};
+
IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
if ( thePict )
{
wxMetafile mf ;
+
mf.SetHMETAFILE( (WXHMETAFILE) thePict ) ;
bitmap->Create( mf.GetWidth() , mf.GetHeight() ) ;
wxMemoryDC dc ;
return true ;
}
-#endif //wxUSE_METAFILE
+#endif
return false ;
}
data.m_height = GetHeight() ;
data.m_stride = GetWidth() * 4 ;
- return GetRawAccess() ;
+ return BeginRawAccess() ;
}
void wxBitmap::UngetRawData(wxPixelDataBase& dataBase)
{
- if ( !Ok() )
- return;
-
- // TODO : if we have some information about the API we should check
- // this code looks strange...
-
- if ( !M_BITMAPDATA->HasAlpha() )
- return;
-
- wxAlphaPixelData& data = (wxAlphaPixelData&)dataBase;
- int w = data.GetWidth();
- int h = data.GetHeight();
-
- wxBitmap bmpMask( GetWidth(), GetHeight(), 32 );
- wxAlphaPixelData dataMask( bmpMask, data.GetOrigin(), wxSize( w, h ) );
- wxAlphaPixelData::Iterator pMask( dataMask ), p( data );
-
- for ( int y = 0; y < h; y++ )
- {
- wxAlphaPixelData::Iterator rowStartMask = pMask;
- wxAlphaPixelData::Iterator rowStart = p;
-
- for ( int x = 0; x < w; x++ )
- {
- const wxAlphaPixelData::Iterator::ChannelType alpha = p.Alpha();
-
- pMask.Red() = alpha;
- pMask.Green() = alpha;
- pMask.Blue() = alpha;
-
- ++p;
- ++pMask;
- }
-
- p = rowStart;
- p.OffsetY( data, 1 );
-
- pMask = rowStartMask;
- pMask.OffsetY( dataMask, 1 );
- }
-
- SetMask( new wxMask( bmpMask ) );
+ EndRawAccess() ;
}
void wxBitmap::UseAlpha()