📄 bitmap.cpp
字号:
membuf = new wxMemoryBuffer( imageSize ) ; memcpy( membuf->GetData() , dataBuffer , imageSize ) ; unsigned char *sourcemaskstart = (unsigned char *) m_bitmapMask->GetRawAccess() ; int maskrowbytes = m_bitmapMask->GetBytesPerRow() ; unsigned char *destalpha = (unsigned char *) membuf->GetData() ; for ( int y = 0 ; y < h ; ++y , sourcemaskstart += maskrowbytes) { unsigned char *sourcemask = sourcemaskstart ; for ( int x = 0 ; x < w ; ++x , sourcemask += 4 , destalpha += 4 ) { *destalpha = 0xFF - *sourcemask ; } } } else { if ( m_hasAlpha ) {#if wxMAC_USE_PREMULTIPLIED_ALPHA alphaInfo = kCGImageAlphaPremultipliedFirst ;#else alphaInfo = kCGImageAlphaFirst ;#endif } membuf = new wxMemoryBuffer( m_memBuf ) ; } CGDataProviderRef dataProvider = NULL ; if ( m_depth == 1 ) { wxMemoryBuffer* maskBuf = new wxMemoryBuffer( m_width * m_height ); unsigned char * maskBufData = (unsigned char *) maskBuf->GetData(); unsigned char * bufData = (unsigned char *) membuf->GetData() ; // copy one color component for( int i = 0 ; i < m_width * m_height ; ++i ) maskBufData[i] = bufData[i*4+3]; dataProvider = CGDataProviderCreateWithData( maskBuf , (const void *) maskBufData , m_width * m_height, wxMacMemoryBufferReleaseProc ); // as we are now passing the mask buffer to the data provider, we have // to release the membuf ourselves delete membuf ; image = ::CGImageMaskCreate( w, h, 8, 8, m_width , dataProvider, NULL, false ); } else { CGColorSpaceRef colorSpace = wxMacGetGenericRGBColorSpace(); 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 ;}#endifGWorldPtr 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 ; }#ifndef __LP64__ 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 ; }#endif 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(const 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);}wxObjectRefData* wxBitmap::CreateRefData() const{ return new wxBitmapRefData;}wxObjectRefData* wxBitmap::CloneRefData(const wxObjectRefData* data) const{ return new wxBitmapRefData(*wx_static_cast(const wxBitmapRefData *, data));}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() ;}#ifdef __WXMAC_OSX__WXCGIMAGEREF wxBitmap::CGImageCreate() const{ wxCHECK_MSG( Ok(), NULL , wxT("invalid bitmap") ) ; return M_BITMAPDATA->CGImageCreate() ;}#endifwxBitmap 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(const 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_IMAGEwxBitmap::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 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -