#include "wx/bitmap.h"
#include "wx/icon.h"
#include "wx/log.h"
+#include "wx/image.h"
+#include "wx/xpmdecod.h"
-extern "C"
+#ifndef __UNIX__
+ #define OBSOLETE_XPM_DATA_HANDLER
+#endif
+
+extern "C"
{
-#ifdef __UNIX__
- #include "xpm/xpm.h"
-#else
- #include "xpm.h"
+#ifdef OBSOLETE_XPM_DATA_HANDLER
+ #include "xpm.h"
#endif
} ;
#include <PictUtils.h>
#endif
+#include "wx/mac/uma.h"
+
CTabHandle wxMacCreateColorTable( int numColors )
{
CTabHandle newColors; /* Handle to the new color table */
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_bitmapType = kMacBitmapTypeUnknownType ;
}
wxBitmapRefData::~wxBitmapRefData()
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)
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
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);
#endif
}
-
+#ifdef OBSOLETE_XPM_DATA_HANDLER
class WXDLLEXPORT wxXPMDataHandler: public wxBitmapHandler
{
DECLARE_DYNAMIC_CLASS(wxXPMDataHandler)
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,
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
{
}
return FALSE;
}
+#endif
class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler
{
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);
}