23#include <QtCore/QString>
24#include <QtGui/QPixmap>
25#include <QtCore/QFile>
26#include <QtCore/QDataStream>
27#include <QtCore/QFileInfo>
28#include <QtCore/QDateTime>
29#include <QtGui/QPixmapCache>
30#include <QtCore/QtGlobal>
31#include <QtGui/QPainter>
32#include <QtCore/QQueue>
33#include <QtCore/QTimer>
34#include <QtCore/QMutex>
35#include <QtCore/QMutexLocker>
36#include <QtCore/QList>
55#if defined(HAVE_MADVISE)
63extern "C" int madvise(caddr_t addr,
size_t len,
int advice);
67#define KPIXMAPCACHE_VERSION 0x000208
74 KPCLockFile(
const QString& filename)
80 for (
int i = 0; i < 5; i++) {
90 kError() <<
"Failed to lock file" << filename <<
", last result =" << result;
107 bool isValid()
const {
return mValid; }
121static const char KPC_MAGIC[] =
"KDE PIXMAP CACHE DEUX";
122struct KPixmapCacheDataHeader
126 char magic[
sizeof(KPC_MAGIC) - 1];
127 quint32 cacheVersion;
131struct KPixmapCacheIndexHeader
135 char magic[
sizeof(KPC_MAGIC) - 1];
136 quint32 cacheVersion;
147 KPCMemoryDevice(
char* start, quint32* size, quint32 available);
148 virtual ~KPCMemoryDevice();
150 virtual qint64 size()
const {
return *mSize; }
151 void setSize(quint32 s) { *mSize = s; }
152 virtual bool seek(qint64 pos);
155 virtual qint64 readData(
char* data, qint64 maxSize);
156 virtual qint64 writeData(
const char* data, qint64 maxSize);
160 KPixmapCacheIndexHeader *mHeader;
162 quint32 mInitialSize;
167KPCMemoryDevice::KPCMemoryDevice(
char* start, quint32* size, quint32 available) :
QIODevice()
170 mHeader =
reinterpret_cast<KPixmapCacheIndexHeader *
>(start);
172 mAvailable = available;
175 this->
open(QIODevice::ReadWrite);
178 *mSize = mHeader->size;
180 mInitialSize = *mSize;
183KPCMemoryDevice::~KPCMemoryDevice()
185 if (*mSize != mInitialSize) {
187 mHeader->size = *mSize;
191bool KPCMemoryDevice::seek(qint64 pos)
193 if (pos < 0 || pos > *mSize) {
197 return QIODevice::seek(pos);
200qint64 KPCMemoryDevice::readData(
char* data, qint64 len)
202 len = qMin(len, qint64(*mSize) - mPos);
206 memcpy(data, mMemory + mPos, len);
211qint64 KPCMemoryDevice::writeData(
const char* data, qint64 len)
213 if (mPos + len > mAvailable) {
214 kError() <<
"Overflow of" << mPos+len - mAvailable;
217 memcpy(mMemory + mPos, (uchar*)data, len);
219 *mSize = qMax(*mSize, mPos);
226class KPixmapCache::Private
243 void invalidateMmapFiles();
248 static unsigned kpcNumber;
250 int findOffset(
const QString& key);
251 int binarySearchKey(QDataStream& stream,
const QString& key,
int start);
252 void writeIndexEntry(QDataStream& stream,
const QString& key,
int dataoffset);
254 bool checkLockFile();
255 bool checkFileVersion(
const QString& filename);
256 bool loadIndexHeader();
257 bool loadDataHeader();
259 bool removeEntries(
int newsize);
260 bool scheduleRemoveEntries(
int newsize);
263 bool loadData(
int offset, QPixmap& pix);
264 int writeData(
const QString& key,
const QPixmap& pix);
265 void writeIndex(
const QString& key,
int offset);
269 QString indexKey(
const QString& key);
273 QString qpcKey(
const QString& key)
const;
279 quint32 mIndexRootOffset;
284 QString mLockFileName;
291 bool mUseQPixmapCache:4;
300 MmapInfo() { file = 0; indexHeader = 0; }
304 KPixmapCacheIndexHeader *indexHeader;
309 MmapInfo mIndexMmapInfo;
310 MmapInfo mDataMmapInfo;
312 bool mmapFile(
const QString& filename, MmapInfo* info,
int newsize);
313 void unmmapFile(MmapInfo* info);
317 class KPixmapCacheEntry
320 KPixmapCacheEntry(
int indexoffset_,
const QString& key_,
int dataoffset_,
321 int pos_, quint32 timesused_, quint32 lastused_)
322 : indexoffset(indexoffset_),
324 dataoffset(dataoffset_),
326 timesused(timesused_),
341 static bool compareEntriesByAge(
const KPixmapCacheEntry& a,
const KPixmapCacheEntry& b)
343 return a.pos > b.pos;
345 static bool compareEntriesByTimesUsed(
const KPixmapCacheEntry& a,
const KPixmapCacheEntry& b)
347 return a.timesused > b.timesused;
349 static bool compareEntriesByLastUsed(
const KPixmapCacheEntry& a,
const KPixmapCacheEntry& b)
351 return a.lastused > b.lastused;
358unsigned KPixmapCache::Private::kpcNumber = 0;
363 mCaches.append(
this);
364 mThisString = QString(
"%1").arg(kpcNumber++);
367KPixmapCache::Private::~Private()
369 mCaches.removeAll(
this);
372bool KPixmapCache::Private::mmapFiles()
380 int cacheLimit = mCacheLimit > 0 ? mCacheLimit : 100 * 1024;
381 if (!mmapFile(mIndexFile, &mIndexMmapInfo, (
int)(cacheLimit * 0.4 + 100) * 1024)) {
386 if (!mmapFile(mDataFile, &mDataMmapInfo, (
int)(cacheLimit * 1.5 + 500) * 1024)) {
387 unmmapFile(&mIndexMmapInfo);
395void KPixmapCache::Private::unmmapFiles()
397 unmmapFile(&mIndexMmapInfo);
398 unmmapFile(&mDataMmapInfo);
401void KPixmapCache::Private::invalidateMmapFiles()
406 if (mIndexMmapInfo.file) {
407 kDebug(264) <<
"Invalidating cache";
408 mIndexMmapInfo.indexHeader->cacheId = 0;
412bool KPixmapCache::Private::mmapFile(
const QString& filename, MmapInfo* info,
int newsize)
414 info->file =
new QFile(filename);
415 if (!info->file->open(QIODevice::ReadWrite)) {
416 kDebug(264) <<
"Couldn't open" << filename;
423 info->size = info->file->size();
425 info->available = newsize;
429 if (info->file->size() < info->available && !info->file->resize(info->available)) {
430 kError(264) <<
"Couldn't resize" << filename <<
"to" << newsize;
437 void *indexMem = info->file->map(0, info->available);
439 kError() <<
"mmap failed for" << filename;
444 info->indexHeader =
reinterpret_cast<KPixmapCacheIndexHeader *
>(indexMem);
446 posix_madvise(indexMem, info->size, POSIX_MADV_WILLNEED);
453 if(0 == info->indexHeader->size) {
456 info->indexHeader->size = mHeaderSize;
457 info->size = info->indexHeader->size;
463void KPixmapCache::Private::unmmapFile(MmapInfo* info)
466 info->file->unmap(
reinterpret_cast<uchar*
>(info->indexHeader));
467 info->indexHeader = 0;
477QIODevice* KPixmapCache::Private::indexDevice()
481 if (mIndexMmapInfo.file) {
483 QFileInfo fi(mIndexFile);
485 if (!fi.exists() || fi.size() != mIndexMmapInfo.available) {
486 kDebug(264) <<
"File size has changed, re-initializing.";
487 q->recreateCacheFiles();
491 if(fi.exists() && fi.size() == mIndexMmapInfo.available) {
493 device =
new KPCMemoryDevice(
494 reinterpret_cast<char*
>(mIndexMmapInfo.indexHeader),
495 &mIndexMmapInfo.size, mIndexMmapInfo.available);
507 QFile* file =
new QFile(mIndexFile);
508 if (!file->exists() || (
size_t) file->size() <
sizeof(KPixmapCacheIndexHeader)) {
509 q->recreateCacheFiles();
512 if (!q->isValid() || !file->open(QIODevice::ReadWrite)) {
513 kDebug(264) <<
"Couldn't open index file" << mIndexFile;
522 KPixmapCacheIndexHeader indexHeader;
524 int numRead = device->read(
reinterpret_cast<char *
>(&indexHeader),
sizeof indexHeader);
525 if (
sizeof indexHeader != numRead) {
526 kError(264) <<
"Unable to read header from pixmap cache index.";
531 if (indexHeader.cacheId != mCacheId) {
532 kDebug(264) <<
"Cache has changed, reloading";
539 return indexDevice();
546QIODevice* KPixmapCache::Private::dataDevice()
548 if (mDataMmapInfo.file) {
550 QFileInfo fi(mDataFile);
552 if (!fi.exists() || fi.size() != mDataMmapInfo.available) {
553 kDebug(264) <<
"File size has changed, re-initializing.";
554 q->recreateCacheFiles();
562 if (fi.exists() && fi.size() == mDataMmapInfo.available) {
564 return new KPCMemoryDevice(
565 reinterpret_cast<char*
>(mDataMmapInfo.indexHeader),
566 &mDataMmapInfo.size, mDataMmapInfo.available);
572 QFile* file =
new QFile(mDataFile);
573 if (!file->exists() || (
size_t) file->size() <
sizeof(KPixmapCacheDataHeader)) {
574 q->recreateCacheFiles();
580 if (!file->open(QIODevice::ReadWrite)) {
581 kDebug(264) <<
"Couldn't open data file" << mDataFile;
588int KPixmapCache::Private::binarySearchKey(QDataStream& stream,
const QString& key,
int start)
590 stream.device()->seek(start);
594 quint32 timesused, lastused;
595 qint32 leftchild, rightchild;
596 stream >> fkey >> foffset >> timesused >> lastused >> leftchild >> rightchild;
598 if (fkey.isEmpty()) {
604 return binarySearchKey(stream, key, leftchild);
606 }
else if (key == fkey) {
608 }
else if (rightchild) {
609 return binarySearchKey(stream, key, rightchild);
615int KPixmapCache::Private::findOffset(
const QString& key)
622 device->seek(mIndexRootOffset);
623 QDataStream stream(device);
628 if (!stream.atEnd()) {
635 if (fkey.isEmpty()) {
640 int nodeoffset = binarySearchKey(stream, key, mIndexRootOffset);
643 device->seek(nodeoffset);
649 quint32 timesused, lastused;
650 stream >> foffset >> timesused;
653 lastused = ::time(0);
654 stream.device()->seek(stream.device()->pos() -
sizeof(quint32));
655 stream << timesused << lastused;
666bool KPixmapCache::Private::checkLockFile()
669 if (QFile::exists(mLockFileName)) {
670 if (!QFile::remove(mLockFileName)) {
671 kError() <<
"Couldn't remove lockfile" << mLockFileName;
678bool KPixmapCache::Private::checkFileVersion(
const QString& filename)
684 if (QFile::exists(filename)) {
687 if (!f.open(QIODevice::ReadOnly)) {
688 kError() <<
"Couldn't open file" << filename;
694 KPixmapCacheIndexHeader indexHeader;
697 if(
sizeof indexHeader != f.read(
reinterpret_cast<char*
>(&indexHeader),
sizeof indexHeader) ||
698 qstrncmp(indexHeader.magic, KPC_MAGIC,
sizeof(indexHeader.magic)) != 0)
700 kDebug(264) <<
"File" << filename <<
"is not KPixmapCache file, or is";
701 kDebug(264) <<
"version <= 0x000207, will recreate...";
702 return q->recreateCacheFiles();
711 kDebug(264) <<
"File" << filename <<
"has newer version, disabling cache";
715 kDebug(264) <<
"File" << filename <<
"is outdated, will recreate...";
718 return q->recreateCacheFiles();
721bool KPixmapCache::Private::loadDataHeader()
724 QFile file(mDataFile);
725 if (!file.open(QIODevice::ReadOnly)) {
729 KPixmapCacheDataHeader dataHeader;
730 if(
sizeof dataHeader != file.read(
reinterpret_cast<char*
>(&dataHeader),
sizeof dataHeader)) {
731 kDebug(264) <<
"Unable to read from data file" << mDataFile;
735 mDataMmapInfo.size = dataHeader.size;
739bool KPixmapCache::Private::loadIndexHeader()
742 QFile file(mIndexFile);
743 if (!file.open(QIODevice::ReadOnly)) {
747 KPixmapCacheIndexHeader indexHeader;
748 if(
sizeof indexHeader != file.read(
reinterpret_cast<char*
>(&indexHeader),
sizeof indexHeader)) {
749 kWarning(264) <<
"Failed to read index file's header";
750 q->recreateCacheFiles();
754 mCacheId = indexHeader.cacheId;
755 mTimestamp = indexHeader.timestamp;
756 mIndexMmapInfo.size = indexHeader.size;
758 QDataStream stream(&file);
761 if (!q->loadCustomIndexHeader(stream)) {
765 mHeaderSize = file.pos();
766 mIndexRootOffset = file.pos();
771QString KPixmapCache::Private::indexKey(
const QString& key)
773 const QByteArray latin1 = key.toLatin1();
774 return QString(
"%1%2").arg((ushort)qChecksum(latin1.data(), latin1.size()), 4, 16, QLatin1Char(
'0')).arg(key);
778QString KPixmapCache::Private::qpcKey(
const QString& key)
const
780 return mThisString + key;
783void KPixmapCache::Private::writeIndexEntry(QDataStream& stream,
const QString& key,
int dataoffset)
786 qint32 offset = stream.device()->size();
788 int parentoffset = binarySearchKey(stream, key, mIndexRootOffset);
789 if (parentoffset != stream.device()->size()) {
792 stream.device()->seek(parentoffset);
796 if (key == fkey || fkey.isEmpty()) {
798 offset = parentoffset;
802 stream.device()->seek(offset);
804 stream << key << (qint32)dataoffset;
806 stream << (quint32)1 << (quint32)::time(0);
808 stream << (qint32)0 << (qint32)0;
813 if (parentoffset != offset) {
814 stream.device()->seek(parentoffset);
817 quint32 timesused, lastused;
818 stream >> fkey >> foffset >> timesused >> lastused;
830bool KPixmapCache::Private::removeEntries(
int newsize)
832 KPCLockFile lock(mLockFileName);
833 if (!lock.isValid()) {
834 kDebug(264) <<
"Couldn't lock cache" << mName;
837 QMutexLocker mutexlocker(&mMutex);
840 QFile indexfile(mIndexFile);
841 if (!indexfile.open(QIODevice::ReadOnly)) {
842 kDebug(264) <<
"Couldn't open old index file";
845 QDataStream istream(&indexfile);
846 QFile datafile(mDataFile);
847 if (!datafile.open(QIODevice::ReadOnly)) {
848 kDebug(264) <<
"Couldn't open old data file";
851 if (datafile.size() <= newsize*1024) {
852 kDebug(264) <<
"Cache size is already within limit (" << datafile.size() <<
" <= " << newsize*1024 <<
")";
855 QDataStream dstream(&datafile);
857 QFile newindexfile(mIndexFile +
".new");
858 if (!newindexfile.open(QIODevice::ReadWrite)) {
859 kDebug(264) <<
"Couldn't open new index file";
862 QDataStream newistream(&newindexfile);
863 QFile newdatafile(mDataFile +
".new");
864 if (!newdatafile.open(QIODevice::WriteOnly)) {
865 kDebug(264) <<
"Couldn't open new data file";
868 QDataStream newdstream(&newdatafile);
871 char*
header =
new char[mHeaderSize];
872 if (istream.readRawData(header, mHeaderSize) != (
int)mHeaderSize) {
873 kDebug(264) <<
"Couldn't read index header";
879 reinterpret_cast<KPixmapCacheIndexHeader *
>(
header)->size = 0;
880 newistream.writeRawData(header, mHeaderSize);
883 int dataheaderlen =
sizeof(KPixmapCacheDataHeader);
887 if (dstream.readRawData(header, dataheaderlen) != dataheaderlen) {
888 kDebug(264) <<
"Couldn't read data header";
894 reinterpret_cast<KPixmapCacheDataHeader *
>(
header)->size = 0;
895 newdstream.writeRawData(header, dataheaderlen);
902 open.enqueue(mIndexRootOffset);
903 while (!
open.isEmpty()) {
904 int indexoffset =
open.dequeue();
905 indexfile.seek(indexoffset);
908 quint32 timesused, lastused;
909 qint32 leftchild, rightchild;
910 istream >> fkey >> foffset >> timesused >> lastused >> leftchild >> rightchild;
911 entries.append(KPixmapCacheEntry(indexoffset, fkey, foffset, entries.count(), timesused, lastused));
913 open.enqueue(leftchild);
916 open.enqueue(rightchild);
922 if (q->removeEntryStrategy() == RemoveOldest) {
923 qSort(entries.begin(), entries.end(), compareEntriesByAge);
924 }
else if (q->removeEntryStrategy() == RemoveSeldomUsed) {
925 qSort(entries.begin(), entries.end(), compareEntriesByTimesUsed);
927 qSort(entries.begin(), entries.end(), compareEntriesByLastUsed);
931 int entrieswritten = 0;
932 for (entrieswritten = 0; entrieswritten < entries.count(); entrieswritten++) {
933 const KPixmapCacheEntry& entry = entries[entrieswritten];
935 datafile.seek(entry.dataoffset);
936 int entrysize = -datafile.pos();
941 qint32 format, w, h, bpl;
942 dstream >> format >> w >> h >> bpl;
943 QByteArray imgdatacompressed;
944 dstream >> imgdatacompressed;
946 if (!q->loadCustomData(dstream)) {
950 entrysize += datafile.pos();
953 if (newdatafile.size() + entrysize > newsize*1024) {
958 int newdataoffset = newdatafile.pos();
960 newdstream << format << w << h << bpl;
961 newdstream << imgdatacompressed;
962 q->writeCustomData(newdstream);
965 writeIndexEntry(newistream, entry.key, newdataoffset);
971 newindexfile.rename(mIndexFile);
972 newdatafile.rename(mDataFile);
973 invalidateMmapFiles();
975 kDebug(264) <<
"Wrote back" << entrieswritten <<
"of" << entries.count() <<
"entries";
984 :d(new Private(this))
987 d->mUseQPixmapCache =
true;
988 d->mCacheLimit = 3 * 1024;
1002void KPixmapCache::Private::init()
1006#ifdef DISABLE_PIXMAPCACHE
1007 mValid = mEnabled =
false;
1017 mEnabled &= checkLockFile();
1018 mEnabled &= checkFileVersion(mDataFile);
1019 mEnabled &= checkFileVersion(mIndexFile);
1021 kDebug(264) <<
"Pixmap cache" << mName <<
"is disabled";
1025 q->setValid(loadIndexHeader());
1057 return d->mEnabled && d->mValid;
1069 return d->mTimestamp;
1078 KPCLockFile lock(d->mLockFileName);
1079 if (!lock.isValid()) {
1089 KPixmapCacheIndexHeader
header;
1098 device->write(
reinterpret_cast<char *
>(&
header),
sizeof header);
1106 if (d->mDataMmapInfo.file) {
1107 return d->mDataMmapInfo.size / 1024;
1109 return QFileInfo(d->mDataFile).size() / 1024;
1114 d->mUseQPixmapCache = use;
1119 return d->mUseQPixmapCache;
1124 return d->mCacheLimit;
1134 d->mCacheLimit = kbytes;
1138 if (d->mInited && d->mCacheLimit &&
size() > d->mCacheLimit) {
1139 if (
size() > (
int)(d->mCacheLimit)) {
1141 d->removeEntries(d->mCacheLimit * 0.65);
1148 return d->mRemoveStrategy;
1153 d->mRemoveStrategy = strategy;
1162 KPCLockFile lock(d->mLockFileName);
1165 d->invalidateMmapFiles();
1166 d->mEnabled =
false;
1170 if (!indexfile.
open(QIODevice::WriteOnly)) {
1171 kError() <<
"Couldn't create index file" << d->mIndexFile;
1175 d->mCacheId = ::time(0);
1176 d->mTimestamp = ::time(0);
1180 KPixmapCacheIndexHeader indexHeader = { {0},
KPIXMAPCACHE_VERSION, 0, d->mCacheId, d->mTimestamp };
1181 memcpy(indexHeader.magic, KPC_MAGIC,
sizeof(indexHeader.magic));
1183 indexfile.write(
reinterpret_cast<char*
>(&indexHeader),
sizeof indexHeader);
1187 if (!datafile.
open(QIODevice::WriteOnly)) {
1188 kError() <<
"Couldn't create data file" << d->mDataFile;
1193 memcpy(dataHeader.magic, KPC_MAGIC,
sizeof(dataHeader.magic));
1195 datafile.write(
reinterpret_cast<char*
>(&dataHeader),
sizeof dataHeader);
1199 QDataStream istream(&indexfile);
1201 d->mHeaderSize = indexfile.pos();
1203 d->mIndexRootOffset = d->mHeaderSize;
1222 QFile::remove(indexFile);
1223 QFile::remove(dataFile);
1232 KPCLockFile lock(d->mLockFileName);
1233 if(!lock.isValid()) {
1234 kError(264) <<
"Unable to lock pixmap cache when trying to discard it";
1240 kError(264) <<
"Unable to access index when trying to discard cache";
1244 device->seek(d->mIndexRootOffset);
1245 QDataStream stream(device);
1249 stream << QString();
1251 if (d->mUseQPixmapCache) {
1254 QPixmapCache::clear();
1261 newsize = d->mCacheLimit;
1269 d->removeEntries(newsize);
1281 if (d->mUseQPixmapCache && QPixmapCache::find(d->qpcKey(key), &pix)) {
1286 KPCLockFile lock(d->mLockFileName);
1287 if (!lock.isValid()) {
1292 QString indexkey = d->indexKey(key);
1293 int offset = d->findOffset(indexkey);
1300 bool ret = d->loadData(offset, pix);
1301 if (ret && d->mUseQPixmapCache) {
1303 QPixmapCache::insert(d->qpcKey(key), pix);
1308bool KPixmapCache::Private::loadData(
int offset, QPixmap& pix)
1316 if (!device->seek(offset)) {
1317 kError() <<
"Couldn't seek to pos" << offset;
1321 QDataStream stream(device);
1328 qint32 format, w, h, bpl;
1329 stream >> format >> w >> h >> bpl;
1330 QByteArray imgdatacompressed;
1331 stream >> imgdatacompressed;
1337 QByteArray imgdata = qUncompress(imgdatacompressed);
1338 if (!imgdata.isEmpty()) {
1339 QImage img((
const uchar*)imgdata.constData(), w, h, bpl, (QImage::Format)format);
1341 pix = QPixmap::fromImage(img);
1343 pix = QPixmap(w, h);
1346 if (!q->loadCustomData(stream)) {
1352 if (stream.status() != QDataStream::Ok) {
1353 kError() <<
"stream is bad :-( status=" << stream.status();
1375 if (d->mUseQPixmapCache) {
1376 QPixmapCache::insert(d->qpcKey(key), pix);
1379 KPCLockFile lock(d->mLockFileName);
1380 if (!lock.isValid()) {
1385 QString indexkey = d->indexKey(key);
1386 int offset = d->writeData(key, pix);
1392 d->writeIndex(indexkey, offset);
1395 if (d->mCacheLimit &&
size() > d->mCacheLimit) {
1397 if (
size() > (
int)(d->mCacheLimit)) {
1399 d->removeEntries(d->mCacheLimit * 0.65);
1404int KPixmapCache::Private::writeData(
const QString& key,
const QPixmap& pix)
1411 int offset = device->size();
1412 device->seek(offset);
1413 QDataStream stream(device);
1418 QImage img = pix.toImage();
1419 QByteArray imgdatacompressed = qCompress(img.bits(), img.numBytes());
1420 stream << (qint32)img.format() << (qint32)img.width() << (qint32)img.height() << (qint32)img.bytesPerLine();
1421 stream << imgdatacompressed;
1423 q->writeCustomData(stream);
1434void KPixmapCache::Private::writeIndex(
const QString& key,
int dataoffset)
1441 QDataStream stream(device);
1443 writeIndexEntry(stream, key, dataoffset);
1449 QFileInfo fi(filename);
1452 }
else if (fi.lastModified().toTime_t() >
timestamp()) {
1458 QString key(
"file:" + filename);
1459 if (!
find(key, pix)) {
1461 pix = QPixmap(filename);
1475 QFileInfo fi(filename);
1478 }
else if (fi.lastModified().toTime_t() >
timestamp()) {
1484 QString key = QString(
"file:%1_%2_%3").arg(filename).arg(size.width()).arg(size.height());
1485 if (!
find(key, pix)) {
1488 if (!svg.load(filename)) {
1491 QSize pixSize = size.isValid() ? size : svg.defaultSize();
1492 pix = QPixmap(pixSize);
1493 pix.fill(Qt::transparent);
1496 svg.render(&p, QRectF(QPointF(), pixSize));
General-purpose pixmap cache for KDE.
virtual bool writeCustomData(QDataStream &stream)
Can be used by subclasses to write custom data into the stream.
bool isEnabled() const
Cache will be disabled when e.g.
virtual void insert(const QString &key, const QPixmap &pix)
Inserts the pixmap pix into the cache, associated with the key key.
KPixmapCache(const QString &name)
Constucts the pixmap cache object.
virtual bool loadCustomData(QDataStream &stream)
Can be used by subclasses to load custom data from the stream.
void setCacheLimit(int kbytes)
Sets the maximum size of the cache (in kilobytes).
static void deleteCache(const QString &name)
Deletes a pixmap cache.
void setRemoveEntryStrategy(RemoveStrategy strategy)
Sets the removeEntryStrategy used when removing entries.
void setValid(bool valid)
Sets whether this cache is valid or not.
virtual void writeCustomIndexHeader(QDataStream &stream)
Can be used by subclasses to write custom data into cache's header.
unsigned int timestamp() const
virtual bool find(const QString &key, QPixmap &pix)
Tries to load pixmap with the specified key from cache.
QPixmap loadFromSvg(const QString &filename, const QSize &size=QSize())
Same as loadFromFile(), but using an SVG file instead.
bool useQPixmapCache() const
Whether QPixmapCache should be used to cache pixmaps in memory in addition to caching them on the dis...
void setTimestamp(unsigned int time)
Sets the timestamp of app-specific cache.
RemoveStrategy removeEntryStrategy() const
RemoveStrategy
Describes which entries will be removed first during cache cleanup.
@ RemoveLeastRecentlyUsed
least recently used entries are removed first.
void removeEntries(int newsize=0)
Removes some of the entries in the cache according to current removeEntryStrategy().
bool recreateCacheFiles()
This function causes the cache files to be recreate by invalidating the cache.
virtual bool loadCustomIndexHeader(QDataStream &stream)
Can be used by subclasses to load custom data from cache's header.
void setUseQPixmapCache(bool use)
Sets whether QPixmapCache (memory caching) should be used in addition to disk cache.
QPixmap loadFromFile(const QString &filename)
Loads a pixmap from given file, using the cache.
void discard()
Deletes all entries and reinitializes this cache.
void ensureInited() const
Makes sure that the cache is initialized correctly, including the loading of the cache index and data...
virtual bool open(OpenMode flags=QIODevice::ReadWrite)
static QString locateLocal(const char *type, const QString &filename, bool createDir, const KComponentData &cData=KGlobal::mainComponent())
int madvise(caddr_t addr, size_t len, int advice)
#define KPIXMAPCACHE_VERSION
int open(const QString &pathname, int flags, mode_t mode)