]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/bitmap.cpp
moved splines rendering code into wxDCBase
[wxWidgets.git] / src / mac / carbon / bitmap.cpp
index 3a66121d493152449872e4bf661e882abaad6552..5c1aec6c5f341c7e94e4e63a30d5b66636728132 100644 (file)
@@ -13,6 +13,7 @@
 #pragma implementation "bitmap.h"
 #endif
 
+#include "wx/wx.h"
 #include "wx/setup.h"
 #include "wx/utils.h"
 #include "wx/palette.h"
 
 extern "C" 
 {
+#ifdef __UNIX__
+    #include "xpm/xpm.h"
+#else
        #include "xpm.h"
+#endif
 } ;
 
 #if !USE_SHARED_LIBRARIES
@@ -30,12 +35,16 @@ IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
 #endif
 
-#include <PictUtils.h>
+#ifdef __UNIX__
+    #include <QD/PictUtils.h>
+#else
+    #include <PictUtils.h>
+#endif
 
 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,24 +72,15 @@ 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 )
        {
-               // get max pixel depth
-               CGrafPtr port ;
-               GetCWMgrPort( &port ) ; 
-               GDHandle maxDevice ;
-               
-               maxDevice = GetMaxDevice( &port->portRect ) ;
-               if ( maxDevice )
-                       depth = (**((**maxDevice).gdPMap)).pixelSize ;
-               else
-                       depth = 8 ; 
+               depth = wxDisplayDepth() ;     
        }
                
        err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ;
@@ -89,7 +89,7 @@ GWorldPtr wxMacCreateGWorld( int height , int width , int depth )
                return port ;
        }
        return NULL ;
-} 
+}
 
 void wxMacDestroyGWorld( GWorldPtr gw )
 {
@@ -136,7 +136,7 @@ wxBitmapRefData::~wxBitmapRefData()
                default :
                        // unkown type ?
                        break ;
-       } ;
+       }
        
   if (m_bitmapMask)
   {
@@ -171,8 +171,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 ;
@@ -180,7 +180,8 @@ 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 ) ) ;
+                       
                        // bits is a word aligned array
                        
                        unsigned char* linestart = (unsigned char*) bits ;
@@ -188,16 +189,16 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits
                        if ( the_width % 16 )
                        {
                                linesize += 2 ;
-                       } ;
+                       }
                        
                        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 ;
@@ -213,12 +214,13 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits
                                }
                                
                        }
+               UnlockPixels( GetGWorldPixMap( (CGrafPtr) M_BITMAPDATA->m_hBitmap ) ) ;
        
                SetGWorld( origPort , origDevice ) ;
           }
           else
           {
-                               //multicolor BITMAPs not yet implemented
+         wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
           }
 
     if ( wxTheBitmapList )
