Implement wxMask given a wxBitmap and a mask wxColour.

TODO: Masks from other sources.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24719 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
David Elliott 2003-12-08 15:01:39 +00:00
parent 878973f1fa
commit 016b064360
2 changed files with 119 additions and 36 deletions

View File

@ -24,38 +24,36 @@ class WXDLLEXPORT wxPixelDataBase;
// ========================================================================
// wxMask
// ========================================================================
/* DFE: wxMask is not implemented yet */
// A mask is a mono bitmap used for drawing bitmaps
// transparently.
// A mask is a 1-bit alpha bitmap used for drawing bitmaps transparently.
class WXDLLEXPORT wxMask: public wxObject
{
DECLARE_DYNAMIC_CLASS(wxMask)
public:
wxMask();
wxMask();
// Construct a mask from a bitmap and a colour indicating
// the transparent area
wxMask(const wxBitmap& bitmap, const wxColour& colour);
// Construct a mask from a bitmap and a colour indicating
// the transparent area
wxMask(const wxBitmap& bitmap, const wxColour& colour);
// Construct a mask from a bitmap and a palette index indicating
// the transparent area
wxMask(const wxBitmap& bitmap, int paletteIndex);
// Construct a mask from a bitmap and a palette index indicating
// the transparent area
wxMask(const wxBitmap& bitmap, int paletteIndex);
// Construct a mask from a mono bitmap (copies the bitmap).
wxMask(const wxBitmap& bitmap);
// Construct a mask from a mono bitmap (copies the bitmap).
wxMask(const wxBitmap& bitmap);
~wxMask();
~wxMask();
bool Create(const wxBitmap& bitmap, const wxColour& colour);
bool Create(const wxBitmap& bitmap, int paletteIndex);
bool Create(const wxBitmap& bitmap);
bool Create(const wxBitmap& bitmap, const wxColour& colour);
bool Create(const wxBitmap& bitmap, int paletteIndex);
bool Create(const wxBitmap& bitmap);
// Implementation
// inline WXHBITMAP GetMaskBitmap() const { return m_maskBitmap; }
// inline void SetMaskBitmap(WXHBITMAP bmp) { m_maskBitmap = bmp; }
// wxCocoa
inline WX_NSBitmapImageRep GetNSBitmapImageRep()
{ return m_cocoaNSBitmapImageRep; }
protected:
// WXHBITMAP m_maskBitmap;
WX_NSBitmapImageRep m_cocoaNSBitmapImageRep;
};
// ========================================================================

View File

@ -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"
@ -393,7 +394,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 +437,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 +452,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 +460,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 +485,103 @@ bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
return FALSE;
}
template <class PixelData>
static bool wxMask_CreateFromBitmapData(PixelData srcData, const wxColour& colour, unsigned char *dstData)
{
wxCHECK_MSG(dstData,false,"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<nRows; ++y)
{
class PixelData::Iterator rowStart(p);
unsigned char *dstRow = dstData + y*dstRowLength;
for(int x=0; x<width_aligned; x+=8)
{
unsigned char *dstByte = dstRow + x/8;
*dstByte = 0;
// Take source RGB, compare it with the wxColour
for(int j=0; j<8; ++j, ++p)
{
*dstByte +=
( p.Red()!=colour.Red()
|| p.Green()!=colour.Green()
|| p.Blue()!=colour.Blue()
) << (7-j);
}
}
// Handle the remaining 0-7 pixels in the row
unsigned char *dstByte = dstRow + width_aligned/8;
*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;
}
// Create a mask from a bitmap and a colour indicating
// the transparent area
bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
{
// TODO
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 = ((wxBitmapRefData*)bitmap.GetRefData())->m_cocoaNSBitmapImageRep;
wxCHECK_MSG(srcBitmapRep,false,"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];
if([srcBitmapRep bitsPerPixel]==24 && [srcBitmapRep bitsPerSample]==8 && [srcBitmapRep samplesPerPixel]==3 && [srcBitmapRep hasAlpha]==NO)
{
wxPixelData<wxBitmap,wxNativePixelFormat> pixelData(const_cast<wxBitmap&>(bitmap));
wxCHECK_MSG(wxMask_CreateFromBitmapData(pixelData, colour, dstData),
false, "Unable to access raw data");
}
else if([srcBitmapRep bitsPerPixel]==32 && [srcBitmapRep bitsPerSample]==8 && [srcBitmapRep samplesPerPixel]==4 && [srcBitmapRep hasAlpha]==YES)
{
wxPixelData<wxBitmap,wxAlphaPixelFormat> pixelData(const_cast<wxBitmap&>(bitmap));
wxCHECK_MSG(wxMask_CreateFromBitmapData(pixelData, colour, dstData),
false, "Unable to access raw data");
}
else
{ wxCHECK_MSG(false,false,"Unimplemented pixel format"); }
// maskRep was autoreleased in case we had to exit quickly
m_cocoaNSBitmapImageRep = [maskRep retain];
return true;
}