⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmap.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////////// Name:        src/mac/carbon/bitmap.cpp// Purpose:     wxBitmap// Author:      Stefan Csomor// Modified by:// Created:     1998-01-01// RCS-ID:      $Id: bitmap.cpp,v 1.103 2006/11/01 03:23:28 RD Exp $// Copyright:   (c) Stefan Csomor// Licence:     wxWindows licence/////////////////////////////////////////////////////////////////////////////#include "wx/wxprec.h"#include "wx/bitmap.h"#ifndef WX_PRECOMP    #include "wx/log.h"    #include "wx/dcmemory.h"    #include "wx/icon.h"    #include "wx/image.h"#endif#include "wx/metafile.h"#include "wx/xpmdecod.h"#include "wx/rawbmp.h"IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)#ifdef __DARWIN__    #include <ApplicationServices/ApplicationServices.h>#else    #include <PictUtils.h>#endif#include "wx/mac/uma.h"// Implementation Notes// --------------------//// we are always working with a 32 bit deep pixel buffer// under QuickDraw its alpha parts are going to be ignored in the GWorld,// therefore we have a separate GWorld there for blitting the mask in// under Quartz then content is transformed into a CGImageRef representing the same data// which can be transferred to the GPU by the OS for fast rendering// we don't dare use premultiplied alpha yet#define wxMAC_USE_PREMULTIPLIED_ALPHA 0#if wxUSE_BMPBUTTONvoid wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType ){    memset( info , 0 , sizeof(ControlButtonContentInfo) ) ;    if ( bitmap.Ok() )    {        wxBitmapRefData * bmap = bitmap.GetBitmapData() ;        if ( bmap == NULL )            return ;        if ( ( bmap->HasNativeSize() && forceType == 0 ) || forceType == kControlContentIconRef )        {            wxBitmap scaleBmp ;            wxBitmapRefData* bmp = bmap ;            if ( !bmap->HasNativeSize() )            {                // as PICT conversion will only result in a 16x16 icon, let's attempt                // a few scales for better results                int w = bitmap.GetWidth() ;                int h = bitmap.GetHeight() ;                int sz = wxMax( w , h ) ;                if ( sz == 24 || sz == 64 )                {                    scaleBmp = wxBitmap( bitmap.ConvertToImage().Scale( w * 2 , h * 2 ) ) ;                    bmp = scaleBmp.GetBitmapData() ;                }            }            info->contentType = kControlContentIconRef ;            info->u.iconRef = bmp->GetIconRef() ;            AcquireIconRef( info->u.iconRef ) ;        }#if defined( __WXMAC_OSX__ ) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2        else if ( forceType == kControlContentCGImageRef )        {            info->contentType = kControlContentCGImageRef ;            info->u.imageRef = (CGImageRef) bmap->CGImageCreate() ;        }#endif        else        {#ifndef __LP64__            info->contentType = kControlContentPictHandle ;            info->u.picture = bmap->GetPictHandle() ;#endif        }    }}void wxMacReleaseBitmapButton( ControlButtonContentInfo*info ){    if ( info->contentType == kControlContentIconRef )    {        ReleaseIconRef( info->u.iconRef ) ;    }    else if ( info->contentType == kControlNoContent )    {        // there's no bitmap at all, fall through silently    }    else if ( info->contentType == kControlContentPictHandle )    {        // owned by the bitmap, no release here    }#if defined( __WXMAC_OSX__ ) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2    else if ( info->contentType == kControlContentCGImageRef )    {        CGImageRelease( info->u.imageRef ) ;    }#endif    else    {        wxFAIL_MSG(wxT("Unexpected bitmap type") ) ;    }}#endif //wxUSE_BMPBUTTON#define M_BITMAPDATA ((wxBitmapRefData *)m_refData)void wxBitmapRefData::Init(){    m_width = 0 ;    m_height = 0 ;    m_depth = 0 ;    m_ok = false ;    m_bitmapMask = NULL ;#ifdef __WXMAC_OSX__    m_cgImageRef = NULL ;#endif    m_iconRef = NULL ;    m_pictHandle = NULL ;    m_hBitmap = NULL ;    m_hMaskBitmap = NULL;    m_maskBytesPerRow = 0 ;    m_rawAccessCount = 0 ;    m_hasAlpha = false;}wxBitmapRefData::wxBitmapRefData(const wxBitmapRefData &tocopy){    Init();    Create(tocopy.m_width, tocopy.m_height, tocopy.m_depth);         if (tocopy.m_bitmapMask)        m_bitmapMask = new wxMask(*tocopy.m_bitmapMask);    unsigned char* dest = (unsigned char*)GetRawAccess();    unsigned char* source = (unsigned char*)tocopy.GetRawAccess();    size_t numbytes = tocopy.m_width * tocopy.m_height * 4;        for (size_t i=0; i<numbytes; i++)    {        *dest++ = *source++;    }        UseAlpha(tocopy.m_hasAlpha);    // TODO:  Copy palette?}wxBitmapRefData::wxBitmapRefData(){    Init() ;}wxBitmapRefData::wxBitmapRefData( int w , int h , int d ){    Init() ;    Create( w , h , d ) ;}bool wxBitmapRefData::Create( int w , int h , int d ){    m_width = wxMax(1, w);    m_height = wxMax(1, h);    m_depth = d ;    m_bytesPerRow = w * 4 ;    size_t size = m_bytesPerRow * h ;    void* data = m_memBuf.GetWriteBuf( size ) ;    memset( data , 0 , size ) ;    m_memBuf.UngetWriteBuf( size ) ;    m_hBitmap = NULL ;    Rect rect = { 0 , 0 , m_height , m_width } ;#ifndef __LP64__    verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 ,        (char*) data , m_bytesPerRow ) ) ;    wxASSERT_MSG( m_hBitmap , wxT("Unable to create GWorld context") ) ;#endif    m_ok = ( m_hBitmap != NULL ) ;    return m_ok ;}void wxBitmapRefData::UseAlpha( bool use ){    if ( m_hasAlpha == use )        return ;    m_hasAlpha = use ;    if ( m_hasAlpha )    {        wxASSERT( m_hMaskBitmap == NULL ) ;        int width = GetWidth() ;        int height = GetHeight() ;        m_maskBytesPerRow = ( width * 4 + 3 ) & 0xFFFFFFC ;        size_t size = height * m_maskBytesPerRow ;        unsigned char * data = (unsigned char * ) m_maskMemBuf.GetWriteBuf( size ) ;        wxASSERT( data != NULL ) ;        memset( data , 0 , size ) ;        Rect rect = { 0 , 0 , height , width } ;#ifndef __LP64__        verify_noerr( NewGWorldFromPtr( (GWorldPtr*) &m_hMaskBitmap , k32ARGBPixelFormat , &rect , NULL , NULL , 0 ,            (char*) data , m_maskBytesPerRow ) ) ;        wxASSERT_MSG( m_hMaskBitmap , wxT("Unable to create GWorld context for alpha mask") ) ;#endif        m_maskMemBuf.UngetWriteBuf(size) ;#if !wxMAC_USE_CORE_GRAPHICS        UpdateAlphaMask() ;#endif    }    else    {#ifndef __LP64__        DisposeGWorld( m_hMaskBitmap ) ;#endif        m_hMaskBitmap = NULL ;        m_maskBytesPerRow = 0 ;    }}void *wxBitmapRefData::GetRawAccess() const{    wxCHECK_MSG( Ok(), NULL , wxT("invalid bitmap") ) ;    return m_memBuf.GetData() ;}void *wxBitmapRefData::BeginRawAccess(){    wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ) ;    wxASSERT( m_rawAccessCount == 0 ) ;    wxASSERT_MSG( m_pictHandle == NULL && m_iconRef == NULL ,        wxT("Currently, modifing bitmaps that are used in controls already is not supported") ) ;    ++m_rawAccessCount ;#ifdef __WXMAC_OSX__    // we must destroy an existing cached image, as    // the bitmap data may change now    if ( m_cgImageRef )    {        CGImageRelease( m_cgImageRef ) ;        m_cgImageRef = NULL ;    }#endif    return m_memBuf.GetData() ;}void wxBitmapRefData::EndRawAccess(){    wxCHECK_RET( Ok() , wxT("invalid bitmap") ) ;    wxASSERT( m_rawAccessCount == 1 ) ;    --m_rawAccessCount ;#if !wxMAC_USE_CORE_GRAPHICS    UpdateAlphaMask() ;#endif}bool wxBitmapRefData::HasNativeSize(){    int w = GetWidth() ;    int h = GetHeight() ;    int sz = wxMax( w , h ) ;    return ( sz == 128 || sz == 48 || sz == 32 || sz == 16 );}IconRef wxBitmapRefData::GetIconRef(){    if ( m_iconRef == NULL )    {        // Create Icon Family Handle        IconFamilyHandle iconFamily = NULL ;#ifdef WORDS_BIGENDIAN        iconFamily = (IconFamilyHandle) NewHandle( 8 ) ;        (**iconFamily).resourceType = kIconFamilyType ;        (**iconFamily).resourceSize = sizeof(OSType) + sizeof(Size);#else        // test this solution on big endian as well        iconFamily = (IconFamilyHandle) NewHandle( 0 ) ;#endif        int w = GetWidth() ;        int h = GetHeight() ;        int sz = wxMax( w , h ) ;        OSType dataType = 0 ;        OSType maskType = 0 ;        switch (sz)        {            case 128:                dataType = kThumbnail32BitData ;                maskType = kThumbnail8BitMask ;                break;            case 48:                dataType = kHuge32BitData ;                maskType = kHuge8BitMask ;                break;            case 32:                dataType = kLarge32BitData ;                maskType = kLarge8BitMask ;                break;            case 16:                dataType = kSmall32BitData ;                maskType = kSmall8BitMask ;                break;            default:                break;        }        if ( dataType != 0 )        {            // setup the header properly            Handle data = NULL ;            Handle maskdata = NULL ;            unsigned char * maskptr = NULL ;            unsigned char * ptr = NULL ;            size_t datasize, masksize ;            datasize = sz * sz * 4 ;            data = NewHandle( datasize ) ;            HLock( data ) ;            ptr = (unsigned char*) *data ;            memset( ptr , 0, datasize ) ;            masksize = sz * sz ;            maskdata = NewHandle( masksize ) ;            HLock( maskdata ) ;            maskptr = (unsigned char*) *maskdata ;            memset( maskptr , 0 , masksize ) ;            bool hasAlpha = HasAlpha() ;            wxMask *mask = m_bitmapMask ;            unsigned char * source = (unsigned char*) GetRawAccess() ;            unsigned char * masksource = mask ? (unsigned char*) mask->GetRawAccess() : NULL ;            for ( int y = 0 ; y < h ; ++y )            {                unsigned char * dest = ptr + y * sz * 4 ;                unsigned char * maskdest = maskptr + y * sz ;                unsigned char a, r, g, b;                for ( int x = 0 ; x < w ; ++x )                {                    a = *source ++ ;                    r = *source ++ ;                    g = *source ++ ;                    b = *source ++ ;                    *dest++ = 0 ;                    *dest++ = r ;                    *dest++ = g ;                    *dest++ = b ;                    if ( mask )                    {                        *maskdest++ = 0xFF - *masksource++ ;                        masksource++ ;                        masksource++ ;                        masksource++ ;                    }                    else if ( hasAlpha )                        *maskdest++ = a ;                    else                        *maskdest++ = 0xFF ;                }            }            OSStatus err = SetIconFamilyData( iconFamily, dataType , data ) ;            wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ;            err = SetIconFamilyData( iconFamily, maskType , maskdata ) ;            wxASSERT_MSG( err == noErr , wxT("Error when adding mask") ) ;            HUnlock( data ) ;            HUnlock( maskdata ) ;            DisposeHandle( data ) ;            DisposeHandle( maskdata ) ;        }        else        {            PicHandle pic = GetPictHandle() ;            SetIconFamilyData( iconFamily, 'PICT' , (Handle) pic ) ;        }        // transform into IconRef#if defined( __WXMAC_OSX__ ) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2        // cleaner version existing from 10.3 upwards        HLock((Handle) iconFamily);        OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &m_iconRef );        HUnlock((Handle) iconFamily);        wxASSERT_MSG( err == noErr , wxT("Error when constructing icon ref") );#else        static int iconCounter = 2 ;        OSStatus err = RegisterIconRefFromIconFamily( 'WXNG' , (OSType) iconCounter, iconFamily, &m_iconRef ) ;        wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ;        // we have to retain a reference, as Unregister will decrement it        AcquireIconRef( m_iconRef ) ;        UnregisterIconRef( 'WXNG' , (OSType) iconCounter ) ;        ++iconCounter ;#endif        DisposeHandle( (Handle) iconFamily ) ;    }    return m_iconRef ;}PicHandle wxBitmapRefData::GetPictHandle(){    if ( m_pictHandle == NULL )    {#ifndef __LP64__        CGrafPtr origPort = NULL ;        GDHandle origDev = NULL ;        GWorldPtr wp = NULL ;        GWorldPtr mask = NULL ;        int height = GetHeight() ;        int width = GetWidth() ;        Rect rect = { 0 , 0 , height , width } ;        RgnHandle clipRgn = NULL ;        GetGWorld( &origPort , &origDev ) ;        wp = GetHBITMAP( &mask ) ;        if ( mask )        {            GWorldPtr monoworld ;            clipRgn = NewRgn() ;            OSStatus err = NewGWorld( &monoworld , 1 , &rect , NULL , NULL , 0 ) ;            verify_noerr(err) ;            LockPixels( GetGWorldPixMap( monoworld ) ) ;            LockPixels( GetGWorldPixMap( mask ) ) ;            SetGWorld( monoworld , NULL ) ;            RGBColor white = { 0xffff , 0xffff , 0xffff } ;            RGBColor black = { 0x0000 , 0x0000 , 0x0000 } ;            RGBForeColor( &black ) ;            RGBBackColor( &white ) ;            CopyBits(GetPortBitMapForCopyBits(mask),                    GetPortBitMapForCopyBits(monoworld),                    &rect,                    &rect,                    srcCopy, NULL);            BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( monoworld ) ) ;            UnlockPixels( GetGWorldPixMap( monoworld ) ) ;            UnlockPixels( GetGWorldPixMap( mask ) ) ;            DisposeGWorld( monoworld ) ;        }        SetGWorld( wp , NULL ) ;        Rect portRect ;        GetPortBounds( wp , &portRect ) ;        m_pictHandle = OpenPicture(&portRect);        if (m_pictHandle)        {            RGBColor white = { 0xffff , 0xffff , 0xffff } ;            RGBColor black = { 0x0000 , 0x0000 , 0x0000 } ;            RGBForeColor( &black ) ;            RGBBackColor( &white ) ;            if ( clipRgn )                SetClip( clipRgn ) ;            LockPixels( GetGWorldPixMap( wp ) ) ;            CopyBits(GetPortBitMapForCopyBits(wp),                    GetPortBitMapForCopyBits(wp),                    &portRect,                    &portRect,                    srcCopy,clipRgn);            UnlockPixels( GetGWorldPixMap( wp ) ) ;            ClosePicture();        }        SetGWorld( origPort , origDev ) ;        if ( clipRgn )            DisposeRgn( clipRgn ) ;#endif    }    return m_pictHandle ;}#ifdef __WXMAC_OSX__void wxMacMemoryBufferReleaseProc(void *info, const void *data, size_t size){    wxMemoryBuffer* membuf = (wxMemoryBuffer*) info ;    wxASSERT( data == membuf->GetData() ) ;    delete membuf ;}CGImageRef wxBitmapRefData::CGImageCreate() const{    wxASSERT( m_ok ) ;    wxASSERT( m_rawAccessCount >= 0 ) ;    CGImageRef image ;    if ( m_rawAccessCount > 0 || m_cgImageRef == NULL )    {        size_t imageSize = m_width * m_height * 4 ;        void * dataBuffer = m_memBuf.GetData() ;        int w = m_width ;        int h = m_height ;        CGImageAlphaInfo alphaInfo = kCGImageAlphaNoneSkipFirst ;        wxMemoryBuffer* membuf = NULL ;        if ( m_bitmapMask )        {            alphaInfo = kCGImageAlphaFirst ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -