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
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26
27 #include "SlsBitmapCache.hxx"
28 #include "SlsCacheCompactor.hxx"
29 #include "SlsBitmapCompressor.hxx"
30 #include "SlsCacheConfiguration.hxx"
31
32 #include "sdpage.hxx"
33 #include "drawdoc.hxx"
34
35 // Uncomment the following define for some more OSL_TRACE messages.
36 #ifdef DEBUG
37 //#define VERBOSE
38 #endif
39
40 // Define the default value for the maximal cache size that is used for
41 // previews that are currently not visible. The visible previews are all
42 // held in memory at all times. This default is used only when the
43 // configuration does not have a value.
44 static const sal_Int32 MAXIMAL_CACHE_SIZE = 4L*1024L*1024L;
45
46 using namespace ::com::sun::star::uno;
47
48 namespace sd { namespace slidesorter { namespace cache {
49
50 class BitmapCache::CacheEntry
51 {
52 public:
53 CacheEntry(const Bitmap& rBitmap, sal_Int32 nLastAccessTime, bool bIsPrecious);
54 CacheEntry(sal_Int32 nLastAccessTime, bool bIsPrecious);
~CacheEntry(void)55 ~CacheEntry (void) {};
56 inline void Recycle (const CacheEntry& rEntry);
57 inline sal_Int32 GetMemorySize (void) const;
58 void Compress (const ::boost::shared_ptr<BitmapCompressor>& rpCompressor);
59 inline void Decompress (void);
60
IsUpToDate(void) const61 bool IsUpToDate (void) const { return mbIsUpToDate; }
SetUpToDate(bool bIsUpToDate)62 void SetUpToDate (bool bIsUpToDate) { mbIsUpToDate = bIsUpToDate; }
GetAccessTime(void) const63 sal_Int32 GetAccessTime (void) const { return mnLastAccessTime; }
SetAccessTime(sal_Int32 nAccessTime)64 void SetAccessTime (sal_Int32 nAccessTime) { mnLastAccessTime = nAccessTime; }
65
GetPreview(void) const66 Bitmap GetPreview (void) const { return maPreview; }
67 inline void SetPreview (const Bitmap& rPreview);
68 bool HasPreview (void) const;
69
GetMarkedPreview(void) const70 Bitmap GetMarkedPreview (void) const { return maMarkedPreview; }
71 inline void SetMarkedPreview (const Bitmap& rMarkePreview);
72 bool HasMarkedPreview (void) const;
73
HasReplacement(void) const74 bool HasReplacement (void) const { return (mpReplacement.get() != NULL); }
75 inline bool HasLosslessReplacement (void) const;
Clear(void)76 void Clear (void) { maPreview.SetEmpty(); maMarkedPreview.SetEmpty();
77 mpReplacement.reset(); mpCompressor.reset(); }
Invalidate(void)78 void Invalidate (void) { mpReplacement.reset(); mpCompressor.reset(); mbIsUpToDate = false; }
IsPrecious(void) const79 bool IsPrecious (void) const { return mbIsPrecious; }
SetPrecious(bool bIsPrecious)80 void SetPrecious (bool bIsPrecious) { mbIsPrecious = bIsPrecious; }
81
82 private:
83 Bitmap maPreview;
84 Bitmap maMarkedPreview;
85 ::boost::shared_ptr<BitmapReplacement> mpReplacement;
86 ::boost::shared_ptr<BitmapCompressor> mpCompressor;
87 Size maBitmapSize;
88 bool mbIsUpToDate;
89 sal_Int32 mnLastAccessTime;
90 // When this flag is set then the bitmap is not modified by a cache
91 // compactor.
92 bool mbIsPrecious;
93 };
94 class CacheEntry;
95
96 class CacheHash {
97 public:
operator ()(const BitmapCache::CacheKey & p) const98 size_t operator()(const BitmapCache::CacheKey& p) const
99 { return (size_t)p; }
100 };
101
102 class BitmapCache::CacheBitmapContainer
103 : public ::std::hash_map<CacheKey, CacheEntry, CacheHash>
104 {
105 public:
CacheBitmapContainer(void)106 CacheBitmapContainer (void) {}
107 };
108
109 namespace {
110
111 typedef ::std::vector<
112 ::std::pair< ::sd::slidesorter::cache::BitmapCache::CacheKey,
113 ::sd::slidesorter::cache::BitmapCache::CacheEntry>
114 > SortableBitmapContainer;
115
116 /** Compare elements of the bitmap cache according to their last access
117 time.
118 */
119 class AccessTimeComparator
120 {
121 public:
operator ()(const SortableBitmapContainer::value_type & e1,const SortableBitmapContainer::value_type & e2)122 bool operator () (
123 const SortableBitmapContainer::value_type& e1,
124 const SortableBitmapContainer::value_type& e2)
125 {
126 return e1.second.GetAccessTime() < e2.second.GetAccessTime();
127 }
128 };
129
130
131 } // end of anonymous namespace
132
133
134 //===== BitmapCache =========================================================
135
BitmapCache(const sal_Int32 nMaximalNormalCacheSize)136 BitmapCache::BitmapCache (const sal_Int32 nMaximalNormalCacheSize)
137 : maMutex(),
138 mpBitmapContainer(new CacheBitmapContainer()),
139 mnNormalCacheSize(0),
140 mnPreciousCacheSize(0),
141 mnCurrentAccessTime(0),
142 mnMaximalNormalCacheSize(MAXIMAL_CACHE_SIZE),
143 mpCacheCompactor(),
144 mbIsFull(false)
145 {
146 if (nMaximalNormalCacheSize > 0)
147 mnMaximalNormalCacheSize = nMaximalNormalCacheSize;
148 else
149 {
150 Any aCacheSize (CacheConfiguration::Instance()->GetValue(
151 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CacheSize"))));
152 if (aCacheSize.has<sal_Int32>())
153 aCacheSize >>= mnMaximalNormalCacheSize;
154 }
155
156 mpCacheCompactor = CacheCompactor::Create(*this,mnMaximalNormalCacheSize);
157 }
158
159
160
161
~BitmapCache(void)162 BitmapCache::~BitmapCache (void)
163 {
164 Clear();
165 }
166
167
168
169
Clear(void)170 void BitmapCache::Clear (void)
171 {
172 ::osl::MutexGuard aGuard (maMutex);
173
174 mpBitmapContainer->clear();
175 mnNormalCacheSize = 0;
176 mnPreciousCacheSize = 0;
177 mnCurrentAccessTime = 0;
178 }
179
180
181
182
IsFull(void) const183 bool BitmapCache::IsFull (void) const
184 {
185 return mbIsFull;
186 }
187
188
189
190
GetSize(void)191 sal_Int32 BitmapCache::GetSize (void)
192 {
193 return mnNormalCacheSize;
194 }
195
196
197
198
HasBitmap(const CacheKey & rKey)199 bool BitmapCache::HasBitmap (const CacheKey& rKey)
200 {
201 ::osl::MutexGuard aGuard (maMutex);
202
203 CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
204 return (iEntry != mpBitmapContainer->end()
205 && (iEntry->second.HasPreview() || iEntry->second.HasReplacement()));
206 }
207
208
209
210
BitmapIsUpToDate(const CacheKey & rKey)211 bool BitmapCache::BitmapIsUpToDate (const CacheKey& rKey)
212 {
213 ::osl::MutexGuard aGuard (maMutex);
214
215 bool bIsUpToDate = false;
216 CacheBitmapContainer::iterator aIterator (mpBitmapContainer->find(rKey));
217 if (aIterator != mpBitmapContainer->end())
218 bIsUpToDate = aIterator->second.IsUpToDate();
219
220 return bIsUpToDate;
221 }
222
223
224
225
GetBitmap(const CacheKey & rKey)226 Bitmap BitmapCache::GetBitmap (const CacheKey& rKey)
227 {
228 ::osl::MutexGuard aGuard (maMutex);
229
230 CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
231 if (iEntry == mpBitmapContainer->end())
232 {
233 // Create an empty bitmap for the given key that acts as placeholder
234 // until we are given the real one. Mark it as not being up to date.
235 SetBitmap(rKey, Bitmap(), false);
236 iEntry = mpBitmapContainer->find(rKey);
237 iEntry->second.SetUpToDate(false);
238 }
239 else
240 {
241 iEntry->second.SetAccessTime(mnCurrentAccessTime++);
242
243 // Maybe we have to decompress the preview.
244 if ( ! iEntry->second.HasPreview() && iEntry->second.HasReplacement())
245 {
246 UpdateCacheSize(iEntry->second, REMOVE);
247 iEntry->second.Decompress();
248 UpdateCacheSize(iEntry->second, ADD);
249 }
250 }
251 return iEntry->second.GetPreview();
252 }
253
254
255
256
GetMarkedBitmap(const CacheKey & rKey)257 Bitmap BitmapCache::GetMarkedBitmap (const CacheKey& rKey)
258 {
259 ::osl::MutexGuard aGuard (maMutex);
260
261 CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
262 if (iEntry != mpBitmapContainer->end())
263 {
264 iEntry->second.SetAccessTime(mnCurrentAccessTime++);
265 return iEntry->second.GetMarkedPreview();
266 }
267 else
268 return Bitmap();
269 }
270
271
272
273
ReleaseBitmap(const CacheKey & rKey)274 void BitmapCache::ReleaseBitmap (const CacheKey& rKey)
275 {
276 ::osl::MutexGuard aGuard (maMutex);
277
278 CacheBitmapContainer::iterator aIterator (mpBitmapContainer->find(rKey));
279 if (aIterator != mpBitmapContainer->end())
280 {
281 UpdateCacheSize(aIterator->second, REMOVE);
282 mpBitmapContainer->erase(aIterator);
283 }
284 }
285
286
287
288
InvalidateBitmap(const CacheKey & rKey)289 bool BitmapCache::InvalidateBitmap (const CacheKey& rKey)
290 {
291 ::osl::MutexGuard aGuard (maMutex);
292
293 CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
294 if (iEntry != mpBitmapContainer->end())
295 {
296 iEntry->second.SetUpToDate(false);
297
298 // When there is a preview then we release the replacement. The
299 // preview itself is kept until a new one is created.
300 if (iEntry->second.HasPreview())
301 {
302 UpdateCacheSize(iEntry->second, REMOVE);
303 iEntry->second.Invalidate();
304 UpdateCacheSize(iEntry->second, ADD);
305 }
306 return true;
307 }
308 else
309 return false;
310 }
311
312
313
314
InvalidateCache(void)315 void BitmapCache::InvalidateCache (void)
316 {
317 ::osl::MutexGuard aGuard (maMutex);
318
319 CacheBitmapContainer::iterator iEntry;
320 for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end(); ++iEntry)
321 {
322 iEntry->second.Invalidate();
323 }
324 ReCalculateTotalCacheSize();
325 }
326
327
328
329
SetBitmap(const CacheKey & rKey,const Bitmap & rPreview,bool bIsPrecious)330 void BitmapCache::SetBitmap (
331 const CacheKey& rKey,
332 const Bitmap& rPreview,
333 bool bIsPrecious)
334 {
335 ::osl::MutexGuard aGuard (maMutex);
336
337 CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
338 if (iEntry != mpBitmapContainer->end())
339 {
340 UpdateCacheSize(iEntry->second, REMOVE);
341 iEntry->second.SetPreview(rPreview);
342 iEntry->second.SetUpToDate(true);
343 iEntry->second.SetAccessTime(mnCurrentAccessTime++);
344 }
345 else
346 {
347 iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type (
348 rKey,
349 CacheEntry(rPreview, mnCurrentAccessTime++, bIsPrecious))
350 ).first;
351 }
352
353 if (iEntry != mpBitmapContainer->end())
354 UpdateCacheSize(iEntry->second, ADD);
355 }
356
357
358
359
SetMarkedBitmap(const CacheKey & rKey,const Bitmap & rPreview)360 void BitmapCache::SetMarkedBitmap (
361 const CacheKey& rKey,
362 const Bitmap& rPreview)
363 {
364 ::osl::MutexGuard aGuard (maMutex);
365
366 CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
367 if (iEntry != mpBitmapContainer->end())
368 {
369 UpdateCacheSize(iEntry->second, REMOVE);
370 iEntry->second.SetMarkedPreview(rPreview);
371 iEntry->second.SetAccessTime(mnCurrentAccessTime++);
372 UpdateCacheSize(iEntry->second, ADD);
373 }
374 }
375
376
377
378
SetPrecious(const CacheKey & rKey,bool bIsPrecious)379 void BitmapCache::SetPrecious (const CacheKey& rKey, bool bIsPrecious)
380 {
381 ::osl::MutexGuard aGuard (maMutex);
382
383 CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
384 if (iEntry != mpBitmapContainer->end())
385 {
386 if (iEntry->second.IsPrecious() != bIsPrecious)
387 {
388 UpdateCacheSize(iEntry->second, REMOVE);
389 iEntry->second.SetPrecious(bIsPrecious);
390 UpdateCacheSize(iEntry->second, ADD);
391 }
392 }
393 else if (bIsPrecious)
394 {
395 iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type (
396 rKey,
397 CacheEntry(Bitmap(), mnCurrentAccessTime++, bIsPrecious))
398 ).first;
399 UpdateCacheSize(iEntry->second, ADD);
400 }
401 }
402
403
404
405
ReCalculateTotalCacheSize(void)406 void BitmapCache::ReCalculateTotalCacheSize (void)
407 {
408 ::osl::MutexGuard aGuard (maMutex);
409
410 mnNormalCacheSize = 0;
411 mnPreciousCacheSize = 0;
412 CacheBitmapContainer::iterator iEntry;
413 for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end(); ++iEntry)
414 {
415 if (iEntry->second.IsPrecious())
416 mnPreciousCacheSize += iEntry->second.GetMemorySize();
417 else
418 mnNormalCacheSize += iEntry->second.GetMemorySize();
419 }
420 mbIsFull = (mnNormalCacheSize >= mnMaximalNormalCacheSize);
421
422 #ifdef VERBOSE
423 OSL_TRACE("cache size is %d/%d", mnNormalCacheSize, mnPreciousCacheSize);
424 #endif
425 }
426
427
428
429
Recycle(const BitmapCache & rCache)430 void BitmapCache::Recycle (const BitmapCache& rCache)
431 {
432 ::osl::MutexGuard aGuard (maMutex);
433
434 CacheBitmapContainer::const_iterator iOtherEntry;
435 for (iOtherEntry=rCache.mpBitmapContainer->begin();
436 iOtherEntry!=rCache.mpBitmapContainer->end();
437 ++iOtherEntry)
438 {
439 CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(iOtherEntry->first));
440 if (iEntry == mpBitmapContainer->end())
441 {
442 iEntry = mpBitmapContainer->insert(CacheBitmapContainer::value_type (
443 iOtherEntry->first,
444 CacheEntry(mnCurrentAccessTime++, true))
445 ).first;
446 UpdateCacheSize(iEntry->second, ADD);
447 }
448 if (iEntry != mpBitmapContainer->end())
449 {
450 UpdateCacheSize(iEntry->second, REMOVE);
451 iEntry->second.Recycle(iOtherEntry->second);
452 UpdateCacheSize(iEntry->second, ADD);
453 }
454 }
455 }
456
457
458
459
GetCacheIndex(bool bIncludePrecious,bool bIncludeNoPreview) const460 ::std::auto_ptr<BitmapCache::CacheIndex> BitmapCache::GetCacheIndex (
461 bool bIncludePrecious,
462 bool bIncludeNoPreview) const
463 {
464 ::osl::MutexGuard aGuard (maMutex);
465
466 // Create a copy of the bitmap container.
467 SortableBitmapContainer aSortedContainer;
468 aSortedContainer.reserve(mpBitmapContainer->size());
469
470 // Copy the relevant entries.
471 CacheBitmapContainer::iterator iEntry;
472 for (iEntry=mpBitmapContainer->begin(); iEntry!=mpBitmapContainer->end(); ++iEntry)
473 {
474 if ( ! bIncludePrecious && iEntry->second.IsPrecious())
475 continue;
476
477 if ( ! bIncludeNoPreview && ! iEntry->second.HasPreview())
478 continue;
479
480 aSortedContainer.push_back(SortableBitmapContainer::value_type(
481 iEntry->first,iEntry->second));
482 }
483
484 // Sort the remaining entries.
485 ::std::sort(aSortedContainer.begin(), aSortedContainer.end(), AccessTimeComparator());
486
487 // Return a list with the keys of the sorted entries.
488 ::std::auto_ptr<CacheIndex> pIndex(new CacheIndex());
489 SortableBitmapContainer::iterator iIndexEntry;
490 pIndex->reserve(aSortedContainer.size());
491 for (iIndexEntry=aSortedContainer.begin(); iIndexEntry!=aSortedContainer.end(); ++iIndexEntry)
492 pIndex->push_back(iIndexEntry->first);
493 return pIndex;
494 }
495
496
497
498
Compress(const CacheKey & rKey,const::boost::shared_ptr<BitmapCompressor> & rpCompressor)499 void BitmapCache::Compress (
500 const CacheKey& rKey,
501 const ::boost::shared_ptr<BitmapCompressor>& rpCompressor)
502 {
503 ::osl::MutexGuard aGuard (maMutex);
504
505 CacheBitmapContainer::iterator iEntry (mpBitmapContainer->find(rKey));
506 if (iEntry != mpBitmapContainer->end() && iEntry->second.HasPreview())
507 {
508 UpdateCacheSize(iEntry->second, REMOVE);
509 iEntry->second.Compress(rpCompressor);
510 UpdateCacheSize(iEntry->second, ADD);
511 }
512 }
513
514
515
516
UpdateCacheSize(const CacheEntry & rEntry,CacheOperation eOperation)517 void BitmapCache::UpdateCacheSize (const CacheEntry& rEntry, CacheOperation eOperation)
518 {
519 sal_Int32 nEntrySize (rEntry.GetMemorySize());
520 sal_Int32& rCacheSize (rEntry.IsPrecious() ? mnPreciousCacheSize : mnNormalCacheSize);
521 switch (eOperation)
522 {
523 case ADD:
524 rCacheSize += nEntrySize;
525 if ( ! rEntry.IsPrecious() && mnNormalCacheSize>mnMaximalNormalCacheSize)
526 {
527 mbIsFull = true;
528 #ifdef VERBOSE
529 OSL_TRACE("cache size is %d > %d", mnNormalCacheSize,mnMaximalNormalCacheSize);
530 #endif
531 mpCacheCompactor->RequestCompaction();
532 }
533 break;
534
535 case REMOVE:
536 rCacheSize -= nEntrySize;
537 if (mnNormalCacheSize < mnMaximalNormalCacheSize)
538 mbIsFull = false;
539 break;
540
541 default:
542 OSL_ASSERT(false);
543 break;
544 }
545 }
546
547
548
549
550 //===== CacheEntry ============================================================
551
CacheEntry(sal_Int32 nLastAccessTime,bool bIsPrecious)552 BitmapCache::CacheEntry::CacheEntry(
553 sal_Int32 nLastAccessTime,
554 bool bIsPrecious)
555 : maPreview(),
556 maMarkedPreview(),
557 mbIsUpToDate(true),
558 mnLastAccessTime(nLastAccessTime),
559 mbIsPrecious(bIsPrecious)
560 {
561 }
562
563
564
565
CacheEntry(const Bitmap & rPreview,sal_Int32 nLastAccessTime,bool bIsPrecious)566 BitmapCache::CacheEntry::CacheEntry(
567 const Bitmap& rPreview,
568 sal_Int32 nLastAccessTime,
569 bool bIsPrecious)
570 : maPreview(rPreview),
571 maMarkedPreview(),
572 mbIsUpToDate(true),
573 mnLastAccessTime(nLastAccessTime),
574 mbIsPrecious(bIsPrecious)
575 {
576 }
577
578
579
580
Recycle(const CacheEntry & rEntry)581 inline void BitmapCache::CacheEntry::Recycle (const CacheEntry& rEntry)
582 {
583 if ((rEntry.HasPreview() || rEntry.HasLosslessReplacement())
584 && ! (HasPreview() || HasLosslessReplacement()))
585 {
586 maPreview = rEntry.maPreview;
587 maMarkedPreview = rEntry.maMarkedPreview;
588 mpReplacement = rEntry.mpReplacement;
589 mpCompressor = rEntry.mpCompressor;
590 mnLastAccessTime = rEntry.mnLastAccessTime;
591 mbIsUpToDate = rEntry.mbIsUpToDate;
592 }
593 }
594
595
596
597
GetMemorySize(void) const598 inline sal_Int32 BitmapCache::CacheEntry::GetMemorySize (void) const
599 {
600 sal_Int32 nSize (0);
601 nSize += maPreview.GetSizeBytes();
602 nSize += maMarkedPreview.GetSizeBytes();
603 if (mpReplacement.get() != NULL)
604 nSize += mpReplacement->GetMemorySize();
605 return nSize;
606 }
607
608
609
610
Compress(const::boost::shared_ptr<BitmapCompressor> & rpCompressor)611 void BitmapCache::CacheEntry::Compress (const ::boost::shared_ptr<BitmapCompressor>& rpCompressor)
612 {
613 if ( ! maPreview.IsEmpty())
614 {
615 if (mpReplacement.get() == NULL)
616 {
617 mpReplacement = rpCompressor->Compress(maPreview);
618
619 #ifdef VERBOSE
620 sal_uInt32 nOldSize (maPreview.GetSizeBytes());
621 sal_uInt32 nNewSize (mpReplacement.get()!=NULL ? mpReplacement->GetMemorySize() : 0);
622 if (nOldSize == 0)
623 nOldSize = 1;
624 sal_Int32 nRatio (100L * nNewSize / nOldSize);
625 OSL_TRACE("compressing bitmap for %x from %d to %d bytes (%d%%)",
626 this,
627 nOldSize,
628 nNewSize,
629 nRatio);
630 #endif
631
632 mpCompressor = rpCompressor;
633 }
634
635 maPreview.SetEmpty();
636 maMarkedPreview.SetEmpty();
637 }
638 }
639
640
641
642
Decompress(void)643 inline void BitmapCache::CacheEntry::Decompress (void)
644 {
645 if (mpReplacement.get()!=NULL && mpCompressor.get()!=NULL && maPreview.IsEmpty())
646 {
647 maPreview = mpCompressor->Decompress(*mpReplacement);
648 maMarkedPreview.SetEmpty();
649 if ( ! mpCompressor->IsLossless())
650 mbIsUpToDate = false;
651 }
652 }
653
654
655
SetPreview(const Bitmap & rPreview)656 inline void BitmapCache::CacheEntry::SetPreview (const Bitmap& rPreview)
657 {
658 maPreview = rPreview;
659 maMarkedPreview.SetEmpty();
660 mpReplacement.reset();
661 mpCompressor.reset();
662 }
663
664
665
666
HasPreview(void) const667 bool BitmapCache::CacheEntry::HasPreview (void) const
668 {
669 return ! maPreview.IsEmpty();
670 }
671
672
673
674
SetMarkedPreview(const Bitmap & rMarkedPreview)675 inline void BitmapCache::CacheEntry::SetMarkedPreview (const Bitmap& rMarkedPreview)
676 {
677 maMarkedPreview = rMarkedPreview;
678 }
679
680
681
682
HasMarkedPreview(void) const683 bool BitmapCache::CacheEntry::HasMarkedPreview (void) const
684 {
685 return ! maMarkedPreview.IsEmpty();
686 }
687
688
689
690
HasLosslessReplacement(void) const691 inline bool BitmapCache::CacheEntry::HasLosslessReplacement (void) const
692 {
693 return mpReplacement.get()!=NULL
694 && mpCompressor.get()!=NULL
695 && mpCompressor->IsLossless();
696 }
697
698
699 } } } // end of namespace ::sd::slidesorter::cache
700