X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5fde6fcc9b551340a194ae4c726db5ab64b5c594..544421165fa7f656d23b69801443b7aa69f71db8:/src/mac/bitmap.cpp diff --git a/src/mac/bitmap.cpp b/src/mac/bitmap.cpp index 5cc2a537fd..9e47fe6728 100644 --- a/src/mac/bitmap.cpp +++ b/src/mac/bitmap.cpp @@ -20,13 +20,13 @@ #include "wx/bitmap.h" #include "wx/icon.h" #include "wx/log.h" +#include "wx/image.h" +#include "wx/xpmdecod.h" -extern "C" +extern "C" { -#ifdef __UNIX__ - #include "xpm/xpm.h" -#else - #include "xpm.h" +#ifdef OBSOLETE_XPM_DATA_HANDLER + #include "xpm.h" #endif } ; @@ -41,6 +41,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) #include #endif +#include "wx/mac/uma.h" + CTabHandle wxMacCreateColorTable( int numColors ) { CTabHandle newColors; /* Handle to the new color table */ @@ -197,9 +199,10 @@ wxBitmapRefData::wxBitmapRefData() m_quality = 0; m_numColors = 0; m_bitmapMask = NULL; - m_hBitmap = NULL ; - m_hPict = NULL ; - m_bitmapType = kMacBitmapTypeUnknownType ; + m_hBitmap = NULL ; + m_hPict = NULL ; + m_hIcon = NULL ; + m_bitmapType = kMacBitmapTypeUnknownType ; } wxBitmapRefData::~wxBitmapRefData() @@ -224,6 +227,13 @@ wxBitmapRefData::~wxBitmapRefData() } } break ; + case kMacBitmapTypeIcon : + if ( m_hIcon ) + { + DisposeCIcon( m_hIcon ) ; + m_hIcon = NULL ; + } + default : // unkown type ? break ; @@ -260,73 +270,61 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits M_BITMAPDATA->m_height = the_height ; M_BITMAPDATA->m_depth = 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_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ; + if ( no_bits == 1 ) + { + 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 ; - GDHandle origDevice ; - - GetGWorld( &origPort , &origDevice ) ; - SetGWorld( M_BITMAPDATA->m_hBitmap , NULL ) ; - 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 ; - int linesize = ( the_width / 16 ) * 2 ; - 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 x = 0 ; x < the_width ; ++x ) - { - int index = x / 8 ; - int bit = x % 8 ; - int mask = 1 << bit ; - if ( linestart[index] & mask ) - { - SetCPixel( x , y , &colors[1] ) ; - } - else - { - SetCPixel( x , y , &colors[0] ) ; - } - } - - } - UnlockPixels( GetGWorldPixMap( M_BITMAPDATA->m_hBitmap ) ) ; + CGrafPtr origPort ; + GDHandle origDevice ; - SetGWorld( origPort , origDevice ) ; - } - else - { - wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); - } - - if ( wxTheBitmapList ) + GetGWorld( &origPort , &origDevice ) ; + SetGWorld( M_BITMAPDATA->m_hBitmap , NULL ) ; + LockPixels( GetGWorldPixMap( M_BITMAPDATA->m_hBitmap ) ) ; + + // bits is a char array + + 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); + } + + RGBColor colors[2] = { + { 0xFFFF , 0xFFFF , 0xFFFF } , + { 0, 0 , 0 } + } ; + + for ( int y = 0 ; y < the_height ; ++y , linestart += linesize ) + { + for ( int x = 0 ; x < the_width ; ++x ) + { + int index = x / 8 ; + int bit = x % 8 ; + int mask = 1 << bit ; + if ( linestart[index] & mask ) + { + SetCPixel( x , y , &colors[1] ) ; + } + else + { + SetCPixel( x , y , &colors[0] ) ; + } + } + } + UnlockPixels( GetGWorldPixMap( M_BITMAPDATA->m_hBitmap ) ) ; + + SetGWorld( origPort , origDevice ) ; + } + else + { + wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); + } + + if ( wxTheBitmapList ) { wxTheBitmapList->AddBitmap(this); + } } wxBitmap::wxBitmap(int w, int h, int d) @@ -353,14 +351,33 @@ wxBitmap::wxBitmap(const wxString& filename, long type) wxTheBitmapList->AddBitmap(this); } -wxBitmap::wxBitmap(const char **data) +bool wxBitmap::CreateFromXpm(const char **bits) { - (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0); + 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); + if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); + return TRUE; } -wxBitmap::wxBitmap(char **data) +wxBitmap::wxBitmap(const char **bits) { - (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0); +#ifdef OBSOLETE_XPM_DATA_HANDLER + (void) Create((void *)bits, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0); +#else + (void) CreateFromXpm(bits); +#endif +} + +wxBitmap::wxBitmap(char **bits) +{ +#ifdef OBSOLETE_XPM_DATA_HANDLER + (void) Create((void *)bits, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0); +#else + (void) CreateFromXpm((const char **)bits); +#endif } wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const @@ -479,7 +496,7 @@ void wxBitmap::SetHBITMAP(WXHBITMAP bmp) { M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; M_BITMAPDATA->m_hBitmap = bmp ; - M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ; + M_BITMAPDATA->m_ok = (M_BITMAPDATA->m_hBitmap != NULL ) ; } bool wxBitmap::LoadFile(const wxString& filename, long type) @@ -516,6 +533,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() ) { + SetMask(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); @@ -1138,7 +1289,7 @@ bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type #endif } - +#ifdef OBSOLETE_XPM_DATA_HANDLER class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler { DECLARE_DYNAMIC_CLASS(wxXPMDataHandler) @@ -1156,10 +1307,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxXPMDataHandler, wxBitmapHandler) bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int width, int height, int depth) { - XImage * ximage = NULL ; - XImage * xshapeimage = NULL ; - int ErrorStatus; - XpmAttributes xpmAttr; + XImage * ximage = NULL ; + XImage * xshapeimage = NULL ; + int ErrorStatus; + XpmAttributes xpmAttr; xpmAttr.valuemask = XpmReturnInfos; // get infos back ErrorStatus = XpmCreateImageFromData( GetMainDevice() , (char **)data, @@ -1167,27 +1318,27 @@ bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int widt if (ErrorStatus == XpmSuccess) { - M_BITMAPHANDLERDATA->m_ok = FALSE; - M_BITMAPHANDLERDATA->m_numColors = 0; - M_BITMAPHANDLERDATA->m_hBitmap = ximage->gworldptr ; + M_BITMAPHANDLERDATA->m_ok = FALSE; + M_BITMAPHANDLERDATA->m_numColors = 0; + M_BITMAPHANDLERDATA->m_hBitmap = ximage->gworldptr ; - M_BITMAPHANDLERDATA->m_width = ximage->width; - M_BITMAPHANDLERDATA->m_height = ximage->height; - M_BITMAPHANDLERDATA->m_depth = ximage->depth; - M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels; + M_BITMAPHANDLERDATA->m_width = ximage->width; + M_BITMAPHANDLERDATA->m_height = ximage->height; + M_BITMAPHANDLERDATA->m_depth = ximage->depth; + M_BITMAPHANDLERDATA->m_numColors = xpmAttr.npixels; XpmFreeAttributes(&xpmAttr); - M_BITMAPHANDLERDATA->m_ok = TRUE; - ximage->gworldptr = NULL ; - XImageFree(ximage); // releases the malloc, but does not detroy + M_BITMAPHANDLERDATA->m_ok = TRUE; + ximage->gworldptr = NULL ; + 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; + M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; + if ( xshapeimage != NULL ) + { + wxMask* m = new wxMask() ; + m->SetMaskBitmap( xshapeimage->gworldptr ) ; + M_BITMAPHANDLERDATA->m_bitmapMask = m ; + } + return TRUE; } else { @@ -1196,6 +1347,7 @@ bool wxXPMDataHandler::Create(wxBitmap *bitmap, void *data, long flags, int widt } return FALSE; } +#endif class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler { @@ -1290,10 +1442,12 @@ void wxBitmap::CleanUpHandlers() void wxBitmap::InitStandardHandlers() { - AddHandler( new wxPICTResourceHandler ) ; - AddHandler( new wxICONResourceHandler ) ; - AddHandler(new wxXPMFileHandler); - AddHandler(new wxXPMDataHandler); - AddHandler(new wxBMPResourceHandler); - AddHandler(new wxBMPFileHandler); + AddHandler(new wxPICTResourceHandler) ; + AddHandler(new wxICONResourceHandler) ; + AddHandler(new wxXPMFileHandler); +#ifdef OBSOLETE_XPM_DATA_HANDLER + AddHandler(new wxXPMDataHandler); +#endif + AddHandler(new wxBMPResourceHandler); + AddHandler(new wxBMPFileHandler); }