diff options
author | Rüdiger Timm <rt@openoffice.org> | 2004-05-21 13:38:36 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2004-05-21 13:38:36 +0000 |
commit | b069f933caebdedb4d4dd4e99c2dbbccd62bc85c (patch) | |
tree | c6820333c67e8f95569634616bce30267fbdfe48 /vcl/source | |
parent | e394b447585e5c60b18ee6e9b2c459cb71e2fcd3 (diff) |
INTEGRATION: CWS bmpres01 (1.9.34); FILE MERGED
2004/04/27 13:28:04 ka 1.9.34.7: using new image resource structure
2004/04/23 14:39:41 ka 1.9.34.6: added support for ZIPped image directory
2004/04/21 14:25:36 ka 1.9.34.5: added support for external compressed image tree
2004/04/15 11:48:58 ka 1.9.34.4: added support for MONOCHROME_BLACK AND ..._WHITE images/bitmaps
2004/02/18 09:58:55 ka 1.9.34.3: #i22149#: added support for alpha masks
2004/02/12 11:39:37 ka 1.9.34.2: #i22149# support for alpha masks
2004/02/11 16:15:08 ka 1.9.34.1: #i22149#: added alpha mask support for Images/ImageLists
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/gdi/image.cxx | 1842 |
1 files changed, 785 insertions, 1057 deletions
diff --git a/vcl/source/gdi/image.cxx b/vcl/source/gdi/image.cxx index 8d06142ffe59..26d1635fe271 100644 --- a/vcl/source/gdi/image.cxx +++ b/vcl/source/gdi/image.cxx @@ -2,9 +2,9 @@ * * $RCSfile: image.cxx,v $ * - * $Revision: 1.9 $ + * $Revision: 1.10 $ * - * last change: $Author: vg $ $Date: 2004-01-06 13:41:07 $ + * last change: $Author: rt $ $Date: 2004-05-21 14:38:36 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -59,15 +59,12 @@ * ************************************************************************/ -#include <string.h> - #ifndef _DEBUG_HXX #include <tools/debug.hxx> #endif #ifndef _STREAM_HXX #include <tools/stream.hxx> #endif - #ifndef _SV_RC_H #include <tools/rc.h> #endif @@ -83,292 +80,144 @@ #ifndef _SV_OUTDEV_HXX #include <outdev.hxx> #endif +#ifndef _SV_IMPIMAGETREE_H +#include <impimagetree.hxx> +#endif #ifndef _SV_IMAGE_H #include <image.h> #endif -#define private public #ifndef _SV_IMAGE_HXX #include <image.hxx> #endif -#undef private - -// ======================================================================= DBG_NAME( Image ); DBG_NAME( ImageList ); -#define IMAGE_FILE_VERSION 100 - -// ======================================================================= - -ImplImageList::~ImplImageList() -{ - if ( mpImageBitmap ) - delete mpImageBitmap; - delete[] mpAry; -} - -// ======================================================================= - -ImplImageRefData::~ImplImageRefData() -{ - mpImplData->mnIRefCount--; - if ( mpImplData->mnRefCount || mpImplData->mnIRefCount ) - { - mpImplData->mpAry[mnIndex].mnRefCount--; - if ( !mpImplData->mpAry[mnIndex].mnRefCount ) - mpImplData->mnRealCount--; - } - else - delete mpImplData; -} - -// ----------------------------------------------------------------------- - -BOOL ImplImageRefData::IsEqual( const ImplImageRefData& rData ) -{ - if ( (mpImplData == rData.mpImplData) && (mnIndex == rData.mnIndex) ) - return TRUE; - else - return FALSE; -} - -// ======================================================================= - -ImplImageData::ImplImageData( const Bitmap& rBmp, const Bitmap& rMaskBmp ) : - maBmp( rBmp ), - maMaskBmp( rMaskBmp ) -{ - mbColor = FALSE; - mpImageBitmap = NULL; -} - -// ----------------------------------------------------------------------- - -ImplImageData::ImplImageData( const Bitmap& rBmp, const Color& rColor ) : - maBmp( rBmp ), - maColor( rColor ) -{ - mbColor = TRUE; - mpImageBitmap = NULL; -} - -// ----------------------------------------------------------------------- - -ImplImageData::~ImplImageData() -{ - if ( mpImageBitmap ) - delete mpImageBitmap; -} - -// ----------------------------------------------------------------------- - -BOOL ImplImageData::IsEqual( const ImplImageData& rData ) -{ - if ( (maBmp == rData.maBmp) && (maMaskBmp == rData.maMaskBmp) && - (maColor == rData.maColor) && (mbColor == rData.mbColor) ) - return TRUE; - else - return FALSE; -} - -// ======================================================================= +#define IMAGE_FILE_VERSION 100 -ImplImage::~ImplImage() -{ - switch ( meType ) - { - case IMAGETYPE_BITMAP: - delete (Bitmap*)mpData; - break; +// --------- +// - Image - +// --------- - case IMAGETYPE_IMAGE: - delete (ImplImageData*)mpData; - break; - - case IMAGETYPE_IMAGEREF: - delete (ImplImageRefData*)mpData; - break; - } -} - -// ======================================================================= - -Image::Image() +Image::Image() : + mpImplData( NULL ) { DBG_CTOR( Image, NULL ); - - mpImplData = NULL; } // ----------------------------------------------------------------------- -Image::Image( const ResId& rResId ) +Image::Image( const ResId& rResId ) : + mpImplData( NULL ) { DBG_CTOR( Image, NULL ); rResId.SetRT( RSC_IMAGE ); + ResMgr* pResMgr = rResId.GetResMgr(); - if ( !pResMgr ) + + if( !pResMgr ) pResMgr = Resource::GetResManager(); - if ( pResMgr->GetResource( rResId ) ) + if( pResMgr->GetResource( rResId ) ) { - // Header ueberspringen pResMgr->Increment( sizeof( RSHEADER_TYPE ) ); - USHORT nObjMask = pResMgr->ReadShort(); + BitmapEx aBmpEx; + USHORT nObjMask = pResMgr->ReadShort(); - Bitmap aImageBitmap; - Bitmap aMaskBitmap; - Color aMaskColor; if( nObjMask & RSC_IMAGE_IMAGEBITMAP ) { - aImageBitmap = Bitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - } - if( nObjMask & RSC_IMAGE_MASKBITMAP ) - { - aMaskBitmap = Bitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - } - if( nObjMask & RSC_IMAGE_MASKCOLOR ) - { - aMaskColor = Color( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); + aBmpEx = BitmapEx( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); } - if ( !aImageBitmap ) - mpImplData = NULL; - else + if( !aBmpEx.IsEmpty() ) { - mpImplData = new ImplImage; - mpImplData->mnRefCount = 1; - if ( !aMaskBitmap ) + if( nObjMask & RSC_IMAGE_MASKBITMAP ) { - if( nObjMask & RSC_IMAGE_MASKCOLOR ) + if( aBmpEx.GetTransparentType() == TRANSPARENT_NONE ) { - mpImplData->meType = IMAGETYPE_IMAGE; - mpImplData->mpData = new ImplImageData( aImageBitmap, aMaskColor ); + const Bitmap aMaskBitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); + aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskBitmap ); } - else - { - mpImplData->meType = IMAGETYPE_BITMAP; - mpImplData->mpData = new Bitmap( aImageBitmap ); - } + + pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); } - else + + if( nObjMask & RSC_IMAGE_MASKCOLOR ) { - mpImplData->meType = IMAGETYPE_IMAGE; - mpImplData->mpData = new ImplImageData( aImageBitmap, aMaskBitmap ); + if( aBmpEx.GetTransparentType() == TRANSPARENT_NONE ) + { + const Color aMaskColor( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); + aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskColor ); + } + + pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); } + + ImplInit( aBmpEx ); } } else { DBG_ERROR( "Image::Image( const ResId& rResId ): No resource!" ); - mpImplData = NULL; } } // ----------------------------------------------------------------------- -Image::Image( const Image& rImage ) +Image::Image( const Image& rImage ) : + mpImplData( rImage.mpImplData ) { DBG_CTOR( Image, NULL ); - mpImplData = rImage.mpImplData; - if ( mpImplData ) - mpImplData->mnRefCount++; + if( mpImplData ) + ++mpImplData->mnRefCount; } // ----------------------------------------------------------------------- -Image::Image( const Bitmap& rBitmap ) +Image::Image( const BitmapEx& rBitmapEx ) : + mpImplData( NULL ) { DBG_CTOR( Image, NULL ); - if ( !rBitmap ) - mpImplData = NULL; - else - { - mpImplData = new ImplImage; - mpImplData->mnRefCount = 1; - mpImplData->meType = IMAGETYPE_BITMAP; - mpImplData->mpData = new Bitmap( rBitmap ); - } + ImplInit( rBitmapEx ); } // ----------------------------------------------------------------------- -Image::Image( const Bitmap& rBitmap, const Bitmap& rMaskBitmap ) +Image::Image( const Bitmap& rBitmap ) : + mpImplData( NULL ) { DBG_CTOR( Image, NULL ); - if ( !rBitmap ) - mpImplData = NULL; - else - { - mpImplData = new ImplImage; - mpImplData->mnRefCount = 1; - if ( !rMaskBitmap ) - { - mpImplData->meType = IMAGETYPE_BITMAP; - mpImplData->mpData = new Bitmap( rBitmap ); - } - else - { - mpImplData->meType = IMAGETYPE_IMAGE; - mpImplData->mpData = new ImplImageData( rBitmap, rMaskBitmap ); - } - } + ImplInit( rBitmap ); } // ----------------------------------------------------------------------- -Image::Image( const Bitmap& rBitmap, const Color& rColor ) +Image::Image( const Bitmap& rBitmap, const Bitmap& rMaskBitmap ) : + mpImplData( NULL ) { DBG_CTOR( Image, NULL ); - if ( !rBitmap ) - mpImplData = NULL; - else - { - mpImplData = new ImplImage; - mpImplData->mnRefCount = 1; - mpImplData->meType = IMAGETYPE_IMAGE; - mpImplData->mpData = new ImplImageData( rBitmap, rColor ); - } + const BitmapEx aBmpEx( rBitmap, rMaskBitmap ); + + ImplInit( aBmpEx ); } // ----------------------------------------------------------------------- -Image::Image( const BitmapEx& rBitmapEx ) +Image::Image( const Bitmap& rBitmap, const Color& rColor ) : + mpImplData( NULL ) { DBG_CTOR( Image, NULL ); - const Bitmap aBmp( rBitmapEx.GetBitmap() ); + const BitmapEx aBmpEx( rBitmap, rColor ); - if( !aBmp ) - mpImplData = NULL; - else - { - const Bitmap aMask( rBitmapEx.GetMask() ); - - mpImplData = new ImplImage; - mpImplData->mnRefCount = 1; - - if( !aMask ) - { - mpImplData->meType = IMAGETYPE_BITMAP; - mpImplData->mpData = new Bitmap( aBmp ); - } - else - { - mpImplData->meType = IMAGETYPE_IMAGE; - mpImplData->mpData = new ImplImageData( aBmp, aMask ); - } - } + ImplInit( aBmpEx ); } // ----------------------------------------------------------------------- @@ -377,175 +226,92 @@ Image::~Image() { DBG_DTOR( Image, NULL ); - if ( mpImplData ) - { - if ( mpImplData->mnRefCount > 1 ) - mpImplData->mnRefCount--; - else - delete mpImplData; - } + if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) + delete mpImplData; } // ----------------------------------------------------------------------- -Size Image::GetSizePixel() const +void Image::ImplInit( const BitmapEx& rBmpEx ) { - DBG_CHKTHIS( Image, NULL ); - - if ( mpImplData ) + if( !rBmpEx.IsEmpty() ) { - switch ( mpImplData->meType ) - { - case IMAGETYPE_BITMAP: - return ((Bitmap*)mpImplData->mpData)->GetSizePixel(); - - case IMAGETYPE_IMAGE: - return ((ImplImageData*)mpImplData->mpData)->maBmp.GetSizePixel(); - - case IMAGETYPE_IMAGEREF: - return ((ImplImageRefData*)mpImplData->mpData)->mpImplData->maImageSize; - } - } - - return Size(); -} - -// ----------------------------------------------------------------------- - -Bitmap Image::GetBitmap() const -{ - DBG_CHKTHIS( Image, NULL ); + mpImplData = new ImplImage; + mpImplData->mnRefCount = 1; - if ( mpImplData ) - { - switch ( mpImplData->meType ) + if( rBmpEx.GetTransparentType() == TRANSPARENT_NONE ) { - case IMAGETYPE_BITMAP: - return *((Bitmap*)mpImplData->mpData); - - case IMAGETYPE_IMAGE: - return ((ImplImageData*)mpImplData->mpData)->maBmp; - - case IMAGETYPE_IMAGEREF: - { - ImplImageRefData* pData = (ImplImageRefData*)mpImplData->mpData; - return pData->mpImplData->mpImageBitmap->GetBitmap( 1, &pData->mnIndex ); - } + mpImplData->meType = IMAGETYPE_BITMAP; + mpImplData->mpData = new Bitmap( rBmpEx.GetBitmap() ); } - } - - return Bitmap(); -} - -// ----------------------------------------------------------------------- - -Bitmap Image::GetMaskBitmap() const -{ - DBG_CHKTHIS( Image, NULL ); - - if ( mpImplData ) - { - switch ( mpImplData->meType ) + else { - case IMAGETYPE_BITMAP: - return Bitmap(); - - case IMAGETYPE_IMAGE: - return ((ImplImageData*)mpImplData->mpData)->maMaskBmp; - - case IMAGETYPE_IMAGEREF: - { - ImplImageRefData* pData = (ImplImageRefData*)mpImplData->mpData; - if( pData->mpImplData->mpImageBitmap->HasMaskBitmap() ) - return pData->mpImplData->mpImageBitmap->GetMaskBitmap( 1, &pData->mnIndex ); - else - return Bitmap(); - } + mpImplData->meType = IMAGETYPE_IMAGE; + mpImplData->mpData = new ImplImageData( rBmpEx ); } } - - return Bitmap(); } // ----------------------------------------------------------------------- -BOOL Image::HasMaskBitmap() const +Size Image::GetSizePixel() const { DBG_CHKTHIS( Image, NULL ); - if ( mpImplData ) - { - switch ( mpImplData->meType ) - { - case IMAGETYPE_BITMAP: - return FALSE; + Size aRet; - case IMAGETYPE_IMAGE: - return !!((ImplImageData*)mpImplData->mpData)->maMaskBmp; - - case IMAGETYPE_IMAGEREF: - { - ImplImageRefData* pData = (ImplImageRefData*)mpImplData->mpData; - return pData->mpImplData->mpImageBitmap->HasMaskBitmap(); - } - } - } - - return FALSE; -} - -// ----------------------------------------------------------------------- - -BOOL Image::HasMaskColor() const -{ - DBG_CHKTHIS( Image, NULL ); - - if ( mpImplData ) + if( mpImplData ) { - switch ( mpImplData->meType ) + switch( mpImplData->meType ) { case IMAGETYPE_BITMAP: - return FALSE; + aRet = static_cast< Bitmap* >( mpImplData->mpData )->GetSizePixel(); + break; case IMAGETYPE_IMAGE: - return ((ImplImageData*)mpImplData->mpData)->mbColor; + aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx.GetSizePixel(); + break; case IMAGETYPE_IMAGEREF: - { - ImplImageRefData* pData = (ImplImageRefData*)mpImplData->mpData; - return pData->mpImplData->mpImageBitmap->HasMaskColor(); - } + aRet = static_cast< ImplImageRefData* >( mpImplData->mpData )->mpImplData->maImageSize; + break; } } - return FALSE; + return aRet; } // ----------------------------------------------------------------------- -Color Image::GetMaskColor() const +BitmapEx Image::GetBitmapEx() const { DBG_CHKTHIS( Image, NULL ); - if ( mpImplData ) + BitmapEx aRet; + + if( mpImplData ) { - switch ( mpImplData->meType ) + switch( mpImplData->meType ) { case IMAGETYPE_BITMAP: - return Color(); + aRet = *static_cast< Bitmap* >( mpImplData->mpData ); + break; case IMAGETYPE_IMAGE: - return ((ImplImageData*)mpImplData->mpData)->maColor; + aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx; + break; case IMAGETYPE_IMAGEREF: - { - ImplImageRefData* pData = (ImplImageRefData*)mpImplData->mpData; - return pData->mpImplData->mpImageBitmap->GetMaskColor(); - } + { + ImplImageRefData* pData = static_cast< ImplImageRefData* >( mpImplData->mpData ); + + aRet = pData->mpImplData->mpImageBitmap->GetBitmapEx( 1, &pData->mnIndex ); + } + break; } } - return Color(); + return aRet; } // ----------------------------------------------------------------------- @@ -556,11 +322,11 @@ Image Image::GetColorTransformedImage( ImageColorTransform eColorTransform ) con Image aRet; - if( IMAGECOLORTRANSFORM_NONE != eColorTransform ) + if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform ) { - Bitmap aBmp( GetBitmap() ); + BitmapEx aBmpEx( GetBitmapEx() ); - if( !aBmp.IsEmpty() ) + if( !aBmpEx.IsEmpty() ) { Color* pSrcColors = NULL; Color* pDstColors = NULL; @@ -570,34 +336,22 @@ Image Image::GetColorTransformedImage( ImageColorTransform eColorTransform ) con if( nColorCount && pSrcColors && pDstColors ) { - aBmp.Replace( pSrcColors, pDstColors, nColorCount ); - - if( HasMaskBitmap() ) - aRet = Image( aBmp, GetMaskBitmap() ); - else if( HasMaskColor() ) - { - Color aMaskColor( GetMaskColor() ); - BOOL bDone = FALSE; - - for( ULONG i = 0; ( i < nColorCount ) && !bDone; i++ ) - { - if( aMaskColor == pSrcColors[ i ] ) - { - aMaskColor = pDstColors[ i ]; - bDone = TRUE; - } - } - - aRet = Image( aBmp, aMaskColor ); - } - else - aRet = Image( aBmp ); + aBmpEx.Replace( pSrcColors, pDstColors, nColorCount ); + aRet = Image( aBmpEx ); } delete[] pSrcColors; delete[] pDstColors; } } + else if( IMAGECOLORTRANSFORM_MONOCHROME_BLACK == eColorTransform || + IMAGECOLORTRANSFORM_MONOCHROME_WHITE == eColorTransform ) + { + BitmapEx aBmpEx( GetBitmapEx() ); + + if( !aBmpEx.IsEmpty() ) + aRet = Image( aBmpEx.GetColorTransformedBitmapEx( static_cast< BmpColorMode >( eColorTransform ) ) ); + } if( !aRet ) aRet = *this; @@ -642,20 +396,12 @@ Image& Image::operator=( const Image& rImage ) DBG_CHKTHIS( Image, NULL ); DBG_CHKOBJ( &rImage, Image, NULL ); - // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann - if ( rImage.mpImplData ) - rImage.mpImplData->mnRefCount++; + if( rImage.mpImplData ) + ++rImage.mpImplData->mnRefCount; - // Abkoppeln - if ( mpImplData ) - { - if ( mpImplData->mnRefCount > 1 ) - mpImplData->mnRefCount--; - else - delete mpImplData; - } + if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) + delete mpImplData; - // Neue Daten zuweisen mpImplData = rImage.mpImplData; return *this; @@ -668,294 +414,278 @@ BOOL Image::operator==( const Image& rImage ) const DBG_CHKTHIS( Image, NULL ); DBG_CHKOBJ( &rImage, Image, NULL ); - if ( rImage.mpImplData == mpImplData ) - return TRUE; - if ( !rImage.mpImplData || !mpImplData ) - return FALSE; - - if ( rImage.mpImplData->mpData == mpImplData->mpData ) - return TRUE; + BOOL bRet; - if ( rImage.mpImplData->meType == mpImplData->meType ) + if( rImage.mpImplData == mpImplData ) + bRet = true; + else if( !rImage.mpImplData || !mpImplData ) + bRet = false; + else if( rImage.mpImplData->mpData == mpImplData->mpData ) + bRet = true; + else if( rImage.mpImplData->meType == mpImplData->meType ) { - switch ( mpImplData->meType ) + switch( mpImplData->meType ) { case IMAGETYPE_BITMAP: - if ( *((Bitmap*)rImage.mpImplData->mpData) == *((Bitmap*)mpImplData->mpData) ) - return TRUE; - break; + bRet = ( *static_cast< Bitmap* >( rImage.mpImplData->mpData ) == *static_cast< Bitmap* >( mpImplData->mpData ) ); + break; case IMAGETYPE_IMAGE: - if ( ((ImplImageData*)rImage.mpImplData->mpData)->IsEqual( *((ImplImageData*)mpImplData->mpData) ) ) - return TRUE; - break; + bRet = static_cast< ImplImageData* >( rImage.mpImplData->mpData )->IsEqual( *static_cast< ImplImageData* >( mpImplData->mpData ) ); + break; case IMAGETYPE_IMAGEREF: - if ( ((ImplImageRefData*)rImage.mpImplData->mpData)->IsEqual( *((ImplImageRefData*)mpImplData->mpData) ) ) - return TRUE; - break; + bRet = static_cast< ImplImageRefData* >( rImage.mpImplData->mpData )->IsEqual( *static_cast< ImplImageRefData* >( mpImplData->mpData ) ); + break; + + default: + bRet = false; + break; } } - return FALSE; + return bRet; +} + +// ------------- +// - ImageList - +// ------------- + +ImageList::ImageList( USHORT nInit, USHORT nGrow ) : + mpImplData( NULL ), + mnInitSize( nInit ), + mnGrowSize( nGrow ) +{ + DBG_CTOR( ImageList, NULL ); } // ----------------------------------------------------------------------- -void Image::ClearCaches() +ImageList::ImageList( const ResId& rResId ) : + mpImplData( NULL ), + mnInitSize( 1 ), + mnGrowSize( 4 ) { - DBG_CHKTHIS( Image, NULL ); + DBG_CTOR( ImageList, NULL ); + + rResId.SetRT( RSC_IMAGELIST ); + + ResMgr* pResMgr = rResId.GetResMgr(); + + if( !pResMgr ) + pResMgr = Resource::GetResManager(); - if ( mpImplData ) + if( pResMgr->GetResource( rResId ) ) { - switch ( mpImplData->meType ) + pResMgr->Increment( sizeof( RSHEADER_TYPE ) ); + + static ImplImageTreeSingletonRef aImageTree; + USHORT nObjMask = pResMgr->ReadShort(); + const String aPrefix( pResMgr->ReadString() ); + Color aMaskColor; + BitmapEx aBmpEx; + + if( nObjMask & RSC_IMAGE_MASKCOLOR ) + aMaskColor = Color( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); + + pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); + + if( nObjMask & RSC_IMAGELIST_IDLIST ) { - case IMAGETYPE_IMAGE: - ImplImageBmp * pBmp - = ((ImplImageData*)mpImplData->mpData)->mpImageBitmap; - if ( pBmp ) - pBmp->ClearCaches(); - break; + const USHORT nCount = pResMgr->ReadShort(); + for( int i = 0; i < nCount; ++i ) + pResMgr->ReadShort(); + } + + ::rtl::OUString aResMgrName( pResMgr->GetFileName() ), aUserImage; + sal_Int32 nPos = aResMgrName.lastIndexOf( '\\' ); + sal_Int32 nCount = pResMgr->ReadShort(); + USHORT* pIdAry = new USHORT[ nCount ]; + String* pStringAry = new String[ nCount ]; - // nothing to do for cases IMAGETYPE_BITMAP and IMAGETYPE_IMAGEREF + // load file entry list + for( sal_Int32 i = 0; i < nCount; ++i ) + { + pStringAry[ i ] = pResMgr->ReadString(); + pIdAry[ i ] = static_cast< USHORT >( pResMgr->ReadLong() ); } - } -} -// ======================================================================= + // try to load cached image first + if( -1 == nPos ) + nPos = aResMgrName.lastIndexOf( '/' ); -static void ImplCopyImageListData( ImageList* pThis ) -{ - if ( pThis->mpImplData && pThis->mpImplData->mnRefCount > 1 ) - { - pThis->mpImplData->mnRefCount--; - - ImplImageList* pNewData = new ImplImageList; - pNewData->mnRefCount = 1; - pNewData->mnIRefCount = 0; - pNewData->mnCount = pThis->mpImplData->mnCount; - pNewData->mnRealCount = pThis->mpImplData->mnRealCount; - pNewData->mnArySize = pThis->mpImplData->mnArySize; - pNewData->mpAry = new ImageAryData[pNewData->mnArySize]; - pNewData->maImageSize = pThis->mpImplData->maImageSize; - pNewData->mpImageBitmap = new ImplImageBmp; - pNewData->mpImageBitmap->Create( pNewData->maImageSize.Width(), - pNewData->maImageSize.Height(), - pNewData->mnArySize ); - memset( pNewData->mpAry, 0, pNewData->mnArySize*sizeof(ImageAryData) ); + if( -1 != nPos++ ) + { + const sal_Int32 nSecondPos = aResMgrName.lastIndexOf( '.' ); + aUserImage = aResMgrName.copy( nPos, ( ( -1 != nSecondPos ) ? nSecondPos : aResMgrName.getLength() ) - nPos ); + } - USHORT i = 0; - USHORT n = 0; - while ( i < pThis->mpImplData->mnArySize ) + if( !aImageTree->loadImage( aUserImage += String::CreateFromInt32( rResId.GetId() ), aBmpEx ) ) { - // Nur die Images kopieren, die gebraucht werden - if ( pThis->mpImplData->mpAry[i].mnId ) - { - pNewData->mpAry[n].mnId = pThis->mpImplData->mpAry[i].mnId; - pNewData->mpAry[n].mnRefCount = 1; - pNewData->mpImageBitmap->Replace( n, - *(pThis->mpImplData->mpImageBitmap), - i ); - n++; - } + BitmapEx aWorkBmpEx; + Size aItemSizePixel; + bool bInit = false; - i++; - } + for( sal_Int32 i = 0; i < nCount; ++i ) + { + if( aImageTree->loadImage( pStringAry[ i ], aWorkBmpEx ) ) + { + const Size aWorkSizePixel( aWorkBmpEx.GetSizePixel() ); - pThis->mpImplData = pNewData; - } -} + if( !bInit ) + { + aItemSizePixel = aWorkSizePixel; + aBmpEx = Bitmap( Size( aWorkSizePixel.Width() * nCount, aWorkSizePixel.Height() ), 24 ); + bInit = true; + } -// ----------------------------------------------------------------------- + DBG_ASSERT( aItemSizePixel == aWorkSizePixel, "Differerent dimensions in ItemList images" ); -static void ImplBmpImageCreate( ImageList* pThis, - const Bitmap& rBitmap, const Bitmap& rMaskBmp, - const Color& rColor, BOOL bColor, - USHORT nInit, USHORT* mpIdAry = NULL, - USHORT nGrow = 4 ) -{ - // Falls es sich um eine leere ImageListe handelt, dann Defaul-Werte - // setzen und nichts machen - if ( !nInit ) - { - pThis->mpImplData = NULL; - pThis->mnInitSize = 1; - pThis->mnGrowSize = nGrow; - return; - } + const Rectangle aRectDst( Point( aItemSizePixel.Width() * i, 0 ), aItemSizePixel ); + const Rectangle aRectSrc( Point( 0, 0 ), aWorkSizePixel ); - DBG_ASSERT( !nInit || rBitmap.GetSizePixel().Width(), - "ImageList::ImageList(): nInitSize != 0 and BmpSize.Width() == 0" ); - DBG_ASSERT( (rBitmap.GetSizePixel().Width() % nInit) == 0, - "ImageList::ImageList(): BmpSize % nInitSize != 0" ); - DBG_ASSERT( !rMaskBmp || (rMaskBmp.GetSizePixel() == rBitmap.GetSizePixel()), - "ImageList::ImageList(): BmpSize != MaskBmpSize" ); + aBmpEx.CopyPixel( aRectDst, aRectSrc, &aWorkBmpEx ); + } #ifdef DBG_UTIL - if ( mpIdAry ) - { - for ( USHORT n1 = 0; n1 < nInit; n1++ ) - { - USHORT nId = mpIdAry[n1]; - if ( !nId ) - { - DBG_ERROR( "ImageList::ImageList(): Id == 0" ); - } - for ( USHORT n2 = 0; n2 < n1; n2++ ) - { - if ( nId == mpIdAry[n2] ) + else { - DBG_ERROR1( "ImageList::ImageList(): Double Id (%u)", nId ); + ByteString aErrorStr( "ImageList::ImageList( const ResId& rResId ): could not load image <" ); + DBG_ERROR( ( aErrorStr += ByteString( pStringAry[ i ], RTL_TEXTENCODING_ASCII_US ) ) += '>' ); } - } - } - } #endif + } - Size aBmpSize = rBitmap.GetSizePixel(); - pThis->mnInitSize = nInit; - pThis->mnGrowSize = nGrow; - pThis->mpImplData = new ImplImageList; - pThis->mpImplData->mnRefCount = 1; - pThis->mpImplData->mnIRefCount = 0; - pThis->mpImplData->mnCount = nInit; - pThis->mpImplData->mnRealCount = nInit; - pThis->mpImplData->mnArySize = nInit; - pThis->mpImplData->mpAry = new ImageAryData[nInit]; - pThis->mpImplData->maImageSize = Size( aBmpSize.Width() / nInit, aBmpSize.Height() ); - - for ( USHORT i = 0; i < nInit; i++ ) - { - if ( mpIdAry ) - pThis->mpImplData->mpAry[i].mnId = mpIdAry[i]; - else - pThis->mpImplData->mpAry[i].mnId = i+1; - pThis->mpImplData->mpAry[i].mnRefCount = 1; - } + if( !aBmpEx.IsEmpty() ) + aImageTree->addUserImage( aUserImage, aBmpEx ); + } - pThis->mpImplData->mpImageBitmap = new ImplImageBmp; - pThis->mpImplData->mpImageBitmap->Create( rBitmap, rMaskBmp, - rColor, bColor, - pThis->mpImplData->maImageSize.Width(), - pThis->mpImplData->maImageSize.Height(), - nInit ); -} + if( !aBmpEx.IsEmpty() && !aBmpEx.IsTransparent() && ( nObjMask & RSC_IMAGE_MASKCOLOR ) ) + aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskColor ); -// ======================================================================= + if( nObjMask & RSC_IMAGELIST_IDCOUNT ) + pResMgr->ReadShort(); -ImageList::ImageList( USHORT nInit, USHORT nGrow ) -{ - DBG_CTOR( ImageList, NULL ); + ImplInit( aBmpEx, nCount, pIdAry, NULL, 4 ); - mpImplData = NULL; - mnInitSize = nInit; - mnGrowSize = nGrow; + delete[] pIdAry; + delete[] pStringAry; + } } // ----------------------------------------------------------------------- -ImageList::ImageList( const ResId& rResId ) +ImageList::ImageList( const ::std::vector< ::rtl::OUString >& rNameVector, const Color* pMaskColor ) : + mpImplData( NULL ), + mnInitSize( 1 ), + mnGrowSize( 4 ) { DBG_CTOR( ImageList, NULL ); - rResId.SetRT( RSC_IMAGELIST ); - ResMgr* pResMgr = rResId.GetResMgr(); - if ( !pResMgr ) - pResMgr = Resource::GetResManager(); + static ImplImageTreeSingletonRef aImageTree; + ::rtl::OUString aProjectName; + BitmapEx aBmpEx, aWorkBmpEx; + Size aItemSizePixel; + bool bInit = false; - if ( pResMgr->GetResource( rResId ) ) + for( int i = 0; i < rNameVector.size(); ++i ) { - // Header ueberspringen - pResMgr->Increment( sizeof( RSHEADER_TYPE ) ); + if( aImageTree->loadImage( rNameVector[ i ], aWorkBmpEx ) ) + { + const Size aWorkSizePixel( aWorkBmpEx.GetSizePixel() ); - USHORT nObjMask = pResMgr->ReadShort(); + if( !bInit ) + { + aItemSizePixel = aWorkSizePixel; + aBmpEx = Bitmap( Size( aWorkSizePixel.Width() * rNameVector.size(), aWorkSizePixel.Height() ), 24 ); + bInit = true; + } - Bitmap aImageBitmap; - Bitmap aMaskBitmap; - Color aMaskColor; - BOOL bCol = FALSE; - BOOL bIsIdList = FALSE; + DBG_ASSERT( aItemSizePixel == aWorkSizePixel, "Differerent dimensions in ItemList images" ); - if ( nObjMask & RSC_IMAGELIST_IMAGEBITMAP ) - { - aImageBitmap = Bitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - } - if ( nObjMask & RSC_IMAGELIST_MASKBITMAP ) - { - aMaskBitmap = Bitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - } - if ( nObjMask & RSC_IMAGELIST_MASKCOLOR ) - { - aMaskColor = Color( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); - bCol = TRUE; - } - if ( nObjMask & RSC_IMAGELIST_IDLIST ) - { - bIsIdList = TRUE; - USHORT nCount = pResMgr->ReadShort(); - USHORT* pAry = new USHORT[ nCount ]; - for( int i = 0; i < nCount; i++ ) - pAry[ i ] = pResMgr->ReadShort(); - ImplBmpImageCreate( this, aImageBitmap, aMaskBitmap, aMaskColor, - bCol, nCount, pAry, 4 ); - delete[] pAry; + const Rectangle aRectDst( Point( aItemSizePixel.Width() * i, 0 ), aItemSizePixel ); + const Rectangle aRectSrc( Point( 0, 0 ), aWorkSizePixel ); + + aBmpEx.CopyPixel( aRectDst, aRectSrc, &aWorkBmpEx ); } - if ( nObjMask & RSC_IMAGELIST_IDCOUNT ) +#ifdef DBG_UTIL + else { - USHORT nCount = pResMgr->ReadShort(); - if ( !bIsIdList ) - { - ImplBmpImageCreate( this, aImageBitmap, aMaskBitmap, aMaskColor, - bCol, nCount, NULL, 4 ); - } + ByteString aErrorStr( "ImageList::ImageList( const ::std::vector< ::rtl::OUString >& rNameVector, const Color* pMaskColor ): could not load image <" ); + DBG_ERROR( ( aErrorStr += ByteString( aFileName, RTL_TEXTENCODING_ASCII_US ) ) += '>' ); } +#endif } + + if( !aBmpEx.IsEmpty() && !aBmpEx.IsTransparent() && pMaskColor ) + aBmpEx = BitmapEx( aBmpEx.GetBitmap(), *pMaskColor ); + + ImplInit( aBmpEx, static_cast< USHORT >( rNameVector.size() ), NULL, &rNameVector, 4 ); } // ----------------------------------------------------------------------- -ImageList::ImageList( const ImageList& rImageList ) +ImageList::ImageList( const ImageList& rImageList ) : + mpImplData( rImageList.mpImplData ), + mnInitSize( rImageList.mnInitSize ), + mnGrowSize( rImageList.mnGrowSize ) { DBG_CTOR( ImageList, NULL ); - mpImplData = rImageList.mpImplData; - if ( mpImplData ) - mpImplData->mnRefCount++; + if( mpImplData ) + ++mpImplData->mnRefCount; +} + +// ----------------------------------------------------------------------- + +ImageList::ImageList( const BitmapEx& rBitmapEx, + USHORT nInit, USHORT* pIdAry, USHORT nGrow ) : + mpImplData( NULL ), + mnInitSize( nInit ), + mnGrowSize( nGrow ) +{ + DBG_CTOR( ImageList, NULL ); + + ImplInit( rBitmapEx, nInit, pIdAry, NULL, nGrow ); } // ----------------------------------------------------------------------- ImageList::ImageList( const Bitmap& rBitmap, - USHORT nInit, USHORT* mpIdAry, USHORT nGrow ) + USHORT nInit, USHORT* pIdAry, USHORT nGrow ) : + mpImplData( NULL ), + mnInitSize( nInit ), + mnGrowSize( nGrow ) { DBG_CTOR( ImageList, NULL ); - ImplBmpImageCreate( this, rBitmap, Bitmap(), Color(), FALSE, - nInit, mpIdAry, nGrow ); + ImplInit( rBitmap, nInit, pIdAry, NULL, nGrow ); } // ----------------------------------------------------------------------- ImageList::ImageList( const Bitmap& rBitmap, const Bitmap& rMaskBmp, - USHORT nInit, USHORT* mpIdAry, USHORT nGrow ) + USHORT nInit, USHORT* pIdAry, USHORT nGrow ) : + mpImplData( NULL ), + mnInitSize( nInit ), + mnGrowSize( nGrow ) { DBG_CTOR( ImageList, NULL ); - ImplBmpImageCreate( this, rBitmap, rMaskBmp, Color(), FALSE, - nInit, mpIdAry, nGrow ); + const BitmapEx aBmpEx( rBitmap, rMaskBmp ); + + ImplInit( aBmpEx, nInit, pIdAry, NULL, nGrow ); } // ----------------------------------------------------------------------- ImageList::ImageList( const Bitmap& rBitmap, const Color& rColor, - USHORT nInit, USHORT* mpIdAry, USHORT nGrow ) + USHORT nInit, USHORT* pIdAry, USHORT nGrow ) { DBG_CTOR( ImageList, NULL ); - ImplBmpImageCreate( this, rBitmap, Bitmap(), rColor, TRUE, - nInit, mpIdAry, nGrow ); + const BitmapEx aBmpEx( rBitmap, rColor ); + + ImplInit( aBmpEx, nInit, pIdAry, NULL, nGrow ); } // ----------------------------------------------------------------------- @@ -964,12 +694,121 @@ ImageList::~ImageList() { DBG_DTOR( ImageList, NULL ); - if ( mpImplData ) + if( mpImplData && ( 0 == --mpImplData->mnRefCount ) && ( 0 == mpImplData->mnIRefCount ) ) + delete mpImplData; +} + +// ----------------------------------------------------------------------- + +void ImageList::ImplInit( const BitmapEx& rBitmapEx, + USHORT nInit, const USHORT* pIdAry, + const ::std::vector< ::rtl::OUString >* pNames, + USHORT nGrow ) +{ + if( !nInit ) + { + mpImplData = NULL; + mnInitSize = 1; + mnGrowSize = nGrow; + } + else + { + DBG_ASSERT( !nInit || rBitmapEx.GetSizePixel().Width(), "ImageList::ImageList(): nInitSize != 0 and BmpSize.Width() == 0" ); + DBG_ASSERT( (rBitmapEx.GetSizePixel().Width() % nInit) == 0, "ImageList::ImageList(): BmpSize % nInitSize != 0" ); + + Size aBmpSize( rBitmapEx.GetSizePixel() ); + + mpImplData = new ImplImageList; + mnInitSize = nInit; + mnGrowSize = nGrow; + + mpImplData->mnRefCount = 1; + mpImplData->mnIRefCount = 0; + mpImplData->mnCount = nInit; + mpImplData->mnRealCount = nInit; + mpImplData->mnArySize = nInit; + mpImplData->mpAry = new ImageAryData[nInit]; + mpImplData->maImageSize = Size( aBmpSize.Width() / nInit, aBmpSize.Height() ); + + for( USHORT i = 0; i < nInit; i++ ) + { + mpImplData->mpAry[ i ].mnId = pIdAry ? pIdAry[ i ] : ( i + 1 ); + mpImplData->mpAry[ i ].mnRefCount = 1; + + if( pNames && ( i < pNames->size() ) ) + mpImplData->mpAry[ i ].maName = (*pNames)[ i ]; + } + + mpImplData->mpImageBitmap = new ImplImageBmp; + mpImplData->mpImageBitmap->Create( rBitmapEx, + mpImplData->maImageSize.Width(), + mpImplData->maImageSize.Height(), + nInit ); + } +} + +// ----------------------------------------------------------------------- + +void ImageList::ImplMakeUnique() +{ + if( mpImplData && mpImplData->mnRefCount > 1 ) + { + ImplImageList* pNewData = new ImplImageList; + USHORT i = 0, n = 0; + + --mpImplData->mnRefCount; + + pNewData->mnRefCount = 1; + pNewData->mnIRefCount = 0; + pNewData->mnCount = mpImplData->mnCount; + pNewData->mnRealCount = mpImplData->mnRealCount; + pNewData->mnArySize = mpImplData->mnArySize; + pNewData->mpAry = new ImageAryData[ pNewData->mnArySize ]; + pNewData->maImageSize = mpImplData->maImageSize; + pNewData->mpImageBitmap = new ImplImageBmp; + pNewData->mpImageBitmap->Create( pNewData->maImageSize.Width(), pNewData->maImageSize.Height(), pNewData->mnArySize ); + + while( i < mpImplData->mnArySize ) + { + if( mpImplData->mpAry[i].mnId ) + { + pNewData->mpAry[n].maName = mpImplData->mpAry[i].maName; + pNewData->mpAry[n].mnId = mpImplData->mpAry[i].mnId; + pNewData->mpAry[n].mnRefCount = 1; + pNewData->mpImageBitmap->Replace( n, *mpImplData->mpImageBitmap, i ); + ++n; + } + + ++i; + } + + mpImplData = pNewData; + } +} + +// ----------------------------------------------------------------------- + +USHORT ImageList::ImplGetImageId( const ::rtl::OUString& rImageName ) const +{ + DBG_CHKTHIS( ImageList, NULL ); + + if( mpImplData && rImageName.getLength() ) { - mpImplData->mnRefCount--; - if ( !mpImplData->mnRefCount && !mpImplData->mnIRefCount ) - delete mpImplData; + USHORT nPos = 0, i = 0; + + while( i < mpImplData->mnArySize ) + { + if( mpImplData->mpAry[i].maName == rImageName ) + return mpImplData->mpAry[i].mnId; + + if ( mpImplData->mpAry[i].mnId ) + ++nPos; + + ++i; + } } + + return 0; } // ----------------------------------------------------------------------- @@ -979,25 +818,23 @@ void ImageList::AddImage( USHORT nId, const Image& rImage ) DBG_CHKTHIS( ImageList, NULL ); DBG_CHKOBJ( &rImage, Image, NULL ); DBG_ASSERT( nId, "ImageList::AddImage(): ImageId == 0" ); - DBG_ASSERT( GetImagePos( nId ) == IMAGELIST_IMAGE_NOTFOUND, - "ImageList::AddImage() - ImageId already exists" ); + DBG_ASSERT( GetImagePos( nId ) == IMAGELIST_IMAGE_NOTFOUND, "ImageList::AddImage() - ImageId already exists" ); DBG_ASSERT( rImage.mpImplData, "ImageList::AddImage(): Wrong Size" ); - DBG_ASSERT( !mpImplData || (rImage.GetSizePixel() == mpImplData->maImageSize), - "ImageList::AddImage(): Wrong Size" ); + DBG_ASSERT( !mpImplData || (rImage.GetSizePixel() == mpImplData->maImageSize), "ImageList::AddImage(): Wrong Size" ); - BOOL bHasImage = ( rImage.mpImplData != 0 ); + bool bHasImage = ( rImage.mpImplData != 0 ); ImageType eImageType = IMAGETYPE_BITMAP; Size aImageSize; USHORT nIndex; - if ( bHasImage ) + if( bHasImage ) { eImageType = rImage.mpImplData->meType; aImageSize = rImage.GetSizePixel(); } else { - if ( mpImplData ) + if( mpImplData ) { eImageType = IMAGETYPE_BITMAP; aImageSize = mpImplData->maImageSize; @@ -1006,89 +843,125 @@ void ImageList::AddImage( USHORT nId, const Image& rImage ) return; } - if ( !mpImplData ) + if( !mpImplData ) { - mpImplData = new ImplImageList; - mpImplData->mnRefCount = 1; - mpImplData->mnIRefCount = 0; - mpImplData->mnCount = 0; - mpImplData->mnRealCount = 0; - mpImplData->mnArySize = mnInitSize; - mpImplData->mpAry = new ImageAryData[mnInitSize]; - mpImplData->maImageSize = aImageSize; - mpImplData->mpImageBitmap = new ImplImageBmp; - mpImplData->mpImageBitmap->Create( aImageSize.Width(), aImageSize.Height(), - mnInitSize ); - memset( mpImplData->mpAry, 0, mpImplData->mnArySize*sizeof(ImageAryData) ); + mpImplData = new ImplImageList; + mpImplData->mnRefCount = 1; + mpImplData->mnIRefCount = 0; + mpImplData->mnCount = 0; + mpImplData->mnRealCount = 0; + mpImplData->mnArySize = mnInitSize; + mpImplData->mpAry = new ImageAryData[mnInitSize]; + mpImplData->maImageSize = aImageSize; + mpImplData->mpImageBitmap = new ImplImageBmp; + mpImplData->mpImageBitmap->Create( aImageSize.Width(), aImageSize.Height(), mnInitSize ); } else - ImplCopyImageListData( this ); + ImplMakeUnique(); - // Gegebenenfalls unser Array erweitern und freien Index ermitteln - if ( mpImplData->mnRealCount == mpImplData->mnArySize ) + if( mpImplData->mnRealCount == mpImplData->mnArySize ) { ImageAryData* pOldAry = mpImplData->mpAry; USHORT nOldSize = mpImplData->mnArySize; mpImplData->mnArySize += mnGrowSize; mpImplData->mpAry = new ImageAryData[mpImplData->mnArySize]; - memset( mpImplData->mpAry, 0, mpImplData->mnArySize*sizeof(ImageAryData) ); - memcpy( mpImplData->mpAry, pOldAry, nOldSize*sizeof(ImageAryData) ); + + for( USHORT i = 0; i < nOldSize; ++i ) + mpImplData->mpAry[ i ] = pOldAry[ i ]; + mpImplData->mpImageBitmap->Expand( mnGrowSize ); delete[] pOldAry; - nIndex = mpImplData->mnRealCount; } else { nIndex = 0; - while ( mpImplData->mpAry[nIndex].mnRefCount ) - nIndex++; + + while( mpImplData->mpAry[nIndex].mnRefCount ) + ++nIndex; } - // Image in Bitmap einfuegen - switch ( eImageType ) + switch( eImageType ) { case IMAGETYPE_BITMAP: - if ( !bHasImage ) + { + if( !bHasImage ) { - // Use empty b/w bitmap with correct size as empty image and black a transparent color - Bitmap aBitmap( aImageSize, 1 ); - mpImplData->mpImageBitmap->Replace( nIndex, aBitmap, COL_BLACK ); + const Bitmap aBmp( aImageSize, 1 ); + const BitmapEx aBmpEx( aBmp, COL_BLACK ); + + mpImplData->mpImageBitmap->Replace( nIndex, aBmpEx ); } else - mpImplData->mpImageBitmap->Replace( nIndex, *((Bitmap*)rImage.mpImplData->mpData) ); - break; + mpImplData->mpImageBitmap->Replace( nIndex, *static_cast< Bitmap* >( rImage.mpImplData->mpData ) ); + } + break; case IMAGETYPE_IMAGE: - { - ImplImageData* pData = (ImplImageData*)rImage.mpImplData->mpData; - if ( pData->mpImageBitmap ) - mpImplData->mpImageBitmap->Replace( nIndex, *(pData->mpImageBitmap), 0 ); + { + ImplImageData* pData = static_cast< ImplImageData* >( rImage.mpImplData->mpData ); + + if( pData->mpImageBitmap ) + mpImplData->mpImageBitmap->Replace( nIndex, *pData->mpImageBitmap, 0 ); else + mpImplData->mpImageBitmap->Replace( nIndex, pData->maBmpEx ); + } + break; + + case IMAGETYPE_IMAGEREF: + { + ImplImageRefData* pData = static_cast< ImplImageRefData* >( rImage.mpImplData->mpData ); + + mpImplData->mpImageBitmap->Replace( nIndex, *pData->mpImplData->mpImageBitmap, pData->mnIndex ); + } + break; + } + + ++mpImplData->mnCount; + ++mpImplData->mnRealCount; + mpImplData->mpAry[nIndex].mnId = nId; + mpImplData->mpAry[nIndex].mnRefCount = 1; +} + +// ----------------------------------------------------------------------- + +void ImageList::AddImage( const ::rtl::OUString& rImageName, const Image& rImage ) +{ + DBG_ASSERT( GetImagePos( rImageName ) == IMAGELIST_IMAGE_NOTFOUND, "ImageList::AddImage() - ImageName already exists" ); + + if( mpImplData ) + { + USHORT i, nMax = 0; + + for( i = 0; i < mpImplData->mnArySize; ++i ) + { + if( mpImplData->mpAry[ i ].mnId > nMax ) { - if ( pData->mbColor ) - mpImplData->mpImageBitmap->Replace( nIndex, pData->maBmp, pData->maColor ); - else - mpImplData->mpImageBitmap->Replace( nIndex, pData->maBmp, pData->maMaskBmp ); - } + nMax = mpImplData->mpAry[ i ].mnId; } - break; + } - case IMAGETYPE_IMAGEREF: + if( nMax < USHRT_MAX ) + { + AddImage( ++nMax, rImage ); + + for( i = 0; i < mpImplData->mnArySize; ++i ) { - ImplImageRefData* pData = (ImplImageRefData*)rImage.mpImplData->mpData; - mpImplData->mpImageBitmap->Replace( nIndex, *(pData->mpImplData->mpImageBitmap), - pData->mnIndex ); + if( mpImplData->mpAry[ i ].mnId == nMax ) + { + mpImplData->mpAry[ i ].maName = rImageName; + break; + } } - break; + } + else + { + DBG_ERROR( "No free image id left" ); + } } - - // Array-Daten updaten - mpImplData->mnCount++; - mpImplData->mnRealCount++; - mpImplData->mpAry[nIndex].mnId = nId; - mpImplData->mpAry[nIndex].mnRefCount = 1; + else + AddImage( 1, rImage ); } // ----------------------------------------------------------------------- @@ -1097,58 +970,60 @@ void ImageList::CopyImage( USHORT nId, USHORT nCopyId ) { DBG_CHKTHIS( ImageList, NULL ); DBG_ASSERT( nId, "ImageList::CopyImage(): ImageId == 0" ); - DBG_ASSERT( GetImagePos( nId ) == IMAGELIST_IMAGE_NOTFOUND, - "ImageList::CopyImage(): ImageId already exists" ); - DBG_ASSERT( GetImagePos( nCopyId ) != IMAGELIST_IMAGE_NOTFOUND, - "ImageList::CopyImage(): Unknown nCopyId" ); + DBG_ASSERT( GetImagePos( nId ) == IMAGELIST_IMAGE_NOTFOUND, "ImageList::CopyImage(): ImageId already exists" ); + DBG_ASSERT( GetImagePos( nCopyId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::CopyImage(): Unknown nCopyId" ); - USHORT nIndex; - USHORT nCopyIndex = 0; + USHORT nIndex, nCopyIndex = 0; - // Index von CopyId holen - while ( nCopyIndex < mpImplData->mnArySize ) + while( nCopyIndex < mpImplData->mnArySize ) { if ( mpImplData->mpAry[nCopyIndex].mnId == nCopyId ) break; - nCopyIndex++; + ++nCopyIndex; } - if ( nCopyIndex >= mpImplData->mnArySize ) - return; - // Referenz-Counter ueberpruefen - ImplCopyImageListData( this ); - - // Gegebenenfalls unser Array erweitern - if ( mpImplData->mnRealCount == mpImplData->mnArySize ) + if( nCopyIndex < mpImplData->mnArySize ) { - ImageAryData* pOldAry = mpImplData->mpAry; - USHORT nOldSize = mpImplData->mnArySize; + ImplMakeUnique(); - mpImplData->mnArySize += mnGrowSize; - mpImplData->mpAry = new ImageAryData[mpImplData->mnArySize]; - memset( mpImplData->mpAry, 0, mpImplData->mnArySize*sizeof(ImageAryData) ); - memcpy( mpImplData->mpAry, pOldAry, nOldSize*sizeof(ImageAryData) ); - mpImplData->mpImageBitmap->Expand( mnGrowSize ); - delete[] pOldAry; + if( mpImplData->mnRealCount == mpImplData->mnArySize ) + { + ImageAryData* pOldAry = mpImplData->mpAry; + USHORT nOldSize = mpImplData->mnArySize; - nIndex = mpImplData->mnRealCount; - } - else - { - nIndex = 0; - while ( mpImplData->mpAry[nIndex].mnRefCount ) - nIndex++; + mpImplData->mnArySize += mnGrowSize; + mpImplData->mpAry = new ImageAryData[mpImplData->mnArySize]; + + for( USHORT i = 0; i < nOldSize; ++i ) + mpImplData->mpAry[ i ] = pOldAry[ i ]; + + mpImplData->mpImageBitmap->Expand( mnGrowSize ); + delete[] pOldAry; + nIndex = mpImplData->mnRealCount; + } + else + { + nIndex = 0; + + while( mpImplData->mpAry[nIndex].mnRefCount ) + nIndex++; + } + + mpImplData->mpImageBitmap->Replace( nIndex, *mpImplData->mpImageBitmap, nCopyIndex ); + + ++mpImplData->mnCount; + ++mpImplData->mnRealCount; + mpImplData->mpAry[nIndex].mnId = nId; + mpImplData->mpAry[nIndex].mnRefCount = 1; } +} - // Kopieren - mpImplData->mpImageBitmap->Replace( nIndex, *(mpImplData->mpImageBitmap), nCopyIndex ); +// ----------------------------------------------------------------------- - // Array-Daten updaten - mpImplData->mnCount++; - mpImplData->mnRealCount++; - mpImplData->mpAry[nIndex].mnId = nId; - mpImplData->mpAry[nIndex].mnRefCount = 1; +void ImageList::CopyImage( const ::rtl::OUString& rImageName, const ::rtl::OUString& rCopyName ) +{ + CopyImage( ImplGetImageId( rImageName ), ImplGetImageId( rCopyName ) ); } // ----------------------------------------------------------------------- @@ -1157,8 +1032,7 @@ void ImageList::ReplaceImage( USHORT nId, const Image& rImage ) { DBG_CHKTHIS( ImageList, NULL ); DBG_CHKOBJ( &rImage, Image, NULL ); - DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND, - "ImageList::ReplaceImage(): Unknown nId" ); + DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::ReplaceImage(): Unknown nId" ); RemoveImage( nId ); AddImage( nId, rImage ); @@ -1166,86 +1040,52 @@ void ImageList::ReplaceImage( USHORT nId, const Image& rImage ) // ----------------------------------------------------------------------- -void ImageList::ReplaceImage( USHORT nId, USHORT nReplaceId ) +void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const Image& rImage ) { - DBG_CHKTHIS( ImageList, NULL ); - DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND, - "ImageList::ReplaceImage(): Unknown nId" ); - DBG_ASSERT( GetImagePos( nReplaceId ) != IMAGELIST_IMAGE_NOTFOUND, - "ImageList::ReplaceImage(): Unknown nReplaceId" ); - - USHORT nPos1 = 0; - USHORT nPos2 = 0; - - // Index von Id holen - while ( nPos1 < mpImplData->mnArySize ) - { - if ( mpImplData->mpAry[nPos1].mnId == nId ) - break; - - nPos1++; - } - if ( nPos1 >= mpImplData->mnArySize ) - return; - - // Index von ReplaceId holen - while ( nPos2 < mpImplData->mnArySize ) - { - if ( mpImplData->mpAry[nPos2].mnId == nReplaceId ) - break; - - nPos2++; - } - if ( nPos2 >= mpImplData->mnArySize ) - return; - - // Referenz-Counter ueberpruefen - ImplCopyImageListData( this ); - - // Ersetzen - mpImplData->mpImageBitmap->Replace( nPos1, nPos2 ); + ReplaceImage( ImplGetImageId( rImageName ), rImage ); } // ----------------------------------------------------------------------- -void ImageList::MergeImage( USHORT nId, USHORT nMergeId ) +void ImageList::ReplaceImage( USHORT nId, USHORT nReplaceId ) { DBG_CHKTHIS( ImageList, NULL ); - DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND, - "ImageList::MergeImage(): Unknown nId" ); - DBG_ASSERT( GetImagePos( nMergeId ) != IMAGELIST_IMAGE_NOTFOUND, - "ImageList::MergeImage(): Unknown nMergeId" ); + DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::ReplaceImage(): Unknown nId" ); + DBG_ASSERT( GetImagePos( nReplaceId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::ReplaceImage(): Unknown nReplaceId" ); - USHORT nPos1 = 0; - USHORT nPos2 = 0; + USHORT nPos1 = 0, nPos2 = 0; - // Index von Id holen - while ( nPos1 < mpImplData->mnArySize ) + while( nPos1 < mpImplData->mnArySize ) { if ( mpImplData->mpAry[nPos1].mnId == nId ) break; - nPos1++; + ++nPos1; } - if ( nPos1 >= mpImplData->mnArySize ) - return; - // Index von MergeId holen - while ( nPos2 < mpImplData->mnArySize ) + if( nPos1 < mpImplData->mnArySize ) { - if ( mpImplData->mpAry[nPos2].mnId == nMergeId ) - break; + while( nPos2 < mpImplData->mnArySize ) + { + if( mpImplData->mpAry[nPos2].mnId == nReplaceId ) + break; + + ++nPos2; + } - nPos2++; + if( nPos2 < mpImplData->mnArySize ) + { + ImplMakeUnique(); + mpImplData->mpImageBitmap->Replace( nPos1, nPos2 ); + } } - if ( nPos2 >= mpImplData->mnArySize ) - return; +} - // Referenz-Counter ueberpruefen - ImplCopyImageListData( this ); +// ----------------------------------------------------------------------- - // Ersetzen - mpImplData->mpImageBitmap->Merge( nPos1, nPos2 ); +void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const ::rtl::OUString& rReplaceName ) +{ + ReplaceImage( ImplGetImageId( rImageName ), ImplGetImageId( rReplaceName ) ); } // ----------------------------------------------------------------------- @@ -1254,56 +1094,66 @@ void ImageList::RemoveImage( USHORT nId ) { DBG_CHKTHIS( ImageList, NULL ); - if ( mpImplData ) + if( mpImplData ) { - ImplCopyImageListData( this ); - USHORT i = 0; - while ( i < mpImplData->mnArySize ) + + ImplMakeUnique(); + + while( i < mpImplData->mnArySize ) { - if ( mpImplData->mpAry[i].mnId == nId ) + if( mpImplData->mpAry[i].mnId == nId ) break; - i++; + ++i; } - if ( i < mpImplData->mnArySize ) + if( i < mpImplData->mnArySize ) { - mpImplData->mpAry[i].mnRefCount--; + --mpImplData->mpAry[i].mnRefCount; mpImplData->mpAry[i].mnId = 0; - if ( !mpImplData->mpAry[i].mnRefCount ) - mpImplData->mnRealCount--; - mpImplData->mnCount--; + if( !mpImplData->mpAry[i].mnRefCount ) + --mpImplData->mnRealCount; + + --mpImplData->mnCount; } } } // ----------------------------------------------------------------------- +void ImageList::RemoveImage( const ::rtl::OUString& rImageName ) +{ + RemoveImage( ImplGetImageId( rImageName ) ); +} + +// ----------------------------------------------------------------------- + Image ImageList::GetImage( USHORT nId ) const { DBG_CHKTHIS( ImageList, NULL ); Image aImage; - if ( mpImplData ) + if( mpImplData ) { USHORT i = 0; - while ( i < mpImplData->mnArySize ) + + while( i < mpImplData->mnArySize ) { - if ( mpImplData->mpAry[i].mnId == nId ) + if( mpImplData->mpAry[i].mnId == nId ) break; - i++; + ++i; } - if ( i < mpImplData->mnArySize ) + if( i < mpImplData->mnArySize ) { ImplImageRefData* mpData = new ImplImageRefData; - mpImplData->mnIRefCount++; - mpImplData->mpAry[i].mnRefCount++; + ++mpImplData->mnIRefCount; + ++mpImplData->mpAry[i].mnRefCount; mpData->mpImplData = mpImplData; mpData->mnIndex = i; @@ -1319,19 +1169,21 @@ Image ImageList::GetImage( USHORT nId ) const // ----------------------------------------------------------------------- +Image ImageList::GetImage( const ::rtl::OUString& rImageName ) const +{ + return GetImage( ImplGetImageId( rImageName ) ); +} + +// ----------------------------------------------------------------------- + void ImageList::Clear() { DBG_CHKTHIS( ImageList, NULL ); - if ( mpImplData ) - { - if ( mpImplData->mnRefCount > 1 ) - mpImplData->mnRefCount--; - else - delete mpImplData; - } + if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) + delete mpImplData; - mpImplData = 0; + mpImplData = NULL; } // ----------------------------------------------------------------------- @@ -1340,10 +1192,7 @@ USHORT ImageList::GetImageCount() const { DBG_CHKTHIS( ImageList, NULL ); - if ( mpImplData ) - return mpImplData->mnCount; - else - return 0; + return( mpImplData ? mpImplData->mnCount : 0 ); } // ----------------------------------------------------------------------- @@ -1352,18 +1201,19 @@ USHORT ImageList::GetImagePos( USHORT nId ) const { DBG_CHKTHIS( ImageList, NULL ); - if ( mpImplData && nId ) + if( mpImplData && nId ) { - USHORT nPos = 0; - USHORT i = 0; - while ( i < mpImplData->mnArySize ) + USHORT nPos = 0, i = 0; + + while( i < mpImplData->mnArySize ) { - if ( mpImplData->mpAry[i].mnId == nId ) + if( mpImplData->mpAry[i].mnId == nId ) return nPos; if ( mpImplData->mpAry[i].mnId ) - nPos++; - i++; + ++nPos; + + ++i; } } @@ -1372,140 +1222,120 @@ USHORT ImageList::GetImagePos( USHORT nId ) const // ----------------------------------------------------------------------- -USHORT ImageList::GetImageId( USHORT nPos ) const +USHORT ImageList::GetImagePos( const ::rtl::OUString& rImageName ) const { DBG_CHKTHIS( ImageList, NULL ); - if ( mpImplData ) + if( mpImplData && rImageName.getLength() ) { - USHORT nRealPos = 0; - USHORT i = 0; - while ( i < mpImplData->mnArySize ) + USHORT nPos = 0, i = 0; + + while( i < mpImplData->mnArySize ) { - if ( (nPos == nRealPos) && (mpImplData->mpAry[i].mnId) ) - return mpImplData->mpAry[i].mnId; + if( mpImplData->mpAry[i].maName == rImageName ) + return nPos; if ( mpImplData->mpAry[i].mnId ) - nRealPos++; - i++; + ++nPos; + + ++i; } } - return 0; -} - -// ----------------------------------------------------------------------- - -Size ImageList::GetImageSize() const -{ - DBG_CHKTHIS( ImageList, NULL ); - - if ( mpImplData ) - return mpImplData->maImageSize; - else - return Size(); + return IMAGELIST_IMAGE_NOTFOUND; } // ----------------------------------------------------------------------- -Bitmap ImageList::GetBitmap() const +USHORT ImageList::GetImageId( USHORT nPos ) const { DBG_CHKTHIS( ImageList, NULL ); - Bitmap aBmp; - - if ( mpImplData ) + if( mpImplData ) { - // Positionen ermitteln, die in der Bitmap enthalten sein sollen - USHORT* mpPosAry = new USHORT[mpImplData->mnCount]; - USHORT nPosCount = 0; - for ( USHORT i = 0; i < mpImplData->mnArySize; i++ ) + USHORT nRealPos = 0, i = 0; + + while( i < mpImplData->mnArySize ) { - if ( mpImplData->mpAry[i].mnId ) - { - mpPosAry[nPosCount] = i; - nPosCount++; - } - } + if( (nPos == nRealPos) && (mpImplData->mpAry[i].mnId) ) + return mpImplData->mpAry[i].mnId; - // Bitmap besorgen - aBmp = mpImplData->mpImageBitmap->GetBitmap( nPosCount, mpPosAry ); + if ( mpImplData->mpAry[i].mnId ) + ++nRealPos; - // Temporaeres Array loeschen - delete[] mpPosAry; + ++i; + } } - return aBmp; + return 0; } // ----------------------------------------------------------------------- -Bitmap ImageList::GetMaskBitmap() const +::rtl::OUString ImageList::GetImageName( USHORT nPos ) const { DBG_CHKTHIS( ImageList, NULL ); - Bitmap aBmp; - - if ( HasMaskBitmap() ) + if( mpImplData ) { - // Positionen ermitteln, die in der Bitmap enthalten sein sollen - USHORT* mpPosAry = new USHORT[mpImplData->mnCount]; - USHORT nPosCount = 0; - for ( USHORT i = 0; i < mpImplData->mnArySize; i++ ) + USHORT nRealPos = 0, i = 0; + + while( i < mpImplData->mnArySize ) { - if ( mpImplData->mpAry[i].mnId ) - { - mpPosAry[nPosCount] = i; - nPosCount++; - } - } + if( (nPos == nRealPos) && (mpImplData->mpAry[i].mnId) ) + return mpImplData->mpAry[i].maName; - // Bitmap besorgen - aBmp = mpImplData->mpImageBitmap->GetMaskBitmap( nPosCount, mpPosAry ); + if ( mpImplData->mpAry[i].mnId ) + ++nRealPos; - // Temporaeres Array loeschen - delete[] mpPosAry; + ++i; + } } - return aBmp; + return ::rtl::OUString(); } // ----------------------------------------------------------------------- -BOOL ImageList::HasMaskBitmap() const +Size ImageList::GetImageSize() const { DBG_CHKTHIS( ImageList, NULL ); - if ( mpImplData ) - return mpImplData->mpImageBitmap->HasMaskBitmap(); - else - return FALSE; + Size aRet; + + if( mpImplData ) + aRet = mpImplData->maImageSize; + + return aRet; } // ----------------------------------------------------------------------- -Color ImageList::GetMaskColor() const +BitmapEx ImageList::GetBitmapEx() const { DBG_CHKTHIS( ImageList, NULL ); - Color aColor; + BitmapEx aRet; - if ( HasMaskColor() ) - aColor = mpImplData->mpImageBitmap->GetMaskColor(); - - return aColor; -} + if( mpImplData ) + { + USHORT* pPosAry = new USHORT[ mpImplData->mnCount ]; + USHORT nPosCount = 0; -// ----------------------------------------------------------------------- + for( USHORT i = 0; i < mpImplData->mnArySize; i++ ) + { + if( mpImplData->mpAry[i].mnId ) + { + pPosAry[ nPosCount ] = i; + ++nPosCount; + } + } -BOOL ImageList::HasMaskColor() const -{ - DBG_CHKTHIS( ImageList, NULL ); + aRet = mpImplData->mpImageBitmap->GetBitmapEx( nPosCount, pPosAry ); + delete[] pPosAry; + } - if ( mpImplData ) - return mpImplData->mpImageBitmap->HasMaskColor(); - else - return FALSE; + return aRet; } // ----------------------------------------------------------------------- @@ -1516,22 +1346,30 @@ ImageList ImageList::GetColorTransformedImageList( ImageColorTransform eColorTra ImageList aRet; - if( IMAGECOLORTRANSFORM_NONE != eColorTransform ) + if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform ) { Color* pSrcColors = NULL; Color* pDstColors = NULL; ULONG nColorCount = 0; aRet = *this; - ImplCopyImageListData( &aRet ); + aRet.ImplMakeUnique(); + Image::GetColorTransformArrays( eColorTransform, pSrcColors, pDstColors, nColorCount ); if( nColorCount && pSrcColors && pDstColors && mpImplData ) - mpImplData->mpImageBitmap->ReplaceColors( pSrcColors, pDstColors, nColorCount ); + aRet.mpImplData->mpImageBitmap->ReplaceColors( pSrcColors, pDstColors, nColorCount ); delete[] pSrcColors; delete[] pDstColors; } + else if( IMAGECOLORTRANSFORM_MONOCHROME_BLACK == eColorTransform || + IMAGECOLORTRANSFORM_MONOCHROME_WHITE == eColorTransform ) + { + aRet = *this; + aRet.ImplMakeUnique(); + aRet.mpImplData->mpImageBitmap->ColorTransform( static_cast< BmpColorMode >( eColorTransform ) ); + } if( !aRet.GetImageCount() ) aRet = *this; @@ -1546,19 +1384,12 @@ ImageList& ImageList::operator=( const ImageList& rImageList ) DBG_CHKTHIS( ImageList, NULL ); DBG_CHKOBJ( &rImageList, ImageList, NULL ); - // Zuerst Referenzcounter erhoehen, damit man sich selbst zuweisen kann - if ( rImageList.mpImplData ) - rImageList.mpImplData->mnRefCount++; + if( rImageList.mpImplData ) + ++rImageList.mpImplData->mnRefCount; - // Abkoppeln - if ( mpImplData ) - { - mpImplData->mnRefCount--; - if ( !mpImplData->mnRefCount && !mpImplData->mnIRefCount ) - delete mpImplData; - } + if( mpImplData && ( 0 == --mpImplData->mnRefCount ) && ( 0 == mpImplData->mnIRefCount ) ) + delete mpImplData; - // Neue Daten zuweisen mpImplData = rImageList.mpImplData; mnInitSize = rImageList.mnInitSize; mnGrowSize = rImageList.mnGrowSize; @@ -1573,16 +1404,19 @@ BOOL ImageList::operator==( const ImageList& rImageList ) const DBG_CHKTHIS( ImageList, NULL ); DBG_CHKOBJ( &rImageList, ImageList, NULL ); - if ( rImageList.mpImplData == mpImplData ) - return TRUE; - if ( !rImageList.mpImplData || !mpImplData ) - return FALSE; + BOOL bRet; - if ( (rImageList.mpImplData->mnCount == mpImplData->mnCount) && - (rImageList.mpImplData->maImageSize == mpImplData->maImageSize) ) - return TRUE; + if( rImageList.mpImplData == mpImplData ) + bRet = true; + else if( !rImageList.mpImplData || !mpImplData ) + bRet = false; + else if( ( rImageList.mpImplData->mnCount == mpImplData->mnCount ) && + ( rImageList.mpImplData->maImageSize == mpImplData->maImageSize ) ) + { + bRet = true; + } - return FALSE; + return bRet; } // ----------------------------------------------------------------------- @@ -1591,231 +1425,125 @@ SvStream& operator>>( SvStream& rIStream, ImageList& rImageList ) { DBG_CHKOBJ( &rImageList, ImageList, NULL ); - // Falls es eine bestehende ImageListe ist, dann erst abkoppeln - if ( rImageList.mpImplData ) + if( rImageList.mpImplData ) { - rImageList.mpImplData->mnRefCount--; - if ( !rImageList.mpImplData->mnRefCount && !rImageList.mpImplData->mnIRefCount ) + --rImageList.mpImplData->mnRefCount; + + if( ( 0 == rImageList.mpImplData->mnRefCount ) && ( 0 == rImageList.mpImplData->mnIRefCount ) ) delete rImageList.mpImplData; } + rImageList.mpImplData = NULL; - // Daten lesen USHORT nVersion; Size aImageSize; BOOL bImageList; - rIStream >> nVersion; - rIStream >> rImageList.mnInitSize; - rIStream >> rImageList.mnGrowSize; - rIStream >> bImageList; - - // Wenn es eine leere ImageListe ist, dann brauchen wir nicht weiter lesen - if ( !bImageList ) - return rIStream; - - // Image-Groesse lesen - rIStream >> aImageSize.Width(); - rIStream >> aImageSize.Height(); - - // Image-Daten anlegen und initialisieren - rImageList.mpImplData = new ImplImageList; - rImageList.mpImplData->mnRefCount = 1; - rImageList.mpImplData->mnIRefCount = 0; - rImageList.mpImplData->mnCount = rImageList.mnInitSize; - rImageList.mpImplData->mnRealCount = rImageList.mnInitSize; - rImageList.mpImplData->mnArySize = rImageList.mnInitSize; - rImageList.mpImplData->mpAry = new ImageAryData[rImageList.mnInitSize]; - rImageList.mpImplData->maImageSize = aImageSize; - - // Array mit ID's lesen und initialisieren - for ( USHORT i = 0; i < rImageList.mnInitSize; i++ ) - { - rIStream >> rImageList.mpImplData->mpAry[i].mnId; - rImageList.mpImplData->mpAry[i].mnRefCount = 1; - } - // Bitmaps lesen - Bitmap aBitmap; - Bitmap aMaskBitmap; - Color aMaskColor; - BYTE bMaskBitmap; - BYTE bMaskColor; - rIStream >> aBitmap; - rIStream >> bMaskBitmap; - if ( bMaskBitmap ) - rIStream >> aMaskBitmap; - rIStream >> bMaskColor; - if ( bMaskColor ) - rIStream >> aMaskColor; - - // Systemdaten anlegen - rImageList.mpImplData->mpImageBitmap = new ImplImageBmp; - rImageList.mpImplData->mpImageBitmap->Create( aBitmap, aMaskBitmap, - aMaskColor, bMaskColor, - aImageSize.Width(), - aImageSize.Height(), - rImageList.mnInitSize ); - return rIStream; -} + rIStream >> nVersion >> rImageList.mnInitSize >> rImageList.mnGrowSize >> bImageList; -// ----------------------------------------------------------------------- - -SvStream& operator<<( SvStream& rOStream, const ImageList& rImageList ) -{ - DBG_CHKOBJ( &rImageList, ImageList, NULL ); - - BOOL bImageList = (rImageList.mpImplData) ? TRUE : FALSE; - - USHORT nVersion = IMAGE_FILE_VERSION; - rOStream << nVersion; - - // Wenn es eine leere ImageListe ist, dann nur InitSize und - // GrowSize schreiben - if ( !bImageList || !rImageList.mpImplData->mnCount ) + if( bImageList ) { - BOOL bSaveImageList = FALSE; - rOStream << rImageList.mnInitSize; - rOStream << rImageList.mnGrowSize; - rOStream << bSaveImageList; - return rOStream; - } - - // Normale Daten schreiben - rOStream << rImageList.mpImplData->mnCount; - rOStream << rImageList.mnGrowSize; - rOStream << bImageList; - rOStream << rImageList.mpImplData->maImageSize.Width(); - rOStream << rImageList.mpImplData->maImageSize.Height(); - - // Array schreiben und feststellen, welche Eintraege gespeichert werden - // muessen - USHORT* mpPosAry = new USHORT[rImageList.mpImplData->mnCount]; - USHORT nPosCount = 0; - for ( USHORT i = 0; i < rImageList.mpImplData->mnArySize; i++ ) - { - if ( rImageList.mpImplData->mpAry[i].mnId ) + BitmapEx aBmpEx; + Bitmap aBmp; + BYTE bMaskOrAlpha, bMaskColor; + + rIStream >> aImageSize.Width() >> aImageSize.Height(); + + rImageList.mpImplData = new ImplImageList; + rImageList.mpImplData->mnRefCount = 1; + rImageList.mpImplData->mnIRefCount= 0; + rImageList.mpImplData->mnCount = rImageList.mnInitSize; + rImageList.mpImplData->mnRealCount = rImageList.mnInitSize; + rImageList.mpImplData->mnArySize = rImageList.mnInitSize; + rImageList.mpImplData->mpAry = new ImageAryData[ rImageList.mnInitSize ]; + rImageList.mpImplData->maImageSize = aImageSize; + + for( USHORT i = 0; i < rImageList.mnInitSize; ++i ) { - rOStream << rImageList.mpImplData->mpAry[i].mnId; - mpPosAry[nPosCount] = i; - nPosCount++; + rIStream >> rImageList.mpImplData->mpAry[i].mnId; + rImageList.mpImplData->mpAry[i].mnRefCount = 1; } - } - - // Bitmaps rausschreiben - Bitmap aBmp; - BYTE bMaskBitmap = (BYTE)rImageList.mpImplData->mpImageBitmap->HasMaskBitmap(); - BYTE bMaskColor = (BYTE)rImageList.mpImplData->mpImageBitmap->HasMaskColor(); - aBmp = rImageList.mpImplData->mpImageBitmap->GetBitmap( nPosCount, mpPosAry ); - rOStream << aBmp; - rOStream << bMaskBitmap; - if ( bMaskBitmap ) - { - aBmp = rImageList.mpImplData->mpImageBitmap->GetMaskBitmap( nPosCount, mpPosAry ); - rOStream << aBmp; - } - rOStream << bMaskColor; - if ( bMaskColor ) - { - Color aColor = rImageList.mpImplData->mpImageBitmap->GetMaskColor(); - rOStream << aColor; - } - - // Temporaeres Array loeschen - delete[] mpPosAry; - - return rOStream; -} -// ======================================================================= + rIStream >> aBmp >> bMaskOrAlpha; -void OutputDevice::DrawImage( const Point& rPos, const Image& rImage, - USHORT nStyle ) -{ - DBG_CHKOBJ( &rImage, Image, NULL ); - DBG_ASSERT( GetOutDevType() != OUTDEV_PRINTER, - "DrawImage(): Images can't be drawn on any mprinter" ); + if( bMaskOrAlpha ) + { + Bitmap aMaskOrAlpha; - if( !rImage.mpImplData || ImplIsRecordLayout() ) - return; + rIStream >> aMaskOrAlpha; - switch( rImage.mpImplData->meType ) - { - case IMAGETYPE_BITMAP: - { - DrawBitmap( rPos, *((Bitmap*)rImage.mpImplData->mpData) ); + if( aMaskOrAlpha.GetBitCount() == 8 && aMaskOrAlpha.HasGreyPalette() ) + aBmpEx = BitmapEx( aBmp, AlphaMask( aMaskOrAlpha ) ); + else + aBmpEx = BitmapEx( aBmp, aMaskOrAlpha ); } - break; - case IMAGETYPE_IMAGE: + rIStream >> bMaskColor; + + if( bMaskColor ) { - ImplImageData* pData = (ImplImageData*)rImage.mpImplData->mpData; + Color aMaskColor; - if ( !pData->mpImageBitmap ) - { - Size aSize = pData->maBmp.GetSizePixel(); - pData->mpImageBitmap = new ImplImageBmp; - pData->mpImageBitmap->Create( pData->maBmp, pData->maMaskBmp, - pData->maColor, pData->mbColor, - aSize.Width(), aSize.Height(), - 1 ); - } + rIStream >> aMaskColor; - pData->mpImageBitmap->Draw( 0, this, rPos, nStyle ); + if( !aBmpEx.IsAlpha() && !aBmpEx.IsTransparent() ) + aBmpEx = BitmapEx( aBmp, aMaskColor ); } - break; - case IMAGETYPE_IMAGEREF: - { - ImplImageRefData* pData = (ImplImageRefData*)rImage.mpImplData->mpData; - pData->mpImplData->mpImageBitmap->Draw( pData->mnIndex, this, rPos, nStyle ); - } - break; + rImageList.mpImplData->mpImageBitmap = new ImplImageBmp; + rImageList.mpImplData->mpImageBitmap->Create( aBmpEx, aImageSize.Width(), aImageSize.Height(), rImageList.mnInitSize ); } + + return rIStream; } -// ======================================================================= +// ----------------------------------------------------------------------- -void OutputDevice::DrawImage( const Point& rPos, const Size& rSize, - const Image& rImage, USHORT nStyle ) +SvStream& operator<<( SvStream& rOStream, const ImageList& rImageList ) { - DBG_CHKOBJ( &rImage, Image, NULL ); - DBG_ASSERT( GetOutDevType() != OUTDEV_PRINTER, - "DrawImage(): Images can't be drawn on any mprinter" ); + DBG_CHKOBJ( &rImageList, ImageList, NULL ); + + USHORT nVersion = IMAGE_FILE_VERSION; + BOOL bImageList = rImageList.mpImplData ? true : false; - if( !rImage.mpImplData || ImplIsRecordLayout() ) - return; + rOStream << nVersion; - switch( rImage.mpImplData->meType ) + if ( !bImageList || !rImageList.mpImplData->mnCount ) + rOStream << rImageList.mnInitSize << rImageList.mnGrowSize << ( bImageList = FALSE ); + else { - case IMAGETYPE_BITMAP: - { - DrawBitmap( rPos, rSize, *((Bitmap*)rImage.mpImplData->mpData) ); - } - break; + rOStream << rImageList.mpImplData->mnCount; + rOStream << rImageList.mnGrowSize; + rOStream << bImageList; + rOStream << rImageList.mpImplData->maImageSize.Width(); + rOStream << rImageList.mpImplData->maImageSize.Height(); - case IMAGETYPE_IMAGE: - { - ImplImageData* pData = (ImplImageData*)rImage.mpImplData->mpData; + USHORT* mpPosAry = new USHORT[rImageList.mpImplData->mnCount]; + USHORT nPosCount = 0; - if ( !pData->mpImageBitmap ) + for( USHORT i = 0; i < rImageList.mpImplData->mnArySize; ++i ) + { + if( rImageList.mpImplData->mpAry[i].mnId ) { - Size aSize = pData->maBmp.GetSizePixel(); - pData->mpImageBitmap = new ImplImageBmp; - pData->mpImageBitmap->Create( pData->maBmp, pData->maMaskBmp, - pData->maColor, pData->mbColor, - aSize.Width(), aSize.Height(), - 1 ); + rOStream << rImageList.mpImplData->mpAry[i].mnId; + mpPosAry[ nPosCount++ ] = i; } - - pData->mpImageBitmap->Draw( 0, this, rPos, nStyle, &rSize ); } - break; - case IMAGETYPE_IMAGEREF: - { - ImplImageRefData* pData = (ImplImageRefData*)rImage.mpImplData->mpData; - pData->mpImplData->mpImageBitmap->Draw( pData->mnIndex, this, rPos, nStyle, &rSize ); - } - break; + BitmapEx aBmpEx( rImageList.mpImplData->mpImageBitmap->GetBitmapEx( nPosCount, mpPosAry ) ); + const BOOL bMaskOrAlpha = aBmpEx.IsAlpha() || aBmpEx.IsTransparent(); + const BOOL bMaskColor = false; + + rOStream << aBmpEx.GetBitmap() << bMaskOrAlpha; + + if( bMaskOrAlpha ) + rOStream << ( aBmpEx.IsAlpha() ? aBmpEx.GetAlpha().ImplGetBitmap() : aBmpEx.GetMask() ); + + // BitmapEx doesn't have internal mask colors anymore + rOStream << bMaskColor; + + delete[] mpPosAry; } + + return rOStream; } |