X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b60c6e9776cdadbc013b4bcc5a33c7e048ed554d..6efbb55bf6f927320f5438c71afb93fdacd62fe3:/src/cocoa/bitmap.mm?ds=sidebyside diff --git a/src/cocoa/bitmap.mm b/src/cocoa/bitmap.mm index 20eb68c03a..2b13a11ef6 100644 --- a/src/cocoa/bitmap.mm +++ b/src/cocoa/bitmap.mm @@ -15,6 +15,7 @@ #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/image.h" @@ -26,6 +27,7 @@ #import #import +#import // ======================================================================== // wxBitmapRefData @@ -144,6 +146,27 @@ WX_NSBitmapImageRep wxBitmap::GetNSBitmapImageRep() return M_BITMAPDATA->m_cocoaNSBitmapImageRep; } +WX_NSImage wxBitmap::GetNSImage(bool useMask) const +{ + 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()) + { + NSImage *maskImage = [[NSImage alloc] + initWithSize:NSMakeSize(GetWidth(), GetHeight())]; + [maskImage addRepresentation: GetMask()->GetNSBitmapImageRep()]; + [nsimage lockFocus]; + [maskImage compositeToPoint:NSZeroPoint operation:NSCompositeDestinationIn]; + [nsimage unlockFocus]; + } + return nsimage; +} + void wxBitmap::SetNSBitmapImageRep(WX_NSBitmapImageRep bitmapImageRep) { if(!M_BITMAPDATA) @@ -273,7 +296,7 @@ bool wxBitmap::Create(int w, int h, int d) bytesPerRow: 0 bitsPerPixel: 0]; - wxLogDebug("M_BITMAPDATA=%p NSBitmapImageRep bitmapData=%p", M_BITMAPDATA, [M_BITMAPDATA->m_cocoaNSBitmapImageRep bitmapData]); + 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; @@ -339,8 +362,8 @@ wxBitmap wxBitmap::GetSubBitmap(wxRect const&) const wxImage wxBitmap::ConvertToImage() const { - if(!M_BITMAPDATA->m_ok) - return wxImage(5,5)/*wxNullImage*/; + if(!Ok()) + return /*wxImage(5,5)*/wxNullImage; return wxImage(M_BITMAPDATA->m_width,M_BITMAPDATA->m_height); } @@ -393,7 +416,7 @@ bool wxBitmap::CreateFromImage(const wxImage& image, int depth) M_BITMAPDATA->m_numColors = 0; M_BITMAPDATA->m_quality = 0; M_BITMAPDATA->m_cocoaNSBitmapImageRep = bitmapImage; - M_BITMAPDATA->m_bitmapMask = NULL; + M_BITMAPDATA->m_bitmapMask = new wxMask(*this,wxColour(image.GetMaskRed(),image.GetMaskGreen(),image.GetMaskBlue())); return true; } @@ -436,18 +459,14 @@ IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject) wxMask::wxMask() { -/* TODO - m_maskBitmap = 0; -*/ + m_cocoaNSBitmapImageRep = nil; } // 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; -*/ + m_cocoaNSBitmapImageRep = nil; Create(bitmap, colour); } @@ -455,9 +474,7 @@ wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour) // the transparent area wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex) { -/* TODO - m_maskBitmap = 0; -*/ + m_cocoaNSBitmapImageRep = nil; Create(bitmap, paletteIndex); } @@ -465,16 +482,14 @@ wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex) // Construct a mask from a mono bitmap (copies the bitmap). wxMask::wxMask(const wxBitmap& bitmap) { -/* TODO - m_maskBitmap = 0; -*/ + m_cocoaNSBitmapImageRep = nil; Create(bitmap); } wxMask::~wxMask() { -// TODO: delete mask bitmap + [m_cocoaNSBitmapImageRep release]; } // Create a mask from a mono bitmap (copies the bitmap). @@ -492,11 +507,113 @@ bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex) 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")); + class 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; y(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; }