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