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

1676 lines
47 KiB
C++
Raw Normal View History

/*************************************************************************
2000-09-18 16:07:07 +00:00
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 16:07:07 +00:00
*
* $RCSfile: image.cxx,v $
2000-09-18 16:07:07 +00:00
*
* $Revision: 1.26 $
2000-09-18 16:07:07 +00:00
*
* last change: $Author: obo $ $Date: 2006-09-17 12:02:02 $
2000-09-18 16:07:07 +00:00
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
2000-09-18 16:07:07 +00:00
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
2000-09-18 16:07:07 +00:00
*
* 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.
2000-09-18 16:07:07 +00:00
*
* 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.
2000-09-18 16:07:07 +00:00
*
* 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
2000-09-18 16:07:07 +00:00
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#ifndef _RTL_LOGFILE_HXX_
#include <rtl/logfile.hxx>
#endif
2000-09-18 16:07:07 +00:00
#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_GRAPH_HXX
#include <graph.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <svapp.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 )
2000-09-18 16:07:07 +00:00
#define IMAGE_FILE_VERSION 100
2000-09-18 16:07:07 +00:00
using namespace ::com::sun::star;
// ---------
// - 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;
ULONG nObjMask = pResMgr->ReadLong();
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( nObjMask & RSC_IMAGE_MASKBITMAP )
2000-09-18 16:07:07 +00:00
{
if( !aBmpEx.IsEmpty() )
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() ) );
}
if( nObjMask & RSC_IMAGE_MASKCOLOR )
{
if( ! aBmpEx.IsEmpty() )
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 );
}
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( !aBmpEx.IsEmpty() )
ImplInit( aBmpEx );
2000-09-18 16:07:07 +00:00
}
}
// -----------------------------------------------------------------------
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( const uno::Reference< graphic::XGraphic >& rxGraphic ) :
mpImplData( NULL )
{
DBG_CTOR( Image, NULL );
const Graphic aGraphic( rxGraphic );
ImplInit( aGraphic.GetBitmapEx() );
}
// -----------------------------------------------------------------------
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
}
// -----------------------------------------------------------------------
uno::Reference< graphic::XGraphic > Image::GetXGraphic() const
{
const Graphic aGraphic( GetBitmapEx() );
return aGraphic.GetXGraphic();
}
// -----------------------------------------------------------------------
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::Invert()
{
BitmapEx aInvertedBmp( GetBitmapEx() );
aInvertedBmp.Invert();
*this = aInvertedBmp;
}
// -----------------------------------------------------------------------
2002-03-01 11:35:42 +00:00
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 = false;
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 )
{
RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImageList( const ResId& rResId )" );
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 ) );
ULONG nObjMask = pResMgr->ReadLong();
const String aPrefix( pResMgr->ReadString() );
::boost::scoped_ptr< Color > spMaskColor;
if( nObjMask & RSC_IMAGE_MASKCOLOR )
spMaskColor.reset( new Color( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) ) );
pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
if( nObjMask & RSC_IMAGELIST_IDLIST )
{
for( sal_Int32 i = 0, nCount = pResMgr->ReadLong(); i < nCount; ++i )
pResMgr->ReadLong();
}
BitmapEx aBmpEx;
sal_Int32 nCount = pResMgr->ReadLong();
::boost::scoped_array< USHORT > aIdArray( new USHORT[ nCount ] );
::std::vector< ::rtl::OUString > aImageNames( nCount );
::rtl::OUString aResMgrName( pResMgr->GetFileName() );
::rtl::OUString aUserImageName;
sal_Int32 nPos = aResMgrName.lastIndexOf( '\\' );
// load file entry list
for( sal_Int32 i = 0; i < nCount; ++i )
{
aImageNames[ i ] = pResMgr->ReadString();
aIdArray[ i ] = static_cast< USHORT >( pResMgr->ReadLong() );
}
if( -1 == nPos )
nPos = aResMgrName.lastIndexOf( '/' );
2000-09-18 16:07:07 +00:00
if( -1 != nPos++ )
{
const sal_Int32 nSecondPos = aResMgrName.lastIndexOf( '.' );
aUserImageName = aResMgrName.copy( nPos, ( ( -1 != nSecondPos ) ? nSecondPos : aResMgrName.getLength() ) - nPos );
}
2000-09-18 16:07:07 +00:00
aUserImageName += ::rtl::OUString::valueOf( static_cast< sal_Int32 >( rResId.GetId() ) );
aUserImageName += ::rtl::OUString::valueOf( nCount );
2000-09-18 16:07:07 +00:00
::rtl::OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
aUserImageName += aCurrentSymbolsStyle;
ImplInitBitmapEx( aUserImageName, aImageNames, aCurrentSymbolsStyle, aBmpEx, spMaskColor.get() );
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, sal::static_int_cast<USHORT>(nCount), aIdArray.get(), NULL, 4 );
}
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------
ImageList::ImageList( const ::std::vector< ::rtl::OUString >& rNameVector,
const ::rtl::OUString& rPrefix,
const Color* pMaskColor ) :
mpImplData( NULL ),
mnInitSize( 1 ),
mnGrowSize( 4 )
2000-09-18 16:07:07 +00:00
{
RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImageList(const vector< OUString >& ..." );
2000-09-18 16:07:07 +00:00
DBG_CTOR( ImageList, NULL );
BitmapEx aBmpEx;
::rtl::OUString aUserImageName( rPrefix );
::std::vector< ::rtl::OUString > aImageNames( rNameVector.size() );
const lang::Locale& rLocale = Application::GetSettings().GetUILocale();
for( sal_Int32 i = 0, nCount = rNameVector.size(); i < nCount; ++i )
( aImageNames[ i ] = rPrefix ) += rNameVector[ i ];
aUserImageName = ( ( aUserImageName += rLocale.Language ) += rLocale.Country ).replace( '/', '_' );
aUserImageName += ::rtl::OUString::valueOf( static_cast< sal_Int32 >( rNameVector.size() ) );
::rtl::OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
aUserImageName += aCurrentSymbolsStyle;
ImplInitBitmapEx( aUserImageName, aImageNames, aCurrentSymbolsStyle, aBmpEx, 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 BitmapEx& rBitmapEx,
const ::std::vector< ::rtl::OUString >& rNameVector,
USHORT nGrow ) :
mpImplData( NULL ),
mnInitSize( static_cast< USHORT >( rNameVector.size() ) ),
mnGrowSize( nGrow )
{
RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImageList( const BitmapEx& ..." );
DBG_CTOR( ImageList, NULL );
ImplInit( rBitmapEx, static_cast< USHORT >( rNameVector.size() ), NULL, &rNameVector, 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::ImplInitBitmapEx( const ::rtl::OUString& rUserImageName,
const ::std::vector< ::rtl::OUString >& rImageNames,
const ::rtl::OUString& rSymbolsStyle,
BitmapEx& rBmpEx,
const Color* pMaskColor ) const
{
static ImplImageTreeSingletonRef aImageTree;
if( !aImageTree->loadImage( rUserImageName, rSymbolsStyle, rBmpEx ) )
{
BitmapEx aCurBmpEx;
Size aItemSizePixel;
bool bInit = false;
for( sal_Int32 i = 0, nCount = rImageNames.size(); i < nCount; ++i )
{
if( aImageTree->loadImage( rImageNames[ i ], rSymbolsStyle, aCurBmpEx, true ) )
{
const Size aCurSizePixel( aCurBmpEx.GetSizePixel() );
if( !bInit )
{
const Size aTotalSize( aCurSizePixel.Width() * nCount, aCurSizePixel.Height() );
BYTE cTransparent = 255;
const Bitmap aBmp( aTotalSize, 24 );
const AlphaMask aAlphaMask( aTotalSize, &cTransparent );
aItemSizePixel = aCurSizePixel;
rBmpEx = BitmapEx( aBmp, aAlphaMask );
bInit = true;
}
#ifdef DBG_UTIL
if( ( aItemSizePixel.Width() < aCurSizePixel.Width() ) ||
( aItemSizePixel.Height() < aCurSizePixel.Height() ) )
{
ByteString aStr( "Differerent dimensions in ItemList images: " );
aStr += ByteString( String( rImageNames[ i ] ), RTL_TEXTENCODING_ASCII_US );
aStr += " is ";
aStr += ByteString::CreateFromInt32( aCurSizePixel.Width() );
aStr += "x";
aStr += ByteString::CreateFromInt32( aCurSizePixel.Height() );
aStr += " but needs to be ";
aStr += ByteString::CreateFromInt32( aItemSizePixel.Width() );
aStr += "x";
aStr += ByteString::CreateFromInt32( aItemSizePixel.Height() );
DBG_ERROR( aStr.GetBuffer() );
}
#endif
const Rectangle aRectDst( Point( aItemSizePixel.Width() * i, 0 ), aItemSizePixel );
const Rectangle aRectSrc( Point( 0, 0 ), aCurSizePixel );
rBmpEx.CopyPixel( aRectDst, aRectSrc, &aCurBmpEx );
}
#ifdef DBG_UTIL
else
{
ByteString aErrorStr( "ImageList::ImplInitBitmapEx(...): could not load image <" );
DBG_ERROR( ( ( aErrorStr += ByteString( String( rImageNames[ i ] ), RTL_TEXTENCODING_ASCII_US ) ) += '>' ).GetBuffer() );
}
#endif
}
if( !rBmpEx.IsEmpty() )
{
if( !rBmpEx.IsTransparent() && pMaskColor )
rBmpEx = BitmapEx( rBmpEx.GetBitmap(), *pMaskColor );
aImageTree->addUserImage( rUserImageName, rBmpEx );
}
}
}
// -----------------------------------------------------------------------
void ImageList::ImplInit( const BitmapEx& rBitmapEx,
USHORT nInit, const USHORT* pIdAry,
const ::std::vector< ::rtl::OUString >* pNames,
USHORT nGrow )
{
RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImplInit" );
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 = sal::static_int_cast<USHORT>(mpImplData->mnArySize + mnGrowSize);
2000-09-18 16:07:07 +00:00
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, Color( 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" );
USHORT i, nMax = 0;
if( mpImplData )
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 )
{
if( mpImplData->mpAry[ i ].mnId == nMax )
2000-09-18 16:07:07 +00:00
{
mpImplData->mpAry[ i ].maName = rImageName;
break;
2000-09-18 16:07:07 +00:00
}
}
2000-09-18 16:07:07 +00:00
}
else
{
DBG_ERROR( "No free image id left" );
}
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 = sal::static_int_cast<USHORT>(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 )
{
const USHORT nId1 = ImplGetImageId( rImageName ), nId2 = ImplGetImageId( rCopyName );
if( nId1 && nId2 )
CopyImage( nId1, nId2 );
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
{
const USHORT nId = ImplGetImageId( rImageName );
if( nId )
ReplaceImage( nId, 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 )
{
const USHORT nId1 = ImplGetImageId( rImageName ), nId2 = ImplGetImageId( rReplaceName );
if( nId1 && nId2 )
ReplaceImage( nId1, nId2 );
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 )
{
const USHORT nId = ImplGetImageId( rImageName );
if( nId )
RemoveImage( nId );
}
// -----------------------------------------------------------------------
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
{
const USHORT nId = ImplGetImageId( rImageName );
if( nId )
return GetImage( nId );
else
return Image();
}
// -----------------------------------------------------------------------
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
}
// -----------------------------------------------------------------------
void ImageList::GetImageIds( ::std::vector< USHORT >& rIds ) const
{
RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::GetImageIds" );
DBG_CHKTHIS( ImageList, NULL );
rIds = ::std::vector< USHORT >();
if( mpImplData )
{
for( USHORT i = 0; i < mpImplData->mnArySize; ++i )
{
if( mpImplData->mpAry[ i ].mnId )
rIds.push_back( mpImplData->mpAry[ i ].mnId );
}
}
}
// -----------------------------------------------------------------------
::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
}
// -----------------------------------------------------------------------
void ImageList::GetImageNames( ::std::vector< ::rtl::OUString >& rNames ) const
{
RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::GetImageNames" );
DBG_CHKTHIS( ImageList, NULL );
rNames = ::std::vector< ::rtl::OUString >();
if( mpImplData )
{
for( USHORT i = 0; i < mpImplData->mnArySize; ++i )
{
if( mpImplData->mpAry[ i ].mnId )
rNames.push_back( mpImplData->mpAry[ i ].maName );
}
}
}
// -----------------------------------------------------------------------
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;
}
// -----------------------------------------------------------------------
void ImageList::Invert()
{
ImageList aNew( *this );
aNew.ImplMakeUnique();
aNew.mpImplData->mpImageBitmap->Invert();
*this = aNew;
}
// -----------------------------------------------------------------------
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 = false;
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
}