1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 // MARKER(update_precomp.py): autogen include statement, do not remove 28 #include "precompiled_vcl.hxx" 29 30 #include <boost/scoped_ptr.hpp> 31 #include <boost/scoped_array.hpp> 32 33 #include <rtl/logfile.hxx> 34 35 #include <tools/debug.hxx> 36 #include <tools/stream.hxx> 37 #include <tools/rc.h> 38 #include <tools/rc.hxx> 39 #include <tools/resmgr.hxx> 40 41 #include <vcl/settings.hxx> 42 #include <vcl/outdev.hxx> 43 #include <vcl/graph.hxx> 44 #include <vcl/svapp.hxx> 45 #include <vcl/image.hxx> 46 47 #include <impimagetree.hxx> 48 #include <image.h> 49 50 #if OSL_DEBUG_LEVEL > 0 51 #include <rtl/strbuf.hxx> 52 #endif 53 54 DBG_NAME( Image ) 55 DBG_NAME( ImageList ) 56 57 #define IMAGE_FILE_VERSION 100 58 59 using namespace ::com::sun::star; 60 61 // --------- 62 // - Image - 63 // --------- 64 65 Image::Image() : 66 mpImplData( NULL ) 67 { 68 DBG_CTOR( Image, NULL ); 69 } 70 71 // ----------------------------------------------------------------------- 72 73 Image::Image( const ResId& rResId ) : 74 mpImplData( NULL ) 75 { 76 DBG_CTOR( Image, NULL ); 77 78 rResId.SetRT( RSC_IMAGE ); 79 80 ResMgr* pResMgr = rResId.GetResMgr(); 81 if( pResMgr && pResMgr->GetResource( rResId ) ) 82 { 83 pResMgr->Increment( sizeof( RSHEADER_TYPE ) ); 84 85 BitmapEx aBmpEx; 86 sal_uLong nObjMask = pResMgr->ReadLong(); 87 88 if( nObjMask & RSC_IMAGE_IMAGEBITMAP ) 89 { 90 aBmpEx = BitmapEx( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) ); 91 pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); 92 } 93 94 if( nObjMask & RSC_IMAGE_MASKBITMAP ) 95 { 96 if( !aBmpEx.IsEmpty() && aBmpEx.GetTransparentType() == TRANSPARENT_NONE ) 97 { 98 const Bitmap aMaskBitmap( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) ); 99 aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskBitmap ); 100 } 101 102 pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); 103 } 104 105 if( nObjMask & RSC_IMAGE_MASKCOLOR ) 106 { 107 if( !aBmpEx.IsEmpty() && aBmpEx.GetTransparentType() == TRANSPARENT_NONE ) 108 { 109 const Color aMaskColor( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) ); 110 aBmpEx = BitmapEx( aBmpEx.GetBitmap(), aMaskColor ); 111 } 112 113 pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); 114 } 115 if( ! aBmpEx.IsEmpty() ) 116 ImplInit( aBmpEx ); 117 } 118 } 119 120 // ----------------------------------------------------------------------- 121 122 Image::Image( const Image& rImage ) : 123 mpImplData( rImage.mpImplData ) 124 { 125 DBG_CTOR( Image, NULL ); 126 127 if( mpImplData ) 128 ++mpImplData->mnRefCount; 129 } 130 131 // ----------------------------------------------------------------------- 132 133 Image::Image( const BitmapEx& rBitmapEx ) : 134 mpImplData( NULL ) 135 { 136 DBG_CTOR( Image, NULL ); 137 138 ImplInit( rBitmapEx ); 139 } 140 141 // ----------------------------------------------------------------------- 142 143 Image::Image( const Bitmap& rBitmap ) : 144 mpImplData( NULL ) 145 { 146 DBG_CTOR( Image, NULL ); 147 148 ImplInit( rBitmap ); 149 } 150 151 // ----------------------------------------------------------------------- 152 153 Image::Image( const Bitmap& rBitmap, const Bitmap& rMaskBitmap ) : 154 mpImplData( NULL ) 155 { 156 DBG_CTOR( Image, NULL ); 157 158 const BitmapEx aBmpEx( rBitmap, rMaskBitmap ); 159 160 ImplInit( aBmpEx ); 161 } 162 163 // ----------------------------------------------------------------------- 164 165 Image::Image( const Bitmap& rBitmap, const Color& rColor ) : 166 mpImplData( NULL ) 167 { 168 DBG_CTOR( Image, NULL ); 169 170 const BitmapEx aBmpEx( rBitmap, rColor ); 171 172 ImplInit( aBmpEx ); 173 } 174 175 // ----------------------------------------------------------------------- 176 177 Image::Image( const uno::Reference< graphic::XGraphic >& rxGraphic ) : 178 mpImplData( NULL ) 179 { 180 DBG_CTOR( Image, NULL ); 181 182 const Graphic aGraphic( rxGraphic ); 183 ImplInit( aGraphic.GetBitmapEx() ); 184 } 185 186 // ----------------------------------------------------------------------- 187 188 Image::~Image() 189 { 190 DBG_DTOR( Image, NULL ); 191 192 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) 193 delete mpImplData; 194 } 195 196 // ----------------------------------------------------------------------- 197 198 void Image::ImplInit( const BitmapEx& rBmpEx ) 199 { 200 if( !rBmpEx.IsEmpty() ) 201 { 202 mpImplData = new ImplImage; 203 mpImplData->mnRefCount = 1; 204 205 if( rBmpEx.GetTransparentType() == TRANSPARENT_NONE ) 206 { 207 mpImplData->meType = IMAGETYPE_BITMAP; 208 mpImplData->mpData = new Bitmap( rBmpEx.GetBitmap() ); 209 } 210 else 211 { 212 mpImplData->meType = IMAGETYPE_IMAGE; 213 mpImplData->mpData = new ImplImageData( rBmpEx ); 214 } 215 } 216 } 217 218 // ----------------------------------------------------------------------- 219 220 Size Image::GetSizePixel() const 221 { 222 DBG_CHKTHIS( Image, NULL ); 223 224 Size aRet; 225 226 if( mpImplData ) 227 { 228 switch( mpImplData->meType ) 229 { 230 case IMAGETYPE_BITMAP: 231 aRet = static_cast< Bitmap* >( mpImplData->mpData )->GetSizePixel(); 232 break; 233 234 case IMAGETYPE_IMAGE: 235 aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx.GetSizePixel(); 236 break; 237 } 238 } 239 240 return aRet; 241 } 242 243 // ----------------------------------------------------------------------- 244 245 BitmapEx Image::GetBitmapEx() const 246 { 247 DBG_CHKTHIS( Image, NULL ); 248 249 BitmapEx aRet; 250 251 if( mpImplData ) 252 { 253 switch( mpImplData->meType ) 254 { 255 case IMAGETYPE_BITMAP: 256 aRet = *static_cast< Bitmap* >( mpImplData->mpData ); 257 break; 258 259 case IMAGETYPE_IMAGE: 260 aRet = static_cast< ImplImageData* >( mpImplData->mpData )->maBmpEx; 261 break; 262 } 263 } 264 265 return aRet; 266 } 267 268 // ----------------------------------------------------------------------- 269 270 uno::Reference< graphic::XGraphic > Image::GetXGraphic() const 271 { 272 const Graphic aGraphic( GetBitmapEx() ); 273 274 return aGraphic.GetXGraphic(); 275 } 276 277 // ----------------------------------------------------------------------- 278 279 Image Image::GetColorTransformedImage( ImageColorTransform eColorTransform ) const 280 { 281 DBG_CHKTHIS( Image, NULL ); 282 283 Image aRet; 284 285 if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform ) 286 { 287 BitmapEx aBmpEx( GetBitmapEx() ); 288 289 if( !aBmpEx.IsEmpty() ) 290 { 291 Color* pSrcColors = NULL; 292 Color* pDstColors = NULL; 293 sal_uLong nColorCount = 0; 294 295 Image::GetColorTransformArrays( eColorTransform, pSrcColors, pDstColors, nColorCount ); 296 297 if( nColorCount && pSrcColors && pDstColors ) 298 { 299 aBmpEx.Replace( pSrcColors, pDstColors, nColorCount ); 300 aRet = Image( aBmpEx ); 301 } 302 303 delete[] pSrcColors; 304 delete[] pDstColors; 305 } 306 } 307 else if( IMAGECOLORTRANSFORM_MONOCHROME_BLACK == eColorTransform || 308 IMAGECOLORTRANSFORM_MONOCHROME_WHITE == eColorTransform ) 309 { 310 BitmapEx aBmpEx( GetBitmapEx() ); 311 312 if( !aBmpEx.IsEmpty() ) 313 aRet = Image( aBmpEx.GetColorTransformedBitmapEx( ( BmpColorMode )( eColorTransform ) ) ); 314 } 315 316 if( !aRet ) 317 aRet = *this; 318 319 return aRet; 320 } 321 322 // ----------------------------------------------------------------------- 323 324 void Image::Invert() 325 { 326 BitmapEx aInvertedBmp( GetBitmapEx() ); 327 aInvertedBmp.Invert(); 328 *this = aInvertedBmp; 329 } 330 331 // ----------------------------------------------------------------------- 332 333 void Image::GetColorTransformArrays( ImageColorTransform eColorTransform, 334 Color*& rpSrcColor, Color*& rpDstColor, sal_uLong& rColorCount ) 335 { 336 if( IMAGECOLORTRANSFORM_HIGHCONTRAST == eColorTransform ) 337 { 338 rpSrcColor = new Color[ 4 ]; 339 rpDstColor = new Color[ 4 ]; 340 rColorCount = 4; 341 342 rpSrcColor[ 0 ] = Color( COL_BLACK ); 343 rpDstColor[ 0 ] = Color( COL_WHITE ); 344 345 rpSrcColor[ 1 ] = Color( COL_WHITE ); 346 rpDstColor[ 1 ] = Color( COL_BLACK ); 347 348 rpSrcColor[ 2 ] = Color( COL_BLUE ); 349 rpDstColor[ 2 ] = Color( COL_WHITE ); 350 351 rpSrcColor[ 3 ] = Color( COL_LIGHTBLUE ); 352 rpDstColor[ 3 ] = Color( COL_WHITE ); 353 } 354 else 355 { 356 rpSrcColor = rpDstColor = NULL; 357 rColorCount = 0; 358 } 359 } 360 361 // ----------------------------------------------------------------------- 362 363 Image& Image::operator=( const Image& rImage ) 364 { 365 DBG_CHKTHIS( Image, NULL ); 366 DBG_CHKOBJ( &rImage, Image, NULL ); 367 368 if( rImage.mpImplData ) 369 ++rImage.mpImplData->mnRefCount; 370 371 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) 372 delete mpImplData; 373 374 mpImplData = rImage.mpImplData; 375 376 return *this; 377 } 378 379 // ----------------------------------------------------------------------- 380 381 sal_Bool Image::operator==( const Image& rImage ) const 382 { 383 DBG_CHKTHIS( Image, NULL ); 384 DBG_CHKOBJ( &rImage, Image, NULL ); 385 386 bool bRet = false; 387 388 if( rImage.mpImplData == mpImplData ) 389 bRet = true; 390 else if( !rImage.mpImplData || !mpImplData ) 391 bRet = false; 392 else if( rImage.mpImplData->mpData == mpImplData->mpData ) 393 bRet = true; 394 else if( rImage.mpImplData->meType == mpImplData->meType ) 395 { 396 switch( mpImplData->meType ) 397 { 398 case IMAGETYPE_BITMAP: 399 bRet = ( *static_cast< Bitmap* >( rImage.mpImplData->mpData ) == *static_cast< Bitmap* >( mpImplData->mpData ) ); 400 break; 401 402 case IMAGETYPE_IMAGE: 403 bRet = static_cast< ImplImageData* >( rImage.mpImplData->mpData )->IsEqual( *static_cast< ImplImageData* >( mpImplData->mpData ) ); 404 break; 405 406 default: 407 bRet = false; 408 break; 409 } 410 } 411 412 return bRet; 413 } 414 415 // ------------- 416 // - ImageList - 417 // ------------- 418 419 ImageList::ImageList( sal_uInt16 nInit, sal_uInt16 nGrow ) : 420 mpImplData( NULL ), 421 mnInitSize( nInit ), 422 mnGrowSize( nGrow ) 423 { 424 DBG_CTOR( ImageList, NULL ); 425 } 426 427 // ----------------------------------------------------------------------- 428 429 ImageList::ImageList( const ResId& rResId ) : 430 mpImplData( NULL ), 431 mnInitSize( 1 ), 432 mnGrowSize( 4 ) 433 { 434 RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImageList( const ResId& rResId )" ); 435 436 DBG_CTOR( ImageList, NULL ); 437 438 rResId.SetRT( RSC_IMAGELIST ); 439 440 ResMgr* pResMgr = rResId.GetResMgr(); 441 442 if( pResMgr && pResMgr->GetResource( rResId ) ) 443 { 444 pResMgr->Increment( sizeof( RSHEADER_TYPE ) ); 445 446 sal_uLong nObjMask = pResMgr->ReadLong(); 447 const String aPrefix( pResMgr->ReadString() ); 448 ::boost::scoped_ptr< Color > spMaskColor; 449 450 if( nObjMask & RSC_IMAGE_MASKCOLOR ) 451 spMaskColor.reset( new Color( ResId( (RSHEADER_TYPE*)pResMgr->GetClass(), *pResMgr ) ) ); 452 453 pResMgr->Increment( pResMgr->GetObjSize( (RSHEADER_TYPE*)pResMgr->GetClass() ) ); 454 455 if( nObjMask & RSC_IMAGELIST_IDLIST ) 456 { 457 for( sal_Int32 i = 0, nCount = pResMgr->ReadLong(); i < nCount; ++i ) 458 pResMgr->ReadLong(); 459 } 460 461 sal_Int32 nCount = pResMgr->ReadLong(); 462 ImplInit( static_cast< sal_uInt16 >( nCount ), Size() ); 463 464 BitmapEx aEmpty; 465 for( sal_Int32 i = 0; i < nCount; ++i ) 466 { 467 rtl::OUString aName = pResMgr->ReadString(); 468 sal_uInt16 nId = static_cast< sal_uInt16 >( pResMgr->ReadLong() ); 469 mpImplData->AddImage( aName, nId, aEmpty ); 470 } 471 472 if( nObjMask & RSC_IMAGELIST_IDCOUNT ) 473 pResMgr->ReadShort(); 474 } 475 } 476 477 // ----------------------------------------------------------------------- 478 479 ImageList::ImageList( const ::std::vector< ::rtl::OUString >& rNameVector, 480 const ::rtl::OUString& rPrefix, 481 const Color* ) : 482 mpImplData( NULL ), 483 mnInitSize( 1 ), 484 mnGrowSize( 4 ) 485 { 486 RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::ImageList(const vector< OUString >& ..." ); 487 488 DBG_CTOR( ImageList, NULL ); 489 490 ImplInit( sal::static_int_cast< sal_uInt16 >( rNameVector.size() ), Size() ); 491 492 mpImplData->maPrefix = rPrefix; 493 for( sal_uInt32 i = 0; i < rNameVector.size(); ++i ) 494 { 495 // fprintf (stderr, "List %p [%d]: '%s'\n", 496 // this, i, rtl::OUStringToOString( rNameVector[i], RTL_TEXTENCODING_UTF8 ).getStr() ); 497 mpImplData->AddImage( rNameVector[ i ], static_cast< sal_uInt16 >( i ) + 1, BitmapEx() ); 498 } 499 } 500 501 // ----------------------------------------------------------------------- 502 503 ImageList::ImageList( const ImageList& rImageList ) : 504 mpImplData( rImageList.mpImplData ), 505 mnInitSize( rImageList.mnInitSize ), 506 mnGrowSize( rImageList.mnGrowSize ) 507 { 508 DBG_CTOR( ImageList, NULL ); 509 510 if( mpImplData ) 511 ++mpImplData->mnRefCount; 512 } 513 514 // ----------------------------------------------------------------------- 515 516 ImageList::~ImageList() 517 { 518 DBG_DTOR( ImageList, NULL ); 519 520 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) 521 delete mpImplData; 522 } 523 524 void ImageList::ImplInit( sal_uInt16 nItems, const Size &rSize ) 525 { 526 mpImplData = new ImplImageList; 527 mpImplData->mnRefCount = 1; 528 mpImplData->maImages.reserve( nItems ); 529 mpImplData->maImageSize = rSize; 530 } 531 532 // ----------------------------------------------------------------------- 533 534 void ImageAryData::Load(const rtl::OUString &rPrefix) 535 { 536 static ImplImageTreeSingletonRef aImageTree; 537 538 ::rtl::OUString aSymbolsStyle = Application::GetSettings().GetStyleSettings().GetCurrentSymbolsStyleName(); 539 540 BitmapEx aBmpEx; 541 542 // fprintf (stderr, "Attempt load of '%s'\n", 543 // rtl::OUStringToOString( maName, RTL_TEXTENCODING_UTF8 ).getStr() ); 544 545 rtl::OUString aFileName = rPrefix; 546 aFileName += maName; 547 #if OSL_DEBUG_LEVEL > 0 548 bool bSuccess = 549 #endif 550 aImageTree->loadImage( aFileName, aSymbolsStyle, maBitmapEx, true ); 551 #if OSL_DEBUG_LEVEL > 0 552 if ( !bSuccess ) 553 { 554 ::rtl::OStringBuffer aMessage; 555 aMessage.append( "ImageAryData::Load: failed to load image '" ); 556 aMessage.append( ::rtl::OUStringToOString( aFileName, RTL_TEXTENCODING_UTF8 ).getStr() ); 557 aMessage.append( "'" ); 558 OSL_ENSURE( false, aMessage.makeStringAndClear().getStr() ); 559 } 560 #endif 561 } 562 563 // ----------------------------------------------------------------------- 564 565 void ImageList::ImplMakeUnique() 566 { 567 if( mpImplData && mpImplData->mnRefCount > 1 ) 568 { 569 --mpImplData->mnRefCount; 570 mpImplData = new ImplImageList( *mpImplData ) ; 571 } 572 } 573 574 // ----------------------------------------------------------------------- 575 // Rather a performance hazard: 576 BitmapEx ImageList::GetAsHorizontalStrip() const 577 { 578 Size aSize( mpImplData->maImageSize ); 579 sal_uInt16 nCount = GetImageCount(); 580 if( !nCount ) 581 return BitmapEx(); 582 aSize.Width() *= nCount; 583 584 // Load any stragglers 585 for (sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++) 586 { 587 ImageAryData *pData = mpImplData->maImages[ nIdx ]; 588 if( pData->IsLoadable() ) 589 pData->Load( mpImplData->maPrefix ); 590 } 591 592 BitmapEx aTempl = mpImplData->maImages[ 0 ]->maBitmapEx; 593 BitmapEx aResult; 594 Bitmap aPixels( aSize, aTempl.GetBitmap().GetBitCount() ); 595 if( aTempl.IsAlpha() ) 596 aResult = BitmapEx( aPixels, AlphaMask( aSize ) ); 597 else if( aTempl.IsTransparent() ) 598 aResult = BitmapEx( aPixels, Bitmap( aSize, aTempl.GetMask().GetBitCount() ) ); 599 else 600 aResult = BitmapEx( aPixels ); 601 602 Rectangle aSrcRect( Point( 0, 0 ), mpImplData->maImageSize ); 603 for (sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++) 604 { 605 Rectangle aDestRect( Point( nIdx * mpImplData->maImageSize.Width(), 0 ), 606 mpImplData->maImageSize ); 607 ImageAryData *pData = mpImplData->maImages[ nIdx ]; 608 aResult.CopyPixel( aDestRect, aSrcRect, &pData->maBitmapEx); 609 } 610 611 return aResult; 612 } 613 614 // ----------------------------------------------------------------------- 615 616 void ImageList::InsertFromHorizontalStrip( const BitmapEx &rBitmapEx, 617 const std::vector< rtl::OUString > &rNameVector ) 618 { 619 sal_uInt16 nItems = sal::static_int_cast< sal_uInt16 >( rNameVector.size() ); 620 621 // fprintf (stderr, "InsertFromHorizontalStrip (1) [%d items]\n", nItems); 622 623 if (!nItems) 624 return; 625 626 Size aSize( rBitmapEx.GetSizePixel() ); 627 DBG_ASSERT (rBitmapEx.GetSizePixel().Width() % nItems == 0, 628 "ImageList::InsertFromHorizontalStrip - very odd size"); 629 aSize.Width() /= nItems; 630 ImplInit( nItems, aSize ); 631 632 for (sal_uInt16 nIdx = 0; nIdx < nItems; nIdx++) 633 { 634 BitmapEx aBitmap( rBitmapEx, Point( nIdx * aSize.Width(), 0 ), aSize ); 635 mpImplData->AddImage( rNameVector[ nIdx ], nIdx + 1, aBitmap ); 636 } 637 } 638 639 // ----------------------------------------------------------------------- 640 641 void ImageList::InsertFromHorizontalBitmap( const ResId& rResId, 642 sal_uInt16 nCount, 643 const Color *pMaskColor, 644 const Color *pSearchColors, 645 const Color *pReplaceColors, 646 sal_uLong nColorCount) 647 { 648 BitmapEx aBmpEx( rResId ); 649 if (!aBmpEx.IsTransparent()) 650 { 651 if( pMaskColor ) 652 aBmpEx = BitmapEx( aBmpEx.GetBitmap(), *pMaskColor ); 653 else 654 aBmpEx = BitmapEx( aBmpEx.GetBitmap() ); 655 } 656 if ( nColorCount && pSearchColors && pReplaceColors ) 657 aBmpEx.Replace( pSearchColors, pReplaceColors, nColorCount ); 658 659 std::vector< rtl::OUString > aNames( nCount ); 660 InsertFromHorizontalStrip( aBmpEx, aNames ); 661 } 662 663 // ----------------------------------------------------------------------- 664 665 sal_uInt16 ImageList::ImplGetImageId( const ::rtl::OUString& rImageName ) const 666 { 667 DBG_CHKTHIS( ImageList, NULL ); 668 669 ImageAryData *pImg = mpImplData->maNameHash[ rImageName ]; 670 if( pImg ) 671 return pImg->mnId; 672 else 673 return 0; 674 } 675 676 // ----------------------------------------------------------------------- 677 678 void ImageList::AddImage( sal_uInt16 nId, const Image& rImage ) 679 { 680 DBG_CHKTHIS( ImageList, NULL ); 681 DBG_CHKOBJ( &rImage, Image, NULL ); 682 DBG_ASSERT( nId, "ImageList::AddImage(): ImageId == 0" ); 683 DBG_ASSERT( GetImagePos( nId ) == IMAGELIST_IMAGE_NOTFOUND, "ImageList::AddImage() - ImageId already exists" ); 684 DBG_ASSERT( rImage.mpImplData, "ImageList::AddImage(): Wrong Size" ); 685 DBG_ASSERT( !mpImplData || (rImage.GetSizePixel() == mpImplData->maImageSize), "ImageList::AddImage(): Wrong Size" ); 686 687 if( !mpImplData ) 688 ImplInit( 0, rImage.GetSizePixel() ); 689 690 mpImplData->AddImage( rtl::OUString(), nId, rImage.GetBitmapEx()); 691 } 692 693 // ----------------------------------------------------------------------- 694 695 void ImageList::AddImage( const ::rtl::OUString& rImageName, const Image& rImage ) 696 { 697 DBG_ASSERT( GetImagePos( rImageName ) == IMAGELIST_IMAGE_NOTFOUND, "ImageList::AddImage() - ImageName already exists" ); 698 699 if( !mpImplData ) 700 ImplInit( 0, rImage.GetSizePixel() ); 701 702 mpImplData->AddImage( rImageName, GetImageCount() + 1, 703 rImage.GetBitmapEx() ); 704 } 705 706 // ----------------------------------------------------------------------- 707 708 void ImageList::ReplaceImage( sal_uInt16 nId, const Image& rImage ) 709 { 710 DBG_CHKTHIS( ImageList, NULL ); 711 DBG_CHKOBJ( &rImage, Image, NULL ); 712 DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::ReplaceImage(): Unknown nId" ); 713 714 RemoveImage( nId ); 715 AddImage( nId, rImage ); 716 } 717 718 // ----------------------------------------------------------------------- 719 720 void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const Image& rImage ) 721 { 722 const sal_uInt16 nId = ImplGetImageId( rImageName ); 723 724 if( nId ) 725 { 726 RemoveImage( nId ); 727 728 if( !mpImplData ) 729 ImplInit( 0, rImage.GetSizePixel() ); 730 mpImplData->AddImage( rImageName, nId, rImage.GetBitmapEx()); 731 } 732 } 733 734 // ----------------------------------------------------------------------- 735 736 void ImageList::ReplaceImage( sal_uInt16 nId, sal_uInt16 nReplaceId ) 737 { 738 DBG_CHKTHIS( ImageList, NULL ); 739 DBG_ASSERT( GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::ReplaceImage(): Unknown nId" ); 740 DBG_ASSERT( GetImagePos( nReplaceId ) != IMAGELIST_IMAGE_NOTFOUND, "ImageList::ReplaceImage(): Unknown nReplaceId" ); 741 742 sal_uLong nPosDest = GetImagePos( nId ); 743 sal_uLong nPosSrc = GetImagePos( nReplaceId ); 744 if( nPosDest != IMAGELIST_IMAGE_NOTFOUND && 745 nPosSrc != IMAGELIST_IMAGE_NOTFOUND ) 746 { 747 ImplMakeUnique(); 748 mpImplData->maImages[nPosDest] = mpImplData->maImages[nPosSrc]; 749 } 750 } 751 752 // ----------------------------------------------------------------------- 753 754 void ImageList::ReplaceImage( const ::rtl::OUString& rImageName, const ::rtl::OUString& rReplaceName ) 755 { 756 const sal_uInt16 nId1 = ImplGetImageId( rImageName ), nId2 = ImplGetImageId( rReplaceName ); 757 758 if( nId1 && nId2 ) 759 ReplaceImage( nId1, nId2 ); 760 } 761 762 // ----------------------------------------------------------------------- 763 764 void ImageList::RemoveImage( sal_uInt16 nId ) 765 { 766 DBG_CHKTHIS( ImageList, NULL ); 767 768 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); ++i ) 769 { 770 if( mpImplData->maImages[ i ]->mnId == nId ) 771 { 772 mpImplData->RemoveImage( static_cast< sal_uInt16 >( i ) ); 773 break; 774 } 775 } 776 } 777 778 // ----------------------------------------------------------------------- 779 780 void ImageList::RemoveImage( const ::rtl::OUString& rImageName ) 781 { 782 const sal_uInt16 nId = ImplGetImageId( rImageName ); 783 784 if( nId ) 785 RemoveImage( nId ); 786 } 787 788 // ----------------------------------------------------------------------- 789 790 Image ImageList::GetImage( sal_uInt16 nId ) const 791 { 792 DBG_CHKTHIS( ImageList, NULL ); 793 794 // fprintf (stderr, "GetImage %d\n", nId); 795 796 Image aRet; 797 798 if( mpImplData ) 799 { 800 std::vector<ImageAryData *>::iterator aIter; 801 for( aIter = mpImplData->maImages.begin(); 802 aIter != mpImplData->maImages.end(); aIter++) 803 { 804 if ((*aIter)->mnId == nId) 805 { 806 if( (*aIter)->IsLoadable() ) 807 (*aIter)->Load( mpImplData->maPrefix ); 808 809 aRet = Image( (*aIter)->maBitmapEx ); 810 } 811 } 812 } 813 814 return aRet; 815 } 816 817 // ----------------------------------------------------------------------- 818 819 Image ImageList::GetImage( const ::rtl::OUString& rImageName ) const 820 { 821 // fprintf (stderr, "GetImage '%s'\n", 822 // rtl::OUStringToOString( rImageName, RTL_TEXTENCODING_UTF8 ).getStr() ); 823 824 if( mpImplData ) 825 { 826 ImageAryData *pImg = mpImplData->maNameHash[ rImageName ]; 827 828 if( pImg ) 829 { 830 if( pImg->IsLoadable() ) 831 pImg->Load( mpImplData->maPrefix ); 832 return Image( pImg->maBitmapEx ); 833 } 834 } 835 // fprintf (stderr, "no such image\n"); 836 837 return Image(); 838 } 839 840 // ----------------------------------------------------------------------- 841 842 void ImageList::Clear() 843 { 844 DBG_CHKTHIS( ImageList, NULL ); 845 846 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) 847 delete mpImplData; 848 849 mpImplData = NULL; 850 } 851 852 // ----------------------------------------------------------------------- 853 854 sal_uInt16 ImageList::GetImageCount() const 855 { 856 DBG_CHKTHIS( ImageList, NULL ); 857 858 return mpImplData ? static_cast< sal_uInt16 >( mpImplData->maImages.size() ) : 0; 859 } 860 861 // ----------------------------------------------------------------------- 862 863 sal_uInt16 ImageList::GetImagePos( sal_uInt16 nId ) const 864 { 865 DBG_CHKTHIS( ImageList, NULL ); 866 867 if( mpImplData && nId ) 868 { 869 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); ++i ) 870 { 871 if (mpImplData->maImages[ i ]->mnId == nId) 872 return static_cast< sal_uInt16 >( i ); 873 } 874 } 875 876 return IMAGELIST_IMAGE_NOTFOUND; 877 } 878 879 bool ImageList::HasImageAtPos( sal_uInt16 nId ) const 880 { 881 return GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND; 882 } 883 884 // ----------------------------------------------------------------------- 885 886 sal_uInt16 ImageList::GetImagePos( const ::rtl::OUString& rImageName ) const 887 { 888 DBG_CHKTHIS( ImageList, NULL ); 889 890 if( mpImplData && rImageName.getLength() ) 891 { 892 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); i++ ) 893 { 894 if (mpImplData->maImages[i]->maName == rImageName) 895 return static_cast< sal_uInt16 >( i ); 896 } 897 } 898 899 return IMAGELIST_IMAGE_NOTFOUND; 900 } 901 902 // ----------------------------------------------------------------------- 903 904 sal_uInt16 ImageList::GetImageId( sal_uInt16 nPos ) const 905 { 906 DBG_CHKTHIS( ImageList, NULL ); 907 908 if( mpImplData && (nPos < GetImageCount()) ) 909 return mpImplData->maImages[ nPos ]->mnId; 910 911 return 0; 912 } 913 914 // ----------------------------------------------------------------------- 915 916 void ImageList::GetImageIds( ::std::vector< sal_uInt16 >& rIds ) const 917 { 918 RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::GetImageIds" ); 919 920 DBG_CHKTHIS( ImageList, NULL ); 921 922 rIds = ::std::vector< sal_uInt16 >(); 923 924 if( mpImplData ) 925 { 926 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); i++ ) 927 rIds.push_back( mpImplData->maImages[i]->mnId ); 928 } 929 } 930 931 // ----------------------------------------------------------------------- 932 933 ::rtl::OUString ImageList::GetImageName( sal_uInt16 nPos ) const 934 { 935 DBG_CHKTHIS( ImageList, NULL ); 936 937 if( mpImplData && (nPos < GetImageCount()) ) 938 return mpImplData->maImages[ nPos ]->maName; 939 940 return ::rtl::OUString(); 941 } 942 943 // ----------------------------------------------------------------------- 944 945 void ImageList::GetImageNames( ::std::vector< ::rtl::OUString >& rNames ) const 946 { 947 RTL_LOGFILE_CONTEXT( aLog, "vcl: ImageList::GetImageNames" ); 948 949 DBG_CHKTHIS( ImageList, NULL ); 950 951 rNames = ::std::vector< ::rtl::OUString >(); 952 953 if( mpImplData ) 954 { 955 for( sal_uInt32 i = 0; i < mpImplData->maImages.size(); i++ ) 956 { 957 const rtl::OUString& rName( mpImplData->maImages[ i ]->maName ); 958 if( rName.getLength() != 0 ) 959 rNames.push_back( rName ); 960 } 961 } 962 } 963 964 // ----------------------------------------------------------------------- 965 966 Size ImageList::GetImageSize() const 967 { 968 DBG_CHKTHIS( ImageList, NULL ); 969 970 Size aRet; 971 972 if( mpImplData ) 973 { 974 aRet = mpImplData->maImageSize; 975 976 // force load of 1st image to see - uncommon case. 977 if( aRet.Width() == 0 && aRet.Height() == 0 && 978 !mpImplData->maImages.empty() ) 979 { 980 Image aTmp = GetImage( mpImplData->maImages[ 0 ]->mnId ); 981 aRet = mpImplData->maImageSize = aTmp.GetSizePixel(); 982 } 983 } 984 // fprintf (stderr, "GetImageSize returns %d, %d\n", 985 // aRet.Width(), aRet.Height()); 986 987 return aRet; 988 } 989 990 // ----------------------------------------------------------------------- 991 992 ImageList& ImageList::operator=( const ImageList& rImageList ) 993 { 994 DBG_CHKTHIS( ImageList, NULL ); 995 DBG_CHKOBJ( &rImageList, ImageList, NULL ); 996 997 if( rImageList.mpImplData ) 998 ++rImageList.mpImplData->mnRefCount; 999 1000 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) ) 1001 delete mpImplData; 1002 1003 mpImplData = rImageList.mpImplData; 1004 1005 return *this; 1006 } 1007 1008 // ----------------------------------------------------------------------- 1009 1010 sal_Bool ImageList::operator==( const ImageList& rImageList ) const 1011 { 1012 DBG_CHKTHIS( ImageList, NULL ); 1013 DBG_CHKOBJ( &rImageList, ImageList, NULL ); 1014 1015 bool bRet = false; 1016 1017 if( rImageList.mpImplData == mpImplData ) 1018 bRet = true; 1019 else if( !rImageList.mpImplData || !mpImplData ) 1020 bRet = false; 1021 else if( rImageList.GetImageCount() == GetImageCount() && 1022 rImageList.mpImplData->maImageSize == mpImplData->maImageSize ) 1023 bRet = true; // strange semantic 1024 1025 return bRet; 1026 } 1027