From 2a391f87180f6f6a04a472722521204504005c0d Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 9 Feb 2003 08:19:28 +0000 Subject: [PATCH 1/1] clipboard bitmap support extended git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19152 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/mac/bitmap.cpp | 221 ++++++++++++++++--------------------- src/mac/carbon/bitmap.cpp | 221 ++++++++++++++++--------------------- src/mac/carbon/dataobj.cpp | 82 +++++++------- src/mac/dataobj.cpp | 82 +++++++------- 4 files changed, 270 insertions(+), 336 deletions(-) diff --git a/src/mac/bitmap.cpp b/src/mac/bitmap.cpp index cd1c398c99..f88e89343b 100644 --- a/src/mac/bitmap.cpp +++ b/src/mac/bitmap.cpp @@ -369,43 +369,46 @@ wxBitmapRefData::wxBitmapRefData() // TODO move this to a public function of Bitmap Ref static void DisposeBitmapRefData(wxBitmapRefData *data) { - switch (data->m_bitmapType) - { - case kMacBitmapTypePict : - { - if ( data->m_hPict ) - { - KillPicture( MAC_WXHMETAFILE( data->m_hPict ) ) ; - data->m_hPict = NULL ; - } - } - break ; - case kMacBitmapTypeGrafWorld : - { - if ( data->m_hBitmap ) - { - wxMacDestroyGWorld( MAC_WXHBITMAP(data->m_hBitmap) ) ; - data->m_hBitmap = NULL ; - } - } - break ; - case kMacBitmapTypeIcon : - if ( data->m_hIcon ) - { - DisposeCIcon( MAC_WXHICON(data->m_hIcon) ) ; - data->m_hIcon = NULL ; - } - - default : - // unkown type ? - break ; - } + if ( !data ) + return ; + + switch (data->m_bitmapType) + { + case kMacBitmapTypePict : + { + if ( data->m_hPict ) + { + KillPicture( MAC_WXHMETAFILE( data->m_hPict ) ) ; + data->m_hPict = NULL ; + } + } + break ; + case kMacBitmapTypeGrafWorld : + { + if ( data->m_hBitmap ) + { + wxMacDestroyGWorld( MAC_WXHBITMAP(data->m_hBitmap) ) ; + data->m_hBitmap = NULL ; + } + } + break ; + case kMacBitmapTypeIcon : + if ( data->m_hIcon ) + { + DisposeCIcon( MAC_WXHICON(data->m_hIcon) ) ; + data->m_hIcon = NULL ; + } + + default : + // unkown type ? + break ; + } - if (data->m_bitmapMask) - { - delete data->m_bitmapMask; - data->m_bitmapMask = NULL; - } + if (data->m_bitmapMask) + { + delete data->m_bitmapMask; + data->m_bitmapMask = NULL; + } } wxBitmapRefData::~wxBitmapRefData() @@ -637,11 +640,38 @@ int wxBitmap::GetBitmapType() const void wxBitmap::SetHBITMAP(WXHBITMAP bmp) { - DisposeBitmapRefData( M_BITMAPDATA ) ; + if (!M_BITMAPDATA) + m_refData = new wxBitmapRefData; + else + DisposeBitmapRefData( M_BITMAPDATA ) ; M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; M_BITMAPDATA->m_hBitmap = bmp ; - M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ; + M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ; +} + +void wxBitmap::SetHICON(WXHICON ico) +{ + if (!M_BITMAPDATA) + m_refData = new wxBitmapRefData; + else + DisposeBitmapRefData( M_BITMAPDATA ) ; + + M_BITMAPDATA->m_bitmapType = kMacBitmapTypeIcon ; + M_BITMAPDATA->m_hIcon = ico ; + M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hIcon != NULL ) ; +} + +void wxBitmap::SetPict(WXHMETAFILE pict) +{ + if (!M_BITMAPDATA) + m_refData = new wxBitmapRefData; + else + DisposeBitmapRefData( M_BITMAPDATA ) ; + + M_BITMAPDATA->m_bitmapType = kMacBitmapTypePict ; + M_BITMAPDATA->m_hPict = pict ; + M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hPict != NULL ) ; } bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) @@ -1006,96 +1036,35 @@ WXHBITMAP wxBitmap::GetHBITMAP() const return MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap); } -WXHMETAFILE wxBitmap::GetPict() const +WXHMETAFILE wxBitmap::GetPict( bool *created ) const { - wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); + wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); - PicHandle picture; // This is the returned picture - - // If bitmap already in Pict format return pointer - if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) { - return M_BITMAPDATA->m_hPict; - } - else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) { - // Invalid bitmap - return NULL; - } - - RGBColor gray = { 0xCCCC ,0xCCCC , 0xCCCC } ; - RGBColor white = { 0xffff ,0xffff , 0xffff } ; - RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ; - CGrafPtr origPort; - GDHandle origDev ; - wxMask *mask; - Rect portRect ; - - GetPortBounds( (GWorldPtr) GetHBITMAP() , &portRect ) ; - int width = portRect.right - portRect.left ; - int height = portRect.bottom - portRect.top ; - - LockPixels( GetGWorldPixMap( (GWorldPtr) GetHBITMAP() ) ) ; - GetGWorld( &origPort , &origDev ) ; - - mask = GetMask(); - - SetGWorld( (GWorldPtr) GetHBITMAP() , NULL ) ; - - picture = OpenPicture(&portRect); // open a picture, this disables drawing - if(!picture) { - return NULL; - } - - if( mask ) - { -#ifdef __DARWIN__ - RGBColor trans = white; -#else - RGBBackColor( &gray ); - EraseRect( &portRect ); - RGBColor trans = gray; -#endif - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - PenMode(transparent); - - for ( int y = 0 ; y < height ; ++y ) - { - for( int x = 0 ; x < width ; ++x ) - { - if ( !mask->PointMasked(x,y) ) - { - RGBColor col ; - - GetCPixel( x + portRect.left , y + portRect.top , &col ) ; - SetCPixel( x + portRect.left , y + portRect.top , &col ) ; - } - else { - // With transparency this sets a blank pixel - SetCPixel( x + portRect.left , y + portRect.top , &trans); - } - } - } - } - else - { - RGBBackColor( &gray ) ; - EraseRect(&portRect); - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - - CopyBits(GetPortBitMapForCopyBits( (GWorldPtr) GetHBITMAP()), - // src PixMap - we copy image over itself - - GetPortBitMapForCopyBits( (GWorldPtr) GetHBITMAP()), - // dst PixMap - no drawing occurs - &portRect, // srcRect - it will be recorded and compressed - - &portRect, // dstRect - into the picture that is open - - srcCopy,NULL); // copyMode and no clip region - } - ClosePicture(); // We are done recording the picture - UnlockPixels( GetGWorldPixMap( (GWorldPtr) GetHBITMAP() ) ) ; - SetGWorld( origPort , origDev ) ; - - return picture; // return our groovy pict handle + PicHandle picture = NULL ; // This is the returned picture + if ( created ) + (*created) = false ; + // If bitmap already in Pict format return pointer + if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) { + return M_BITMAPDATA->m_hPict; + } + else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) { + // Invalid bitmap + return NULL; + } + else + { + if ( GetMask() ) + { + picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , MAC_WXHBITMAP(GetMask()->GetMaskBitmap() ) ) ; + } + else + { + picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , NULL ) ; + } + if ( created && picture ) + (*created) = true ; + } + return picture ; } /* diff --git a/src/mac/carbon/bitmap.cpp b/src/mac/carbon/bitmap.cpp index cd1c398c99..f88e89343b 100644 --- a/src/mac/carbon/bitmap.cpp +++ b/src/mac/carbon/bitmap.cpp @@ -369,43 +369,46 @@ wxBitmapRefData::wxBitmapRefData() // TODO move this to a public function of Bitmap Ref static void DisposeBitmapRefData(wxBitmapRefData *data) { - switch (data->m_bitmapType) - { - case kMacBitmapTypePict : - { - if ( data->m_hPict ) - { - KillPicture( MAC_WXHMETAFILE( data->m_hPict ) ) ; - data->m_hPict = NULL ; - } - } - break ; - case kMacBitmapTypeGrafWorld : - { - if ( data->m_hBitmap ) - { - wxMacDestroyGWorld( MAC_WXHBITMAP(data->m_hBitmap) ) ; - data->m_hBitmap = NULL ; - } - } - break ; - case kMacBitmapTypeIcon : - if ( data->m_hIcon ) - { - DisposeCIcon( MAC_WXHICON(data->m_hIcon) ) ; - data->m_hIcon = NULL ; - } - - default : - // unkown type ? - break ; - } + if ( !data ) + return ; + + switch (data->m_bitmapType) + { + case kMacBitmapTypePict : + { + if ( data->m_hPict ) + { + KillPicture( MAC_WXHMETAFILE( data->m_hPict ) ) ; + data->m_hPict = NULL ; + } + } + break ; + case kMacBitmapTypeGrafWorld : + { + if ( data->m_hBitmap ) + { + wxMacDestroyGWorld( MAC_WXHBITMAP(data->m_hBitmap) ) ; + data->m_hBitmap = NULL ; + } + } + break ; + case kMacBitmapTypeIcon : + if ( data->m_hIcon ) + { + DisposeCIcon( MAC_WXHICON(data->m_hIcon) ) ; + data->m_hIcon = NULL ; + } + + default : + // unkown type ? + break ; + } - if (data->m_bitmapMask) - { - delete data->m_bitmapMask; - data->m_bitmapMask = NULL; - } + if (data->m_bitmapMask) + { + delete data->m_bitmapMask; + data->m_bitmapMask = NULL; + } } wxBitmapRefData::~wxBitmapRefData() @@ -637,11 +640,38 @@ int wxBitmap::GetBitmapType() const void wxBitmap::SetHBITMAP(WXHBITMAP bmp) { - DisposeBitmapRefData( M_BITMAPDATA ) ; + if (!M_BITMAPDATA) + m_refData = new wxBitmapRefData; + else + DisposeBitmapRefData( M_BITMAPDATA ) ; M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ; M_BITMAPDATA->m_hBitmap = bmp ; - M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ; + M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ; +} + +void wxBitmap::SetHICON(WXHICON ico) +{ + if (!M_BITMAPDATA) + m_refData = new wxBitmapRefData; + else + DisposeBitmapRefData( M_BITMAPDATA ) ; + + M_BITMAPDATA->m_bitmapType = kMacBitmapTypeIcon ; + M_BITMAPDATA->m_hIcon = ico ; + M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hIcon != NULL ) ; +} + +void wxBitmap::SetPict(WXHMETAFILE pict) +{ + if (!M_BITMAPDATA) + m_refData = new wxBitmapRefData; + else + DisposeBitmapRefData( M_BITMAPDATA ) ; + + M_BITMAPDATA->m_bitmapType = kMacBitmapTypePict ; + M_BITMAPDATA->m_hPict = pict ; + M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hPict != NULL ) ; } bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type) @@ -1006,96 +1036,35 @@ WXHBITMAP wxBitmap::GetHBITMAP() const return MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap); } -WXHMETAFILE wxBitmap::GetPict() const +WXHMETAFILE wxBitmap::GetPict( bool *created ) const { - wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); + wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") ); - PicHandle picture; // This is the returned picture - - // If bitmap already in Pict format return pointer - if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) { - return M_BITMAPDATA->m_hPict; - } - else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) { - // Invalid bitmap - return NULL; - } - - RGBColor gray = { 0xCCCC ,0xCCCC , 0xCCCC } ; - RGBColor white = { 0xffff ,0xffff , 0xffff } ; - RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ; - CGrafPtr origPort; - GDHandle origDev ; - wxMask *mask; - Rect portRect ; - - GetPortBounds( (GWorldPtr) GetHBITMAP() , &portRect ) ; - int width = portRect.right - portRect.left ; - int height = portRect.bottom - portRect.top ; - - LockPixels( GetGWorldPixMap( (GWorldPtr) GetHBITMAP() ) ) ; - GetGWorld( &origPort , &origDev ) ; - - mask = GetMask(); - - SetGWorld( (GWorldPtr) GetHBITMAP() , NULL ) ; - - picture = OpenPicture(&portRect); // open a picture, this disables drawing - if(!picture) { - return NULL; - } - - if( mask ) - { -#ifdef __DARWIN__ - RGBColor trans = white; -#else - RGBBackColor( &gray ); - EraseRect( &portRect ); - RGBColor trans = gray; -#endif - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - PenMode(transparent); - - for ( int y = 0 ; y < height ; ++y ) - { - for( int x = 0 ; x < width ; ++x ) - { - if ( !mask->PointMasked(x,y) ) - { - RGBColor col ; - - GetCPixel( x + portRect.left , y + portRect.top , &col ) ; - SetCPixel( x + portRect.left , y + portRect.top , &col ) ; - } - else { - // With transparency this sets a blank pixel - SetCPixel( x + portRect.left , y + portRect.top , &trans); - } - } - } - } - else - { - RGBBackColor( &gray ) ; - EraseRect(&portRect); - RGBForeColor( &black ) ; - RGBBackColor( &white ) ; - - CopyBits(GetPortBitMapForCopyBits( (GWorldPtr) GetHBITMAP()), - // src PixMap - we copy image over itself - - GetPortBitMapForCopyBits( (GWorldPtr) GetHBITMAP()), - // dst PixMap - no drawing occurs - &portRect, // srcRect - it will be recorded and compressed - - &portRect, // dstRect - into the picture that is open - - srcCopy,NULL); // copyMode and no clip region - } - ClosePicture(); // We are done recording the picture - UnlockPixels( GetGWorldPixMap( (GWorldPtr) GetHBITMAP() ) ) ; - SetGWorld( origPort , origDev ) ; - - return picture; // return our groovy pict handle + PicHandle picture = NULL ; // This is the returned picture + if ( created ) + (*created) = false ; + // If bitmap already in Pict format return pointer + if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) { + return M_BITMAPDATA->m_hPict; + } + else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) { + // Invalid bitmap + return NULL; + } + else + { + if ( GetMask() ) + { + picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , MAC_WXHBITMAP(GetMask()->GetMaskBitmap() ) ) ; + } + else + { + picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , NULL ) ; + } + if ( created && picture ) + (*created) = true ; + } + return picture ; } /* diff --git a/src/mac/carbon/dataobj.cpp b/src/mac/carbon/dataobj.cpp index c2f75326c0..3d6437c7b7 100644 --- a/src/mac/carbon/dataobj.cpp +++ b/src/mac/carbon/dataobj.cpp @@ -230,8 +230,10 @@ wxBitmapDataObject::wxBitmapDataObject( : wxBitmapDataObjectBase(rBitmap) { Init(); - - DoConvertToPng(); + if ( m_bitmap.Ok() ) + { + m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ; + } } wxBitmapDataObject::~wxBitmapDataObject() @@ -243,65 +245,61 @@ void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap ) { - ClearAll(); + Clear(); wxBitmapDataObjectBase::SetBitmap(rBitmap); - DoConvertToPng(); + if ( m_bitmap.Ok() ) + { + m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ; + } +} + +void wxBitmapDataObject::Init() +{ + m_pictHandle = NULL ; + m_pictCreated = false ; +} + +void wxBitmapDataObject::Clear() +{ + if ( m_pictCreated && m_pictHandle ) + { + KillPicture( (PicHandle) m_pictHandle ) ; + } + m_pictHandle = NULL ; } bool wxBitmapDataObject::GetDataHere( void* pBuf ) const { - if (!m_pngSize) + if (!m_pictHandle) { wxFAIL_MSG(wxT("attempt to copy empty bitmap failed")); return FALSE; } - memcpy(pBuf, m_pngData, m_pngSize); + memcpy(pBuf, *(Handle)m_pictHandle, GetHandleSize((Handle)m_pictHandle)); return TRUE; } +size_t wxBitmapDataObject::GetDataSize() const +{ + return GetHandleSize((Handle)m_pictHandle) ; +} + bool wxBitmapDataObject::SetData( size_t nSize , const void* pBuf ) { Clear(); - m_pngSize = nSize; - m_pngData = malloc(m_pngSize); - - memcpy(m_pngData, pBuf, m_pngSize); - - wxMemoryInputStream vMstream((char*)m_pngData, m_pngSize); - wxImage vImage; - wxPNGHandler vHandler; - - if (!vHandler.LoadFile(&vImage, vMstream)) - { - return FALSE; - } - - m_bitmap = wxBitmap( vImage ) ; + PicHandle picHandle = (PicHandle) NewHandle( nSize ) ; + memcpy( *picHandle , pBuf , nSize ) ; + m_pictHandle = picHandle ; + m_pictCreated = false ; + Rect frame = (**picHandle).picFrame ; + + m_bitmap.SetPict( picHandle ) ; + m_bitmap.SetWidth( frame.right - frame.left ) ; + m_bitmap.SetHeight( frame.bottom - frame.top ) ; return m_bitmap.Ok(); } - -void wxBitmapDataObject::DoConvertToPng() -{ - if (!m_bitmap.Ok()) - return; - - wxCHECK_RET( wxImage::FindHandler(wxBITMAP_TYPE_PNG) != NULL, - wxT("You must call wxImage::AddHandler(new wxPNGHandler); to be able to use clipboard with bitmaps!") ); - - wxImage image = m_bitmap.ConvertToImage(); - - wxCountingOutputStream count; - image.SaveFile(count, wxBITMAP_TYPE_PNG); - - m_pngSize = count.GetSize() + 100; // sometimes the size seems to vary ??? - m_pngData = malloc(m_pngSize); - - wxMemoryOutputStream mstream((char*) m_pngData, m_pngSize); - image.SaveFile(mstream, wxBITMAP_TYPE_PNG); -} - diff --git a/src/mac/dataobj.cpp b/src/mac/dataobj.cpp index c2f75326c0..3d6437c7b7 100644 --- a/src/mac/dataobj.cpp +++ b/src/mac/dataobj.cpp @@ -230,8 +230,10 @@ wxBitmapDataObject::wxBitmapDataObject( : wxBitmapDataObjectBase(rBitmap) { Init(); - - DoConvertToPng(); + if ( m_bitmap.Ok() ) + { + m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ; + } } wxBitmapDataObject::~wxBitmapDataObject() @@ -243,65 +245,61 @@ void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap ) { - ClearAll(); + Clear(); wxBitmapDataObjectBase::SetBitmap(rBitmap); - DoConvertToPng(); + if ( m_bitmap.Ok() ) + { + m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ; + } +} + +void wxBitmapDataObject::Init() +{ + m_pictHandle = NULL ; + m_pictCreated = false ; +} + +void wxBitmapDataObject::Clear() +{ + if ( m_pictCreated && m_pictHandle ) + { + KillPicture( (PicHandle) m_pictHandle ) ; + } + m_pictHandle = NULL ; } bool wxBitmapDataObject::GetDataHere( void* pBuf ) const { - if (!m_pngSize) + if (!m_pictHandle) { wxFAIL_MSG(wxT("attempt to copy empty bitmap failed")); return FALSE; } - memcpy(pBuf, m_pngData, m_pngSize); + memcpy(pBuf, *(Handle)m_pictHandle, GetHandleSize((Handle)m_pictHandle)); return TRUE; } +size_t wxBitmapDataObject::GetDataSize() const +{ + return GetHandleSize((Handle)m_pictHandle) ; +} + bool wxBitmapDataObject::SetData( size_t nSize , const void* pBuf ) { Clear(); - m_pngSize = nSize; - m_pngData = malloc(m_pngSize); - - memcpy(m_pngData, pBuf, m_pngSize); - - wxMemoryInputStream vMstream((char*)m_pngData, m_pngSize); - wxImage vImage; - wxPNGHandler vHandler; - - if (!vHandler.LoadFile(&vImage, vMstream)) - { - return FALSE; - } - - m_bitmap = wxBitmap( vImage ) ; + PicHandle picHandle = (PicHandle) NewHandle( nSize ) ; + memcpy( *picHandle , pBuf , nSize ) ; + m_pictHandle = picHandle ; + m_pictCreated = false ; + Rect frame = (**picHandle).picFrame ; + + m_bitmap.SetPict( picHandle ) ; + m_bitmap.SetWidth( frame.right - frame.left ) ; + m_bitmap.SetHeight( frame.bottom - frame.top ) ; return m_bitmap.Ok(); } - -void wxBitmapDataObject::DoConvertToPng() -{ - if (!m_bitmap.Ok()) - return; - - wxCHECK_RET( wxImage::FindHandler(wxBITMAP_TYPE_PNG) != NULL, - wxT("You must call wxImage::AddHandler(new wxPNGHandler); to be able to use clipboard with bitmaps!") ); - - wxImage image = m_bitmap.ConvertToImage(); - - wxCountingOutputStream count; - image.SaveFile(count, wxBITMAP_TYPE_PNG); - - m_pngSize = count.GetSize() + 100; // sometimes the size seems to vary ??? - m_pngData = malloc(m_pngSize); - - wxMemoryOutputStream mstream((char*) m_pngData, m_pngSize); - image.SaveFile(mstream, wxBITMAP_TYPE_PNG); -} - -- 2.45.2