Files
libreoffice/vcl/source/gdi/image.cxx

1550 lines
44 KiB
C++
Raw Normal View History

2000-09-18 16:07:07 +00:00
/*************************************************************************
*
* $RCSfile: image.cxx,v $
*
* $Revision: 1.13 $
2000-09-18 16:07:07 +00:00
*
* last change: $Author: rt $ $Date: 2004-05-24 15:25:19 $
2000-09-18 16:07:07 +00:00
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#ifndef _DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif
#ifndef _SV_RC_H
#include <tools/rc.h>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _TOOLS_RC_HXX
#include <tools/rc.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_RESMGR_HXX
#include <tools/resmgr.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SV_SETTINGS_HXX
#include <settings.hxx>
#endif
#ifndef _SV_OUTDEV_HXX
#include <outdev.hxx>
#endif
#ifndef _SV_IMPIMAGETREE_H
#include <impimagetree.hxx>
#endif
2000-09-18 16:07:07 +00:00
#ifndef _SV_IMAGE_H
#include <image.h>
#endif
#ifndef _SV_IMAGE_HXX
#include <image.hxx>
#endif
DBG_NAME( Image );
DBG_NAME( ImageList );
#define IMAGE_FILE_VERSION 100
2000-09-18 16:07:07 +00:00
// ---------
// - Image -
// ---------
2000-09-18 16:07:07 +00:00
Image::Image() :
mpImplData( NULL )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( Image, NULL );
}
// -----------------------------------------------------------------------
Image::Image( const ResId& rResId ) :
mpImplData( NULL )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( Image, NULL );
rResId.SetRT( RSC_IMAGE );
2000-09-18 16:07:07 +00:00
ResMgr* pResMgr = rResId.GetResMgr();
if( !pResMgr )
2000-09-18 16:07:07 +00:00
pResMgr = Resource::GetResManager();
if( pResMgr->GetResource( rResId ) )
2000-09-18 16:07:07 +00:00
{
pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
BitmapEx aBmpEx;
USHORT nObjMask = pResMgr->ReadShort();
2000-09-18 16:07:07 +00:00
if( nObjMask & RSC_IMAGE_IMAGEBITMAP )
{
aBmpEx = BitmapEx( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
2000-09-18 16:07:07 +00:00
pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
}
if( !aBmpEx.IsEmpty() )
2000-09-18 16:07:07 +00:00
{
if( nObjMask & RSC_IMAGE_MASKBITMAP )
2000-09-18 16:07:07 +00:00
{
if( aBmpEx.GetTransparentType() == TRANSPARENT_NONE )
2000-09-18 16:07:07 +00:00
{
const Bitmap aMaskBitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskBitmap );
2000-09-18 16:07:07 +00:00
}
pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
2000-09-18 16:07:07 +00:00
}
if( nObjMask & RSC_IMAGE_MASKCOLOR )
2000-09-18 16:07:07 +00:00
{
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() ) );
2000-09-18 16:07:07 +00:00
}
ImplInit( aBmpEx );
2000-09-18 16:07:07 +00:00
}
}
else
{
DBG_ERROR( "Image::Image( const ResId& rResId ): No resource!" );
}
}
// -----------------------------------------------------------------------
Image::Image( const Image& rImage ) :
mpImplData( rImage.mpImplData )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( Image, NULL );
if( mpImplData )
++mpImplData->mnRefCount;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
Image::Image( const BitmapEx& rBitmapEx ) :
mpImplData( NULL )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( Image, NULL );
ImplInit( rBitmapEx );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
Image::Image( const Bitmap& rBitmap ) :
mpImplData( NULL )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( Image, NULL );
ImplInit( rBitmap );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
Image::Image( const Bitmap& rBitmap, const Bitmap& rMaskBitmap ) :
mpImplData( NULL )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( Image, NULL );
const BitmapEx aBmpEx( rBitmap, rMaskBitmap );
ImplInit( aBmpEx );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
Image::Image( const Bitmap& rBitmap, const Color& rColor ) :
mpImplData( NULL )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( Image, NULL );
const BitmapEx aBmpEx( rBitmap, rColor );
2000-09-18 16:07:07 +00:00
ImplInit( aBmpEx );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
Image::~Image()
{
DBG_DTOR( Image, NULL );
if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
delete mpImplData;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void Image::ImplInit( const BitmapEx& rBmpEx )
2000-09-18 16:07:07 +00:00
{
if( !rBmpEx.IsEmpty() )
2000-09-18 16:07:07 +00:00
{
mpImplData = new ImplImage;
mpImplData->mnRefCount = 1;
2001-11-29 08:21:20 +00:00
if( rBmpEx.GetTransparentType() == TRANSPARENT_NONE )
2001-11-29 08:21:20 +00:00
{
mpImplData->meType = IMAGETYPE_BITMAP;
mpImplData->mpData = new Bitmap( rBmpEx.GetBitmap() );
2001-11-29 08:21:20 +00:00
}
else
2001-11-29 08:21:20 +00:00
{
mpImplData->meType = IMAGETYPE_IMAGE;
mpImplData->mpData = new ImplImageData( rBmpEx );
2001-11-29 08:21:20 +00:00
}
}
}
// -----------------------------------------------------------------------
Size Image::GetSizePixel() const
2001-11-29 08:21:20 +00:00
{
DBG_CHKTHIS( Image, NULL );
Size aRet;
2001-11-29 08:21:20 +00:00
if( mpImplData )
2001-11-29 08:21:20 +00:00
{
switch( mpImplData->meType )
2001-11-29 08:21:20 +00:00
{
case IMAGETYPE_BITMAP:
aRet = static_cast< Bitmap* >( mpImplData->mpData )->GetSizePixel();
break;
2001-11-29 08:21:20 +00:00
case IMAGETYPE_IMAGE:
aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx.GetSizePixel();
break;
2001-11-29 08:21:20 +00:00
case IMAGETYPE_IMAGEREF:
aRet = static_cast< ImplImageRefData* >( mpImplData->mpData )->mpImplData->maImageSize;
break;
2001-11-29 08:21:20 +00:00
}
}
return aRet;
2001-11-29 08:21:20 +00:00
}
// -----------------------------------------------------------------------
BitmapEx Image::GetBitmapEx() const
2001-11-29 08:21:20 +00:00
{
DBG_CHKTHIS( Image, NULL );
BitmapEx aRet;
if( mpImplData )
2001-11-29 08:21:20 +00:00
{
switch( mpImplData->meType )
2001-11-29 08:21:20 +00:00
{
case IMAGETYPE_BITMAP:
aRet = *static_cast< Bitmap* >( mpImplData->mpData );
break;
2001-11-29 08:21:20 +00:00
case IMAGETYPE_IMAGE:
aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx;
break;
2001-11-29 08:21:20 +00:00
case IMAGETYPE_IMAGEREF:
{
ImplImageRefData* pData = static_cast< ImplImageRefData* >( mpImplData->mpData );
aRet = pData->mpImplData->mpImageBitmap->GetBitmapEx( 1, &pData->mnIndex );
}
break;
2001-11-29 08:21:20 +00:00
}
}
return aRet;
2001-11-29 08:21:20 +00:00
}
// -----------------------------------------------------------------------
2002-03-01 11:35:42 +00:00
Image Image::GetColorTransformedImage( ImageColorTransform eColorTransform ) const
{
DBG_CHKTHIS( Image, NULL );
Image aRet;
if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform )
2002-03-01 11:35:42 +00:00
{
BitmapEx aBmpEx( GetBitmapEx() );
2002-03-01 11:35:42 +00:00
if( !aBmpEx.IsEmpty() )
2002-03-01 11:35:42 +00:00
{
Color* pSrcColors = NULL;
Color* pDstColors = NULL;
ULONG nColorCount = 0;
Image::GetColorTransformArrays( eColorTransform, pSrcColors, pDstColors, nColorCount );
if( nColorCount && pSrcColors && pDstColors )
{
aBmpEx.Replace( pSrcColors, pDstColors, nColorCount );
aRet = Image( aBmpEx );
2002-03-01 11:35:42 +00:00
}
delete[] pSrcColors;
delete[] pDstColors;
}
}
else if( IMAGECOLORTRANSFORM_MONOCHROME_BLACK == eColorTransform ||
IMAGECOLORTRANSFORM_MONOCHROME_WHITE == eColorTransform )
{
BitmapEx aBmpEx( GetBitmapEx() );
if( !aBmpEx.IsEmpty() )
aRet = Image( aBmpEx.GetColorTransformedBitmapEx( ( BmpColorMode )( eColorTransform ) ) );
}
2002-03-01 11:35:42 +00:00
if( !aRet )
aRet = *this;
return aRet;
}
// -----------------------------------------------------------------------
void Image::GetColorTransformArrays( ImageColorTransform eColorTransform,
Color*& rpSrcColor, Color*& rpDstColor, ULONG& rColorCount )
{
if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform )
{
rpSrcColor = new Color[ 4 ];
rpDstColor = new Color[ 4 ];
rColorCount = 4;
2002-03-01 11:35:42 +00:00
rpSrcColor[ 0 ] = Color( COL_BLACK );
rpDstColor[ 0 ] = Color( COL_WHITE );
rpSrcColor[ 1 ] = Color( COL_WHITE );
rpDstColor[ 1 ] = Color( COL_BLACK );
rpSrcColor[ 2 ] = Color( COL_BLUE );
rpDstColor[ 2 ] = Color( COL_WHITE );
rpSrcColor[ 3 ] = Color( COL_LIGHTBLUE );
rpDstColor[ 3 ] = Color( COL_WHITE );
2002-03-01 11:35:42 +00:00
}
else
{
rpSrcColor = rpDstColor = NULL;
rColorCount = 0;
}
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
Image& Image::operator=( const Image& rImage )
{
DBG_CHKTHIS( Image, NULL );
DBG_CHKOBJ( &rImage, Image, NULL );
if( rImage.mpImplData )
++rImage.mpImplData->mnRefCount;
2000-09-18 16:07:07 +00:00
if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
delete mpImplData;
2000-09-18 16:07:07 +00:00
mpImplData = rImage.mpImplData;
return *this;
}
// -----------------------------------------------------------------------
BOOL Image::operator==( const Image& rImage ) const
{
DBG_CHKTHIS( Image, NULL );
DBG_CHKOBJ( &rImage, Image, NULL );
BOOL bRet;
2000-09-18 16:07:07 +00:00
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 )
2000-09-18 16:07:07 +00:00
{
switch( mpImplData->meType )
2000-09-18 16:07:07 +00:00
{
case IMAGETYPE_BITMAP:
bRet = ( *static_cast< Bitmap* >( rImage.mpImplData->mpData ) == *static_cast< Bitmap* >( mpImplData->mpData ) );
break;
2000-09-18 16:07:07 +00:00
case IMAGETYPE_IMAGE:
bRet = static_cast< ImplImageData* >( rImage.mpImplData->mpData )->IsEqual( *static_cast< ImplImageData* >( mpImplData->mpData ) );
break;
2000-09-18 16:07:07 +00:00
case IMAGETYPE_IMAGEREF:
bRet = static_cast< ImplImageRefData* >( rImage.mpImplData->mpData )->IsEqual( *static_cast< ImplImageRefData* >( mpImplData->mpData ) );
break;
default:
bRet = false;
break;
2000-09-18 16:07:07 +00:00
}
}
return bRet;
}
// -------------
// - ImageList -
// -------------
ImageList::ImageList( USHORT nInit, USHORT nGrow ) :
mpImplData( NULL ),
mnInitSize( nInit ),
mnGrowSize( nGrow )
{
DBG_CTOR( ImageList, NULL );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
ImageList::ImageList( const ResId& rResId ) :
mpImplData( NULL ),
mnInitSize( 1 ),
mnGrowSize( 4 )
{
DBG_CTOR( ImageList, NULL );
rResId.SetRT( RSC_IMAGELIST );
ResMgr* pResMgr = rResId.GetResMgr();
if( !pResMgr )
pResMgr = Resource::GetResManager();
if( pResMgr->GetResource( rResId ) )
{
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 )
{
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 ];
// 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( '/' );
2000-09-18 16:07:07 +00:00
if( -1 != nPos++ )
{
const sal_Int32 nSecondPos = aResMgrName.lastIndexOf( '.' );
aUserImage = aResMgrName.copy( nPos, ( ( -1 != nSecondPos ) ? nSecondPos : aResMgrName.getLength() ) - nPos );
}
2000-09-18 16:07:07 +00:00
if( !aImageTree->loadImage( aUserImage += String::CreateFromInt32( rResId.GetId() ), aBmpEx ) )
2000-09-18 16:07:07 +00:00
{
BitmapEx aWorkBmpEx;
Size aItemSizePixel;
bool bInit = false;
2000-09-18 16:07:07 +00:00
for( sal_Int32 i = 0; i < nCount; ++i )
{
if( aImageTree->loadImage( pStringAry[ i ], aWorkBmpEx ) )
{
const Size aWorkSizePixel( aWorkBmpEx.GetSizePixel() );
2000-09-18 16:07:07 +00:00
if( !bInit )
{
aItemSizePixel = aWorkSizePixel;
aBmpEx = Bitmap( Size( aWorkSizePixel.Width() * nCount, aWorkSizePixel.Height() ), 24 );
bInit = true;
}
2000-09-18 16:07:07 +00:00
DBG_ASSERT( aItemSizePixel == aWorkSizePixel, "Differerent dimensions in ItemList images" );
2000-09-18 16:07:07 +00:00
const Rectangle aRectDst( Point( aItemSizePixel.Width() * i, 0 ), aItemSizePixel );
const Rectangle aRectSrc( Point( 0, 0 ), aWorkSizePixel );
2000-09-18 16:07:07 +00:00
aBmpEx.CopyPixel( aRectDst, aRectSrc, &aWorkBmpEx );
}
2000-09-18 16:07:07 +00:00
#ifdef DBG_UTIL
else
2000-09-18 16:07:07 +00:00
{
ByteString aErrorStr( "ImageList::ImageList( const ResId& rResId ): could not load image <" );
DBG_ERROR( ( ( aErrorStr += ByteString( pStringAry[ i ], RTL_TEXTENCODING_ASCII_US ) ) += '>' ).GetBuffer() );
2000-09-18 16:07:07 +00:00
}
#endif
}
2000-09-18 16:07:07 +00:00
if( !aBmpEx.IsEmpty() )
aImageTree->addUserImage( aUserImage, aBmpEx );
}
2000-09-18 16:07:07 +00:00
if( !aBmpEx.IsEmpty() && !aBmpEx.IsTransparent() && ( nObjMask & RSC_IMAGE_MASKCOLOR ) )
aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskColor );
2000-09-18 16:07:07 +00:00
if( nObjMask & RSC_IMAGELIST_IDCOUNT )
pResMgr->ReadShort();
2000-09-18 16:07:07 +00:00
ImplInit( aBmpEx, nCount, pIdAry, NULL, 4 );
2000-09-18 16:07:07 +00:00
delete[] pIdAry;
delete[] pStringAry;
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
ImageList::ImageList( const ::std::vector< ::rtl::OUString >& rNameVector, const Color* pMaskColor ) :
mpImplData( NULL ),
mnInitSize( 1 ),
mnGrowSize( 4 )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( ImageList, NULL );
static ImplImageTreeSingletonRef aImageTree;
::rtl::OUString aProjectName;
BitmapEx aBmpEx, aWorkBmpEx;
Size aItemSizePixel;
bool bInit = false;
2000-09-18 16:07:07 +00:00
for( int i = 0; i < rNameVector.size(); ++i )
2000-09-18 16:07:07 +00:00
{
if( aImageTree->loadImage( rNameVector[ i ], aWorkBmpEx ) )
{
const Size aWorkSizePixel( aWorkBmpEx.GetSizePixel() );
2000-09-18 16:07:07 +00:00
if( !bInit )
{
aItemSizePixel = aWorkSizePixel;
aBmpEx = Bitmap( Size( aWorkSizePixel.Width() * rNameVector.size(), aWorkSizePixel.Height() ), 24 );
bInit = true;
}
2000-09-18 16:07:07 +00:00
DBG_ASSERT( aItemSizePixel == aWorkSizePixel, "Differerent dimensions in ItemList images" );
2000-09-18 16:07:07 +00:00
const Rectangle aRectDst( Point( aItemSizePixel.Width() * i, 0 ), aItemSizePixel );
const Rectangle aRectSrc( Point( 0, 0 ), aWorkSizePixel );
aBmpEx.CopyPixel( aRectDst, aRectSrc, &aWorkBmpEx );
2000-09-18 16:07:07 +00:00
}
#ifdef DBG_UTIL
else
2000-09-18 16:07:07 +00:00
{
ByteString aErrorStr( "ImageList::ImageList( const ::std::vector< ::rtl::OUString >& rNameVector, const Color* pMaskColor ): could not load image <" );
DBG_ERROR( ( ( aErrorStr += ByteString( String( rNameVector[ i ] ), RTL_TEXTENCODING_ASCII_US ) ) += '>' ).GetBuffer() );
2000-09-18 16:07:07 +00:00
}
#endif
2000-09-18 16:07:07 +00:00
}
if( !aBmpEx.IsEmpty() && !aBmpEx.IsTransparent() && pMaskColor )
aBmpEx = BitmapEx( aBmpEx.GetBitmap(), *pMaskColor );
ImplInit( aBmpEx, static_cast< USHORT >( rNameVector.size() ), NULL, &rNameVector, 4 );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
ImageList::ImageList( const ImageList& rImageList ) :
mpImplData( rImageList.mpImplData ),
mnInitSize( rImageList.mnInitSize ),
mnGrowSize( rImageList.mnGrowSize )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( ImageList, NULL );
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 );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
ImageList::ImageList( const Bitmap& rBitmap,
USHORT nInit, USHORT* pIdAry, USHORT nGrow ) :
mpImplData( NULL ),
mnInitSize( nInit ),
mnGrowSize( nGrow )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( ImageList, NULL );
ImplInit( rBitmap, nInit, pIdAry, NULL, nGrow );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
ImageList::ImageList( const Bitmap& rBitmap, const Bitmap& rMaskBmp,
USHORT nInit, USHORT* pIdAry, USHORT nGrow ) :
mpImplData( NULL ),
mnInitSize( nInit ),
mnGrowSize( nGrow )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( ImageList, NULL );
const BitmapEx aBmpEx( rBitmap, rMaskBmp );
ImplInit( aBmpEx, nInit, pIdAry, NULL, nGrow );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
ImageList::ImageList( const Bitmap& rBitmap, const Color& rColor,
USHORT nInit, USHORT* pIdAry, USHORT nGrow )
2000-09-18 16:07:07 +00:00
{
DBG_CTOR( ImageList, NULL );
const BitmapEx aBmpEx( rBitmap, rColor );
ImplInit( aBmpEx, nInit, pIdAry, NULL, nGrow );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
ImageList::~ImageList()
{
DBG_DTOR( ImageList, NULL );
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 )
2000-09-18 16:07:07 +00:00
{
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 );
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
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() )
{
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;
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
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" );
2000-09-18 16:07:07 +00:00
DBG_ASSERT( rImage.mpImplData, "ImageList::AddImage(): Wrong Size" );
DBG_ASSERT( !mpImplData || (rImage.GetSizePixel() == mpImplData->maImageSize), "ImageList::AddImage(): Wrong Size" );
2000-09-18 16:07:07 +00:00
bool bHasImage = ( rImage.mpImplData != 0 );
ImageType eImageType = IMAGETYPE_BITMAP;
Size aImageSize;
2000-09-18 16:07:07 +00:00
USHORT nIndex;
if( bHasImage )
{
eImageType = rImage.mpImplData->meType;
aImageSize = rImage.GetSizePixel();
}
else
{
if( mpImplData )
{
eImageType = IMAGETYPE_BITMAP;
aImageSize = mpImplData->maImageSize;
}
else
return;
}
if( !mpImplData )
2000-09-18 16:07:07 +00:00
{
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 );
2000-09-18 16:07:07 +00:00
}
else
ImplMakeUnique();
2000-09-18 16:07:07 +00:00
if( mpImplData->mnRealCount == mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
ImageAryData* pOldAry = mpImplData->mpAry;
USHORT nOldSize = mpImplData->mnArySize;
mpImplData->mnArySize += mnGrowSize;
mpImplData->mpAry = new ImageAryData[mpImplData->mnArySize];
for( USHORT i = 0; i < nOldSize; ++i )
mpImplData->mpAry[ i ] = pOldAry[ i ];
2000-09-18 16:07:07 +00:00
mpImplData->mpImageBitmap->Expand( mnGrowSize );
delete[] pOldAry;
2000-09-18 16:07:07 +00:00
nIndex = mpImplData->mnRealCount;
}
else
{
nIndex = 0;
while( mpImplData->mpAry[nIndex].mnRefCount )
++nIndex;
}
switch( eImageType )
{
case IMAGETYPE_BITMAP:
{
if( !bHasImage )
{
const Bitmap aBmp( aImageSize, 1 );
const BitmapEx aBmpEx( aBmp, COL_BLACK );
mpImplData->mpImageBitmap->Replace( nIndex, aBmpEx );
}
else
mpImplData->mpImageBitmap->Replace( nIndex, *static_cast< Bitmap* >( rImage.mpImplData->mpData ) );
}
break;
case IMAGETYPE_IMAGE:
{
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;
2000-09-18 16:07:07 +00:00
}
++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 )
2000-09-18 16:07:07 +00:00
{
USHORT i, nMax = 0;
2000-09-18 16:07:07 +00:00
for( i = 0; i < mpImplData->mnArySize; ++i )
{
if( mpImplData->mpAry[ i ].mnId > nMax )
2000-09-18 16:07:07 +00:00
{
nMax = mpImplData->mpAry[ i ].mnId;
2000-09-18 16:07:07 +00:00
}
}
2000-09-18 16:07:07 +00:00
if( nMax < USHRT_MAX )
{
AddImage( ++nMax, rImage );
for( i = 0; i < mpImplData->mnArySize; ++i )
2000-09-18 16:07:07 +00:00
{
if( mpImplData->mpAry[ i ].mnId == nMax )
{
mpImplData->mpAry[ i ].maName = rImageName;
break;
}
2000-09-18 16:07:07 +00:00
}
}
else
{
DBG_ERROR( "No free image id left" );
}
2000-09-18 16:07:07 +00:00
}
else
AddImage( 1, rImage );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
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" );
2000-09-18 16:07:07 +00:00
USHORT nIndex, nCopyIndex = 0;
2000-09-18 16:07:07 +00:00
while( nCopyIndex < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
if ( mpImplData->mpAry[nCopyIndex].mnId == nCopyId )
break;
++nCopyIndex;
2000-09-18 16:07:07 +00:00
}
if( nCopyIndex < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
ImplMakeUnique();
2000-09-18 16:07:07 +00:00
if( mpImplData->mnRealCount == mpImplData->mnArySize )
{
ImageAryData* pOldAry = mpImplData->mpAry;
USHORT nOldSize = mpImplData->mnArySize;
2000-09-18 16:07:07 +00:00
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;
2000-09-18 16:07:07 +00:00
}
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
void ImageList::CopyImage( const ::rtl::OUString& rImageName, const ::rtl::OUString& rCopyName )
{
CopyImage( ImplGetImageId( rImageName ), ImplGetImageId( rCopyName ) );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
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" );
2000-09-18 16:07:07 +00:00
RemoveImage( nId );
AddImage( nId, rImage );
}
// -----------------------------------------------------------------------
void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const Image& rImage )
2000-09-18 16:07:07 +00:00
{
ReplaceImage( ImplGetImageId( rImageName ), rImage );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void ImageList::ReplaceImage( USHORT nId, USHORT nReplaceId )
2000-09-18 16:07:07 +00:00
{
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" );
2000-09-18 16:07:07 +00:00
USHORT nPos1 = 0, nPos2 = 0;
2000-09-18 16:07:07 +00:00
while( nPos1 < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
if ( mpImplData->mpAry[nPos1].mnId == nId )
break;
++nPos1;
2000-09-18 16:07:07 +00:00
}
if( nPos1 < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
while( nPos2 < mpImplData->mnArySize )
{
if( mpImplData->mpAry[nPos2].mnId == nReplaceId )
break;
++nPos2;
}
2000-09-18 16:07:07 +00:00
if( nPos2 < mpImplData->mnArySize )
{
ImplMakeUnique();
mpImplData->mpImageBitmap->Replace( nPos1, nPos2 );
}
2000-09-18 16:07:07 +00:00
}
}
2000-09-18 16:07:07 +00:00
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const ::rtl::OUString& rReplaceName )
{
ReplaceImage( ImplGetImageId( rImageName ), ImplGetImageId( rReplaceName ) );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
void ImageList::RemoveImage( USHORT nId )
{
DBG_CHKTHIS( ImageList, NULL );
if( mpImplData )
2000-09-18 16:07:07 +00:00
{
USHORT i = 0;
ImplMakeUnique();
while( i < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
if( mpImplData->mpAry[i].mnId == nId )
2000-09-18 16:07:07 +00:00
break;
++i;
2000-09-18 16:07:07 +00:00
}
if( i < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
--mpImplData->mpAry[i].mnRefCount;
2000-09-18 16:07:07 +00:00
mpImplData->mpAry[i].mnId = 0;
if( !mpImplData->mpAry[i].mnRefCount )
--mpImplData->mnRealCount;
--mpImplData->mnCount;
2000-09-18 16:07:07 +00:00
}
}
}
// -----------------------------------------------------------------------
void ImageList::RemoveImage( const ::rtl::OUString& rImageName )
{
RemoveImage( ImplGetImageId( rImageName ) );
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
Image ImageList::GetImage( USHORT nId ) const
{
DBG_CHKTHIS( ImageList, NULL );
Image aImage;
if( mpImplData )
2000-09-18 16:07:07 +00:00
{
USHORT i = 0;
while( i < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
if( mpImplData->mpAry[i].mnId == nId )
2000-09-18 16:07:07 +00:00
break;
++i;
2000-09-18 16:07:07 +00:00
}
if( i < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
ImplImageRefData* mpData = new ImplImageRefData;
++mpImplData->mnIRefCount;
++mpImplData->mpAry[i].mnRefCount;
2000-09-18 16:07:07 +00:00
mpData->mpImplData = mpImplData;
mpData->mnIndex = i;
aImage.mpImplData = new ImplImage;
aImage.mpImplData->mnRefCount = 1;
aImage.mpImplData->meType = IMAGETYPE_IMAGEREF;
aImage.mpImplData->mpData = mpData;
}
}
return aImage;
}
// -----------------------------------------------------------------------
Image ImageList::GetImage( const ::rtl::OUString& rImageName ) const
{
return GetImage( ImplGetImageId( rImageName ) );
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
void ImageList::Clear()
{
DBG_CHKTHIS( ImageList, NULL );
if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
delete mpImplData;
2000-09-18 16:07:07 +00:00
mpImplData = NULL;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
USHORT ImageList::GetImageCount() const
{
DBG_CHKTHIS( ImageList, NULL );
return( mpImplData ? mpImplData->mnCount : 0 );
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
USHORT ImageList::GetImagePos( USHORT nId ) const
{
DBG_CHKTHIS( ImageList, NULL );
if( mpImplData && nId )
2000-09-18 16:07:07 +00:00
{
USHORT nPos = 0, i = 0;
while( i < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
if( mpImplData->mpAry[i].mnId == nId )
2000-09-18 16:07:07 +00:00
return nPos;
if ( mpImplData->mpAry[i].mnId )
++nPos;
++i;
2000-09-18 16:07:07 +00:00
}
}
return IMAGELIST_IMAGE_NOTFOUND;
}
// -----------------------------------------------------------------------
USHORT ImageList::GetImagePos( const ::rtl::OUString& rImageName ) const
2000-09-18 16:07:07 +00:00
{
DBG_CHKTHIS( ImageList, NULL );
if( mpImplData && rImageName.getLength() )
2000-09-18 16:07:07 +00:00
{
USHORT nPos = 0, i = 0;
while( i < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
if( mpImplData->mpAry[i].maName == rImageName )
return nPos;
2000-09-18 16:07:07 +00:00
if ( mpImplData->mpAry[i].mnId )
++nPos;
++i;
2000-09-18 16:07:07 +00:00
}
}
return IMAGELIST_IMAGE_NOTFOUND;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
USHORT ImageList::GetImageId( USHORT nPos ) const
2000-09-18 16:07:07 +00:00
{
DBG_CHKTHIS( ImageList, NULL );
if( mpImplData )
2000-09-18 16:07:07 +00:00
{
USHORT nRealPos = 0, i = 0;
while( i < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
if( (nPos == nRealPos) && (mpImplData->mpAry[i].mnId) )
return mpImplData->mpAry[i].mnId;
2000-09-18 16:07:07 +00:00
if ( mpImplData->mpAry[i].mnId )
++nRealPos;
2000-09-18 16:07:07 +00:00
++i;
}
2000-09-18 16:07:07 +00:00
}
return 0;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
::rtl::OUString ImageList::GetImageName( USHORT nPos ) const
2000-09-18 16:07:07 +00:00
{
DBG_CHKTHIS( ImageList, NULL );
if( mpImplData )
2000-09-18 16:07:07 +00:00
{
USHORT nRealPos = 0, i = 0;
while( i < mpImplData->mnArySize )
2000-09-18 16:07:07 +00:00
{
if( (nPos == nRealPos) && (mpImplData->mpAry[i].mnId) )
return mpImplData->mpAry[i].maName;
2000-09-18 16:07:07 +00:00
if ( mpImplData->mpAry[i].mnId )
++nRealPos;
2000-09-18 16:07:07 +00:00
++i;
}
2000-09-18 16:07:07 +00:00
}
return ::rtl::OUString();
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
Size ImageList::GetImageSize() const
2000-09-18 16:07:07 +00:00
{
DBG_CHKTHIS( ImageList, NULL );
Size aRet;
if( mpImplData )
aRet = mpImplData->maImageSize;
return aRet;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
BitmapEx ImageList::GetBitmapEx() const
2000-09-18 16:07:07 +00:00
{
DBG_CHKTHIS( ImageList, NULL );
BitmapEx aRet;
2000-09-18 16:07:07 +00:00
if( mpImplData )
{
USHORT* pPosAry = new USHORT[ mpImplData->mnCount ];
USHORT nPosCount = 0;
2000-09-18 16:07:07 +00:00
for( USHORT i = 0; i < mpImplData->mnArySize; i++ )
{
if( mpImplData->mpAry[i].mnId )
{
pPosAry[ nPosCount ] = i;
++nPosCount;
}
}
2000-09-18 16:07:07 +00:00
aRet = mpImplData->mpImageBitmap->GetBitmapEx( nPosCount, pPosAry );
delete[] pPosAry;
}
2000-09-18 16:07:07 +00:00
return aRet;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
2002-03-01 11:35:42 +00:00
ImageList ImageList::GetColorTransformedImageList( ImageColorTransform eColorTransform ) const
{
DBG_CHKTHIS( ImageList, NULL );
ImageList aRet;
if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform )
2002-03-01 11:35:42 +00:00
{
Color* pSrcColors = NULL;
Color* pDstColors = NULL;
ULONG nColorCount = 0;
aRet = *this;
aRet.ImplMakeUnique();
2002-03-01 11:35:42 +00:00
Image::GetColorTransformArrays( eColorTransform, pSrcColors, pDstColors, nColorCount );
if( nColorCount && pSrcColors && pDstColors && mpImplData )
aRet.mpImplData->mpImageBitmap->ReplaceColors( pSrcColors, pDstColors, nColorCount );
2002-03-01 11:35:42 +00:00
delete[] pSrcColors;
delete[] pDstColors;
}
else if( IMAGECOLORTRANSFORM_MONOCHROME_BLACK == eColorTransform ||
IMAGECOLORTRANSFORM_MONOCHROME_WHITE == eColorTransform )
{
aRet = *this;
aRet.ImplMakeUnique();
aRet.mpImplData->mpImageBitmap->ColorTransform( ( BmpColorMode )( eColorTransform ) );
}
2002-03-01 11:35:42 +00:00
if( !aRet.GetImageCount() )
aRet = *this;
return aRet;
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
ImageList& ImageList::operator=( const ImageList& rImageList )
{
DBG_CHKTHIS( ImageList, NULL );
DBG_CHKOBJ( &rImageList, ImageList, NULL );
if( rImageList.mpImplData )
++rImageList.mpImplData->mnRefCount;
2000-09-18 16:07:07 +00:00
if( mpImplData && ( 0 == --mpImplData->mnRefCount ) && ( 0 == mpImplData->mnIRefCount ) )
delete mpImplData;
2000-09-18 16:07:07 +00:00
mpImplData = rImageList.mpImplData;
mnInitSize = rImageList.mnInitSize;
mnGrowSize = rImageList.mnGrowSize;
return *this;
}
// -----------------------------------------------------------------------
BOOL ImageList::operator==( const ImageList& rImageList ) const
{
DBG_CHKTHIS( ImageList, NULL );
DBG_CHKOBJ( &rImageList, ImageList, NULL );
BOOL bRet;
2000-09-18 16:07:07 +00:00
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;
}
2000-09-18 16:07:07 +00:00
return bRet;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
SvStream& operator>>( SvStream& rIStream, ImageList& rImageList )
{
DBG_CHKOBJ( &rImageList, ImageList, NULL );
if( rImageList.mpImplData )
2000-09-18 16:07:07 +00:00
{
--rImageList.mpImplData->mnRefCount;
if( ( 0 == rImageList.mpImplData->mnRefCount ) && ( 0 == rImageList.mpImplData->mnIRefCount ) )
2000-09-18 16:07:07 +00:00
delete rImageList.mpImplData;
}
2000-09-18 16:07:07 +00:00
rImageList.mpImplData = NULL;
USHORT nVersion;
Size aImageSize;
BOOL bImageList;
rIStream >> nVersion >> rImageList.mnInitSize >> rImageList.mnGrowSize >> bImageList;
2000-09-18 16:07:07 +00:00
if( bImageList )
2000-09-18 16:07:07 +00:00
{
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 )
2000-09-18 16:07:07 +00:00
{
rIStream >> rImageList.mpImplData->mpAry[i].mnId;
rImageList.mpImplData->mpAry[i].mnRefCount = 1;
2000-09-18 16:07:07 +00:00
}
rIStream >> aBmp >> bMaskOrAlpha;
2000-09-18 16:07:07 +00:00
if( bMaskOrAlpha )
{
Bitmap aMaskOrAlpha;
2000-09-18 16:07:07 +00:00
rIStream >> aMaskOrAlpha;
2000-09-18 16:07:07 +00:00
if( aMaskOrAlpha.GetBitCount() == 8 && aMaskOrAlpha.HasGreyPalette() )
aBmpEx = BitmapEx( aBmp, AlphaMask( aMaskOrAlpha ) );
else
aBmpEx = BitmapEx( aBmp, aMaskOrAlpha );
2000-09-18 16:07:07 +00:00
}
rIStream >> bMaskColor;
if( bMaskColor )
2000-09-18 16:07:07 +00:00
{
Color aMaskColor;
2000-09-18 16:07:07 +00:00
rIStream >> aMaskColor;
2000-09-18 16:07:07 +00:00
if( !aBmpEx.IsAlpha() && !aBmpEx.IsTransparent() )
aBmpEx = BitmapEx( aBmp, aMaskColor );
2000-09-18 16:07:07 +00:00
}
rImageList.mpImplData->mpImageBitmap = new ImplImageBmp;
rImageList.mpImplData->mpImageBitmap->Create( aBmpEx, aImageSize.Width(), aImageSize.Height(), rImageList.mnInitSize );
2000-09-18 16:07:07 +00:00
}
return rIStream;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
SvStream& operator<<( SvStream& rOStream, const ImageList& rImageList )
2000-09-18 16:07:07 +00:00
{
DBG_CHKOBJ( &rImageList, ImageList, NULL );
2000-09-18 16:07:07 +00:00
USHORT nVersion = IMAGE_FILE_VERSION;
BOOL bImageList = rImageList.mpImplData ? true : false;
rOStream << nVersion;
2000-09-18 16:07:07 +00:00
if ( !bImageList || !rImageList.mpImplData->mnCount )
rOStream << rImageList.mnInitSize << rImageList.mnGrowSize << ( bImageList = FALSE );
else
2000-09-18 16:07:07 +00:00
{
rOStream << rImageList.mpImplData->mnCount;
rOStream << rImageList.mnGrowSize;
rOStream << bImageList;
rOStream << rImageList.mpImplData->maImageSize.Width();
rOStream << rImageList.mpImplData->maImageSize.Height();
2000-09-18 16:07:07 +00:00
USHORT* mpPosAry = new USHORT[rImageList.mpImplData->mnCount];
USHORT nPosCount = 0;
2000-09-18 16:07:07 +00:00
for( USHORT i = 0; i < rImageList.mpImplData->mnArySize; ++i )
{
if( rImageList.mpImplData->mpAry[i].mnId )
2000-09-18 16:07:07 +00:00
{
rOStream << rImageList.mpImplData->mpAry[i].mnId;
mpPosAry[ nPosCount++ ] = i;
2000-09-18 16:07:07 +00:00
}
}
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;
2000-09-18 16:07:07 +00:00
}
return rOStream;
2000-09-18 16:07:07 +00:00
}