X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/85f296a34215665472cc3d80b866009947f7bb70..a5a8ff8aab0fd27201ed8d07c17bf1a16aabfc93:/src/mac/carbon/bitmap.cpp diff --git a/src/mac/carbon/bitmap.cpp b/src/mac/carbon/bitmap.cpp index df8d319f43..8d7cf8f4b9 100644 --- a/src/mac/carbon/bitmap.cpp +++ b/src/mac/carbon/bitmap.cpp @@ -22,12 +22,9 @@ #include "wx/image.h" #include "wx/xpmdecod.h" -#if !USE_SHARED_LIBRARIES IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject) IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) -IMPLEMENT_ABSTRACT_CLASS(wxBitmapBase , wxGDIObject ) -IMPLEMENT_ABSTRACT_CLASS(wxBitmapHandlerBase, wxObject ) -#endif +IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject ) #ifdef __DARWIN__ #include @@ -93,95 +90,204 @@ void wxMacDestroyGWorld( GWorldPtr gw ) DisposeGWorld( gw ) ; } -PicHandle wxMacCreatePict(GWorldPtr wp, GWorldPtr mask) +#define kDefaultRes 0x00480000 /* Default resolution is 72 DPI; Fixed type */ + +OSErr SetupCIconHandlePixMap( CIconHandle icon , short depth , Rect *bounds , CTabHandle colors ) { - CGrafPtr origPort ; - GDHandle origDev ; + CTabHandle newColors; /* Color table used for the off-screen PixMap */ + Ptr offBaseAddr; /* Pointer to the off-screen pixel image */ + OSErr error; /* Returns error code */ + short bytesPerRow; /* Number of bytes per row in the PixMap */ - PicHandle pict; // this is the Picture we give back - RGBColor gray = { 0xCCCC ,0xCCCC , 0xCCCC } ; - RGBColor white = { 0xffff ,0xffff , 0xffff } ; - RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ; + error = noErr; + newColors = nil; + offBaseAddr = nil; - unsigned char *maskimage = NULL ; - Rect portRect ; - GetPortBounds( wp , &portRect ) ; - int width = portRect.right - portRect.left ; - int height = portRect.bottom - portRect.top ; + bytesPerRow = ((depth * (bounds->right - bounds->left) + 31) / 32) * 4; - LockPixels( GetGWorldPixMap( wp ) ) ; - GetGWorld( &origPort , &origDev ) ; + /* Clone the clut if indexed color; allocate a dummy clut if direct color*/ + if (depth <= 8) + { + newColors = colors; + error = HandToHand((Handle *) &newColors); + } + else + { + newColors = (CTabHandle) NewHandle(sizeof(ColorTable) - + sizeof(CSpecArray)); + error = MemError(); + } + if (error == noErr) + { + /* Allocate pixel image; long integer multiplication avoids overflow */ + (**icon).iconData = NewHandle((unsigned long) bytesPerRow * (bounds->bottom - + bounds->top)); + if ((**icon).iconData != nil) + { + /* Initialize fields common to indexed and direct PixMaps */ + (**icon).iconPMap.baseAddr = 0; /* Point to image */ + (**icon).iconPMap.rowBytes = bytesPerRow | /* MSB set for PixMap */ + 0x8000; + (**icon).iconPMap.bounds = *bounds; /* Use given bounds */ + (**icon).iconPMap.pmVersion = 0; /* No special stuff */ + (**icon).iconPMap.packType = 0; /* Default PICT pack */ + (**icon).iconPMap.packSize = 0; /* Always zero in mem */ + (**icon).iconPMap.hRes = kDefaultRes; /* 72 DPI default res */ + (**icon).iconPMap.vRes = kDefaultRes; /* 72 DPI default res */ + (**icon).iconPMap.pixelSize = depth; /* Set # bits/pixel */ + + /* Initialize fields specific to indexed and direct PixMaps */ + if (depth <= 8) + { + /* PixMap is indexed */ + (**icon).iconPMap.pixelType = 0; /* Indicates indexed */ + (**icon).iconPMap.cmpCount = 1; /* Have 1 component */ + (**icon).iconPMap.cmpSize = depth; /* Component size=depth */ + (**icon).iconPMap.pmTable = newColors; /* Handle to CLUT */ + } + else + { + /* PixMap is direct */ + (**icon).iconPMap.pixelType = RGBDirect; /* Indicates direct */ + (**icon).iconPMap.cmpCount = 3; /* Have 3 components */ + if (depth == 16) + (**icon).iconPMap.cmpSize = 5; /* 5 bits/component */ + else + (**icon).iconPMap.cmpSize = 8; /* 8 bits/component */ + (**newColors).ctSeed = 3 * (**icon).iconPMap.cmpSize; + (**newColors).ctFlags = 0; + (**newColors).ctSize = 0; + (**icon).iconPMap.pmTable = newColors; + } + } + else + error = MemError(); + } + else + newColors = nil; - 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 ) ) ; - } + /* If no errors occured, return a handle to the new off-screen PixMap */ + if (error != noErr) + { + if (newColors != nil) + DisposeCTable(newColors); + } - SetGWorld( wp , NULL ) ; + /* Return the error code */ + return error; +} - pict = OpenPicture(&portRect); // open a picture, this disables drawing - if(!pict) - return NULL; +CIconHandle wxMacCreateCIcon(GWorldPtr image , GWorldPtr mask , short dstDepth , short iconSize ) +{ + GWorldPtr saveWorld; + GDHandle saveHandle; - if ( maskimage ) - { - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - PenMode(transparent); + GetGWorld(&saveWorld,&saveHandle); // save Graphics env state + SetGWorld(image,nil); - for ( int y = 0 ; y < height ; ++y ) - { - for( int x = 0 ; x < width ; ++x ) - { - if ( maskimage[y*width + x] ) - { - RGBColor col ; + Rect frame = { 0 , 0 , iconSize , iconSize } ; + Rect imageBounds = frame ; + GetPortBounds( image , &imageBounds ) ; - 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 ) ; + int bwSize = iconSize / 8 * iconSize ; + CIconHandle icon = (CIconHandle) NewHandleClear( sizeof ( CIcon ) + 2 * bwSize) ; + HLock((Handle)icon) ; + SetupCIconHandlePixMap( icon , dstDepth , &frame,GetCTable(dstDepth)) ; + HLock( (**icon).iconData ) ; + (**icon).iconPMap.baseAddr = *(**icon).iconData ; + + LockPixels(GetGWorldPixMap(image)); + + CopyBits(GetPortBitMapForCopyBits(image), + (BitMapPtr)&((**icon).iconPMap), + &imageBounds, + &imageBounds, + srcCopy | ditherCopy, nil); + + + UnlockPixels(GetGWorldPixMap(image)); + HUnlock( (**icon).iconData ) ; + + (**icon).iconMask.rowBytes = iconSize / 8 ; + (**icon).iconMask.bounds = frame ; - return pict; // return our groovy pict handle + (**icon).iconBMap.rowBytes = iconSize / 8 ; + (**icon).iconBMap.bounds = frame ; + (**icon).iconMask.baseAddr = (char*) &(**icon).iconMaskData ; + (**icon).iconBMap.baseAddr = (char*) &(**icon).iconMaskData + bwSize ; + + if ( mask ) + { + LockPixels(GetGWorldPixMap(mask) ) ; + CopyBits(GetPortBitMapForCopyBits(mask) , + &(**icon).iconBMap , &imageBounds , &imageBounds, srcCopy , nil ) ; + CopyBits(GetPortBitMapForCopyBits(mask) , + &(**icon).iconMask , &imageBounds , &imageBounds, srcCopy , nil ) ; + UnlockPixels(GetGWorldPixMap( mask ) ) ; + } + else + { + LockPixels(GetGWorldPixMap(image)); + CopyBits(GetPortBitMapForCopyBits(image) , + &(**icon).iconBMap , &imageBounds , &imageBounds, srcCopy , nil ) ; + CopyBits(GetPortBitMapForCopyBits(image) , + &(**icon).iconMask , &imageBounds , &imageBounds, srcCopy , nil ) ; + UnlockPixels(GetGWorldPixMap(image)); + } + + (**icon).iconMask.baseAddr = NULL ; + (**icon).iconBMap.baseAddr = NULL ; + (**icon).iconPMap.baseAddr = NULL ; + HUnlock((Handle)icon) ; + SetGWorld(saveWorld,saveHandle); + + return icon; +} + +PicHandle wxMacCreatePict(GWorldPtr wp, GWorldPtr mask) +{ + CGrafPtr origPort ; + GDHandle origDev ; + + PicHandle pict; + + RGBColor white = { 0xffff ,0xffff , 0xffff } ; + RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ; + + GetGWorld( &origPort , &origDev ) ; + + RgnHandle clipRgn = NULL ; + + if ( mask ) + { + clipRgn = NewRgn() ; + LockPixels( GetGWorldPixMap( mask ) ) ; + BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( mask ) ) ; + UnlockPixels( GetGWorldPixMap( mask ) ) ; + } + + SetGWorld( wp , NULL ) ; + Rect portRect ; + GetPortBounds( wp , &portRect ) ; + + pict = OpenPicture(&portRect); + if(pict) + { + RGBForeColor( &black ) ; + RGBBackColor( &white ) ; + + LockPixels( GetGWorldPixMap( wp ) ) ; + CopyBits(GetPortBitMapForCopyBits(wp), + GetPortBitMapForCopyBits(wp), + &portRect, + &portRect, + srcCopy,clipRgn); + UnlockPixels( GetGWorldPixMap( wp ) ) ; + ClosePicture(); + } + SetGWorld( origPort , origDev ) ; + return pict; } wxBitmapRefData::wxBitmapRefData() @@ -246,9 +352,6 @@ wxBitmapRefData::~wxBitmapRefData() DisposeBitmapRefData( this ) ; } -wxList wxBitmapBase::sm_handlers; - - bool wxBitmap::CopyFromIcon(const wxIcon& icon) { Ref(icon) ; @@ -258,15 +361,10 @@ bool wxBitmap::CopyFromIcon(const wxIcon& icon) wxBitmap::wxBitmap() { m_refData = NULL; - - if ( wxTheBitmapList ) - wxTheBitmapList->AddBitmap(this); } wxBitmap::~wxBitmap() { - if (wxTheBitmapList) - wxTheBitmapList->DeleteObject(this); } wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits) @@ -328,34 +426,21 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits { wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented")); } - - if ( wxTheBitmapList ) { - wxTheBitmapList->AddBitmap(this); - } } wxBitmap::wxBitmap(int w, int h, int d) { (void)Create(w, h, d); - - if ( wxTheBitmapList ) - wxTheBitmapList->AddBitmap(this); } wxBitmap::wxBitmap(void *data, wxBitmapType type, int width, int height, int depth) { (void) Create(data, type, width, height, depth); - - if ( wxTheBitmapList ) - wxTheBitmapList->AddBitmap(this); } wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type) { LoadFile(filename, type); - - if ( wxTheBitmapList ) - wxTheBitmapList->AddBitmap(this); } bool wxBitmap::CreateFromXpm(const char **bits) @@ -365,7 +450,6 @@ bool wxBitmap::CreateFromXpm(const char **bits) wxImage img = decoder.ReadData(bits); wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid bitmap data") ) *this = wxBitmap(img); - if ( wxTheBitmapList ) wxTheBitmapList->AddBitmap(this); return TRUE; } @@ -547,8 +631,6 @@ wxBitmap::wxBitmap(const wxImage& image, int 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(); @@ -913,68 +995,6 @@ PicHandle wxBitmap::GetPict() const return picture; // return our groovy pict handle } -void wxBitmap::AddHandler(wxBitmapHandler *handler) -{ - sm_handlers.Append(handler); -} - -void wxBitmap::InsertHandler(wxBitmapHandler *handler) -{ - sm_handlers.Insert(handler); -} - -bool wxBitmap::RemoveHandler(const wxString& name) -{ - wxBitmapHandler *handler = FindHandler(name); - if ( handler ) - { - sm_handlers.DeleteObject(handler); - return TRUE; - } - else - return FALSE; -} - -wxBitmapHandler *wxBitmap::FindHandler(const wxString& name) -{ - wxNode *node = sm_handlers.First(); - while ( node ) - { - wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - if ( handler->GetName() == name ) - return handler; - node = node->Next(); - } - return NULL; -} - -wxBitmapHandler *wxBitmap::FindHandler(const wxString& extension, wxBitmapType type) -{ - wxNode *node = sm_handlers.First(); - while ( node ) - { - wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - if ( handler->GetExtension() == extension && - (type == -1 || handler->GetType() == type) ) - return handler; - node = node->Next(); - } - return NULL; -} - -wxBitmapHandler *wxBitmap::FindHandler(wxBitmapType type) -{ - wxNode *node = sm_handlers.First(); - while ( node ) - { - wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - if (handler->GetType() == type) - return handler; - node = node->Next(); - } - return NULL; -} - /* * wxMask */ @@ -1135,8 +1155,6 @@ bool wxMask::PointMasked(int x, int y) * wxBitmapHandler */ -IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject) - bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth) { return FALSE; @@ -1207,40 +1225,6 @@ bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, lo return FALSE ; } -#if 0 // The following is an example for creating a bitmap handler - -// TODO: bitmap handlers, a bit like this: -class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler -{ - DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler) -public: - inline wxBMPResourceHandler() - { - m_name = "Windows bitmap resource"; - m_extension = ""; - m_type = wxBITMAP_TYPE_BMP_RESOURCE; - }; - - virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags, - int desiredWidth, int desiredHeight); -}; -IMPLEMENT_DYNAMIC_CLASS(wxBMPResourceHandler, wxBitmapHandler) - -#endif - -void wxBitmap::CleanUpHandlers() -{ - wxNode *node = sm_handlers.First(); - while ( node ) - { - wxBitmapHandler *handler = (wxBitmapHandler *)node->Data(); - wxNode *next = node->Next(); - delete handler; - delete node; - node = next; - } -} - void wxBitmap::InitStandardHandlers() { AddHandler(new wxPICTResourceHandler) ;