| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_vcl.hxx" |
| |
| #include <boost/scoped_ptr.hpp> |
| #include <boost/scoped_array.hpp> |
| |
| #include <rtl/logfile.hxx> |
| |
| #include <tools/debug.hxx> |
| #include <tools/stream.hxx> |
| #include <tools/rc.h> |
| #include <tools/rc.hxx> |
| #include <tools/resmgr.hxx> |
| |
| #include <vcl/settings.hxx> |
| #include <vcl/outdev.hxx> |
| #include <vcl/graph.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vcl/image.hxx> |
| |
| #include <impimagetree.hxx> |
| #include <image.h> |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| #include <rtl/strbuf.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->GetResource( rResId ) ) |
| { |
| pResMgr->Increment( sizeof( RSHEADER_TYPE ) ); |
| |
| BitmapEx aBmpEx; |
| sal_uLong nObjMask = pResMgr->ReadLong(); |
| |
| if( nObjMask & RSC_IMAGE_IMAGEBITMAP ) |
| { |
| aBmpEx = BitmapEx( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) ); |
| pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); |
| } |
| |
| if( nObjMask & RSC_IMAGE_MASKBITMAP ) |
| { |
| if( !aBmpEx.IsEmpty() && aBmpEx.GetTransparentType() == TRANSPARENT_NONE ) |
| { |
| const Bitmap aMaskBitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) ); |
| aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskBitmap ); |
| } |
| |
| pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); |
| } |
| |
| if( nObjMask & RSC_IMAGE_MASKCOLOR ) |
| { |
| if( !aBmpEx.IsEmpty() && aBmpEx.GetTransparentType() == TRANSPARENT_NONE ) |
| { |
| const Color aMaskColor( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) ); |
| 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; |
| } |
| } |
| |
| 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; |
| } |
| } |
| |
| 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; |
| sal_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, sal_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; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_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; |
| |
| default: |
| bRet = false; |
| break; |
| } |
| } |
| |
| return bRet; |
| } |
| |
| // ------------- |
| // - ImageList - |
| // ------------- |
| |
| ImageList::ImageList( sal_uInt16 nInit, sal_uInt16 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->GetResource( rResId ) ) |
| { |
| pResMgr->Increment( sizeof( RSHEADER_TYPE ) ); |
| |
| sal_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 ) ) ); |
| |
| 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(); |
| } |
| |
| sal_Int32 nCount = pResMgr->ReadLong(); |
| ImplInit( static_cast< sal_uInt16 >( nCount ), Size() ); |
| |
| BitmapEx aEmpty; |
| for( sal_Int32 i = 0; i < nCount; ++i ) |
| { |
| rtl::OUString aName = pResMgr->ReadString(); |
| sal_uInt16 nId = static_cast< sal_uInt16 >( pResMgr->ReadLong() ); |
| mpImplData->AddImage( aName, nId, aEmpty ); |
| } |
| |
| if( nObjMask & RSC_IMAGELIST_IDCOUNT ) |
| pResMgr->ReadShort(); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| ImageList::ImageList( const ::std::vector< ::rtl::OUString >& rNameVector, |
| const ::rtl::OUString& rPrefix, |
| const Color* ) : |
| mpImplData( NULL ), |
| mnInitSize( 1 ), |
| mnGrowSize( 4 ) |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImageList(const vector< OUString >& ..." ); |
| |
| DBG_CTOR( ImageList, NULL ); |
| |
| ImplInit( sal::static_int_cast< sal_uInt16 >( rNameVector.size() ), Size() ); |
| |
| mpImplData->maPrefix = rPrefix; |
| for( sal_uInt32 i = 0; i < rNameVector.size(); ++i ) |
| { |
| // fprintf (stderr, "List %p [%d]: '%s'\n", |
| // this, i, rtl::OUStringToOString( rNameVector[i], RTL_TEXTENCODING_UTF8 ).getStr() ); |
| mpImplData->AddImage( rNameVector[ i ], static_cast< sal_uInt16 >( i ) + 1, BitmapEx() ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| ImageList::ImageList( const ImageList& rImageList ) : |
| mpImplData( rImageList.mpImplData ), |
| mnInitSize( rImageList.mnInitSize ), |
| mnGrowSize( rImageList.mnGrowSize ) |
| { |
| DBG_CTOR( ImageList, NULL ); |
| |
| if( mpImplData ) |
| ++mpImplData->mnRefCount; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| ImageList::~ImageList() |
| { |
| DBG_DTOR( ImageList, NULL ); |
| |
| if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) |
| delete mpImplData; |
| } |
| |
| void ImageList::ImplInit( sal_uInt16 nItems, const Size &rSize ) |
| { |
| mpImplData = new ImplImageList; |
| mpImplData->mnRefCount = 1; |
| mpImplData->maImages.reserve( nItems ); |
| mpImplData->maImageSize = rSize; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageAryData::Load(const rtl::OUString &rPrefix) |
| { |
| static ImplImageTreeSingletonRef aImageTree; |
| |
| ::rtl::OUString aSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName(); |
| |
| BitmapEx aBmpEx; |
| |
| // fprintf (stderr, "Attempt load of '%s'\n", |
| // rtl::OUStringToOString( maName, RTL_TEXTENCODING_UTF8 ).getStr() ); |
| |
| rtl::OUString aFileName = rPrefix; |
| aFileName += maName; |
| #if OSL_DEBUG_LEVEL > 0 |
| bool bSuccess = |
| #endif |
| aImageTree->loadImage( aFileName, aSymbolsStyle, maBitmapEx, true ); |
| #if OSL_DEBUG_LEVEL > 0 |
| if ( !bSuccess ) |
| { |
| ::rtl::OStringBuffer aMessage; |
| aMessage.append( "ImageAryData::Load: failed to load image '" ); |
| aMessage.append( ::rtl::OUStringToOString( aFileName, RTL_TEXTENCODING_UTF8 ).getStr() ); |
| aMessage.append( "'" ); |
| OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() ); |
| } |
| #endif |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::ImplMakeUnique() |
| { |
| if( mpImplData && mpImplData->mnRefCount > 1 ) |
| { |
| --mpImplData->mnRefCount; |
| mpImplData = new ImplImageList( *mpImplData ) ; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| // Rather a performance hazard: |
| BitmapEx ImageList::GetAsHorizontalStrip() const |
| { |
| Size aSize( mpImplData->maImageSize ); |
| sal_uInt16 nCount = GetImageCount(); |
| if( !nCount ) |
| return BitmapEx(); |
| aSize.Width() *= nCount; |
| |
| // Load any stragglers |
| for (sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++) |
| { |
| ImageAryData *pData = mpImplData->maImages[ nIdx ]; |
| if( pData->IsLoadable() ) |
| pData->Load( mpImplData->maPrefix ); |
| } |
| |
| BitmapEx aTempl = mpImplData->maImages[ 0 ]->maBitmapEx; |
| BitmapEx aResult; |
| Bitmap aPixels( aSize, aTempl.GetBitmap().GetBitCount() ); |
| if( aTempl.IsAlpha() ) |
| aResult = BitmapEx( aPixels, AlphaMask( aSize ) ); |
| else if( aTempl.IsTransparent() ) |
| aResult = BitmapEx( aPixels, Bitmap( aSize, aTempl.GetMask().GetBitCount() ) ); |
| else |
| aResult = BitmapEx( aPixels ); |
| |
| Rectangle aSrcRect( Point( 0, 0 ), mpImplData->maImageSize ); |
| for (sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++) |
| { |
| Rectangle aDestRect( Point( nIdx * mpImplData->maImageSize.Width(), 0 ), |
| mpImplData->maImageSize ); |
| ImageAryData *pData = mpImplData->maImages[ nIdx ]; |
| aResult.CopyPixel( aDestRect, aSrcRect, &pData->maBitmapEx); |
| } |
| |
| return aResult; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::InsertFromHorizontalStrip( const BitmapEx &rBitmapEx, |
| const std::vector< rtl::OUString > &rNameVector ) |
| { |
| sal_uInt16 nItems = sal::static_int_cast< sal_uInt16 >( rNameVector.size() ); |
| |
| // fprintf (stderr, "InsertFromHorizontalStrip (1) [%d items]\n", nItems); |
| |
| if (!nItems) |
| return; |
| |
| Size aSize( rBitmapEx.GetSizePixel() ); |
| DBG_ASSERT (rBitmapEx.GetSizePixel().Width() % nItems == 0, |
| "ImageList::InsertFromHorizontalStrip - very odd size"); |
| aSize.Width() /= nItems; |
| ImplInit( nItems, aSize ); |
| |
| for (sal_uInt16 nIdx = 0; nIdx < nItems; nIdx++) |
| { |
| BitmapEx aBitmap( rBitmapEx, Point( nIdx * aSize.Width(), 0 ), aSize ); |
| mpImplData->AddImage( rNameVector[ nIdx ], nIdx + 1, aBitmap ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::InsertFromHorizontalBitmap( const ResId& rResId, |
| sal_uInt16 nCount, |
| const Color *pMaskColor, |
| const Color *pSearchColors, |
| const Color *pReplaceColors, |
| sal_uLong nColorCount) |
| { |
| BitmapEx aBmpEx( rResId ); |
| if (!aBmpEx.IsTransparent()) |
| { |
| if( pMaskColor ) |
| aBmpEx = BitmapEx( aBmpEx.GetBitmap(), *pMaskColor ); |
| else |
| aBmpEx = BitmapEx( aBmpEx.GetBitmap() ); |
| } |
| if ( nColorCount && pSearchColors && pReplaceColors ) |
| aBmpEx.Replace( pSearchColors, pReplaceColors, nColorCount ); |
| |
| std::vector< rtl::OUString > aNames( nCount ); |
| InsertFromHorizontalStrip( aBmpEx, aNames ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ImageList::ImplGetImageId( const ::rtl::OUString& rImageName ) const |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| ImageAryData *pImg = mpImplData->maNameHash[ rImageName ]; |
| if( pImg ) |
| return pImg->mnId; |
| else |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::AddImage( sal_uInt16 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" ); |
| |
| if( !mpImplData ) |
| ImplInit( 0, rImage.GetSizePixel() ); |
| |
| mpImplData->AddImage( rtl::OUString(), nId, rImage.GetBitmapEx()); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::AddImage( const ::rtl::OUString& rImageName, const Image& rImage ) |
| { |
| DBG_ASSERT( GetImagePos( rImageName ) == IMAGELIST_IMAGE_NOTFOUND, "ImageList::AddImage() - ImageName already exists" ); |
| |
| if( !mpImplData ) |
| ImplInit( 0, rImage.GetSizePixel() ); |
| |
| mpImplData->AddImage( rImageName, GetImageCount() + 1, |
| rImage.GetBitmapEx() ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::ReplaceImage( sal_uInt16 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 sal_uInt16 nId = ImplGetImageId( rImageName ); |
| |
| if( nId ) |
| { |
| RemoveImage( nId ); |
| |
| if( !mpImplData ) |
| ImplInit( 0, rImage.GetSizePixel() ); |
| mpImplData->AddImage( rImageName, nId, rImage.GetBitmapEx()); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::ReplaceImage( sal_uInt16 nId, sal_uInt16 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" ); |
| |
| sal_uLong nPosDest = GetImagePos( nId ); |
| sal_uLong nPosSrc = GetImagePos( nReplaceId ); |
| if( nPosDest != IMAGELIST_IMAGE_NOTFOUND && |
| nPosSrc != IMAGELIST_IMAGE_NOTFOUND ) |
| { |
| ImplMakeUnique(); |
| mpImplData->maImages[nPosDest] = mpImplData->maImages[nPosSrc]; |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const ::rtl::OUString& rReplaceName ) |
| { |
| const sal_uInt16 nId1 = ImplGetImageId( rImageName ), nId2 = ImplGetImageId( rReplaceName ); |
| |
| if( nId1 && nId2 ) |
| ReplaceImage( nId1, nId2 ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::RemoveImage( sal_uInt16 nId ) |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); ++i ) |
| { |
| if( mpImplData->maImages[ i ]->mnId == nId ) |
| { |
| mpImplData->RemoveImage( static_cast< sal_uInt16 >( i ) ); |
| break; |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::RemoveImage( const ::rtl::OUString& rImageName ) |
| { |
| const sal_uInt16 nId = ImplGetImageId( rImageName ); |
| |
| if( nId ) |
| RemoveImage( nId ); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Image ImageList::GetImage( sal_uInt16 nId ) const |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| // fprintf (stderr, "GetImage %d\n", nId); |
| |
| Image aRet; |
| |
| if( mpImplData ) |
| { |
| std::vector<ImageAryData *>::iterator aIter; |
| for( aIter = mpImplData->maImages.begin(); |
| aIter != mpImplData->maImages.end(); aIter++) |
| { |
| if ((*aIter)->mnId == nId) |
| { |
| if( (*aIter)->IsLoadable() ) |
| (*aIter)->Load( mpImplData->maPrefix ); |
| |
| aRet = Image( (*aIter)->maBitmapEx ); |
| } |
| } |
| } |
| |
| return aRet; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Image ImageList::GetImage( const ::rtl::OUString& rImageName ) const |
| { |
| // fprintf (stderr, "GetImage '%s'\n", |
| // rtl::OUStringToOString( rImageName, RTL_TEXTENCODING_UTF8 ).getStr() ); |
| |
| if( mpImplData ) |
| { |
| ImageAryData *pImg = mpImplData->maNameHash[ rImageName ]; |
| |
| if( pImg ) |
| { |
| if( pImg->IsLoadable() ) |
| pImg->Load( mpImplData->maPrefix ); |
| return Image( pImg->maBitmapEx ); |
| } |
| } |
| // fprintf (stderr, "no such image\n"); |
| |
| return Image(); |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::Clear() |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) |
| delete mpImplData; |
| |
| mpImplData = NULL; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ImageList::GetImageCount() const |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| return mpImplData ? static_cast< sal_uInt16 >( mpImplData->maImages.size() ) : 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ImageList::GetImagePos( sal_uInt16 nId ) const |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| if( mpImplData && nId ) |
| { |
| for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); ++i ) |
| { |
| if (mpImplData->maImages[ i ]->mnId == nId) |
| return static_cast< sal_uInt16 >( i ); |
| } |
| } |
| |
| return IMAGELIST_IMAGE_NOTFOUND; |
| } |
| |
| bool ImageList::HasImageAtPos( sal_uInt16 nId ) const |
| { |
| return GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ImageList::GetImagePos( const ::rtl::OUString& rImageName ) const |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| if( mpImplData && rImageName.getLength() ) |
| { |
| for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); i++ ) |
| { |
| if (mpImplData->maImages[i]->maName == rImageName) |
| return static_cast< sal_uInt16 >( i ); |
| } |
| } |
| |
| return IMAGELIST_IMAGE_NOTFOUND; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_uInt16 ImageList::GetImageId( sal_uInt16 nPos ) const |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| if( mpImplData && (nPos < GetImageCount()) ) |
| return mpImplData->maImages[ nPos ]->mnId; |
| |
| return 0; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| void ImageList::GetImageIds( ::std::vector< sal_uInt16 >& rIds ) const |
| { |
| RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::GetImageIds" ); |
| |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| rIds = ::std::vector< sal_uInt16 >(); |
| |
| if( mpImplData ) |
| { |
| for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); i++ ) |
| rIds.push_back( mpImplData->maImages[i]->mnId ); |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| ::rtl::OUString ImageList::GetImageName( sal_uInt16 nPos ) const |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| if( mpImplData && (nPos < GetImageCount()) ) |
| return mpImplData->maImages[ nPos ]->maName; |
| |
| 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( sal_uInt32 i = 0; i < mpImplData->maImages.size(); i++ ) |
| { |
| const rtl::OUString& rName( mpImplData->maImages[ i ]->maName ); |
| if( rName.getLength() != 0 ) |
| rNames.push_back( rName ); |
| } |
| } |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| Size ImageList::GetImageSize() const |
| { |
| DBG_CHKTHIS( ImageList, NULL ); |
| |
| Size aRet; |
| |
| if( mpImplData ) |
| { |
| aRet = mpImplData->maImageSize; |
| |
| // force load of 1st image to see - uncommon case. |
| if( aRet.Width() == 0 && aRet.Height() == 0 && |
| !mpImplData->maImages.empty() ) |
| { |
| Image aTmp = GetImage( mpImplData->maImages[ 0 ]->mnId ); |
| aRet = mpImplData->maImageSize = aTmp.GetSizePixel(); |
| } |
| } |
| // fprintf (stderr, "GetImageSize returns %d, %d\n", |
| // aRet.Width(), aRet.Height()); |
| |
| return aRet; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| 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 ) ) |
| delete mpImplData; |
| |
| mpImplData = rImageList.mpImplData; |
| |
| return *this; |
| } |
| |
| // ----------------------------------------------------------------------- |
| |
| sal_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.GetImageCount() == GetImageCount() && |
| rImageList.mpImplData->maImageSize == mpImplData->maImageSize ) |
| bRet = true; // strange semantic |
| |
| return bRet; |
| } |