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