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

📄 bitmap.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                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 + -