Update ooo320-m1
[ooovba.git] / vcl / source / gdi / image.cxx
blob7f7fde4e680d5fbe4f8d48dc8a8eb5c820d84f1c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: image.cxx,v $
10 * $Revision: 1.35 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 // MARKER(update_precomp.py): autogen include statement, do not remove
31 #include "precompiled_vcl.hxx"
33 #include <boost/scoped_ptr.hpp>
34 #include <boost/scoped_array.hpp>
36 #include <rtl/logfile.hxx>
37 #include <tools/debug.hxx>
38 #include <tools/stream.hxx>
39 #ifndef _SV_RC_H
40 #include <tools/rc.h>
41 #endif
42 #include <tools/rc.hxx>
43 #ifndef _SV_RESMGR_HXX
44 #include <tools/resmgr.hxx>
45 #endif
46 #include <vcl/settings.hxx>
47 #include <vcl/outdev.hxx>
48 #include <vcl/graph.hxx>
49 #include <vcl/svapp.hxx>
50 #ifndef _SV_IMPIMAGETREE_H
51 #include <vcl/impimagetree.hxx>
52 #endif
53 #include <vcl/image.h>
54 #include <vcl/image.hxx>
56 DBG_NAME( Image )
57 DBG_NAME( ImageList )
59 #define IMAGE_FILE_VERSION 100
61 using namespace ::com::sun::star;
63 // ---------
64 // - Image -
65 // ---------
67 Image::Image() :
68 mpImplData( NULL )
70 DBG_CTOR( Image, NULL );
73 // -----------------------------------------------------------------------
75 Image::Image( const ResId& rResId ) :
76 mpImplData( NULL )
78 DBG_CTOR( Image, NULL );
80 rResId.SetRT( RSC_IMAGE );
82 ResMgr* pResMgr = rResId.GetResMgr();
83 if( pResMgr && pResMgr->GetResource( rResId ) )
85 pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
87 BitmapEx aBmpEx;
88 ULONG nObjMask = pResMgr->ReadLong();
90 if( nObjMask & RSC_IMAGE_IMAGEBITMAP )
92 aBmpEx = BitmapEx( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) );
93 pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
96 if( nObjMask & RSC_IMAGE_MASKBITMAP )
98 if( !aBmpEx.IsEmpty() && aBmpEx.GetTransparentType() == TRANSPARENT_NONE )
100 const Bitmap aMaskBitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) );
101 aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskBitmap );
104 pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
107 if( nObjMask & RSC_IMAGE_MASKCOLOR )
109 if( !aBmpEx.IsEmpty() && aBmpEx.GetTransparentType() == TRANSPARENT_NONE )
111 const Color aMaskColor( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) );
112 aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskColor );
115 pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
117 if( ! aBmpEx.IsEmpty() )
118 ImplInit( aBmpEx );
122 // -----------------------------------------------------------------------
124 Image::Image( const Image& rImage ) :
125 mpImplData( rImage.mpImplData )
127 DBG_CTOR( Image, NULL );
129 if( mpImplData )
130 ++mpImplData->mnRefCount;
133 // -----------------------------------------------------------------------
135 Image::Image( const BitmapEx& rBitmapEx ) :
136 mpImplData( NULL )
138 DBG_CTOR( Image, NULL );
140 ImplInit( rBitmapEx );
143 // -----------------------------------------------------------------------
145 Image::Image( const Bitmap& rBitmap ) :
146 mpImplData( NULL )
148 DBG_CTOR( Image, NULL );
150 ImplInit( rBitmap );
153 // -----------------------------------------------------------------------
155 Image::Image( const Bitmap& rBitmap, const Bitmap& rMaskBitmap ) :
156 mpImplData( NULL )
158 DBG_CTOR( Image, NULL );
160 const BitmapEx aBmpEx( rBitmap, rMaskBitmap );
162 ImplInit( aBmpEx );
165 // -----------------------------------------------------------------------
167 Image::Image( const Bitmap& rBitmap, const Color& rColor ) :
168 mpImplData( NULL )
170 DBG_CTOR( Image, NULL );
172 const BitmapEx aBmpEx( rBitmap, rColor );
174 ImplInit( aBmpEx );
177 // -----------------------------------------------------------------------
179 Image::Image( const uno::Reference< graphic::XGraphic >& rxGraphic ) :
180 mpImplData( NULL )
182 DBG_CTOR( Image, NULL );
184 const Graphic aGraphic( rxGraphic );
185 ImplInit( aGraphic.GetBitmapEx() );
188 // -----------------------------------------------------------------------
190 Image::~Image()
192 DBG_DTOR( Image, NULL );
194 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
195 delete mpImplData;
198 // -----------------------------------------------------------------------
200 void Image::ImplInit( const BitmapEx& rBmpEx )
202 if( !rBmpEx.IsEmpty() )
204 mpImplData = new ImplImage;
205 mpImplData->mnRefCount = 1;
207 if( rBmpEx.GetTransparentType() == TRANSPARENT_NONE )
209 mpImplData->meType = IMAGETYPE_BITMAP;
210 mpImplData->mpData = new Bitmap( rBmpEx.GetBitmap() );
212 else
214 mpImplData->meType = IMAGETYPE_IMAGE;
215 mpImplData->mpData = new ImplImageData( rBmpEx );
220 // -----------------------------------------------------------------------
222 Size Image::GetSizePixel() const
224 DBG_CHKTHIS( Image, NULL );
226 Size aRet;
228 if( mpImplData )
230 switch( mpImplData->meType )
232 case IMAGETYPE_BITMAP:
233 aRet = static_cast< Bitmap* >( mpImplData->mpData )->GetSizePixel();
234 break;
236 case IMAGETYPE_IMAGE:
237 aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx.GetSizePixel();
238 break;
242 return aRet;
245 // -----------------------------------------------------------------------
247 BitmapEx Image::GetBitmapEx() const
249 DBG_CHKTHIS( Image, NULL );
251 BitmapEx aRet;
253 if( mpImplData )
255 switch( mpImplData->meType )
257 case IMAGETYPE_BITMAP:
258 aRet = *static_cast< Bitmap* >( mpImplData->mpData );
259 break;
261 case IMAGETYPE_IMAGE:
262 aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx;
263 break;
267 return aRet;
270 // -----------------------------------------------------------------------
272 uno::Reference< graphic::XGraphic > Image::GetXGraphic() const
274 const Graphic aGraphic( GetBitmapEx() );
276 return aGraphic.GetXGraphic();
279 // -----------------------------------------------------------------------
281 Image Image::GetColorTransformedImage( ImageColorTransform eColorTransform ) const
283 DBG_CHKTHIS( Image, NULL );
285 Image aRet;
287 if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform )
289 BitmapEx aBmpEx( GetBitmapEx() );
291 if( !aBmpEx.IsEmpty() )
293 Color* pSrcColors = NULL;
294 Color* pDstColors = NULL;
295 ULONG nColorCount = 0;
297 Image::GetColorTransformArrays( eColorTransform, pSrcColors, pDstColors, nColorCount );
299 if( nColorCount && pSrcColors && pDstColors )
301 aBmpEx.Replace( pSrcColors, pDstColors, nColorCount );
302 aRet = Image( aBmpEx );
305 delete[] pSrcColors;
306 delete[] pDstColors;
309 else if( IMAGECOLORTRANSFORM_MONOCHROME_BLACK == eColorTransform ||
310 IMAGECOLORTRANSFORM_MONOCHROME_WHITE == eColorTransform )
312 BitmapEx aBmpEx( GetBitmapEx() );
314 if( !aBmpEx.IsEmpty() )
315 aRet = Image( aBmpEx.GetColorTransformedBitmapEx( ( BmpColorMode )( eColorTransform ) ) );
318 if( !aRet )
319 aRet = *this;
321 return aRet;
324 // -----------------------------------------------------------------------
326 void Image::Invert()
328 BitmapEx aInvertedBmp( GetBitmapEx() );
329 aInvertedBmp.Invert();
330 *this = aInvertedBmp;
333 // -----------------------------------------------------------------------
335 void Image::GetColorTransformArrays( ImageColorTransform eColorTransform,
336 Color*& rpSrcColor, Color*& rpDstColor, ULONG& rColorCount )
338 if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform )
340 rpSrcColor = new Color[ 4 ];
341 rpDstColor = new Color[ 4 ];
342 rColorCount = 4;
344 rpSrcColor[ 0 ] = Color( COL_BLACK );
345 rpDstColor[ 0 ] = Color( COL_WHITE );
347 rpSrcColor[ 1 ] = Color( COL_WHITE );
348 rpDstColor[ 1 ] = Color( COL_BLACK );
350 rpSrcColor[ 2 ] = Color( COL_BLUE );
351 rpDstColor[ 2 ] = Color( COL_WHITE );
353 rpSrcColor[ 3 ] = Color( COL_LIGHTBLUE );
354 rpDstColor[ 3 ] = Color( COL_WHITE );
356 else
358 rpSrcColor = rpDstColor = NULL;
359 rColorCount = 0;
363 // -----------------------------------------------------------------------
365 Image& Image::operator=( const Image& rImage )
367 DBG_CHKTHIS( Image, NULL );
368 DBG_CHKOBJ( &rImage, Image, NULL );
370 if( rImage.mpImplData )
371 ++rImage.mpImplData->mnRefCount;
373 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
374 delete mpImplData;
376 mpImplData = rImage.mpImplData;
378 return *this;
381 // -----------------------------------------------------------------------
383 BOOL Image::operator==( const Image& rImage ) const
385 DBG_CHKTHIS( Image, NULL );
386 DBG_CHKOBJ( &rImage, Image, NULL );
388 bool bRet = false;
390 if( rImage.mpImplData == mpImplData )
391 bRet = true;
392 else if( !rImage.mpImplData || !mpImplData )
393 bRet = false;
394 else if( rImage.mpImplData->mpData == mpImplData->mpData )
395 bRet = true;
396 else if( rImage.mpImplData->meType == mpImplData->meType )
398 switch( mpImplData->meType )
400 case IMAGETYPE_BITMAP:
401 bRet = ( *static_cast< Bitmap* >( rImage.mpImplData->mpData ) == *static_cast< Bitmap* >( mpImplData->mpData ) );
402 break;
404 case IMAGETYPE_IMAGE:
405 bRet = static_cast< ImplImageData* >( rImage.mpImplData->mpData )->IsEqual( *static_cast< ImplImageData* >( mpImplData->mpData ) );
406 break;
408 default:
409 bRet = false;
410 break;
414 return bRet;
417 // -------------
418 // - ImageList -
419 // -------------
421 ImageList::ImageList( USHORT nInit, USHORT nGrow ) :
422 mpImplData( NULL ),
423 mnInitSize( nInit ),
424 mnGrowSize( nGrow )
426 DBG_CTOR( ImageList, NULL );
429 // -----------------------------------------------------------------------
431 ImageList::ImageList( const ResId& rResId ) :
432 mpImplData( NULL ),
433 mnInitSize( 1 ),
434 mnGrowSize( 4 )
436 RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImageList( const ResId& rResId )" );
438 DBG_CTOR( ImageList, NULL );
440 rResId.SetRT( RSC_IMAGELIST );
442 ResMgr* pResMgr = rResId.GetResMgr();
444 if( pResMgr && pResMgr->GetResource( rResId ) )
446 pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
448 ULONG nObjMask = pResMgr->ReadLong();
449 const String aPrefix( pResMgr->ReadString() );
450 ::boost::scoped_ptr< Color > spMaskColor;
452 if( nObjMask & RSC_IMAGE_MASKCOLOR )
453 spMaskColor.reset( new Color( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) ) );
455 pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) );
457 if( nObjMask & RSC_IMAGELIST_IDLIST )
459 for( sal_Int32 i = 0, nCount = pResMgr->ReadLong(); i < nCount; ++i )
460 pResMgr->ReadLong();
463 sal_Int32 nCount = pResMgr->ReadLong();
464 ImplInit( static_cast< USHORT >( nCount ), Size() );
466 BitmapEx aEmpty;
467 for( sal_Int32 i = 0; i < nCount; ++i )
469 rtl::OUString aName = pResMgr->ReadString();
470 USHORT nId = static_cast< USHORT >( pResMgr->ReadLong() );
471 mpImplData->AddImage( aName, nId, aEmpty );
474 if( nObjMask & RSC_IMAGELIST_IDCOUNT )
475 pResMgr->ReadShort();
479 // -----------------------------------------------------------------------
481 ImageList::ImageList( const ::std::vector< ::rtl::OUString >& rNameVector,
482 const ::rtl::OUString& rPrefix,
483 const Color* ) :
484 mpImplData( NULL ),
485 mnInitSize( 1 ),
486 mnGrowSize( 4 )
488 RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImageList(const vector< OUString >& ..." );
490 DBG_CTOR( ImageList, NULL );
492 ImplInit( sal::static_int_cast< USHORT >( rNameVector.size() ), Size() );
494 mpImplData->maPrefix = rPrefix;
495 for( sal_uInt32 i = 0; i < rNameVector.size(); ++i )
497 // fprintf (stderr, "List %p [%d]: '%s'\n",
498 // this, i, rtl::OUStringToOString( rNameVector[i], RTL_TEXTENCODING_UTF8 ).getStr() );
499 mpImplData->AddImage( rNameVector[ i ], static_cast< USHORT >( i ) + 1, BitmapEx() );
503 // -----------------------------------------------------------------------
505 ImageList::ImageList( const ImageList& rImageList ) :
506 mpImplData( rImageList.mpImplData ),
507 mnInitSize( rImageList.mnInitSize ),
508 mnGrowSize( rImageList.mnGrowSize )
510 DBG_CTOR( ImageList, NULL );
512 if( mpImplData )
513 ++mpImplData->mnRefCount;
516 // -----------------------------------------------------------------------
518 ImageList::~ImageList()
520 DBG_DTOR( ImageList, NULL );
522 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
523 delete mpImplData;
526 void ImageList::ImplInit( USHORT nItems, const Size &rSize )
528 mpImplData = new ImplImageList;
529 mpImplData->mnRefCount = 1;
530 mpImplData->maImages.reserve( nItems );
531 mpImplData->maImageSize = rSize;
534 // -----------------------------------------------------------------------
536 void ImageAryData::Load(const rtl::OUString &rPrefix)
538 static ImplImageTreeSingletonRef aImageTree;
540 ::rtl::OUString aSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName();
542 BitmapEx aBmpEx;
544 // fprintf (stderr, "Attempt load of '%s'\n",
545 // rtl::OUStringToOString( maName, RTL_TEXTENCODING_UTF8 ).getStr() );
547 rtl::OUString aFileName = rPrefix;
548 aFileName += maName;
549 #ifdef DBG_UTIL
550 bool bSuccess = aImageTree->loadImage( aFileName, aSymbolsStyle, maBitmapEx, true );
551 DBG_ASSERT (bSuccess, "ImageAryData::Failed to load image");
552 #else
553 aImageTree->loadImage( aFileName, aSymbolsStyle, maBitmapEx, true );
554 #endif
557 // -----------------------------------------------------------------------
559 void ImageList::ImplMakeUnique()
561 if( mpImplData && mpImplData->mnRefCount > 1 )
563 --mpImplData->mnRefCount;
564 mpImplData = new ImplImageList( *mpImplData ) ;
568 // -----------------------------------------------------------------------
569 // Rather a performance hazard:
570 BitmapEx ImageList::GetAsHorizontalStrip() const
572 Size aSize( mpImplData->maImageSize );
573 USHORT nCount = GetImageCount();
574 if( !nCount )
575 return BitmapEx();
576 aSize.Width() *= nCount;
578 // Load any stragglers
579 for (USHORT nIdx = 0; nIdx < nCount; nIdx++)
581 ImageAryData *pData = mpImplData->maImages[ nIdx ];
582 if( pData->IsLoadable() )
583 pData->Load( mpImplData->maPrefix );
586 BitmapEx aTempl = mpImplData->maImages[ 0 ]->maBitmapEx;
587 BitmapEx aResult;
588 Bitmap aPixels( aSize, aTempl.GetBitmap().GetBitCount() );
589 if( aTempl.IsAlpha() )
590 aResult = BitmapEx( aPixels, AlphaMask( aSize ) );
591 else if( aTempl.IsTransparent() )
592 aResult = BitmapEx( aPixels, Bitmap( aSize, aTempl.GetMask().GetBitCount() ) );
593 else
594 aResult = BitmapEx( aPixels );
596 Rectangle aSrcRect( Point( 0, 0 ), mpImplData->maImageSize );
597 for (USHORT nIdx = 0; nIdx < nCount; nIdx++)
599 Rectangle aDestRect( Point( nIdx * mpImplData->maImageSize.Width(), 0 ),
600 mpImplData->maImageSize );
601 ImageAryData *pData = mpImplData->maImages[ nIdx ];
602 aResult.CopyPixel( aDestRect, aSrcRect, &pData->maBitmapEx);
605 return aResult;
608 // -----------------------------------------------------------------------
610 void ImageList::InsertFromHorizontalStrip( const BitmapEx &rBitmapEx,
611 const std::vector< rtl::OUString > &rNameVector )
613 USHORT nItems = sal::static_int_cast< USHORT >( rNameVector.size() );
615 // fprintf (stderr, "InsertFromHorizontalStrip (1) [%d items]\n", nItems);
617 if (!nItems)
618 return;
620 Size aSize( rBitmapEx.GetSizePixel() );
621 DBG_ASSERT (rBitmapEx.GetSizePixel().Width() % nItems == 0,
622 "ImageList::InsertFromHorizontalStrip - very odd size");
623 aSize.Width() /= nItems;
624 ImplInit( nItems, aSize );
626 for (USHORT nIdx = 0; nIdx < nItems; nIdx++)
628 BitmapEx aBitmap( rBitmapEx, Point( nIdx * aSize.Width(), 0 ), aSize );
629 mpImplData->AddImage( rNameVector[ nIdx ], nIdx + 1, aBitmap );
633 // -----------------------------------------------------------------------
635 void ImageList::InsertFromHorizontalBitmap( const ResId& rResId,
636 USHORT nCount,
637 const Color *pMaskColor,
638 const Color *pSearchColors,
639 const Color *pReplaceColors,
640 ULONG nColorCount)
642 BitmapEx aBmpEx( rResId );
643 if (!aBmpEx.IsTransparent())
645 if( pMaskColor )
646 aBmpEx = BitmapEx( aBmpEx.GetBitmap(), *pMaskColor );
647 else
648 aBmpEx = BitmapEx( aBmpEx.GetBitmap() );
650 if ( nColorCount && pSearchColors && pReplaceColors )
651 aBmpEx.Replace( pSearchColors, pReplaceColors, nColorCount );
653 std::vector< rtl::OUString > aNames( nCount );
654 InsertFromHorizontalStrip( aBmpEx, aNames );
657 // -----------------------------------------------------------------------
659 USHORT ImageList::ImplGetImageId( const ::rtl::OUString& rImageName ) const
661 DBG_CHKTHIS( ImageList, NULL );
663 ImageAryData *pImg = mpImplData->maNameHash[ rImageName ];
664 if( pImg )
665 return pImg->mnId;
666 else
667 return 0;
670 // -----------------------------------------------------------------------
672 void ImageList::AddImage( USHORT nId, const Image& rImage )
674 DBG_CHKTHIS( ImageList, NULL );
675 DBG_CHKOBJ( &rImage, Image, NULL );
676 DBG_ASSERT( nId, "ImageList::AddImage(): ImageId == 0" );
677 DBG_ASSERT( GetImagePos( nId ) == IMAGELIST_IMAGE_NOTFOUND, "ImageList::AddImage() - ImageId already exists" );
678 DBG_ASSERT( rImage.mpImplData, "ImageList::AddImage(): Wrong Size" );
679 DBG_ASSERT( !mpImplData || (rImage.GetSizePixel() == mpImplData->maImageSize), "ImageList::AddImage(): Wrong Size" );
681 if( !mpImplData )
682 ImplInit( 0, rImage.GetSizePixel() );
684 mpImplData->AddImage( rtl::OUString(), nId, rImage.GetBitmapEx());
687 // -----------------------------------------------------------------------
689 void ImageList::AddImage( const ::rtl::OUString& rImageName, const Image& rImage )
691 DBG_ASSERT( GetImagePos( rImageName ) == IMAGELIST_IMAGE_NOTFOUND, "ImageList::AddImage() - ImageName already exists" );
693 if( !mpImplData )
694 ImplInit( 0, rImage.GetSizePixel() );
696 mpImplData->AddImage( rImageName, GetImageCount() + 1,
697 rImage.GetBitmapEx() );
700 // -----------------------------------------------------------------------
702 void ImageList::ReplaceImage( USHORT nId, const Image& rImage )
704 DBG_CHKTHIS( ImageList, NULL );
705 DBG_CHKOBJ( &rImage, Image, NULL );
706 DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::ReplaceImage(): Unknown nId" );
708 RemoveImage( nId );
709 AddImage( nId, rImage );
712 // -----------------------------------------------------------------------
714 void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const Image& rImage )
716 const USHORT nId = ImplGetImageId( rImageName );
718 if( nId )
720 RemoveImage( nId );
722 if( !mpImplData )
723 ImplInit( 0, rImage.GetSizePixel() );
724 mpImplData->AddImage( rImageName, nId, rImage.GetBitmapEx());
728 // -----------------------------------------------------------------------
730 void ImageList::ReplaceImage( USHORT nId, USHORT nReplaceId )
732 DBG_CHKTHIS( ImageList, NULL );
733 DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::ReplaceImage(): Unknown nId" );
734 DBG_ASSERT( GetImagePos( nReplaceId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::ReplaceImage(): Unknown nReplaceId" );
736 ULONG nPosDest = GetImagePos( nId );
737 ULONG nPosSrc = GetImagePos( nReplaceId );
738 if( nPosDest != IMAGELIST_IMAGE_NOTFOUND &&
739 nPosSrc != IMAGELIST_IMAGE_NOTFOUND )
741 ImplMakeUnique();
742 mpImplData->maImages[nPosDest] = mpImplData->maImages[nPosSrc];
746 // -----------------------------------------------------------------------
748 void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const ::rtl::OUString& rReplaceName )
750 const USHORT nId1 = ImplGetImageId( rImageName ), nId2 = ImplGetImageId( rReplaceName );
752 if( nId1 && nId2 )
753 ReplaceImage( nId1, nId2 );
756 // -----------------------------------------------------------------------
758 void ImageList::RemoveImage( USHORT nId )
760 DBG_CHKTHIS( ImageList, NULL );
762 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); ++i )
764 if( mpImplData->maImages[ i ]->mnId == nId )
766 mpImplData->RemoveImage( static_cast< USHORT >( i ) );
767 break;
772 // -----------------------------------------------------------------------
774 void ImageList::RemoveImage( const ::rtl::OUString& rImageName )
776 const USHORT nId = ImplGetImageId( rImageName );
778 if( nId )
779 RemoveImage( nId );
782 // -----------------------------------------------------------------------
784 Image ImageList::GetImage( USHORT nId ) const
786 DBG_CHKTHIS( ImageList, NULL );
788 // fprintf (stderr, "GetImage %d\n", nId);
790 Image aRet;
792 if( mpImplData )
794 std::vector<ImageAryData *>::iterator aIter;
795 for( aIter = mpImplData->maImages.begin();
796 aIter != mpImplData->maImages.end(); aIter++)
798 if ((*aIter)->mnId == nId)
800 if( (*aIter)->IsLoadable() )
801 (*aIter)->Load( mpImplData->maPrefix );
803 aRet = Image( (*aIter)->maBitmapEx );
808 return aRet;
811 // -----------------------------------------------------------------------
813 Image ImageList::GetImage( const ::rtl::OUString& rImageName ) const
815 // fprintf (stderr, "GetImage '%s'\n",
816 // rtl::OUStringToOString( rImageName, RTL_TEXTENCODING_UTF8 ).getStr() );
818 if( mpImplData )
820 ImageAryData *pImg = mpImplData->maNameHash[ rImageName ];
822 if( pImg )
824 if( pImg->IsLoadable() )
825 pImg->Load( mpImplData->maPrefix );
826 return Image( pImg->maBitmapEx );
829 // fprintf (stderr, "no such image\n");
831 return Image();
834 // -----------------------------------------------------------------------
836 void ImageList::Clear()
838 DBG_CHKTHIS( ImageList, NULL );
840 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
841 delete mpImplData;
843 mpImplData = NULL;
846 // -----------------------------------------------------------------------
848 USHORT ImageList::GetImageCount() const
850 DBG_CHKTHIS( ImageList, NULL );
852 return mpImplData ? static_cast< USHORT >( mpImplData->maImages.size() ) : 0;
855 // -----------------------------------------------------------------------
857 USHORT ImageList::GetImagePos( USHORT nId ) const
859 DBG_CHKTHIS( ImageList, NULL );
861 if( mpImplData && nId )
863 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); ++i )
865 if (mpImplData->maImages[ i ]->mnId == nId)
866 return static_cast< USHORT >( i );
870 return IMAGELIST_IMAGE_NOTFOUND;
873 bool ImageList::HasImageAtPos( USHORT nId ) const
875 return GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND;
878 // -----------------------------------------------------------------------
880 USHORT ImageList::GetImagePos( const ::rtl::OUString& rImageName ) const
882 DBG_CHKTHIS( ImageList, NULL );
884 if( mpImplData && rImageName.getLength() )
886 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); i++ )
888 if (mpImplData->maImages[i]->maName == rImageName)
889 return static_cast< USHORT >( i );
893 return IMAGELIST_IMAGE_NOTFOUND;
896 // -----------------------------------------------------------------------
898 USHORT ImageList::GetImageId( USHORT nPos ) const
900 DBG_CHKTHIS( ImageList, NULL );
902 if( mpImplData && (nPos < GetImageCount()) )
903 return mpImplData->maImages[ nPos ]->mnId;
905 return 0;
908 // -----------------------------------------------------------------------
910 void ImageList::GetImageIds( ::std::vector< USHORT >& rIds ) const
912 RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::GetImageIds" );
914 DBG_CHKTHIS( ImageList, NULL );
916 rIds = ::std::vector< USHORT >();
918 if( mpImplData )
920 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); i++ )
921 rIds.push_back( mpImplData->maImages[i]->mnId );
925 // -----------------------------------------------------------------------
927 ::rtl::OUString ImageList::GetImageName( USHORT nPos ) const
929 DBG_CHKTHIS( ImageList, NULL );
931 if( mpImplData && (nPos < GetImageCount()) )
932 return mpImplData->maImages[ nPos ]->maName;
934 return ::rtl::OUString();
937 // -----------------------------------------------------------------------
939 void ImageList::GetImageNames( ::std::vector< ::rtl::OUString >& rNames ) const
941 RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::GetImageNames" );
943 DBG_CHKTHIS( ImageList, NULL );
945 rNames = ::std::vector< ::rtl::OUString >();
947 if( mpImplData )
949 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); i++ )
951 const rtl::OUString& rName( mpImplData->maImages[ i ]->maName );
952 if( rName.getLength() != 0 )
953 rNames.push_back( rName );
958 // -----------------------------------------------------------------------
960 Size ImageList::GetImageSize() const
962 DBG_CHKTHIS( ImageList, NULL );
964 Size aRet;
966 if( mpImplData )
968 aRet = mpImplData->maImageSize;
970 // force load of 1st image to see - uncommon case.
971 if( aRet.Width() == 0 && aRet.Height() == 0 &&
972 !mpImplData->maImages.empty() )
974 Image aTmp = GetImage( mpImplData->maImages[ 0 ]->mnId );
975 aRet = mpImplData->maImageSize = aTmp.GetSizePixel();
978 // fprintf (stderr, "GetImageSize returns %d, %d\n",
979 // aRet.Width(), aRet.Height());
981 return aRet;
984 // -----------------------------------------------------------------------
986 ImageList& ImageList::operator=( const ImageList& rImageList )
988 DBG_CHKTHIS( ImageList, NULL );
989 DBG_CHKOBJ( &rImageList, ImageList, NULL );
991 if( rImageList.mpImplData )
992 ++rImageList.mpImplData->mnRefCount;
994 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
995 delete mpImplData;
997 mpImplData = rImageList.mpImplData;
999 return *this;
1002 // -----------------------------------------------------------------------
1004 BOOL ImageList::operator==( const ImageList& rImageList ) const
1006 DBG_CHKTHIS( ImageList, NULL );
1007 DBG_CHKOBJ( &rImageList, ImageList, NULL );
1009 bool bRet = false;
1011 if( rImageList.mpImplData == mpImplData )
1012 bRet = true;
1013 else if( !rImageList.mpImplData || !mpImplData )
1014 bRet = false;
1015 else if( rImageList.GetImageCount() == GetImageCount() &&
1016 rImageList.mpImplData->maImageSize == mpImplData->maImageSize )
1017 bRet = true; // strange semantic
1019 return bRet;