00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "cardcache.h"
00022 #include "cardcache_p.h"
00023
00024 #include <QMap>
00025 #include <QPixmap>
00026 #include <QPair>
00027 #include <QImage>
00028 #include <QMutexLocker>
00029 #include <QPainter>
00030 #include <QDateTime>
00031 #include <QSizeF>
00032 #include <QFileInfo>
00033 #include <QDir>
00034
00035 #include <ksvgrenderer.h>
00036 #include <kpixmapcache.h>
00037 #include <kconfig.h>
00038 #include <kstandarddirs.h>
00039
00040 #include "carddeckinfo.h"
00041
00042 #include <kdebug.h>
00043
00044 #define DECKLIST_LENGTH 53
00045
00046 KCardInfo fullDeckList[DECKLIST_LENGTH] = {
00047 KCardInfo( KCardInfo::Club, KCardInfo::Ace ),
00048 KCardInfo( KCardInfo::Heart, KCardInfo::Ace ),
00049 KCardInfo( KCardInfo::Diamond, KCardInfo::Ace ),
00050 KCardInfo( KCardInfo::Spade, KCardInfo::Ace ),
00051 KCardInfo( KCardInfo::Club, KCardInfo::King ),
00052 KCardInfo( KCardInfo::Heart, KCardInfo::King ),
00053 KCardInfo( KCardInfo::Diamond, KCardInfo::King ),
00054 KCardInfo( KCardInfo::Spade, KCardInfo::King ),
00055 KCardInfo( KCardInfo::Club, KCardInfo::Queen ),
00056 KCardInfo( KCardInfo::Heart, KCardInfo::Queen ),
00057 KCardInfo( KCardInfo::Diamond, KCardInfo::Queen ),
00058 KCardInfo( KCardInfo::Spade, KCardInfo::Queen ),
00059 KCardInfo( KCardInfo::Club, KCardInfo::Jack ),
00060 KCardInfo( KCardInfo::Heart, KCardInfo::Jack ),
00061 KCardInfo( KCardInfo::Diamond, KCardInfo::Jack ),
00062 KCardInfo( KCardInfo::Spade, KCardInfo::Jack ),
00063 KCardInfo( KCardInfo::Club, KCardInfo::Ten ),
00064 KCardInfo( KCardInfo::Heart, KCardInfo::Ten ),
00065 KCardInfo( KCardInfo::Diamond, KCardInfo::Ten ),
00066 KCardInfo( KCardInfo::Spade, KCardInfo::Ten ),
00067 KCardInfo( KCardInfo::Club, KCardInfo::Nine ),
00068 KCardInfo( KCardInfo::Heart, KCardInfo::Nine ),
00069 KCardInfo( KCardInfo::Diamond, KCardInfo::Nine ),
00070 KCardInfo( KCardInfo::Spade, KCardInfo::Nine ),
00071 KCardInfo( KCardInfo::Club, KCardInfo::Eight ),
00072 KCardInfo( KCardInfo::Heart, KCardInfo::Eight ),
00073 KCardInfo( KCardInfo::Diamond, KCardInfo::Eight ),
00074 KCardInfo( KCardInfo::Spade, KCardInfo::Eight ),
00075 KCardInfo( KCardInfo::Club, KCardInfo::Seven ),
00076 KCardInfo( KCardInfo::Heart, KCardInfo::Seven ),
00077 KCardInfo( KCardInfo::Diamond, KCardInfo::Seven ),
00078 KCardInfo( KCardInfo::Spade, KCardInfo::Seven ),
00079 KCardInfo( KCardInfo::Club, KCardInfo::Six ),
00080 KCardInfo( KCardInfo::Heart, KCardInfo::Six ),
00081 KCardInfo( KCardInfo::Diamond, KCardInfo::Six ),
00082 KCardInfo( KCardInfo::Spade, KCardInfo::Six ),
00083 KCardInfo( KCardInfo::Club, KCardInfo::Five ),
00084 KCardInfo( KCardInfo::Heart, KCardInfo::Five ),
00085 KCardInfo( KCardInfo::Diamond, KCardInfo::Five ),
00086 KCardInfo( KCardInfo::Spade, KCardInfo::Five ),
00087 KCardInfo( KCardInfo::Club, KCardInfo::Four ),
00088 KCardInfo( KCardInfo::Heart, KCardInfo::Four ),
00089 KCardInfo( KCardInfo::Diamond, KCardInfo::Four ),
00090 KCardInfo( KCardInfo::Spade, KCardInfo::Four ),
00091 KCardInfo( KCardInfo::Club, KCardInfo::Three ),
00092 KCardInfo( KCardInfo::Heart, KCardInfo::Three ),
00093 KCardInfo( KCardInfo::Diamond, KCardInfo::Three ),
00094 KCardInfo( KCardInfo::Spade, KCardInfo::Three ),
00095 KCardInfo( KCardInfo::Club, KCardInfo::Two ),
00096 KCardInfo( KCardInfo::Heart, KCardInfo::Two ),
00097 KCardInfo( KCardInfo::Diamond, KCardInfo::Two ),
00098 KCardInfo( KCardInfo::Spade, KCardInfo::Two ),
00099 KCardInfo( KCardInfo::None, KCardInfo::Joker )
00100 };
00101
00102 KCardInfo::KCardInfo( KCardInfo::Suit s, KCardInfo::Card c )
00103 : m_suit( s ), m_card( c )
00104 {
00105 }
00106
00107 KCardInfo::Card KCardInfo::card() const
00108 {
00109 return m_card;
00110 }
00111
00112 KCardInfo::Suit KCardInfo::suit() const
00113 {
00114 return m_suit;
00115 }
00116
00117 void KCardInfo::setCard( KCardInfo::Card c )
00118 {
00119 m_card = c;
00120 }
00121
00122 void KCardInfo::setSuit( KCardInfo::Suit s )
00123 {
00124 m_suit = s;
00125 }
00126
00127 bool KCardInfo::operator==( const KCardInfo& c ) const
00128 {
00129 return ( c.card() == card() && c.suit() == suit() );
00130 }
00131
00132 QString KCardInfo::pngName() const
00133 {
00134 if( suit() == Club && card() == Ace ) return "1.png";
00135 if( suit() == Spade && card() == Ace ) return "2.png";
00136 if( suit() == Heart && card() == Ace ) return "3.png";
00137 if( suit() == Diamond && card() == Ace ) return "4.png";
00138 if( suit() == Club && card() == King ) return "5.png";
00139 if( suit() == Spade && card() == King ) return "6.png";
00140 if( suit() == Heart && card() == King ) return "7.png";
00141 if( suit() == Diamond && card() == King ) return "8.png";
00142 if( suit() == Club && card() == Queen ) return "9.png";
00143 if( suit() == Spade && card() == Queen ) return "10.png";
00144 if( suit() == Heart && card() == Queen ) return "11.png";
00145 if( suit() == Diamond && card() == Queen ) return "12.png";
00146 if( suit() == Club && card() == Jack ) return "13.png";
00147 if( suit() == Spade && card() == Jack ) return "14.png";
00148 if( suit() == Heart && card() == Jack ) return "15.png";
00149 if( suit() == Diamond && card() == Jack ) return "16.png";
00150 if( suit() == Club && card() == Ten ) return "17.png";
00151 if( suit() == Spade && card() == Ten ) return "18.png";
00152 if( suit() == Heart && card() == Ten ) return "19.png";
00153 if( suit() == Diamond && card() == Ten ) return "20.png";
00154 if( suit() == Club && card() == Nine ) return "21.png";
00155 if( suit() == Spade && card() == Nine ) return "22.png";
00156 if( suit() == Heart && card() == Nine ) return "23.png";
00157 if( suit() == Diamond && card() == Nine ) return "24.png";
00158 if( suit() == Club && card() == Eight ) return "25.png";
00159 if( suit() == Spade && card() == Eight ) return "26.png";
00160 if( suit() == Heart && card() == Eight ) return "27.png";
00161 if( suit() == Diamond && card() == Eight ) return "28.png";
00162 if( suit() == Club && card() == Seven ) return "29.png";
00163 if( suit() == Spade && card() == Seven ) return "30.png";
00164 if( suit() == Heart && card() == Seven ) return "31.png";
00165 if( suit() == Diamond && card() == Seven ) return "32.png";
00166 if( suit() == Club && card() == Six ) return "33.png";
00167 if( suit() == Spade && card() == Six ) return "34.png";
00168 if( suit() == Heart && card() == Six ) return "35.png";
00169 if( suit() == Diamond && card() == Six ) return "36.png";
00170 if( suit() == Club && card() == Five ) return "37.png";
00171 if( suit() == Spade && card() == Five ) return "38.png";
00172 if( suit() == Heart && card() == Five ) return "39.png";
00173 if( suit() == Diamond && card() == Five ) return "40.png";
00174 if( suit() == Club && card() == Four ) return "41.png";
00175 if( suit() == Spade && card() == Four ) return "42.png";
00176 if( suit() == Heart && card() == Four ) return "43.png";
00177 if( suit() == Diamond && card() == Four ) return "44.png";
00178 if( suit() == Club && card() == Three ) return "45.png";
00179 if( suit() == Spade && card() == Three ) return "46.png";
00180 if( suit() == Heart && card() == Three ) return "47.png";
00181 if( suit() == Diamond && card() == Three ) return "48.png";
00182 if( suit() == Club && card() == Two ) return "49.png";
00183 if( suit() == Spade && card() == Two ) return "50.png";
00184 if( suit() == Heart && card() == Two ) return "51.png";
00185 if( suit() == Diamond && card() == Two ) return "52.png";
00186 return "";
00187 }
00188
00189 QString KCardInfo::svgName() const
00190 {
00191 QString s;
00192 if( card() == KCardInfo::Ace )
00193 s += "1_";
00194 if( card() == KCardInfo::King )
00195 s += "king_";
00196 if( card() == KCardInfo::Queen )
00197 s += "queen_";
00198 if( card() == KCardInfo::Jack )
00199 s += "jack_";
00200 if( card() == KCardInfo::Ten )
00201 s += "10_";
00202 if( card() == KCardInfo::Nine )
00203 s += "9_";
00204 if( card() == KCardInfo::Eight )
00205 s += "8_";
00206 if( card() == KCardInfo::Seven )
00207 s += "7_";
00208 if( card() == KCardInfo::Six )
00209 s += "6_";
00210 if( card() == KCardInfo::Five )
00211 s += "5_";
00212 if( card() == KCardInfo::Four )
00213 s += "4_";
00214 if( card() == KCardInfo::Three )
00215 s += "3_";
00216 if( card() == KCardInfo::Two )
00217 s += "2_";
00218 if( suit() == KCardInfo::Club )
00219 s += "club";
00220 if( suit() == KCardInfo::Spade )
00221 s += "spade";
00222 if( suit() == KCardInfo::Diamond )
00223 s += "diamond";
00224 if( suit() == KCardInfo::Heart )
00225 s += "heart";
00226 return s;
00227 }
00228
00229 QPixmap doRender( const QString& element, KSvgRenderer* r, const QSize& s )
00230 {
00231 QImage img = QImage( s, QImage::Format_ARGB32 );
00232 img.fill( qRgba( 0, 0, 255, 0 ) );
00233 QPainter p( &img );
00234 if( r->elementExists( element ) )
00235 {
00236 r->render( &p, element );
00237 }else
00238 {
00239 r->render( &p, "layer1" );
00240 }
00241 p.end();
00242 return QPixmap::fromImage( img );
00243 }
00244
00245 QString keyForPixmap( const QString& theme, const QString& element, const QSize& s )
00246 {
00247 return theme + "_" + element + "_"
00248 + QString::number( s.width() ) + "_"
00249 + QString::number( s.height() );
00250 }
00251
00252 void KCardCachePrivate::ensureNonNullPixmap( QPixmap& pix )
00253 {
00254 if( pix.isNull() )
00255 {
00256 kWarning() << "Couldn't produce a non-null pixmap, creating a red cross";
00257 pix = QPixmap( size );
00258 QPainter p(&pix);
00259 p.fillRect( QRect( 0,0, pix.width(), pix.height() ), QBrush( Qt::white ) );
00260 QPen pen = p.pen();
00261 pen.setWidth( 4 );
00262 pen.setColor( QColor( Qt::red ) );
00263 p.setPen( pen );
00264 p.drawLine( QPoint( 2,2 ), QPoint( pix.width()-2, pix.height()-2 ) );
00265 p.drawLine( QPoint( pix.width()-2,2 ), QPoint( 2, pix.height()-2 ) );
00266 p.end();
00267 }
00268 }
00269
00270 QPixmap KCardCachePrivate::renderFrontSvg( const QString& element )
00271 {
00272 QMutexLocker l( frontRendererMutex );
00273 return doRender( element, frontRenderer, size );
00274 }
00275
00276 QPixmap KCardCachePrivate::renderBackSvg( const QString& element )
00277 {
00278 QMutexLocker l( backRendererMutex );
00279 return doRender( element, backRenderer, size );
00280 }
00281
00282 LoadThread::LoadThread( KCardCache::LoadInfos l_, KCardCachePrivate* d_ )
00283 : d( d_ ), infos( l_ ), killMutex( new QMutex )
00284 {
00285 }
00286
00287 void LoadThread::setSize( const QSize & s )
00288 {
00289 size = s;
00290 }
00291
00292 void LoadThread::setFrontTheme( const QString & frontTheme_ )
00293 {
00294 frontTheme = frontTheme_;
00295 }
00296
00297 void LoadThread::setBackTheme( const QString & backTheme_ )
00298 {
00299 backTheme = backTheme_;
00300 }
00301
00302 void LoadThread::kill()
00303 {
00304 QMutexLocker l(killMutex);
00305 doKill = true;
00306 }
00307
00308 void LoadThread::run()
00309 {
00310 {
00311 QMutexLocker l( killMutex );
00312 if( doKill )
00313 return;
00314 }
00315 if( infos & KCardCache::LoadBackSide )
00316 {
00317 bool found = false;
00318 QString key = keyForPixmap( backTheme, "back", size );
00319 QPixmap pix;
00320 {
00321 QMutexLocker l( d->backcacheMutex );
00322 if( d->backcache && d->backcache->find( key, pix ) )
00323 found = true;
00324 }
00325 if( !found )
00326 {
00327 {
00328 QMutexLocker l( d->backRendererMutex );
00329 pix = doRender( "back", d->backRenderer, size );
00330 }
00331 {
00332 QMutexLocker l( d->backcacheMutex );
00333 if( d->backcache )
00334 d->backcache->insert( keyForPixmap( backTheme, "back", size ), pix );
00335 }
00336 }
00337 }
00338 {
00339 QMutexLocker l( killMutex );
00340 if( doKill )
00341 return;
00342 }
00343 if( infos & KCardCache::LoadFrontSide )
00344 {
00345 int numCards = 53;
00346 if( infos & KCardCache::Load52Cards )
00347 numCards = 52;
00348 if( infos & KCardCache::Load32Cards )
00349 numCards = 32;
00350 for( int i = 0; i < numCards ; i++ )
00351 {
00352 QString element = fullDeckList[i].svgName();
00353 QString key = keyForPixmap( frontTheme, element, size );
00354 QPixmap pix;
00355 {
00356 QMutexLocker l( killMutex );
00357 if( doKill )
00358 return;
00359 }
00360 {
00361 QMutexLocker l( d->frontcacheMutex );
00362 if( d->frontcache && d->frontcache->find( key, pix ) )
00363 continue;
00364 }
00365 {
00366 QMutexLocker l( d->frontRendererMutex );
00367 pix = doRender( element, d->frontRenderer, size );
00368 }
00369 {
00370 QMutexLocker l( d->frontcacheMutex );
00371 QPixmap tmp;
00372 if( d->frontcache )
00373 d->frontcache->insert( key, pix );
00374 }
00375 }
00376 }
00377 }
00378
00379 KCardCache::KCardCache()
00380 : d( new KCardCachePrivate )
00381 {
00382 d->frontcache = 0;
00383 d->backcache = 0;
00384 d->frontcacheMutex = new QMutex();
00385 d->backcacheMutex = new QMutex();
00386 d->frontRendererMutex = new QMutex();
00387 d->backRendererMutex = new QMutex();
00388 d->frontRenderer = 0;
00389 d->backRenderer = 0;
00390 d->loadThread = 0;
00391
00392 }
00393
00394 KCardCache::~KCardCache()
00395 {
00396 if( d->loadThread && d->loadThread->isRunning() )
00397 {
00398 d->loadThread->kill();
00399 }
00400 if( d->loadThread )
00401 delete d->loadThread;
00402 delete d->frontcache;
00403 delete d->backcache;
00404 delete d->frontcacheMutex;
00405 delete d->backcacheMutex;
00406 delete d->frontRendererMutex;
00407 delete d->backRendererMutex;
00408 delete d->frontRenderer;
00409 delete d->backRenderer;
00410 delete d;
00411 }
00412
00413 QPixmap KCardCache::backside( int variant ) const
00414 {
00415 QPixmap pix;
00416 if( d->backTheme.isEmpty() || d->size.isEmpty() )
00417 return pix;
00418 QString element = "back";
00419 if( variant > 0 )
00420 {
00421 element += QString::number(variant);
00422 }
00423 QString key = keyForPixmap( d->backTheme, element, d->size );
00424 if( !CardDeckInfo::isSVGBack( d->backTheme ) )
00425 {
00426 QMutexLocker l( d->backcacheMutex );
00427 if( d->backcache && ( !d->backcache->find( key, pix ) || pix.isNull() ) )
00428 {
00429 QMatrix matrix;
00430 QImage img;
00431 bool ret = img.load( CardDeckInfo::backFilename( d->backTheme ), "PNG" );
00432 if( !ret )
00433 return QPixmap();
00434 matrix.scale( (qreal)d->size.width() / (qreal)img.width(),
00435 (qreal)d->size.height() / (qreal)img.height() );
00436 pix = QPixmap::fromImage( img.transformed( matrix ) );
00437 d->backcache->insert( key, pix );
00438 }
00439 }else
00440 {
00441 QMutexLocker l( d->backcacheMutex );
00442 if( d->backcache && ( !d->backcache->find( key, pix ) || pix.isNull() ) )
00443 {
00444 pix = d->renderBackSvg( element );
00445 d->backcache->insert( key, pix );
00446 }
00447 }
00448
00449 d->ensureNonNullPixmap( pix );
00450 return pix;
00451 }
00452
00453 QPixmap KCardCache::frontside( const KCardInfo& info ) const
00454 {
00455 QPixmap pix;
00456 if( d->frontTheme.isEmpty() || d->size.isEmpty() )
00457 return pix;
00458 QString key = keyForPixmap( d->frontTheme, info.svgName() , d->size );
00459
00460 if( !CardDeckInfo::isSVGFront( d->frontTheme ) )
00461 {
00462 QMutexLocker l( d->frontcacheMutex );
00463 if( d->frontcache && ( !d->frontcache->find( key, pix ) || pix.isNull() ) )
00464 {
00465 QMatrix matrix;
00466 QImage img;
00467 QString filename = CardDeckInfo::frontDir( d->frontTheme )
00468 + "/" + info.pngName();
00469 bool ret = img.load( filename, "PNG" );
00470 if( !ret )
00471 return QPixmap();
00472 matrix.scale( (qreal)d->size.width() / (qreal)img.width(),
00473 (qreal)d->size.height() / (qreal)img.height() );
00474 pix = QPixmap::fromImage( img.transformed( matrix ) );
00475 d->frontcache->insert( key, pix );
00476 }
00477 }else
00478 {
00479 QMutexLocker l( d->frontcacheMutex );
00480 if( d->frontcache && ( !d->frontcache->find( key, pix ) || pix.isNull() ) )
00481 {
00482 pix = d->renderFrontSvg( info.svgName() );
00483 d->frontcache->insert( key, pix );
00484 }
00485 }
00486
00487 d->ensureNonNullPixmap( pix );
00488 return pix;
00489 }
00490
00491 void KCardCache::setSize( const QSize& s )
00492 {
00493 if( s != d->size )
00494 d->size = s;
00495 }
00496
00497 QSize KCardCache::size() const
00498 {
00499 return d->size;
00500 }
00501
00502 void KCardCache::setFrontTheme( const QString& theme )
00503 {
00504 {
00505 QMutexLocker l( d->frontcacheMutex );
00506 delete d->frontcache;
00507 d->frontcache = new KPixmapCache( QString( "kdegames-cards_%1" ).arg( theme ) );
00508 d->frontcache->setUseQPixmapCache( true );
00509 QDateTime dt;
00510 if( CardDeckInfo::isSVGFront( theme ) )
00511 {
00512 dt = QFileInfo( CardDeckInfo::frontSVGFilePath( theme ) ).lastModified();
00513
00514 } else
00515 {
00516 QDir carddir( CardDeckInfo::frontDir( theme ) );
00517 foreach( QFileInfo entry, carddir.entryInfoList( QStringList() << "*.png" ) )
00518 {
00519 if( dt.isNull() || dt < entry.lastModified() )
00520 {
00521 dt = entry.lastModified();
00522 }
00523 }
00524 }
00525 if( d->frontcache->timestamp() < dt.toTime_t() )
00526 {
00527 d->frontcache->discard();
00528 d->frontcache->setTimestamp( dt.toTime_t() );
00529 }
00530 }
00531 {
00532 QMutexLocker l( d->frontRendererMutex );
00533 delete d->frontRenderer;
00534 d->frontRenderer = new KSvgRenderer( CardDeckInfo::frontSVGFilePath( theme ) );
00535 }
00536 d->frontTheme = theme;
00537 }
00538
00539 QString KCardCache::frontTheme() const
00540 {
00541 return d->frontTheme;
00542 }
00543
00544 void KCardCache::setBackTheme( const QString& theme )
00545 {
00546 {
00547 QMutexLocker l( d->backcacheMutex );
00548 delete d->backcache;
00549 d->backcache = new KPixmapCache( QString( "kdegames-cards_%1" ).arg( theme ) );
00550 d->backcache->setUseQPixmapCache( true );
00551 QDateTime dt;
00552 if( CardDeckInfo::isSVGBack( theme ) )
00553 {
00554 dt = QFileInfo( CardDeckInfo::backSVGFilePath( theme ) ).lastModified();
00555
00556 } else
00557 {
00558 dt = QFileInfo( CardDeckInfo::backFilename( theme ) ).lastModified();
00559 }
00560 if( d->backcache->timestamp() < dt.toTime_t() )
00561 {
00562 d->backcache->discard();
00563 d->backcache->setTimestamp( dt.toTime_t() );
00564 }
00565 }
00566 {
00567 QMutexLocker l( d->backRendererMutex );
00568 delete d->backRenderer;
00569 d->backRenderer = new KSvgRenderer( CardDeckInfo::backSVGFilePath( theme ) );
00570 }
00571 d->backTheme = theme;
00572 }
00573
00574 QString KCardCache::backTheme() const
00575 {
00576 return d->backTheme;
00577 }
00578
00579 void KCardCache::loadTheme( LoadInfos infos )
00580 {
00581 if( d->loadThread->isRunning() )
00582 {
00583 d->loadThread->kill();
00584 d->loadThread->wait();
00585 delete d->loadThread;
00586 }
00587 d->loadThread = new LoadThread( infos, d );
00588 d->loadThread->setBackTheme( d->backTheme );
00589 d->loadThread->setFrontTheme( d->frontTheme );
00590 d->loadThread->setSize( d->size );
00591 d->loadThread->start();
00592 }
00593
00594 QSizeF KCardCache::defaultFrontSize( const KCardInfo& info ) const
00595 {
00596 QSizeF size;
00597 if( d->frontTheme.isEmpty() )
00598 return size;
00599 if( !CardDeckInfo::isSVGFront( d->frontTheme ) )
00600 {
00601 QImage img;
00602 if( img.load( CardDeckInfo::frontDir( d->frontTheme )
00603 + "/" + info.pngName(), "PNG" ) )
00604 size = img.size();
00605 }else
00606 {
00607 QMutexLocker( d->frontRendererMutex );
00608 size = d->frontRenderer->boundsOnElement( info.svgName() ).size();
00609 }
00610 return size;
00611 }
00612
00613 QSizeF KCardCache::defaultBackSize( int variant ) const
00614 {
00615 QSizeF size;
00616 if( d->backTheme.isEmpty() )
00617 return size;
00618 QString element = "back";
00619 if( variant > 0 )
00620 {
00621 element += QString::number(variant);
00622 }
00623
00624 if( !CardDeckInfo::isSVGBack( d->backTheme ) )
00625 {
00626 QImage img;
00627 if( img.load( CardDeckInfo::backFilename( d->backTheme ), "PNG" ) )
00628 {
00629 size = img.size();
00630 }
00631 }else
00632 {
00633 QMutexLocker( d->backRendererMutex );
00634 size = d->backRenderer->boundsOnElement( element ).size();
00635 }
00636 return size;
00637 }
00638
00639 void KCardCache::invalidateFrontside()
00640 {
00641 QMutexLocker l( d->frontcacheMutex );
00642 if( d->frontcache )
00643 d->frontcache->discard();
00644 }
00645
00646 void KCardCache::invalidateBackside()
00647 {
00648 QMutexLocker l( d->backcacheMutex );
00649 if( d->backcache )
00650 d->backcache->discard();
00651 }
00652
00653 #include "cardcache_p.moc"