@@ -254,6 +256,11 @@ 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);
+}
+
 bool wxBitmap::Create(int w, int h, int d)
 {
     UnRef();
@@ -448,18 +455,14 @@ wxBitmapHandler *wxBitmap::FindHandler(long bitmapType)
 
 wxMask::wxMask()
 {
-/* TODO
     m_maskBitmap = 0;
-*/
 }
 
 // Construct a mask from a bitmap and a colour indicating
 // the transparent area
 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
 {
-/* TODO
     m_maskBitmap = 0;
-*/
     Create(bitmap, colour);
 }
 
@@ -467,26 +470,24 @@ wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
 // the transparent area
 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
 {
-/* TODO
     m_maskBitmap = 0;
-*/
-
     Create(bitmap, paletteIndex);
 }
 
 // Construct a mask from a mono bitmap (copies the bitmap).
 wxMask::wxMask(const wxBitmap& bitmap)
 {
-/* TODO
     m_maskBitmap = 0;
-*/
-
     Create(bitmap);
 }
 
 wxMask::~wxMask()
 {
-// TODO: delete mask bitmap
+       if ( m_maskBitmap )
+       {
+               wxMacDestroyGWorld( m_maskBitmap ) ;
+               m_maskBitmap = NULL ;
+       }
 }
 
 // Create a mask from a mono bitmap (copies the bitmap).
@@ -508,8 +509,58 @@ bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
 // the transparent area
 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
 {
-// TODO
-    return FALSE;
+       if ( m_maskBitmap )
+       {
+               wxMacDestroyGWorld( m_maskBitmap ) ;
+               m_maskBitmap = NULL ;
+       }
+       wxASSERT( ((wxBitmapRefData*) bitmap.GetRefData())->m_bitmapType == kMacBitmapTypeGrafWorld ) ;
+       // other types would require a temporary bitmap. not yet implemented 
+       
+    if (!bitmap.Ok())
+    {
+        return FALSE;
+    }
+
+       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() ;
+
+    // this is not very efficient, but I can't think
+    // of a better way of doing it
+       CGrafPtr        origPort ;
+       GDHandle        origDevice ;
+                       
+       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 ;
+                       GetCPixel( w , h , &col ) ;
+                       SetGWorld( m_maskBitmap , NULL ) ;
+            if (col.red == maskColor.red && col.blue == maskColor.blue && col.green == maskColor.green)
+            {
+                               SetCPixel( w , h , &colors[0] ) ;
+            }
+            else
+            {
+                               SetCPixel( w , h , &colors[1] ) ;
+            }
+        }
+    }
+       UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
+       UnlockPixels( GetGWorldPixMap( ((wxBitmapRefData*) bitmap.GetRefData())->m_hBitmap ) ) ;
+       SetGWorld( origPort , origDevice ) ;
+
+    return TRUE;
 }
 
 /*
@@ -559,8 +610,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 )
@@ -674,8 +729,8 @@ bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type
       if (dc)
       {
         if (SelectObject(dc, (HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap))
-        { /* for following SetPixel */
-          /* fill the XImage struct 'by hand' */
+        { 
+          
     ximage.width = M_BITMAPHANDLERDATA->m_width; 
      ximage.height = M_BITMAPHANDLERDATA->m_height;
     ximage.depth = M_BITMAPHANDLERDATA->m_depth; 
@@ -687,7 +742,7 @@ bool wxXPMFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type
       DeleteDC(dc);
 
     if (errorStatus == XpmSuccess)
-      return TRUE;    /* no error */
+      return TRUE;    
     else
       return FALSE;
         } else return FALSE;
@@ -715,13 +770,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)
     {
@@ -739,7 +795,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
@@ -771,19 +832,6 @@ bool wxBMPResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long
     int desiredWidth, int desiredHeight)
 {
     // TODO: load colourmap.
-/*
-    M_BITMAPHANDLERDATA->m_hBitmap = (WXHBITMAP) ::LoadBitmap(wxGetInstance(), name);
-    if (M_BITMAPHANDLERDATA->m_hBitmap)
-    {
-      M_BITMAPHANDLERDATA->m_ok = TRUE;
-      BITMAP bm;
-      GetObject((HBITMAP) M_BITMAPHANDLERDATA->m_hBitmap, sizeof(BITMAP), (LPSTR) &bm);
-      M_BITMAPHANDLERDATA->m_width = bm.bmWidth;
-      M_BITMAPHANDLERDATA->m_height = bm.bmHeight;
-      M_BITMAPHANDLERDATA->m_depth = bm.bmBitsPixel;
-      return TRUE;
-    }
-*/
   // it's probably not found
   wxLogError("Can't load bitmap '%s' from resources! Check .rc file.", name.c_str());
 
@@ -814,11 +862,6 @@ bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long fla
 #if USE_IMAGE_LOADING_IN_MSW
     wxPalette *palette = NULL;
     bool success = FALSE;
-/*
-    if (type & wxBITMAP_DISCARD_COLOURMAP)
-      success = wxLoadIntoBitmap(WXSTRINGCAST name, bitmap);
-    else
-*/
     success = (wxLoadIntoBitmap(WXSTRINGCAST name, bitmap, &palette) != 0);
     if (!success && palette)
     {
@@ -846,7 +889,6 @@ bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap, const wxString& name, int type
 }
 
 
-
 void wxBitmap::CleanUpHandlers()
 {
     wxNode *node = sm_handlers.First();
@@ -865,7 +907,7 @@ void wxBitmap::InitStandardHandlers()
        AddHandler( new wxPICTResourceHandler ) ;
        AddHandler( new wxICONResourceHandler ) ;
        AddHandler(new wxXPMFileHandler);
-  AddHandler(new wxXPMDataHandler);
+       AddHandler(new wxXPMDataHandler);
        AddHandler(new wxBMPResourceHandler);
        AddHandler(new wxBMPFileHandler);
 }