X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a24aff654fb10971e82abccc1b56217d556d447b..9ec0e7da983d3c4de9c7007142a72864214514ac:/src/cocoa/bitmap.mm diff --git a/src/cocoa/bitmap.mm b/src/cocoa/bitmap.mm index ed803d8085..97d7712b1e 100644 --- a/src/cocoa/bitmap.mm +++ b/src/cocoa/bitmap.mm @@ -1,30 +1,59 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: bitmap.cpp +// Name: src/cocoa/bitmap.cpp // Purpose: wxBitmap -// Author: AUTHOR +// Author: David Elliott // Modified by: -// Created: ??/??/98 +// Created: 2003/07/19 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) 2003 David Elliott +// Licence: wxWidgets licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "bitmap.h" -#endif - -#include "wx/setup.h" -#include "wx/utils.h" -#include "wx/palette.h" +#include "wx/wxprec.h" +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/utils.h" + #include "wx/palette.h" + #include "wx/icon.h" + #include "wx/colour.h" +#endif //WX_PRECOMP #include "wx/bitmap.h" -#include "wx/icon.h" -#include "wx/log.h" #include "wx/image.h" +#include "wx/xpmdecod.h" +#include "wx/rawbmp.h" -#if !USE_SHARED_LIBRARIES -IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject) -IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) -#endif +#include "wx/cocoa/autorelease.h" +#include "wx/cocoa/string.h" + +#import +#import +#import +#import + +// ======================================================================== +// wxBitmapRefData +// ======================================================================== +class wxBitmapRefData: public wxGDIRefData +{ + friend class wxBitmap; +public: + wxBitmapRefData(); + wxBitmapRefData( const wxBitmapRefData& data ); + virtual ~wxBitmapRefData(); + +protected: + int m_width; + int m_height; + int m_depth; + bool m_ok; + int m_numColors; + wxPalette m_bitmapPalette; + int m_quality; + WX_NSBitmapImageRep m_cocoaNSBitmapImageRep; + wxMask *m_bitmapMask; // Optional mask +}; + +#define M_BITMAPDATA ((wxBitmapRefData *)m_refData) wxBitmapRefData::wxBitmapRefData() { @@ -34,32 +63,44 @@ wxBitmapRefData::wxBitmapRefData() m_depth = 0; m_quality = 0; m_numColors = 0; + m_cocoaNSBitmapImageRep = nil; m_bitmapMask = NULL; } +wxBitmapRefData::wxBitmapRefData( const wxBitmapRefData& data) +{ + m_width = data.m_width; + m_height = data.m_height; + m_depth = data.m_depth; + m_ok = data.m_ok; + m_numColors = data.m_numColors; + m_bitmapPalette = data.m_bitmapPalette; + m_quality = data.m_quality; + m_cocoaNSBitmapImageRep = [data.m_cocoaNSBitmapImageRep copyWithZone:nil]; + m_bitmapMask = data.m_bitmapMask?new wxMask(*data.m_bitmapMask):NULL; +} + wxBitmapRefData::~wxBitmapRefData() { - /* - * TODO: delete the bitmap data here. - */ + [m_cocoaNSBitmapImageRep release]; + m_cocoaNSBitmapImageRep = NULL; - if (m_bitmapMask) - delete m_bitmapMask; + delete m_bitmapMask; m_bitmapMask = NULL; } +// ======================================================================== +// wxBitmap +// ======================================================================== +IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject) + 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) @@ -72,111 +113,74 @@ wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits M_BITMAPDATA->m_numColors = 0; /* TODO: create the bitmap from data */ - - 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); } -wxBitmap::wxBitmap(const wxImage& image, int depth) +wxObjectRefData *wxBitmap::CreateRefData() const { + return new wxBitmapRefData; } -wxBitmap::wxBitmap(char **bits) +wxObjectRefData *wxBitmap::CloneRefData(const wxObjectRefData *data) const { + return new wxBitmapRefData(*(wxBitmapRefData*)data); } -/* TODO: maybe allow creation from XPM -// Create from data -wxBitmap::wxBitmap(const char **data) +WX_NSBitmapImageRep wxBitmap::GetNSBitmapImageRep() { - (void) Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0); + if(!M_BITMAPDATA) + return NULL; + return M_BITMAPDATA->m_cocoaNSBitmapImageRep; } -*/ -bool wxBitmap::Create(int w, int h, int d) +WX_NSImage wxBitmap::GetNSImage(bool useMask) const { - UnRef(); - - m_refData = new wxBitmapRefData; - - M_BITMAPDATA->m_width = w; - M_BITMAPDATA->m_height = h; - M_BITMAPDATA->m_depth = d; - - /* TODO: create new bitmap */ - - return M_BITMAPDATA->m_ok; -} - -bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) -{ - UnRef(); - - m_refData = new wxBitmapRefData; - - wxBitmapHandler *handler = FindHandler(type); - - if ( handler == NULL ) { - wxLogWarning("no bitmap handler for type %d defined.", type); - - return FALSE; - } - - return handler->LoadFile(this, filename, type, -1, -1); -} - -bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int depth) -{ - UnRef(); - - m_refData = new wxBitmapRefData; - - wxBitmapHandler *handler = FindHandler(type); - - if ( handler == NULL ) { - wxLogWarning("no bitmap handler for type %d defined.", type); - - return FALSE; + if(!Ok()) + return nil; + NSImage *nsimage = [[[NSImage alloc] + initWithSize:NSMakeSize(GetWidth(), GetHeight())] autorelease]; + if(!nsimage) + return nil; + [nsimage addRepresentation: M_BITMAPDATA->m_cocoaNSBitmapImageRep]; + if(useMask && GetMask()) + { + // Show before/after to prove that the bitmap itself is not changed + // even though we just composited onto the NSImage + wxLogTrace(wxTRACE_COCOA,wxT("Before: bpp=%d"),[M_BITMAPDATA->m_cocoaNSBitmapImageRep bitsPerPixel]); + NSImage *maskImage = [[NSImage alloc] + initWithSize:NSMakeSize(GetWidth(), GetHeight())]; + [maskImage addRepresentation: GetMask()->GetNSBitmapImageRep()]; + [nsimage lockFocus]; + [maskImage compositeToPoint:NSZeroPoint operation:NSCompositeDestinationIn]; + [nsimage unlockFocus]; + [maskImage release]; + wxLogTrace(wxTRACE_COCOA,wxT("After: bpp=%d"),[M_BITMAPDATA->m_cocoaNSBitmapImageRep bitsPerPixel]); } - - return handler->Create(this, data, type, width, height, depth); + return nsimage; } -bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const +void wxBitmap::SetNSBitmapImageRep(WX_NSBitmapImageRep bitmapImageRep) { - wxBitmapHandler *handler = FindHandler(type); - - if ( handler == NULL ) { - wxLogWarning("no bitmap handler for type %d defined.", type); - - return FALSE; - } - - return handler->SaveFile(this, filename, type, palette); + if(!M_BITMAPDATA) + return; + // NOTE: No checking is done to make sure width/height agree + [bitmapImageRep retain]; + [M_BITMAPDATA->m_cocoaNSBitmapImageRep release]; + M_BITMAPDATA->m_cocoaNSBitmapImageRep = bitmapImageRep; } void wxBitmap::SetWidth(int w) @@ -235,185 +239,428 @@ void wxBitmap::SetMask(wxMask *mask) M_BITMAPDATA->m_bitmapMask = mask ; } -/* - * wxMask - */ - -wxMask::wxMask() +bool wxBitmap::Ok() const { -/* TODO - m_maskBitmap = 0; -*/ + return m_refData && M_BITMAPDATA->m_ok; } -// Construct a mask from a bitmap and a colour indicating -// the transparent area -wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour) +wxPalette* wxBitmap::GetPalette() const { -/* TODO - m_maskBitmap = 0; -*/ - Create(bitmap, colour); + if(!m_refData) + return NULL; + return &M_BITMAPDATA->m_bitmapPalette; } -// Construct a mask from a bitmap and a palette index indicating -// the transparent area -wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex) +wxMask* wxBitmap::GetMask() const { -/* TODO - m_maskBitmap = 0; -*/ - - Create(bitmap, paletteIndex); + if(!m_refData) + return NULL; + return M_BITMAPDATA->m_bitmapMask; } -// Construct a mask from a mono bitmap (copies the bitmap). -wxMask::wxMask(const wxBitmap& bitmap) +int wxBitmap::GetDepth() const { -/* TODO - m_maskBitmap = 0; -*/ - - Create(bitmap); + if(!m_refData) + return 0; + return M_BITMAPDATA->m_depth; } -wxMask::~wxMask() +int wxBitmap::GetWidth() const { -// TODO: delete mask bitmap + if(!m_refData) + return 0; + return M_BITMAPDATA->m_width; } -// Create a mask from a mono bitmap (copies the bitmap). -bool wxMask::Create(const wxBitmap& bitmap) +int wxBitmap::GetHeight() const { -// TODO - return FALSE; + if(!m_refData) + return 0; + return M_BITMAPDATA->m_height; } -// Create a mask from a bitmap and a palette index indicating -// the transparent area -bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex) +bool wxBitmap::Create(int w, int h, int d) { -// TODO - return FALSE; + UnRef(); + + m_refData = new wxBitmapRefData; + + M_BITMAPDATA->m_width = w; + M_BITMAPDATA->m_height = h; + M_BITMAPDATA->m_depth = d; + + /* TODO: create new bitmap */ + M_BITMAPDATA->m_cocoaNSBitmapImageRep = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes: NULL + pixelsWide: w + pixelsHigh: h + bitsPerSample: 8 + samplesPerPixel: 3 + hasAlpha: NO + isPlanar: NO + colorSpaceName: NSCalibratedRGBColorSpace + bytesPerRow: 0 + bitsPerPixel: 0]; + + wxLogTrace(wxTRACE_COCOA,wxT("M_BITMAPDATA=%p NSBitmapImageRep bitmapData=%p"), M_BITMAPDATA, [M_BITMAPDATA->m_cocoaNSBitmapImageRep bitmapData]); + M_BITMAPDATA->m_ok = true; + M_BITMAPDATA->m_numColors = 0; + M_BITMAPDATA->m_quality = 0; + M_BITMAPDATA->m_bitmapMask = NULL; + + return M_BITMAPDATA->m_ok; } -// Create a mask from a bitmap and a colour indicating -// the transparent area -bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) +bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) { -// TODO - return FALSE; -} + wxAutoNSAutoreleasePool pool; + UnRef(); -/* - * wxBitmapHandler - */ + m_refData = new wxBitmapRefData; -IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject) + NSBitmapImageRep *imageRep = [NSBitmapImageRep + imageRepWithContentsOfFile:wxNSStringWithWxString(filename)]; -wxBitmapHandler::~wxBitmapHandler() -{ + if(imageRep) + { + M_BITMAPDATA->m_width = [imageRep pixelsWide]; + M_BITMAPDATA->m_height = [imageRep pixelsHigh]; + M_BITMAPDATA->m_depth = 24; // FIXME + M_BITMAPDATA->m_ok = true; + M_BITMAPDATA->m_numColors = 0; + M_BITMAPDATA->m_quality = 0; + M_BITMAPDATA->m_cocoaNSBitmapImageRep = [imageRep retain]; + M_BITMAPDATA->m_bitmapMask = NULL; + return true; + } + wxImage image; + if(!image.LoadFile(filename,type)) + return false; + if(!image.Ok()) + return false; + *this = wxBitmap(image); + return true; } -bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth) +bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int depth) { - return FALSE; + UnRef(); + + m_refData = new wxBitmapRefData; + + return false; } -bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long type, - int desiredWidth, int desiredHeight) +bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type, const wxPalette *palette) const { - return FALSE; + return false; } -bool wxBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette) +bool wxBitmap::CopyFromIcon(const wxIcon& icon) { - return FALSE; + UnRef(); + if(!icon.GetNSImage()); + [icon.GetNSImage() lockFocus]; + NSRect imageRect; + imageRect.origin.x = imageRect.origin.y = 0.0; + imageRect.size = [icon.GetNSImage() size]; + NSBitmapImageRep *newBitmapRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:imageRect]; + [icon.GetNSImage() unlockFocus]; + if(!newBitmapRep) + return false; + m_refData = new wxBitmapRefData; + M_BITMAPDATA->m_cocoaNSBitmapImageRep = newBitmapRep; + M_BITMAPDATA->m_width = [newBitmapRep pixelsWide]; + M_BITMAPDATA->m_height = [newBitmapRep pixelsHigh]; + M_BITMAPDATA->m_depth = [newBitmapRep bitsPerSample]*[newBitmapRep samplesPerPixel]; + M_BITMAPDATA->m_ok = true; + M_BITMAPDATA->m_numColors = 0; + M_BITMAPDATA->m_quality = 0; + M_BITMAPDATA->m_bitmapMask = NULL; + return true; } -/* - * Standard handlers - */ +wxBitmap wxBitmap::GetSubBitmap(wxRect const&) const +{ + return wxNullBitmap; +} -/* TODO: bitmap handlers, a bit like this: -class WXDLLEXPORT wxBMPResourceHandler: public wxBitmapHandler +wxImage wxBitmap::ConvertToImage() const { - DECLARE_DYNAMIC_CLASS(wxBMPResourceHandler) -public: - inline wxBMPResourceHandler() + wxAutoNSAutoreleasePool pool; + if(!Ok()) + return /*wxImage(5,5)*/wxNullImage; + NSImage *nsimage = GetNSImage(false /* don't use mask */); + wxImage newImage(M_BITMAPDATA->m_width,M_BITMAPDATA->m_height); + [nsimage lockFocus]; + for(int i=0; i < M_BITMAPDATA->m_width; i++) { - 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) -*/ + // Don't let the pool get too big as you'll notice we're creating + // two autoreleased NSColor objects with every iteration. + wxAutoNSAutoreleasePool loopPool; + for(int j=0; j < M_BITMAPDATA->m_height; j++) + { + NSColor *pixelColor = NSReadPixel(NSMakePoint(i,M_BITMAPDATA->m_height - j - 1)); + NSColor *color = [pixelColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + newImage.SetRGB(i,j,int([color redComponent]*255.0), int([color greenComponent]*255.0), int([color blueComponent]*255.0)); + } + } + [nsimage unlockFocus]; + return newImage; +} -void wxBitmap::InitStandardHandlers() +bool wxBitmap::CreateFromXpm(const char **xpm) { -/* TODO: initialize all standard bitmap or derive class handlers here. - AddHandler(new wxBMPResourceHandler); - AddHandler(new wxBMPFileHandler); - AddHandler(new wxXPMFileHandler); - AddHandler(new wxXPMDataHandler); - AddHandler(new wxICOResourceHandler); - AddHandler(new wxICOFileHandler); -*/ +#if wxUSE_IMAGE && wxUSE_XPM + UnRef(); + + wxCHECK_MSG( xpm, false, wxT("invalid XPM data") ) + + wxXPMDecoder decoder; + wxImage img = decoder.ReadData(xpm); + wxCHECK_MSG( img.Ok(), false, wxT("invalid XPM data") ) + + *this = wxBitmap(img); + return true; +#else + return false; +#endif } -bool wxBitmap::CopyFromIcon(const wxIcon& icno) +bool wxBitmap::CreateFromImage(const wxImage& image, int depth) { - return false; + UnRef(); + + wxCHECK_MSG(image.Ok(), false, wxT("invalid image")); + wxCHECK_MSG(depth == -1 || depth == 1, false, wxT("invalid bitmap depth")); + + m_refData = new wxBitmapRefData(); + + M_BITMAPDATA->m_width = image.GetWidth(); + M_BITMAPDATA->m_height = image.GetHeight(); + NSBitmapImageRep *bitmapImage = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes: NULL + pixelsWide: image.GetWidth() + pixelsHigh: image.GetHeight() + bitsPerSample: 8 + samplesPerPixel: 3 + hasAlpha: NO + isPlanar: NO + colorSpaceName: NSCalibratedRGBColorSpace + bytesPerRow: 0 + bitsPerPixel: 0]; + + const int numBytes = image.GetWidth()*image.GetHeight()*3; + memcpy([bitmapImage bitmapData], image.GetData(), numBytes); + // TODO: Alpha and convert to desired depth + M_BITMAPDATA->m_depth = 24; + M_BITMAPDATA->m_ok = true; + M_BITMAPDATA->m_numColors = 0; + M_BITMAPDATA->m_quality = 0; + M_BITMAPDATA->m_cocoaNSBitmapImageRep = bitmapImage; + M_BITMAPDATA->m_bitmapMask = new wxMask(*this,wxColour(image.GetMaskRed(),image.GetMaskGreen(),image.GetMaskBlue())); + return true; } -wxPalette* wxBitmap::GetPalette() const +void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp) { - return NULL; + if(!Ok()) + return NULL; + + NSBitmapImageRep *bitmapRep = M_BITMAPDATA->m_cocoaNSBitmapImageRep; + if(!bitmapRep) + return NULL; + + if([bitmapRep bitsPerPixel]!=bpp) + { + wxFAIL_MSG( _T("incorrect bitmap type in wxBitmap::GetRawData()") ); + return NULL; + } + data.m_width = [bitmapRep pixelsWide]; + data.m_height = [bitmapRep pixelsHigh]; + data.m_stride = [bitmapRep bytesPerRow]; + return [bitmapRep bitmapData]; + + // NOTE: It is up to the user to make sure they used the proper + // pixel format class that details what is actually inside the pixels + // We can only check to make sure that the total number of bits per + // pixel are being iterated over properly + // NSBitmapImageRep can contain grayscale or CMYK data and + // wxPixelDataBase doesn't really define the color format } -wxBitmap wxBitmap::GetSubBitmap(wxRect const&) const +void wxBitmap::UngetRawData(wxPixelDataBase& data) +{ // TODO +} + +void wxBitmap::UseAlpha() +{ // TODO +} + +// ======================================================================== +// wxMask +// ======================================================================== + +IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) + +wxMask::wxMask() { - return wxNullBitmap; + m_cocoaNSBitmapImageRep = nil; } -wxImage wxBitmap::ConvertToImage() const +// Construct a mask from a bitmap and a colour indicating +// the transparent area +wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour) { - return wxNullImage; + m_cocoaNSBitmapImageRep = nil; + Create(bitmap, colour); } -bool wxBitmap::Ok() const +// Construct a mask from a bitmap and a palette index indicating +// the transparent area +wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex) { - return FALSE; + m_cocoaNSBitmapImageRep = nil; + + Create(bitmap, paletteIndex); } -wxMask* wxBitmap::GetMask() const +// Construct a mask from a mono bitmap (copies the bitmap). +wxMask::wxMask(const wxBitmap& bitmap) { - return NULL; + m_cocoaNSBitmapImageRep = nil; + + Create(bitmap); } -int wxBitmap::GetDepth() const +wxMask::~wxMask() { - return 0; + [m_cocoaNSBitmapImageRep release]; } -int wxBitmap::GetWidth() const +// Create a mask from a mono bitmap (copies the bitmap). +bool wxMask::Create(const wxBitmap& bitmap) { - return 0; +// TODO + return FALSE; } -int wxBitmap::GetHeight() const +// Create a mask from a bitmap and a palette index indicating +// the transparent area +bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex) { - return 0; +// TODO + return FALSE; } +template +static bool wxMask_CreateFromBitmapData(PixelData srcData, const wxColour& colour, unsigned char *dstData) +{ + wxCHECK_MSG(dstData,false,wxT("Couldn't access mask data")); + typename PixelData::Iterator p(srcData); + const int nRows = srcData.GetHeight(); + const int nCols = srcData.GetWidth(); + // Total number of bytes per destination column + const int dstRowLength = (nCols+7)/8; + // Number of source columns that fit into a byte in the destination + const int width_aligned = nCols/8*8; + for(int y=0; y0) + *dstByte = 0; + for(int j=0; j<(nCols%8); ++j, ++p) + { + *dstByte += + ( p.Red()!=colour.Red() + || p.Green()!=colour.Green() + || p.Blue()!=colour.Blue() + ) << (7-j); + } + p = rowStart; + p.OffsetY(srcData,1); + } + return true; +} -bool wxBitmap::CreateFromXpm(const char **) +// Create a mask from a bitmap and a colour indicating +// the transparent area +bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour) { - return false; + wxAutoNSAutoreleasePool pool; + if(!bitmap.Ok()) + return false; + int bmpWidth = bitmap.GetWidth(); + int bmpHeight = bitmap.GetHeight(); + int dstRowLength = (bmpWidth+7)/8; + + // Create a bitmap image rep with 1-bit per pixel data representing + // the alpha channel padded such that rows end on byte boundaries + // Since NSBitmapImageRep doesn't have any sort of NSNullColorSpace + // we must have at least one channel of non-alpha data. In order to + // make our life easy, we use planar data which results in two + // separate arrays. We don't need to touch the first because it + // should never be used. The second is the 1-bit "alpha" data. + NSBitmapImageRep *maskRep = [[[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL pixelsWide:bmpWidth + pixelsHigh:bmpHeight bitsPerSample:1 + samplesPerPixel:2 hasAlpha:YES isPlanar:YES + colorSpaceName:NSCalibratedWhiteColorSpace + bytesPerRow:dstRowLength bitsPerPixel:1] autorelease]; + wxCHECK(maskRep,false); + + // We need the source NSBitmapImageRep to detemine its pixel format + NSBitmapImageRep *srcBitmapRep = const_cast(bitmap).GetNSBitmapImageRep(); + wxCHECK_MSG(srcBitmapRep,false,wxT("Can't create mask for an uninitialized bitmap")); + + // Get a pointer to the destination data + unsigned char *dstPlanes[5] = {NULL,NULL,NULL,NULL,NULL}; + [maskRep getBitmapDataPlanes:dstPlanes]; + unsigned char *dstData = dstPlanes[1]; + // The wxImage format (which we use whenever we imported from wxImage) + if([srcBitmapRep bitsPerPixel]==24 && [srcBitmapRep bitsPerSample]==8 && [srcBitmapRep samplesPerPixel]==3 && [srcBitmapRep hasAlpha]==NO) + { + wxPixelData pixelData(const_cast(bitmap)); + wxCHECK_MSG(wxMask_CreateFromBitmapData(pixelData, colour, dstData), + false, wxT("Unable to access raw data")); + } + // 32-bpp RGBx (x=throw away, no alpha) + else if([srcBitmapRep bitsPerPixel]==32 && [srcBitmapRep bitsPerSample]==8 && [srcBitmapRep samplesPerPixel]==3 && [srcBitmapRep hasAlpha]==NO) + { + typedef wxPixelFormat PixelFormat; + wxPixelData pixelData(const_cast(bitmap)); + wxCHECK_MSG(wxMask_CreateFromBitmapData(pixelData, colour, dstData), + false, wxT("Unable to access raw data")); + } + // 32-bpp RGBA + else if([srcBitmapRep bitsPerPixel]==32 && [srcBitmapRep bitsPerSample]==8 && [srcBitmapRep samplesPerPixel]==4 && [srcBitmapRep hasAlpha]==YES) + { + wxPixelData pixelData(const_cast(bitmap)); + wxCHECK_MSG(wxMask_CreateFromBitmapData(pixelData, colour, dstData), + false, wxT("Unable to access raw data")); + } + else + { wxCHECK_MSG(false,false,wxT("Unimplemented pixel format")); } + + // maskRep was autoreleased in case we had to exit quickly + m_cocoaNSBitmapImageRep = [maskRep retain]; + return true; } -// vim:sts=4:sw=4:syn=cpp:et