📄 bitmap.cpp
字号:
alphaInfo = kCGImageAlphaFirst ;
#endif
}
membuf = new wxMemoryBuffer( m_memBuf ) ;
}
CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace();
CGDataProviderRef dataProvider =
CGDataProviderCreateWithData(
membuf , (const void *)membuf->GetData() , imageSize,
wxMacMemoryBufferReleaseProc );
image =
::CGImageCreate(
w, h, 8 , 32 , 4 * m_width , colorSpace, alphaInfo ,
dataProvider, NULL , false , kCGRenderingIntentDefault );
CGDataProviderRelease( dataProvider);
}
else
{
image = m_cgImageRef ;
CGImageRetain( image ) ;
}
if ( m_rawAccessCount == 0 && m_cgImageRef == NULL)
{
// we keep it for later use
m_cgImageRef = image ;
CGImageRetain( image ) ;
}
return image ;
}
#endif
GWorldPtr wxBitmapRefData::GetHBITMAP(GWorldPtr* mask) const
{
wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
if ( mask )
{
*mask = NULL ;
if ( m_bitmapMask )
{
*mask = (GWorldPtr) m_bitmapMask->GetHBITMAP() ;
}
else if ( m_hasAlpha )
{
#if !wxMAC_USE_CORE_GRAPHICS
if ( m_rawAccessCount > 0 )
UpdateAlphaMask() ;
#else
// this structure is not kept in synch when using CG, so if something
// is really accessing the GrafPorts, we have to sync it
UpdateAlphaMask() ;
#endif
*mask = m_hMaskBitmap ;
}
}
return m_hBitmap ;
}
void wxBitmapRefData::UpdateAlphaMask() const
{
if ( m_hasAlpha )
{
unsigned char *sourcemask = (unsigned char *) GetRawAccess() ;
unsigned char *destalphabase = (unsigned char *) m_maskMemBuf.GetData() ;
int h = GetHeight() ;
int w = GetWidth() ;
for ( int y = 0 ; y < h ; ++y , destalphabase += m_maskBytesPerRow )
{
unsigned char* destalpha = destalphabase ;
for ( int x = 0 ; x < w ; ++x , sourcemask += 4 )
{
// we must have 24 bit depth for non quartz smooth alpha
*destalpha++ = 255 ;
*destalpha++ = 255 - *sourcemask ;
*destalpha++ = 255 - *sourcemask ;
*destalpha++ = 255 - *sourcemask ;
}
}
}
}
void wxBitmapRefData::Free()
{
wxASSERT_MSG( m_rawAccessCount == 0 , wxT("Bitmap still selected when destroyed") ) ;
#ifdef __WXMAC_OSX__
if ( m_cgImageRef )
{
CGImageRelease( m_cgImageRef ) ;
m_cgImageRef = NULL ;
}
#endif
if ( m_iconRef )
{
ReleaseIconRef( m_iconRef ) ;
m_iconRef = NULL ;
}
if ( m_pictHandle )
{
KillPicture( m_pictHandle ) ;
m_pictHandle = NULL ;
}
if ( m_hBitmap )
{
DisposeGWorld( MAC_WXHBITMAP(m_hBitmap) ) ;
m_hBitmap = NULL ;
}
if ( m_hMaskBitmap )
{
DisposeGWorld( MAC_WXHBITMAP(m_hMaskBitmap) ) ;
m_hMaskBitmap = NULL ;
}
if (m_bitmapMask)
{
delete m_bitmapMask;
m_bitmapMask = NULL;
}
}
wxBitmapRefData::~wxBitmapRefData()
{
Free() ;
}
bool wxBitmap::CopyFromIcon(const wxIcon& icon)
{
bool created = false ;
int w = icon.GetWidth() ;
int h = icon.GetHeight() ;
Create( icon.GetWidth() , icon.GetHeight() ) ;
if ( w == h && ( w == 16 || w == 32 || w == 48 || w == 128 ) )
{
IconFamilyHandle iconFamily = NULL ;
Handle imagehandle = NewHandle( 0 ) ;
Handle maskhandle = NewHandle( 0 ) ;
OSType maskType = 0;
OSType dataType = 0;
IconSelectorValue selector = 0 ;
switch (w)
{
case 128:
dataType = kThumbnail32BitData ;
maskType = kThumbnail8BitMask ;
selector = kSelectorAllAvailableData ;
break;
case 48:
dataType = kHuge32BitData ;
maskType = kHuge8BitMask ;
selector = kSelectorHuge32Bit | kSelectorHuge8BitMask ;
break;
case 32:
dataType = kLarge32BitData ;
maskType = kLarge8BitMask ;
selector = kSelectorLarge32Bit | kSelectorLarge8BitMask ;
break;
case 16:
dataType = kSmall32BitData ;
maskType = kSmall8BitMask ;
selector = kSelectorSmall32Bit | kSelectorSmall8BitMask ;
break;
default:
break;
}
OSStatus err = IconRefToIconFamily( MAC_WXHICON(icon.GetHICON()) , selector , &iconFamily ) ;
err = GetIconFamilyData( iconFamily , dataType , imagehandle ) ;
err = GetIconFamilyData( iconFamily , maskType , maskhandle ) ;
size_t imagehandlesize = GetHandleSize( imagehandle ) ;
size_t maskhandlesize = GetHandleSize( maskhandle ) ;
if ( imagehandlesize != 0 && maskhandlesize != 0 )
{
wxASSERT( GetHandleSize( imagehandle ) == w * 4 * h ) ;
wxASSERT( GetHandleSize( maskhandle ) == w * h ) ;
UseAlpha() ;
unsigned char *source = (unsigned char *) *imagehandle ;
unsigned char *sourcemask = (unsigned char *) *maskhandle ;
unsigned char* destination = (unsigned char*) BeginRawAccess() ;
for ( int y = 0 ; y < h ; ++y )
{
for ( int x = 0 ; x < w ; ++x )
{
*destination++ = *sourcemask++ ;
source++ ;
*destination++ = *source++ ;
*destination++ = *source++ ;
*destination++ = *source++ ;
}
}
EndRawAccess() ;
DisposeHandle( imagehandle ) ;
DisposeHandle( maskhandle ) ;
created = true ;
}
DisposeHandle( (Handle) iconFamily ) ;
}
if ( !created )
{
wxMemoryDC dc ;
dc.SelectObject( *this ) ;
dc.DrawIcon( icon , 0 , 0 ) ;
dc.SelectObject( wxNullBitmap ) ;
}
return true;
}
wxBitmap::wxBitmap()
{
}
wxBitmap::~wxBitmap()
{
}
wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
{
m_refData = new wxBitmapRefData( the_width , the_height , no_bits ) ;
if ( no_bits == 1 )
{
int linesize = ( the_width / (sizeof(unsigned char) * 8)) ;
if ( the_width % (sizeof(unsigned char) * 8) )
linesize += sizeof(unsigned char);
unsigned char* linestart = (unsigned char*) bits ;
unsigned char* destination = (unsigned char*) BeginRawAccess() ;
for ( int y = 0 ; y < the_height ; ++y , linestart += linesize )
{
int index, bit, mask;
for ( int x = 0 ; x < the_width ; ++x )
{
index = x / 8 ;
bit = x % 8 ;
mask = 1 << bit ;
if ( !(linestart[index] & mask ) )
{
*destination++ = 0xFF ;
*destination++ = 0 ;
*destination++ = 0 ;
*destination++ = 0 ;
}
else
{
*destination++ = 0xFF ;
*destination++ = 0xFF ;
*destination++ = 0xFF ;
*destination++ = 0xFF ;
}
}
}
EndRawAccess() ;
}
else
{
wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
}
}
wxBitmap::wxBitmap(int w, int h, int d)
{
(void)Create(w, h, d);
}
wxBitmap::wxBitmap(void *data, wxBitmapType type, int width, int height, int depth)
{
(void) Create(data, type, width, height, depth);
}
wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
{
LoadFile(filename, type);
}
wxBitmap::wxBitmap(const char **bits)
{
(void) CreateFromXpm(bits);
}
wxBitmap::wxBitmap(char **bits)
{
(void) CreateFromXpm((const char **)bits);
}
void * wxBitmap::GetRawAccess() const
{
wxCHECK_MSG( Ok() , NULL , wxT("invalid bitmap") ) ;
return M_BITMAPDATA->GetRawAccess() ;
}
void * wxBitmap::BeginRawAccess()
{
wxCHECK_MSG( Ok() , NULL , wxT("invalid bitmap") ) ;
return M_BITMAPDATA->BeginRawAccess() ;
}
void wxBitmap::EndRawAccess()
{
wxCHECK_RET( Ok() , wxT("invalid bitmap") ) ;
M_BITMAPDATA->EndRawAccess() ;
}
bool wxBitmap::CreateFromXpm(const char **bits)
{
#if wxUSE_IMAGE
wxCHECK_MSG( bits != NULL, false, wxT("invalid bitmap data") );
wxXPMDecoder decoder;
wxImage img = decoder.ReadData(bits);
wxCHECK_MSG( img.Ok(), false, wxT("invalid bitmap data") );
*this = wxBitmap(img);
return true;
#else
return false;
#endif
}
#ifdef __WXMAC_OSX__
WXCGIMAGEREF wxBitmap::CGImageCreate() const
{
wxCHECK_MSG( Ok(), NULL , wxT("invalid bitmap") ) ;
return M_BITMAPDATA->CGImageCreate() ;
}
#endif
wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
{
wxCHECK_MSG( Ok() &&
(rect.x >= 0) && (rect.y >= 0) &&
(rect.x+rect.width <= GetWidth()) &&
(rect.y+rect.height <= GetHeight()),
wxNullBitmap, wxT("invalid bitmap or bitmap region") );
wxBitmap ret( rect.width, rect.height, GetDepth() );
wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
int sourcewidth = GetWidth() ;
int destwidth = rect.width ;
int destheight = rect.height ;
{
unsigned char *sourcedata = (unsigned char*) GetRawAccess() ;
unsigned char *destdata = (unsigned char*) ret.BeginRawAccess() ;
wxASSERT( (sourcedata != NULL) && (destdata != NULL) ) ;
int sourcelinesize = sourcewidth * 4 ;
int destlinesize = destwidth * 4 ;
unsigned char *source = sourcedata + rect.x * 4 + rect.y * sourcelinesize ;
unsigned char *dest = destdata ;
for (int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize)
{
memcpy( dest , source , destlinesize ) ;
}
}
ret.EndRawAccess() ;
if ( M_BITMAPDATA->m_bitmapMask )
{
wxMemoryBuffer maskbuf ;
int rowBytes = ( destwidth * 4 + 3 ) & 0xFFFFFFC ;
size_t maskbufsize = rowBytes * destheight ;
int sourcelinesize = M_BITMAPDATA->m_bitmapMask->GetBytesPerRow() ;
int destlinesize = rowBytes ;
unsigned char *source = (unsigned char *) M_BITMAPDATA->m_bitmapMask->GetRawAccess() ;
unsigned char *destdata = (unsigned char * ) maskbuf.GetWriteBuf( maskbufsize ) ;
wxASSERT( (source != NULL) && (destdata != NULL) ) ;
source += rect.x * 4 + rect.y * sourcelinesize ;
unsigned char *dest = destdata ;
for (int yy = 0; yy < destheight; ++yy, source += sourcelinesize , dest += destlinesize)
{
memcpy( dest , source , destlinesize ) ;
}
maskbuf.UngetWriteBuf( maskbufsize ) ;
ret.SetMask( new wxMask( maskbuf , destwidth , destheight , rowBytes ) ) ;
}
else if ( HasAlpha() )
ret.UseAlpha() ;
return ret;
}
bool wxBitmap::Create(int w, int h, int d)
{
UnRef();
if ( d < 0 )
d = wxDisplayDepth() ;
m_refData = new wxBitmapRefData( w , h , d );
return M_BITMAPDATA->Ok() ;
}
bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type)
{
UnRef();
wxBitmapHandler *handler = FindHandler(type);
if ( handler )
{
m_refData = new wxBitmapRefData;
return handler->LoadFile(this, filename, type, -1, -1);
}
else
{
#if wxUSE_IMAGE
wxImage loadimage(filename, type);
if (loadimage.Ok())
{
*this = loadimage;
return true;
}
#endif
}
wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
return false;
}
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(wxT("no bitmap handler for type %d defined."), type);
return false;
}
return handler->Create(this, data, type, width, height, depth);
}
#if wxUSE_IMAGE
wxBitmap::wxBitmap(const wxImage& image, int depth)
{
wxCHECK_RET( image.Ok(), wxT("invalid image") );
// width and height of the device-dependent bitmap
int width = image.GetWidth();
int height = image.GetHeight();
m_refData = new wxBitmapRefData( width , height , depth ) ;
// Create picture
bool hasAlpha = false ;
if ( image.HasMask() )
{
// takes precedence, don't mix with alpha info
}
else
{
hasAlpha = image.HasAlpha() ;
}
if ( hasAlpha )
UseAlpha() ;
unsigned char* destination = (unsigned char*) BeginRawAccess() ;
register unsigned char* data = image.GetData();
const unsigned char *alpha = hasAlpha ? image.GetAlpha() : NULL ;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if ( hasAlpha )
{
const unsigned char a = *alpha++;
*destination++ = a ;
#if wxMAC_USE_PREMULTIPLIED_ALPHA
*destination++ = ((*data++) * a + 127) / 255 ;
*destination++ = ((*data++) * a + 127) / 255 ;
*destination++ = ((*data++) * a + 127) / 255 ;
#else
*destination++ = *data++ ;
*destination++ = *data++ ;
*destination++ = *data++ ;
#endif
}
else
{
*destination++ = 0xFF ;
*destination++ = *data++ ;
*destination++ = *data++ ;
*destination++ = *data++ ;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -