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
Image()60 Image::Image() :
61 mpImplData( NULL )
62 {
63 DBG_CTOR( Image, NULL );
64 }
65
66 // -----------------------------------------------------------------------
67
Image(const ResId & rResId)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
Image(const Image & rImage)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
Image(const BitmapEx & rBitmapEx)128 Image::Image( const BitmapEx& rBitmapEx ) :
129 mpImplData( NULL )
130 {
131 DBG_CTOR( Image, NULL );
132
133 ImplInit( rBitmapEx );
134 }
135
136 // -----------------------------------------------------------------------
137
Image(const Bitmap & rBitmap)138 Image::Image( const Bitmap& rBitmap ) :
139 mpImplData( NULL )
140 {
141 DBG_CTOR( Image, NULL );
142
143 ImplInit( rBitmap );
144 }
145
146 // -----------------------------------------------------------------------
147
Image(const Bitmap & rBitmap,const Bitmap & rMaskBitmap)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
Image(const Bitmap & rBitmap,const Color & rColor)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
Image(const uno::Reference<graphic::XGraphic> & rxGraphic)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
~Image()183 Image::~Image()
184 {
185 DBG_DTOR( Image, NULL );
186
187 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
188 delete mpImplData;
189 }
190
191 // -----------------------------------------------------------------------
192
ImplInit(const BitmapEx & rBmpEx)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
GetSizePixel() const215 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
GetBitmapEx() const240 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
GetXGraphic() const265 uno::Reference< graphic::XGraphic > Image::GetXGraphic() const
266 {
267 const Graphic aGraphic( GetBitmapEx() );
268
269 return aGraphic.GetXGraphic();
270 }
271
272 // -----------------------------------------------------------------------
273
GetColorTransformedImage(ImageColorTransform eColorTransform) const274 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
Invert()319 void Image::Invert()
320 {
321 BitmapEx aInvertedBmp( GetBitmapEx() );
322 aInvertedBmp.Invert();
323 *this = aInvertedBmp;
324 }
325
326 // -----------------------------------------------------------------------
327
GetColorTransformArrays(ImageColorTransform eColorTransform,Color * & rpSrcColor,Color * & rpDstColor,sal_uLong & rColorCount)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
operator =(const Image & rImage)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
operator ==(const Image & rImage) const376 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
ImageList(sal_uInt16 nInit,sal_uInt16 nGrow)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
ImageList(const ResId & rResId)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
ImageList(const::std::vector<::rtl::OUString> & rNameVector,const::rtl::OUString & rPrefix,const Color *)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
ImageList(const ImageList & rImageList)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
~ImageList()511 ImageList::~ImageList()
512 {
513 DBG_DTOR( ImageList, NULL );
514
515 if( mpImplData && ( 0 == --mpImplData->mnRefCount ) )
516 delete mpImplData;
517 }
518
ImplInit(sal_uInt16 nItems,const Size & rSize)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
Load(const rtl::OUString & rPrefix)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
ImplMakeUnique()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:
GetAsHorizontalStrip() const571 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
InsertFromHorizontalStrip(const BitmapEx & rBitmapEx,const std::vector<rtl::OUString> & rNameVector)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
InsertFromHorizontalBitmap(const ResId & rResId,sal_uInt16 nCount,const Color * pMaskColor,const Color * pSearchColors,const Color * pReplaceColors,sal_uLong nColorCount)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
ImplGetImageId(const::rtl::OUString & rImageName) const660 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
AddImage(sal_uInt16 nId,const Image & rImage)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
AddImage(const::rtl::OUString & rImageName,const Image & rImage)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
ReplaceImage(sal_uInt16 nId,const Image & rImage)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
ReplaceImage(const::rtl::OUString & rImageName,const Image & rImage)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
ReplaceImage(sal_uInt16 nId,sal_uInt16 nReplaceId)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
ReplaceImage(const::rtl::OUString & rImageName,const::rtl::OUString & rReplaceName)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
RemoveImage(sal_uInt16 nId)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
RemoveImage(const::rtl::OUString & rImageName)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
GetImage(sal_uInt16 nId) const785 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
GetImage(const::rtl::OUString & rImageName) const814 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
Clear()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
GetImageCount() const849 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
GetImagePos(sal_uInt16 nId) const858 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
HasImageAtPos(sal_uInt16 nId) const874 bool ImageList::HasImageAtPos( sal_uInt16 nId ) const
875 {
876 return GetImagePos( nId ) != IMAGELIST_IMAGE_NOTFOUND;
877 }
878
879 // -----------------------------------------------------------------------
880
GetImagePos(const::rtl::OUString & rImageName) const881 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
GetImageId(sal_uInt16 nPos) const899 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
GetImageIds(::std::vector<sal_uInt16> & rIds) const911 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
GetImageName(sal_uInt16 nPos) const928 ::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
GetImageNames(::std::vector<::rtl::OUString> & rNames) const940 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
GetImageSize() const961 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
operator =(const ImageList & rImageList)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
operator ==(const ImageList & rImageList) const1005 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