1676 lines
47 KiB
C++
1676 lines
47 KiB
C++
/*************************************************************************
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* $RCSfile: image.cxx,v $
|
|
*
|
|
* $Revision: 1.26 $
|
|
*
|
|
* last change: $Author: obo $ $Date: 2006-09-17 12:02:02 $
|
|
*
|
|
* The Contents of this file are made available subject to
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
|
*
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2005 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
|
|
*
|
|
************************************************************************/
|
|
|
|
// 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
|
|
#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
|
|
#ifndef _TOOLS_RC_HXX
|
|
#include <tools/rc.hxx>
|
|
#endif
|
|
#ifndef _SV_RESMGR_HXX
|
|
#include <tools/resmgr.hxx>
|
|
#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
|
|
#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
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
// ---------
|
|
// - Image -
|
|
// ---------
|
|
|
|
Image::Image() :
|
|
mpImplData( NULL )
|
|
{
|
|
DBG_CTOR( Image, NULL );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image::Image( const ResId& rResId ) :
|
|
mpImplData( NULL )
|
|
{
|
|
DBG_CTOR( Image, NULL );
|
|
|
|
rResId.SetRT( RSC_IMAGE );
|
|
|
|
ResMgr* pResMgr = rResId.GetResMgr();
|
|
|
|
if( !pResMgr )
|
|
pResMgr = Resource::GetResManager();
|
|
|
|
if( pResMgr->GetResource( rResId ) )
|
|
{
|
|
pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
|
|
|
|
BitmapEx aBmpEx;
|
|
ULONG nObjMask = pResMgr->ReadLong();
|
|
|
|
if( nObjMask & RSC_IMAGE_IMAGEBITMAP )
|
|
{
|
|
aBmpEx = BitmapEx( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
|
|
pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
|
|
}
|
|
|
|
if( nObjMask & RSC_IMAGE_MASKBITMAP )
|
|
{
|
|
if( !aBmpEx.IsEmpty() )
|
|
{
|
|
if( aBmpEx.GetTransparentType() == TRANSPARENT_NONE )
|
|
{
|
|
const Bitmap aMaskBitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
|
|
aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskBitmap );
|
|
}
|
|
}
|
|
|
|
pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
|
|
}
|
|
|
|
if( nObjMask & RSC_IMAGE_MASKCOLOR )
|
|
{
|
|
if( ! aBmpEx.IsEmpty() )
|
|
{
|
|
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() ) );
|
|
}
|
|
if( !aBmpEx.IsEmpty() )
|
|
ImplInit( aBmpEx );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image::Image( const Image& rImage ) :
|
|
mpImplData( rImage.mpImplData )
|
|
{
|
|
DBG_CTOR( Image, NULL );
|
|
|
|
if( mpImplData )
|
|
++mpImplData->mnRefCount;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image::Image( const BitmapEx& rBitmapEx ) :
|
|
mpImplData( NULL )
|
|
{
|
|
DBG_CTOR( Image, NULL );
|
|
|
|
ImplInit( rBitmapEx );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image::Image( const Bitmap& rBitmap ) :
|
|
mpImplData( NULL )
|
|
{
|
|
DBG_CTOR( Image, NULL );
|
|
|
|
ImplInit( rBitmap );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image::Image( const Bitmap& rBitmap, const Bitmap& rMaskBitmap ) :
|
|
mpImplData( NULL )
|
|
{
|
|
DBG_CTOR( Image, NULL );
|
|
|
|
const BitmapEx aBmpEx( rBitmap, rMaskBitmap );
|
|
|
|
ImplInit( aBmpEx );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image::Image( const Bitmap& rBitmap, const Color& rColor ) :
|
|
mpImplData( NULL )
|
|
{
|
|
DBG_CTOR( Image, NULL );
|
|
|
|
const BitmapEx aBmpEx( rBitmap, rColor );
|
|
|
|
ImplInit( aBmpEx );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image::Image( const uno::Reference< graphic::XGraphic >& rxGraphic ) :
|
|
mpImplData( NULL )
|
|
{
|
|
DBG_CTOR( Image, NULL );
|
|
|
|
const Graphic aGraphic( rxGraphic );
|
|
ImplInit( aGraphic.GetBitmapEx() );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image::~Image()
|
|
{
|
|
DBG_DTOR( Image, NULL );
|
|
|
|
if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
|
|
delete mpImplData;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void Image::ImplInit( const BitmapEx& rBmpEx )
|
|
{
|
|
if( !rBmpEx.IsEmpty() )
|
|
{
|
|
mpImplData = new ImplImage;
|
|
mpImplData->mnRefCount = 1;
|
|
|
|
if( rBmpEx.GetTransparentType() == TRANSPARENT_NONE )
|
|
{
|
|
mpImplData->meType = IMAGETYPE_BITMAP;
|
|
mpImplData->mpData = new Bitmap( rBmpEx.GetBitmap() );
|
|
}
|
|
else
|
|
{
|
|
mpImplData->meType = IMAGETYPE_IMAGE;
|
|
mpImplData->mpData = new ImplImageData( rBmpEx );
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Size Image::GetSizePixel() const
|
|
{
|
|
DBG_CHKTHIS( Image, NULL );
|
|
|
|
Size aRet;
|
|
|
|
if( mpImplData )
|
|
{
|
|
switch( mpImplData->meType )
|
|
{
|
|
case IMAGETYPE_BITMAP:
|
|
aRet = static_cast< Bitmap* >( mpImplData->mpData )->GetSizePixel();
|
|
break;
|
|
|
|
case IMAGETYPE_IMAGE:
|
|
aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx.GetSizePixel();
|
|
break;
|
|
|
|
case IMAGETYPE_IMAGEREF:
|
|
aRet = static_cast< ImplImageRefData* >( mpImplData->mpData )->mpImplData->maImageSize;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return aRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
BitmapEx Image::GetBitmapEx() const
|
|
{
|
|
DBG_CHKTHIS( Image, NULL );
|
|
|
|
BitmapEx aRet;
|
|
|
|
if( mpImplData )
|
|
{
|
|
switch( mpImplData->meType )
|
|
{
|
|
case IMAGETYPE_BITMAP:
|
|
aRet = *static_cast< Bitmap* >( mpImplData->mpData );
|
|
break;
|
|
|
|
case IMAGETYPE_IMAGE:
|
|
aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx;
|
|
break;
|
|
|
|
case IMAGETYPE_IMAGEREF:
|
|
{
|
|
ImplImageRefData* pData = static_cast< ImplImageRefData* >( mpImplData->mpData );
|
|
|
|
aRet = pData->mpImplData->mpImageBitmap->GetBitmapEx( 1, &pData->mnIndex );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return aRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
uno::Reference< graphic::XGraphic > Image::GetXGraphic() const
|
|
{
|
|
const Graphic aGraphic( GetBitmapEx() );
|
|
|
|
return aGraphic.GetXGraphic();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image Image::GetColorTransformedImage( ImageColorTransform eColorTransform ) const
|
|
{
|
|
DBG_CHKTHIS( Image, NULL );
|
|
|
|
Image aRet;
|
|
|
|
if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform )
|
|
{
|
|
BitmapEx aBmpEx( GetBitmapEx() );
|
|
|
|
if( !aBmpEx.IsEmpty() )
|
|
{
|
|
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 );
|
|
}
|
|
|
|
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 ) ) );
|
|
}
|
|
|
|
if( !aRet )
|
|
aRet = *this;
|
|
|
|
return aRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void Image::Invert()
|
|
{
|
|
BitmapEx aInvertedBmp( GetBitmapEx() );
|
|
aInvertedBmp.Invert();
|
|
*this = aInvertedBmp;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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;
|
|
|
|
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 );
|
|
}
|
|
else
|
|
{
|
|
rpSrcColor = rpDstColor = NULL;
|
|
rColorCount = 0;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image& Image::operator=( const Image& rImage )
|
|
{
|
|
DBG_CHKTHIS( Image, NULL );
|
|
DBG_CHKOBJ( &rImage, Image, NULL );
|
|
|
|
if( rImage.mpImplData )
|
|
++rImage.mpImplData->mnRefCount;
|
|
|
|
if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
|
|
delete mpImplData;
|
|
|
|
mpImplData = rImage.mpImplData;
|
|
|
|
return *this;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
BOOL Image::operator==( const Image& rImage ) const
|
|
{
|
|
DBG_CHKTHIS( Image, NULL );
|
|
DBG_CHKOBJ( &rImage, Image, NULL );
|
|
|
|
bool bRet = false;
|
|
|
|
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 )
|
|
{
|
|
case IMAGETYPE_BITMAP:
|
|
bRet = ( *static_cast< Bitmap* >( rImage.mpImplData->mpData ) == *static_cast< Bitmap* >( mpImplData->mpData ) );
|
|
break;
|
|
|
|
case IMAGETYPE_IMAGE:
|
|
bRet = static_cast< ImplImageData* >( rImage.mpImplData->mpData )->IsEqual( *static_cast< ImplImageData* >( mpImplData->mpData ) );
|
|
break;
|
|
|
|
case IMAGETYPE_IMAGEREF:
|
|
bRet = static_cast< ImplImageRefData* >( rImage.mpImplData->mpData )->IsEqual( *static_cast< ImplImageRefData* >( mpImplData->mpData ) );
|
|
break;
|
|
|
|
default:
|
|
bRet = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
// -------------
|
|
// - ImageList -
|
|
// -------------
|
|
|
|
ImageList::ImageList( USHORT nInit, USHORT nGrow ) :
|
|
mpImplData( NULL ),
|
|
mnInitSize( nInit ),
|
|
mnGrowSize( nGrow )
|
|
{
|
|
DBG_CTOR( ImageList, NULL );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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( '/' );
|
|
|
|
if( -1 != nPos++ )
|
|
{
|
|
const sal_Int32 nSecondPos = aResMgrName.lastIndexOf( '.' );
|
|
aUserImageName = aResMgrName.copy( nPos, ( ( -1 != nSecondPos ) ? nSecondPos : aResMgrName.getLength() ) - nPos );
|
|
}
|
|
|
|
aUserImageName += ::rtl::OUString::valueOf( static_cast< sal_Int32 >( rResId.GetId() ) );
|
|
aUserImageName += ::rtl::OUString::valueOf( nCount );
|
|
|
|
::rtl::OUString aCurrentSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
|
|
aUserImageName += aCurrentSymbolsStyle;
|
|
|
|
ImplInitBitmapEx( aUserImageName, aImageNames, aCurrentSymbolsStyle, aBmpEx, spMaskColor.get() );
|
|
|
|
if( nObjMask & RSC_IMAGELIST_IDCOUNT )
|
|
pResMgr->ReadShort();
|
|
|
|
ImplInit( aBmpEx, sal::static_int_cast<USHORT>(nCount), aIdArray.get(), NULL, 4 );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
ImageList::ImageList( const ::std::vector< ::rtl::OUString >& rNameVector,
|
|
const ::rtl::OUString& rPrefix,
|
|
const Color* pMaskColor ) :
|
|
mpImplData( NULL ),
|
|
mnInitSize( 1 ),
|
|
mnGrowSize( 4 )
|
|
{
|
|
RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImageList(const vector< OUString >& ..." );
|
|
|
|
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 );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
ImageList::ImageList( const ImageList& rImageList ) :
|
|
mpImplData( rImageList.mpImplData ),
|
|
mnInitSize( rImageList.mnInitSize ),
|
|
mnGrowSize( rImageList.mnGrowSize )
|
|
{
|
|
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 );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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 );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
ImageList::ImageList( const Bitmap& rBitmap,
|
|
USHORT nInit, USHORT* pIdAry, USHORT nGrow ) :
|
|
mpImplData( NULL ),
|
|
mnInitSize( nInit ),
|
|
mnGrowSize( nGrow )
|
|
{
|
|
DBG_CTOR( ImageList, NULL );
|
|
|
|
ImplInit( rBitmap, nInit, pIdAry, NULL, nGrow );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
ImageList::ImageList( const Bitmap& rBitmap, const Bitmap& rMaskBmp,
|
|
USHORT nInit, USHORT* pIdAry, USHORT nGrow ) :
|
|
mpImplData( NULL ),
|
|
mnInitSize( nInit ),
|
|
mnGrowSize( nGrow )
|
|
{
|
|
DBG_CTOR( ImageList, NULL );
|
|
|
|
const BitmapEx aBmpEx( rBitmap, rMaskBmp );
|
|
|
|
ImplInit( aBmpEx, nInit, pIdAry, NULL, nGrow );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
ImageList::ImageList( const Bitmap& rBitmap, const Color& rColor,
|
|
USHORT nInit, USHORT* pIdAry, USHORT nGrow )
|
|
{
|
|
DBG_CTOR( ImageList, NULL );
|
|
|
|
const BitmapEx aBmpEx( rBitmap, rColor );
|
|
|
|
ImplInit( aBmpEx, nInit, pIdAry, NULL, nGrow );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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 )
|
|
{
|
|
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() )
|
|
{
|
|
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;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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( rImage.mpImplData, "ImageList::AddImage(): Wrong Size" );
|
|
DBG_ASSERT( !mpImplData || (rImage.GetSizePixel() == mpImplData->maImageSize), "ImageList::AddImage(): Wrong Size" );
|
|
|
|
bool bHasImage = ( rImage.mpImplData != 0 );
|
|
ImageType eImageType = IMAGETYPE_BITMAP;
|
|
Size aImageSize;
|
|
USHORT nIndex;
|
|
|
|
if( bHasImage )
|
|
{
|
|
eImageType = rImage.mpImplData->meType;
|
|
aImageSize = rImage.GetSizePixel();
|
|
}
|
|
else
|
|
{
|
|
if( mpImplData )
|
|
{
|
|
eImageType = IMAGETYPE_BITMAP;
|
|
aImageSize = mpImplData->maImageSize;
|
|
}
|
|
else
|
|
return;
|
|
}
|
|
|
|
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 );
|
|
}
|
|
else
|
|
ImplMakeUnique();
|
|
|
|
if( mpImplData->mnRealCount == mpImplData->mnArySize )
|
|
{
|
|
ImageAryData* pOldAry = mpImplData->mpAry;
|
|
USHORT nOldSize = mpImplData->mnArySize;
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
++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 )
|
|
{
|
|
for( i = 0; i < mpImplData->mnArySize; ++i )
|
|
{
|
|
if( mpImplData->mpAry[ i ].mnId > nMax )
|
|
{
|
|
nMax = mpImplData->mpAry[ i ].mnId;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( nMax < USHRT_MAX )
|
|
{
|
|
AddImage( ++nMax, rImage );
|
|
|
|
for( i = 0; i < mpImplData->mnArySize; ++i )
|
|
{
|
|
if( mpImplData->mpAry[ i ].mnId == nMax )
|
|
{
|
|
mpImplData->mpAry[ i ].maName = rImageName;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBG_ERROR( "No free image id left" );
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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" );
|
|
|
|
USHORT nIndex, nCopyIndex = 0;
|
|
|
|
while( nCopyIndex < mpImplData->mnArySize )
|
|
{
|
|
if ( mpImplData->mpAry[nCopyIndex].mnId == nCopyId )
|
|
break;
|
|
|
|
++nCopyIndex;
|
|
}
|
|
|
|
if( nCopyIndex < mpImplData->mnArySize )
|
|
{
|
|
ImplMakeUnique();
|
|
|
|
if( mpImplData->mnRealCount == mpImplData->mnArySize )
|
|
{
|
|
ImageAryData* pOldAry = mpImplData->mpAry;
|
|
USHORT nOldSize = mpImplData->mnArySize;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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 );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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" );
|
|
|
|
RemoveImage( nId );
|
|
AddImage( nId, rImage );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const Image& rImage )
|
|
{
|
|
const USHORT nId = ImplGetImageId( rImageName );
|
|
|
|
if( nId )
|
|
ReplaceImage( nId, rImage );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void ImageList::ReplaceImage( USHORT nId, USHORT nReplaceId )
|
|
{
|
|
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, nPos2 = 0;
|
|
|
|
while( nPos1 < mpImplData->mnArySize )
|
|
{
|
|
if ( mpImplData->mpAry[nPos1].mnId == nId )
|
|
break;
|
|
|
|
++nPos1;
|
|
}
|
|
|
|
if( nPos1 < mpImplData->mnArySize )
|
|
{
|
|
while( nPos2 < mpImplData->mnArySize )
|
|
{
|
|
if( mpImplData->mpAry[nPos2].mnId == nReplaceId )
|
|
break;
|
|
|
|
++nPos2;
|
|
}
|
|
|
|
if( nPos2 < mpImplData->mnArySize )
|
|
{
|
|
ImplMakeUnique();
|
|
mpImplData->mpImageBitmap->Replace( nPos1, nPos2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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 );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void ImageList::RemoveImage( USHORT nId )
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
if( mpImplData )
|
|
{
|
|
USHORT i = 0;
|
|
|
|
ImplMakeUnique();
|
|
|
|
while( i < mpImplData->mnArySize )
|
|
{
|
|
if( mpImplData->mpAry[i].mnId == nId )
|
|
break;
|
|
|
|
++i;
|
|
}
|
|
|
|
if( i < mpImplData->mnArySize )
|
|
{
|
|
--mpImplData->mpAry[i].mnRefCount;
|
|
mpImplData->mpAry[i].mnId = 0;
|
|
|
|
if( !mpImplData->mpAry[i].mnRefCount )
|
|
--mpImplData->mnRealCount;
|
|
|
|
--mpImplData->mnCount;
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void ImageList::RemoveImage( const ::rtl::OUString& rImageName )
|
|
{
|
|
const USHORT nId = ImplGetImageId( rImageName );
|
|
|
|
if( nId )
|
|
RemoveImage( nId );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
Image ImageList::GetImage( USHORT nId ) const
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
Image aImage;
|
|
|
|
if( mpImplData )
|
|
{
|
|
USHORT i = 0;
|
|
|
|
while( i < mpImplData->mnArySize )
|
|
{
|
|
if( mpImplData->mpAry[i].mnId == nId )
|
|
break;
|
|
|
|
++i;
|
|
}
|
|
|
|
if( i < mpImplData->mnArySize )
|
|
{
|
|
ImplImageRefData* mpData = new ImplImageRefData;
|
|
|
|
++mpImplData->mnIRefCount;
|
|
++mpImplData->mpAry[i].mnRefCount;
|
|
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();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void ImageList::Clear()
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
|
|
delete mpImplData;
|
|
|
|
mpImplData = NULL;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
USHORT ImageList::GetImageCount() const
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
return( mpImplData ? mpImplData->mnCount : 0 );
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
USHORT ImageList::GetImagePos( USHORT nId ) const
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
if( mpImplData && nId )
|
|
{
|
|
USHORT nPos = 0, i = 0;
|
|
|
|
while( i < mpImplData->mnArySize )
|
|
{
|
|
if( mpImplData->mpAry[i].mnId == nId )
|
|
return nPos;
|
|
|
|
if ( mpImplData->mpAry[i].mnId )
|
|
++nPos;
|
|
|
|
++i;
|
|
}
|
|
}
|
|
|
|
return IMAGELIST_IMAGE_NOTFOUND;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
USHORT ImageList::GetImagePos( 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 nPos;
|
|
|
|
if ( mpImplData->mpAry[i].mnId )
|
|
++nPos;
|
|
|
|
++i;
|
|
}
|
|
}
|
|
|
|
return IMAGELIST_IMAGE_NOTFOUND;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
USHORT ImageList::GetImageId( USHORT nPos ) const
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
if( mpImplData )
|
|
{
|
|
USHORT nRealPos = 0, i = 0;
|
|
|
|
while( i < mpImplData->mnArySize )
|
|
{
|
|
if( (nPos == nRealPos) && (mpImplData->mpAry[i].mnId) )
|
|
return mpImplData->mpAry[i].mnId;
|
|
|
|
if ( mpImplData->mpAry[i].mnId )
|
|
++nRealPos;
|
|
|
|
++i;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
if( mpImplData )
|
|
{
|
|
USHORT nRealPos = 0, i = 0;
|
|
|
|
while( i < mpImplData->mnArySize )
|
|
{
|
|
if( (nPos == nRealPos) && (mpImplData->mpAry[i].mnId) )
|
|
return mpImplData->mpAry[i].maName;
|
|
|
|
if ( mpImplData->mpAry[i].mnId )
|
|
++nRealPos;
|
|
|
|
++i;
|
|
}
|
|
}
|
|
|
|
return ::rtl::OUString();
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
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
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
Size aRet;
|
|
|
|
if( mpImplData )
|
|
aRet = mpImplData->maImageSize;
|
|
|
|
return aRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
BitmapEx ImageList::GetBitmapEx() const
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
BitmapEx aRet;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
aRet = mpImplData->mpImageBitmap->GetBitmapEx( nPosCount, pPosAry );
|
|
delete[] pPosAry;
|
|
}
|
|
|
|
return aRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
ImageList ImageList::GetColorTransformedImageList( ImageColorTransform eColorTransform ) const
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
|
|
ImageList aRet;
|
|
|
|
if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform )
|
|
{
|
|
Color* pSrcColors = NULL;
|
|
Color* pDstColors = NULL;
|
|
ULONG nColorCount = 0;
|
|
|
|
aRet = *this;
|
|
aRet.ImplMakeUnique();
|
|
|
|
Image::GetColorTransformArrays( eColorTransform, pSrcColors, pDstColors, nColorCount );
|
|
|
|
if( nColorCount && pSrcColors && pDstColors && mpImplData )
|
|
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( ( BmpColorMode )( eColorTransform ) );
|
|
}
|
|
|
|
if( !aRet.GetImageCount() )
|
|
aRet = *this;
|
|
|
|
return aRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
void ImageList::Invert()
|
|
{
|
|
ImageList aNew( *this );
|
|
aNew.ImplMakeUnique();
|
|
aNew.mpImplData->mpImageBitmap->Invert();
|
|
|
|
*this = aNew;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
ImageList& ImageList::operator=( const ImageList& rImageList )
|
|
{
|
|
DBG_CHKTHIS( ImageList, NULL );
|
|
DBG_CHKOBJ( &rImageList, ImageList, NULL );
|
|
|
|
if( rImageList.mpImplData )
|
|
++rImageList.mpImplData->mnRefCount;
|
|
|
|
if( mpImplData && ( 0 == --mpImplData->mnRefCount ) && ( 0 == mpImplData->mnIRefCount ) )
|
|
delete mpImplData;
|
|
|
|
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;
|
|
|
|
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 bRet;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
SvStream& operator>>( SvStream& rIStream, ImageList& rImageList )
|
|
{
|
|
DBG_CHKOBJ( &rImageList, ImageList, NULL );
|
|
|
|
if( rImageList.mpImplData )
|
|
{
|
|
--rImageList.mpImplData->mnRefCount;
|
|
|
|
if( ( 0 == rImageList.mpImplData->mnRefCount ) && ( 0 == rImageList.mpImplData->mnIRefCount ) )
|
|
delete rImageList.mpImplData;
|
|
}
|
|
|
|
rImageList.mpImplData = NULL;
|
|
|
|
USHORT nVersion;
|
|
Size aImageSize;
|
|
BOOL bImageList;
|
|
|
|
rIStream >> nVersion >> rImageList.mnInitSize >> rImageList.mnGrowSize >> bImageList;
|
|
|
|
if( bImageList )
|
|
{
|
|
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 )
|
|
{
|
|
rIStream >> rImageList.mpImplData->mpAry[i].mnId;
|
|
rImageList.mpImplData->mpAry[i].mnRefCount = 1;
|
|
}
|
|
|
|
rIStream >> aBmp >> bMaskOrAlpha;
|
|
|
|
if( bMaskOrAlpha )
|
|
{
|
|
Bitmap aMaskOrAlpha;
|
|
|
|
rIStream >> aMaskOrAlpha;
|
|
|
|
if( aMaskOrAlpha.GetBitCount() == 8 && aMaskOrAlpha.HasGreyPalette() )
|
|
aBmpEx = BitmapEx( aBmp, AlphaMask( aMaskOrAlpha ) );
|
|
else
|
|
aBmpEx = BitmapEx( aBmp, aMaskOrAlpha );
|
|
}
|
|
|
|
rIStream >> bMaskColor;
|
|
|
|
if( bMaskColor )
|
|
{
|
|
Color aMaskColor;
|
|
|
|
rIStream >> aMaskColor;
|
|
|
|
if( !aBmpEx.IsAlpha() && !aBmpEx.IsTransparent() )
|
|
aBmpEx = BitmapEx( aBmp, aMaskColor );
|
|
}
|
|
|
|
rImageList.mpImplData->mpImageBitmap = new ImplImageBmp;
|
|
rImageList.mpImplData->mpImageBitmap->Create( aBmpEx, aImageSize.Width(), aImageSize.Height(), rImageList.mnInitSize );
|
|
}
|
|
|
|
return rIStream;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
SvStream& operator<<( SvStream& rOStream, const ImageList& rImageList )
|
|
{
|
|
DBG_CHKOBJ( &rImageList, ImageList, NULL );
|
|
|
|
USHORT nVersion = IMAGE_FILE_VERSION;
|
|
BOOL bImageList = rImageList.mpImplData ? true : false;
|
|
|
|
rOStream << nVersion;
|
|
|
|
if ( !bImageList || !rImageList.mpImplData->mnCount )
|
|
rOStream << rImageList.mnInitSize << rImageList.mnGrowSize << ( bImageList = FALSE );
|
|
else
|
|
{
|
|
rOStream << rImageList.mpImplData->mnCount;
|
|
rOStream << rImageList.mnGrowSize;
|
|
rOStream << bImageList;
|
|
rOStream << rImageList.mpImplData->maImageSize.Width();
|
|
rOStream << rImageList.mpImplData->maImageSize.Height();
|
|
|
|
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 )
|
|
{
|
|
rOStream << rImageList.mpImplData->mpAry[i].mnId;
|
|
mpPosAry[ nPosCount++ ] = i;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|