X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2f1ae4143271ae63a17e052a1a471d16e9cd8c44..947ea04d016852aa293291069d5c91ce4c6dde60:/src/mac/carbon/bitmap.cpp diff --git a/src/mac/carbon/bitmap.cpp b/src/mac/carbon/bitmap.cpp index 2eddb0d5b9..1412aa925b 100644 --- a/src/mac/carbon/bitmap.cpp +++ b/src/mac/carbon/bitmap.cpp @@ -13,16 +13,22 @@ #pragma implementation "bitmap.h" #endif +#include "wx/wx.h" #include "wx/setup.h" #include "wx/utils.h" #include "wx/palette.h" #include "wx/bitmap.h" #include "wx/icon.h" #include "wx/log.h" +#include "wx/image.h" extern "C" { +#ifdef __UNIX__ + #include "xpm/xpm.h" +#else #include "xpm.h" +#endif } ; #if !USE_SHARED_LIBRARIES @@ -30,12 +36,18 @@ IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject) IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) #endif -#include +#ifdef __UNIX__ + #include +#else + #include +#endif + +#include "wx/mac/uma.h" CTabHandle wxMacCreateColorTable( int numColors ) { CTabHandle newColors; /* Handle to the new color table */ - short index; /* Index into the table of colors */ + /* Allocate memory for the color table */ newColors = (CTabHandle)NewHandleClear( sizeof (ColorTable) + sizeof (ColorSpec) * (numColors - 1) ); @@ -63,11 +75,11 @@ void wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int g (**newColors).ctTable[index].rgb.blue = 0 ; // someBlueValue; } -GWorldPtr wxMacCreateGWorld( int height , int width , int depth ) +GWorldPtr wxMacCreateGWorld( int width , int height , int depth ) { OSErr err = noErr ; GWorldPtr port ; - Rect rect = { 0 , 0 , width , height } ; + Rect rect = { 0 , 0 , height , width } ; if ( depth < 0 ) { @@ -80,7 +92,7 @@ GWorldPtr wxMacCreateGWorld( int height , int width , int depth ) return port ; } return NULL ; -} +} void wxMacDestroyGWorld( GWorldPtr gw ) { @@ -88,6 +100,97 @@ void wxMacDestroyGWorld( GWorldPtr gw ) DisposeGWorld( gw ) ; } +PicHandle wxMacCreatePict(GWorldPtr wp, GWorldPtr mask) +{ + CGrafPtr origPort ; + GDHandle origDev ; + + PicHandle pict; // this is the Picture we give back + + RGBColor gray = { 0xCCCC ,0xCCCC , 0xCCCC } ; + RGBColor white = { 0xffff ,0xffff , 0xffff } ; + RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ; + + unsigned char *maskimage = NULL ; + Rect portRect ; + GetPortBounds( wp , &portRect ) ; + int width = portRect.right - portRect.left ; + int height = portRect.bottom - portRect.top ; + + LockPixels( GetGWorldPixMap( wp ) ) ; + GetGWorld( &origPort , &origDev ) ; + + if ( mask ) + { + maskimage = (unsigned char*) malloc( width * height ) ; + SetGWorld( mask , NULL ) ; + LockPixels( GetGWorldPixMap( mask ) ) ; + for ( int y = 0 ; y < height ; y++ ) + { + for( int x = 0 ; x < width ; x++ ) + { + RGBColor col ; + + GetCPixel( x + portRect.left , y + portRect.top , &col ) ; + maskimage[y*width + x] = ( col.red == 0 ) ; // for monochrome masks + } + } + UnlockPixels( GetGWorldPixMap( mask ) ) ; + } + + SetGWorld( wp , NULL ) ; + + pict = OpenPicture(&portRect); // open a picture, this disables drawing + if(!pict) + return NULL; + + if ( maskimage ) + { + RGBForeColor( &black ) ; + RGBBackColor( &white ) ; + PenMode(transparent); + + for ( int y = 0 ; y < height ; ++y ) + { + for( int x = 0 ; x < width ; ++x ) + { + if ( maskimage[y*width + x] ) + { + RGBColor col ; + + GetCPixel( x + portRect.left , y + portRect.top , &col ) ; + SetCPixel( x + portRect.left , y + portRect.top , &col ) ; + } + else { + // With transparency set this sets a blank pixel not a white one + SetCPixel( x + portRect.left , y + portRect.top , &white); + } + } + } + free( maskimage ) ; + maskimage = NULL ; + } + else + { + RGBBackColor( &gray ) ; + EraseRect(&portRect); + RGBForeColor( &black ) ; + RGBBackColor( &white ) ; + + CopyBits(GetPortBitMapForCopyBits(wp), /* src PixMap - we copy image over + * itself - */ + GetPortBitMapForCopyBits(wp), // dst PixMap - no drawing occurs + &portRect, // srcRect - it will be recorded and compressed - + &portRect, // dstRect - into the picture that is open - + srcCopy,NULL); // copyMode and no clip region + } + ClosePicture(); // We are done recording the picture + UnlockPixels( GetGWorldPixMap( wp ) ) ; + SetGWorld( origPort , origDev ) ; + + return pict; // return our groovy pict handle +} + wxBitmapRefData::wxBitmapRefData() { m_ok = FALSE; @@ -127,7 +230,7 @@ wxBitmapRefData::~wxBitmapRefData() default : // unkown type ? break ; - } ; + } if (m_bitmapMask) { @@ -162,8 +265,8 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits M_BITMAPDATA->m_numColors = 0; if ( no_bits == 1 ) { - M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; - M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ; + M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; + M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ; M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ; CGrafPtr origPort ; @@ -171,8 +274,18 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits GetGWorld( &origPort , &origDevice ) ; SetGWorld( M_BITMAPDATA->m_hBitmap , NULL ) ; - LockPixels( GetGWorldPixMap( (CGrafPtr) M_BITMAPDATA->m_hBitmap ) ) ; - + LockPixels( GetGWorldPixMap( M_BITMAPDATA->m_hBitmap ) ) ; + +#ifdef __UNIX__ + // bits is a word aligned array?? Don't think so + // bits is a char array on MAC OS X however using the benefit of the + // doubt I replaced references to 16 with sizeof(unsigned char)*8 + unsigned char* linestart = (unsigned char*) bits ; + int linesize = ( the_width / (sizeof(unsigned char) * 8)) ; + if ( the_width % (sizeof(unsigned char) * 8) ) { + linesize += sizeof(unsigned char); + } +#else // bits is a word aligned array unsigned char* linestart = (unsigned char*) bits ; @@ -180,16 +293,17 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits if ( the_width % 16 ) { linesize += 2 ; - } ; + } +#endif RGBColor colors[2] = { { 0xFFFF , 0xFFFF , 0xFFFF } , { 0, 0 , 0 } } ; - for( int y = 0 ; y < the_height ; ++y , linestart += linesize ) + for ( int y = 0 ; y < the_height ; ++y , linestart += linesize ) { - for( int x = 0 ; x < the_width ; ++x ) + for ( int x = 0 ; x < the_width ; ++x ) { int index = x / 8 ; int bit = x % 8 ; @@ -205,13 +319,13 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits } } - UnlockPixels( GetGWorldPixMap( (CGrafPtr) M_BITMAPDATA->m_hBitmap ) ) ; + UnlockPixels( GetGWorldPixMap( M_BITMAPDATA->m_hBitmap ) ) ; SetGWorld( origPort , origDevice ) ; } else { - //multicolor BITMAPs not yet implemented + wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); } if ( wxTheBitmapList ) @@ -247,6 +361,100 @@ wxBitmap::wxBitmap(const char **data) (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0); } +wxBitmap::wxBitmap(char **data) +{ + (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0); +} + +wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const +{ + wxCHECK_MSG( Ok() && + (rect.x >= 0) && (rect.y >= 0) && + (rect.x+rect.width <= GetWidth()) && + (rect.y+rect.height <= GetHeight()), + wxNullBitmap, wxT("invalid bitmap or bitmap region") ); + + + wxBitmap ret( rect.width, rect.height, GetDepth() ); + wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") ); + + WXHBITMAP origPort; + GDHandle origDevice; + + GetGWorld( &origPort, &origDevice ); + + // Update the subbitmaps reference data + wxBitmapRefData *ref = (wxBitmapRefData *)ret.GetRefData(); + + ref->m_numColors = M_BITMAPDATA->m_numColors; + ref->m_bitmapPalette = M_BITMAPDATA->m_bitmapPalette; + ref->m_bitmapType = M_BITMAPDATA->m_bitmapType; + + // Copy sub region of this bitmap + if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) + { + printf("GetSubBitmap: Copy a region of a Pict structure - TODO\n"); + } + else if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypeGrafWorld) + { + // Copy mask + if(GetMask()) + { + WXHBITMAP submask, mask; + RGBColor color; + + mask = GetMask()->GetMaskBitmap(); + submask = wxMacCreateGWorld(rect.width, rect.height, 1); + LockPixels(GetGWorldPixMap(mask)); + LockPixels(GetGWorldPixMap(submask)); + + for(int yy = 0; yy < rect.height; yy++) + { + for(int xx = 0; xx < rect.width; xx++) + { + SetGWorld(mask, NULL); + GetCPixel(rect.x + xx, rect.y + yy, &color); + SetGWorld(submask, NULL); + SetCPixel(xx,yy, &color); + } + } + UnlockPixels(GetGWorldPixMap(mask)); + UnlockPixels(GetGWorldPixMap(submask)); + ref->m_bitmapMask = new wxMask; + ref->m_bitmapMask->SetMaskBitmap(submask); + } + + // Copy bitmap + if(GetHBITMAP()) + { + WXHBITMAP subbitmap, bitmap; + RGBColor color; + + bitmap = GetHBITMAP(); + subbitmap = wxMacCreateGWorld(rect.width, rect.height, GetDepth()); + LockPixels(GetGWorldPixMap(bitmap)); + LockPixels(GetGWorldPixMap(subbitmap)); + + for(int yy = 0; yy < rect.height; yy++) + { + for(int xx = 0; xx < rect.width; xx++) + { + SetGWorld(bitmap, NULL); + GetCPixel(rect.x + xx, rect.y + yy, &color); + SetGWorld(subbitmap, NULL); + SetCPixel(xx, yy, &color); + } + } + UnlockPixels(GetGWorldPixMap(bitmap)); + UnlockPixels(GetGWorldPixMap(subbitmap)); + ret.SetHBITMAP(subbitmap); + } + } + SetGWorld( origPort, origDevice ); + + return ret; +} + bool wxBitmap::Create(int w, int h, int d) { UnRef(); @@ -263,6 +471,13 @@ bool wxBitmap::Create(int w, int h, int d) return M_BITMAPDATA->m_ok; } +int wxBitmap::GetBitmapType() const +{ + wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType, wxT("invalid bitmap") ); + + return M_BITMAPDATA->m_bitmapType; +} + void wxBitmap::SetHBITMAP(WXHBITMAP bmp) { M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; @@ -304,6 +519,140 @@ bool wxBitmap::Create(void *data, long type, int width, int height, int depth) return handler->Create(this, data, type, width, height, depth); } +wxBitmap::wxBitmap(const wxImage& image, int depth) +{ + wxCHECK_RET( image.Ok(), wxT("invalid image") ) + wxCHECK_RET( depth == -1, wxT("invalid bitmap depth") ) + + m_refData = new wxBitmapRefData(); + + if (wxTheBitmapList) wxTheBitmapList->AddBitmap(this); + + // width and height of the device-dependent bitmap + int width = image.GetWidth(); + int height = image.GetHeight(); + + // Create picture + + Create( width , height , wxDisplayDepth() ) ; + wxBitmap maskBitmap( width, height, 1); + + CGrafPtr origPort ; + GDHandle origDevice ; + + LockPixels( GetGWorldPixMap(GetHBITMAP()) ); + LockPixels( GetGWorldPixMap(maskBitmap.GetHBITMAP()) ); + + GetGWorld( &origPort , &origDevice ) ; + SetGWorld( GetHBITMAP() , NULL ) ; + + // Render image + wxColour rgb, maskcolor(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue()); + RGBColor color; + RGBColor white = { 0xffff, 0xffff, 0xffff }; + RGBColor black = { 0 , 0 , 0 }; + + register unsigned char* data = image.GetData(); + + int index = 0; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + rgb.Set(data[index++], data[index++], data[index++]); + color = rgb.GetPixel(); + SetCPixel( x , y , &color ) ; + if (image.HasMask()) + { + SetGWorld(maskBitmap.GetHBITMAP(), NULL); + if (rgb == maskcolor) { + SetCPixel(x,y, &white); + } + else { + SetCPixel(x,y, &black); + } + SetGWorld(GetHBITMAP(), NULL); + } + } + } // for height + + // Create mask + if ( image.HasMask() ) { + wxMask *mask = new wxMask( maskBitmap ); + } + + UnlockPixels( GetGWorldPixMap(GetHBITMAP()) ); + UnlockPixels( GetGWorldPixMap(maskBitmap.GetHBITMAP()) ); + SetGWorld( origPort, origDevice ); +} + +wxImage wxBitmap::ConvertToImage() const +{ + wxImage image; + + wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") ); + + // create an wxImage object + int width = GetWidth(); + int height = GetHeight(); + image.Create( width, height ); + + unsigned char *data = image.GetData(); + + wxCHECK_MSG( data, wxNullImage, wxT("Could not allocate data for image") ); + + WXHBITMAP origPort; + GDHandle origDevice; + int index; + RGBColor color; + // background color set to RGB(16,16,16) in consistent with wxGTK + unsigned char mask_r=16, mask_g=16, mask_b=16; + SInt16 r,g,b; + wxMask *mask = GetMask(); + + GetGWorld( &origPort, &origDevice ); + LockPixels(GetGWorldPixMap(GetHBITMAP())); + SetGWorld( GetHBITMAP(), NULL); + + // Copy data into image + index = 0; + for (int yy = 0; yy < height; yy++) + { + for (int xx = 0; xx < width; xx++) + { + GetCPixel(xx,yy, &color); + r = ((color.red ) >> 8); + g = ((color.green ) >> 8); + b = ((color.blue ) >> 8); + data[index ] = r; + data[index + 1] = g; + data[index + 2] = b; + if (mask) + { + if (mask->PointMasked(xx,yy)) + { + data[index ] = mask_r; + data[index + 1] = mask_g; + data[index + 2] = mask_b; + } + } + index += 3; + } + } + if (mask) + { + image.SetMaskColour( mask_r, mask_g, mask_b ); + image.SetMask( true ); + } + + // Free resources + UnlockPixels(GetGWorldPixMap(GetHBITMAP())); + SetGWorld(origPort, origDevice); + + return image; +} + + bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette) { wxBitmapHandler *handler = FindHandler(type); @@ -317,6 +666,46 @@ bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *pal return handler->SaveFile(this, filename, type, palette); } +bool wxBitmap::Ok() const +{ + return (M_BITMAPDATA && M_BITMAPDATA->m_ok); +} + +int wxBitmap::GetHeight() const +{ + wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); + + return M_BITMAPDATA->m_height; +} + +int wxBitmap::GetWidth() const +{ + wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); + + return M_BITMAPDATA->m_width; +} + +int wxBitmap::GetDepth() const +{ + wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); + + return M_BITMAPDATA->m_depth; +} + +int wxBitmap::GetQuality() const +{ + wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") ); + + return M_BITMAPDATA->m_quality; +} + +wxMask *wxBitmap::GetMask() const +{ + wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") ); + + return M_BITMAPDATA->m_bitmapMask; +} + void wxBitmap::SetWidth(int w) { if (!M_BITMAPDATA) @@ -357,6 +746,13 @@ void wxBitmap::SetOk(bool isOk) M_BITMAPDATA->m_ok = isOk; } +wxPalette *wxBitmap::GetPalette() const +{ + wxCHECK_MSG( Ok(), NULL, wxT("Invalid bitmap GetPalette()") ); + + return &M_BITMAPDATA->m_bitmapPalette; +} + void wxBitmap::SetPalette(const wxPalette& palette) { if (!M_BITMAPDATA) @@ -373,6 +769,105 @@ void wxBitmap::SetMask(wxMask *mask) M_BITMAPDATA->m_bitmapMask = mask ; } +WXHBITMAP wxBitmap::GetHBITMAP() const +{ + wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); + + return M_BITMAPDATA->m_hBitmap; +} + +PicHandle wxBitmap::GetPict() const +{ + wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); + + PicHandle picture; // This is the returned picture + + // If bitmap already in Pict format return pointer + if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) { + return M_BITMAPDATA->m_hPict; + } + else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) { + // Invalid bitmap + return NULL; + } + + RGBColor gray = { 0xCCCC ,0xCCCC , 0xCCCC } ; + RGBColor white = { 0xffff ,0xffff , 0xffff } ; + RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ; + CGrafPtr origPort; + GDHandle origDev ; + wxMask *mask; + Rect portRect ; + + GetPortBounds( GetHBITMAP() , &portRect ) ; + int width = portRect.right - portRect.left ; + int height = portRect.bottom - portRect.top ; + + LockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; + GetGWorld( &origPort , &origDev ) ; + + mask = GetMask(); + + SetGWorld( GetHBITMAP() , NULL ) ; + + picture = OpenPicture(&portRect); // open a picture, this disables drawing + if(!picture) { + return NULL; + } + + if( mask ) + { +#ifdef __UNIX__ + RGBColor trans = white; +#else + RGBBackColor( &gray ); + EraseRect( &portRect ); + RGBColor trans = gray; +#endif + RGBForeColor( &black ) ; + RGBBackColor( &white ) ; + PenMode(transparent); + + for ( int y = 0 ; y < height ; ++y ) + { + for( int x = 0 ; x < width ; ++x ) + { + if ( !mask->PointMasked(x,y) ) + { + RGBColor col ; + + GetCPixel( x + portRect.left , y + portRect.top , &col ) ; + SetCPixel( x + portRect.left , y + portRect.top , &col ) ; + } + else { + // With transparency this sets a blank pixel + SetCPixel( x + portRect.left , y + portRect.top , &trans); + } + } + } + } + else + { + RGBBackColor( &gray ) ; + EraseRect(&portRect); + RGBForeColor( &black ) ; + RGBBackColor( &white ) ; + + CopyBits(GetPortBitMapForCopyBits(GetHBITMAP()), + // src PixMap - we copy image over itself - + GetPortBitMapForCopyBits(GetHBITMAP()), + // dst PixMap - no drawing occurs + &portRect, // srcRect - it will be recorded and compressed - + &portRect, // dstRect - into the picture that is open - + srcCopy,NULL); // copyMode and no clip region + } + ClosePicture(); // We are done recording the picture + UnlockPixels( GetGWorldPixMap( GetHBITMAP() ) ) ; + SetGWorld( origPort , origDev ) ; + + return picture; // return our groovy pict handle +} + void wxBitmap::AddHandler(wxBitmapHandler *handler) { sm_handlers.Append(handler); @@ -479,8 +974,32 @@ wxMask::~wxMask() // Create a mask from a mono bitmap (copies the bitmap). bool wxMask::Create(const wxBitmap& bitmap) { -// TODO - return FALSE; + if ( m_maskBitmap ) + { + wxMacDestroyGWorld( m_maskBitmap ) ; + m_maskBitmap = NULL ; + } + wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false, + wxT("Cannot create mask from this bitmap type (TODO)")); + // other types would require a temporary bitmap. not yet implemented + + wxCHECK_MSG( bitmap.Ok(), false, wxT("Invalid bitmap")); + + wxCHECK_MSG(bitmap.GetDepth() == 1, false, + wxT("Cannot create mask from colour bitmap")); + + m_maskBitmap = wxMacCreateGWorld(bitmap.GetWidth(), bitmap.GetHeight(), 1); + Rect rect = { 0,0, bitmap.GetHeight(), bitmap.GetWidth() }; + + LockPixels( GetGWorldPixMap(m_maskBitmap) ); + LockPixels( GetGWorldPixMap(bitmap.GetHBITMAP()) ); + CopyBits(GetPortBitMapForCopyBits(bitmap.GetHBITMAP()), + GetPortBitMapForCopyBits(m_maskBitmap), + &rect, &rect, srcCopy, 0); + UnlockPixels( GetGWorldPixMap(m_maskBitmap) ); + UnlockPixels( GetGWorldPixMap(bitmap.GetHBITMAP()) ); + + return FALSE; } // Create a mask from a bitmap and a palette index indicating @@ -488,6 +1007,7 @@ bool wxMask::Create(const wxBitmap& bitmap) bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex) { // TODO + wxCHECK_MSG( 0, false, wxT("Not implemented")); return FALSE; } @@ -500,39 +1020,35 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) wxMacDestroyGWorld( m_maskBitmap ) ; m_maskBitmap = NULL ; } - wxASSERT( ((wxBitmapRefData*) bitmap.GetRefData())->m_bitmapType == kMacBitmapTypeGrafWorld ) ; + wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false, + wxT("Cannot create mask from this bitmap type (TODO)")); // other types would require a temporary bitmap. not yet implemented - if (!bitmap.Ok()) - { - return FALSE; - } + wxCHECK_MSG( bitmap.Ok(), false, wxT("Illigal bitmap")); - m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 ) ; - LockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ; - LockPixels( GetGWorldPixMap( (CGrafPtr) ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap ) ) ; - RGBColor maskColor = colour.GetPixel() ; + m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 ); + LockPixels( GetGWorldPixMap( m_maskBitmap ) ); + LockPixels( GetGWorldPixMap( bitmap.GetHBITMAP() ) ); + RGBColor maskColor = colour.GetPixel(); // this is not very efficient, but I can't think // of a better way of doing it CGrafPtr origPort ; GDHandle origDevice ; + RGBColor col; + RGBColor colors[2] = { + { 0xFFFF, 0xFFFF, 0xFFFF }, + { 0, 0, 0 }}; GetGWorld( &origPort , &origDevice ) ; for (int w = 0; w < bitmap.GetWidth(); w++) { for (int h = 0; h < bitmap.GetHeight(); h++) { - RGBColor colors[2] = { - { 0xFFFF , 0xFFFF , 0xFFFF } , - { 0, 0 , 0 } - } ; - - SetGWorld( ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap , NULL ) ; - RGBColor col ; + SetGWorld( bitmap.GetHBITMAP(), NULL ) ; GetCPixel( w , h , &col ) ; SetGWorld( m_maskBitmap , NULL ) ; - if (col.red == maskColor.red && col.blue == maskColor.blue && col.green == maskColor.green) + if (col.red == maskColor.red && col.green == maskColor.green && col.blue == maskColor.blue) { SetCPixel( w , h , &colors[0] ) ; } @@ -543,12 +1059,33 @@ bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) } } UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ; - UnlockPixels( GetGWorldPixMap( ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap ) ) ; + UnlockPixels( GetGWorldPixMap( bitmap.GetHBITMAP() ) ) ; SetGWorld( origPort , origDevice ) ; return TRUE; } +bool wxMask::PointMasked(int x, int y) +{ + WXHBITMAP origPort; + GDHandle origDevice; + RGBColor color; + bool masked = true; + + GetGWorld( &origPort, &origDevice); + + //Set port to mask and see if it masked (1) or not ( 0 ) + SetGWorld(m_maskBitmap, NULL); + LockPixels(GetGWorldPixMap(m_maskBitmap)); + GetCPixel(x,y, &color); + masked = !(color.red == 0 && color.green == 0 && color.blue == 0); + UnlockPixels(GetGWorldPixMap(m_maskBitmap)); + + SetGWorld( origPort, origDevice); + + return masked; +} + /* * wxBitmapHandler */ @@ -596,8 +1133,12 @@ bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, lo { Str255 theName ; - strcpy( (char*) theName , name ) ; - c2pstr( (char*) theName ) ; +#if TARGET_CARBON + c2pstrcpy( (StringPtr) theName , name ) ; +#else + strcpy( (char *) theName , name ) ; + c2pstr( (char *)theName ) ; +#endif PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ; if ( thePict ) @@ -752,13 +1293,14 @@ IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler) bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth) { - XImage * ximage; + XImage * ximage = NULL ; + XImage * xshapeimage = NULL ; int ErrorStatus; XpmAttributes xpmAttr; xpmAttr.valuemask = XpmReturnInfos; // get infos back ErrorStatus = XpmCreateImageFromData( GetMainDevice() , (char **)data, - &ximage, (XImage **) NULL, &xpmAttr); + &ximage, &xshapeimage, &xpmAttr); if (ErrorStatus == XpmSuccess) { @@ -776,7 +1318,12 @@ bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int widt XImageFree(ximage); // releases the malloc, but does not detroy // the bitmap M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; - + if ( xshapeimage != NULL ) + { + wxMask* m = new wxMask() ; + m->SetMaskBitmap( xshapeimage->gworldptr ) ; + M_BITMAPHANDLERDATA->m_bitmapMask = m ; + } return TRUE; } else