File indexing completed on 2024-09-01 13:23:15
0001 /* This file is part of the KDE project. 0002 SPDX-FileCopyrightText: 2010 Michael Pyne <mpyne@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #ifndef KIMAGECACHE_H 0008 #define KIMAGECACHE_H 0009 0010 // check that KGUIADDONS_LIB is defined in case the application is not using CMake 0011 // (if KGUIADDONS_LIB is not defined, we cannot assume that KCOREADDONS_LIB not being 0012 // defined means that we are not linked against KCoreAddons) 0013 #if defined(KGUIADDONS_LIB) && !defined(KCOREADDONS_LIB) 0014 #ifdef __GNUC__ 0015 #warning "KImageCache requires KF5CoreAddons (for kshareddatacache.h)" 0016 #else 0017 #pragma message("KImageCache requires KF5CoreAddons (for kshareddatacache.h)") 0018 #endif 0019 #endif 0020 0021 #include <klocalimagecacheimpl.h> 0022 #include <kshareddatacache.h> 0023 0024 #include <QImage> 0025 #include <QPixmap> 0026 0027 #define KImageCache KSharedPixmapCacheMixin<KSharedDataCache> 0028 0029 /** 0030 * @brief A simple wrapping layer over KSharedDataCache to support caching 0031 * images and pixmaps. 0032 * 0033 * This class can be used to share images between different processes, which 0034 * is useful when it is known that such images will be used across many 0035 * processes, or when creating the image is expensive. 0036 * 0037 * In addition, the class also supports caching QPixmaps <em>in a single 0038 * process</em> using the setPixmapCaching() function. 0039 * 0040 * Tips for use: If you already have QPixmaps that you intend to use, and 0041 * you do not need access to the actual image data, then try to store and 0042 * retrieve QPixmaps for use. 0043 * 0044 * On the other hand, if you will need to store and retrieve actual image 0045 * data (to modify the image after retrieval for instance) then you should 0046 * use QImage to save the conversion cost from QPixmap to QImage. 0047 * 0048 * KSharedPixmapCacheMixin is a subclass of KSharedDataCache, so all of the methods that 0049 * can be used with KSharedDataCache can be used with KSharedPixmapCacheMixin, 0050 * <em>with the exception of KSharedDataCache::insert() and 0051 * KSharedDataCache::find()</em>. 0052 * 0053 * @author Michael Pyne <mpyne@kde.org> 0054 * @since 4.5 0055 */ 0056 template<class T> 0057 class KSharedPixmapCacheMixin : public T, private KLocalImageCacheImplementation 0058 { 0059 public: 0060 /** 0061 * Constructs an image cache, named by @p cacheName, with a default 0062 * size of @p defaultCacheSize. 0063 * 0064 * @param cacheName Name of the cache to use. 0065 * @param defaultCacheSize The default size, in bytes, of the cache. 0066 * The actual on-disk size will be slightly larger. If the cache already 0067 * exists, it will not be resized. If it is required to resize the 0068 * cache then use the deleteCache() function to remove that cache first. 0069 * @param expectedItemSize The expected general size of the items to be 0070 * added to the image cache, in bytes. Use 0 if you just want a default 0071 * item size. 0072 */ 0073 KSharedPixmapCacheMixin(const QString &cacheName, unsigned defaultCacheSize, unsigned expectedItemSize = 0) 0074 : T(cacheName, defaultCacheSize, expectedItemSize) 0075 , KLocalImageCacheImplementation(defaultCacheSize) 0076 { 0077 } 0078 0079 /** 0080 * Inserts the pixmap given by @p pixmap to the cache, accessible with 0081 * @p key. The pixmap must be converted to a QImage in order to be stored 0082 * into shared memory. In order to prevent unnecessary conversions from 0083 * taking place @p pixmap will also be cached (but not in shared 0084 * memory) and would be accessible using findPixmap() if pixmap caching is 0085 * enabled. 0086 * 0087 * @param key Name to access @p pixmap with. 0088 * @param pixmap The pixmap to add to the cache. 0089 * @return true if the pixmap was successfully cached, false otherwise. 0090 * @see setPixmapCaching() 0091 */ 0092 bool insertPixmap(const QString &key, const QPixmap &pixmap) 0093 { 0094 insertLocalPixmap(key, pixmap); 0095 0096 // One thing to think about is only inserting things to the shared cache 0097 // that are frequently used. But that would require tracking the use count 0098 // in our local cache too, which I think is probably too much work. 0099 0100 return insertImage(key, pixmap.toImage()); 0101 } 0102 0103 /** 0104 * Inserts the @p image into the shared cache, accessible with @p key. This 0105 * variant is preferred over insertPixmap() if your source data is already a 0106 * QImage, if it is essential that the image be in shared memory (such as 0107 * for SVG icons which have a high render time), or if it will need to be 0108 * in QImage form after it is retrieved from the cache. 0109 * 0110 * @param key Name to access @p image with. 0111 * @param image The image to add to the shared cache. 0112 * @return true if the image was successfully cached, false otherwise. 0113 */ 0114 bool insertImage(const QString &key, const QImage &image) 0115 { 0116 if (this->insert(key, serializeImage(image))) { 0117 updateModifiedTime(); 0118 return true; 0119 } 0120 0121 return false; 0122 } 0123 0124 /** 0125 * Copies the cached pixmap identified by @p key to @p destination. If no such 0126 * pixmap exists @p destination is unchanged. 0127 * 0128 * @return true if the pixmap identified by @p key existed, false otherwise. 0129 * @see setPixmapCaching() 0130 */ 0131 bool findPixmap(const QString &key, QPixmap *destination) const 0132 { 0133 if (findLocalPixmap(key, destination)) { 0134 return true; 0135 } 0136 0137 QByteArray cachedData; 0138 if (!this->find(key, &cachedData) || cachedData.isNull()) { 0139 return false; 0140 } 0141 0142 if (destination) { 0143 destination->loadFromData(cachedData, "PNG"); 0144 0145 // Manually re-insert to pixmap cache if we'll be using this one. 0146 insertLocalPixmap(key, *destination); 0147 } 0148 0149 return true; 0150 } 0151 0152 /** 0153 * Copies the cached image identified by @p key to @p destination. If no such 0154 * image exists @p destination is unchanged. 0155 * 0156 * @return true if the image identified by @p key existed, false otherwise. 0157 */ 0158 bool findImage(const QString &key, QImage *destination) const 0159 { 0160 QByteArray cachedData; 0161 if (!this->find(key, &cachedData) || cachedData.isNull()) { 0162 return false; 0163 } 0164 0165 if (destination) { 0166 destination->loadFromData(cachedData, "PNG"); 0167 } 0168 0169 return true; 0170 } 0171 0172 /** 0173 * Removes all entries from the cache. In addition any cached pixmaps (as per 0174 * setPixmapCaching()) are also removed. 0175 */ 0176 void clear() 0177 { 0178 clearLocalCache(); 0179 T::clear(); 0180 } 0181 0182 /** 0183 * @return The time that an image or pixmap was last inserted into a cache. 0184 */ 0185 using KLocalImageCacheImplementation::lastModifiedTime; 0186 0187 /** 0188 * @return if QPixmaps added with insertPixmap() will be stored in a local 0189 * pixmap cache as well as the shared image cache. The default is to cache 0190 * pixmaps locally. 0191 */ 0192 using KLocalImageCacheImplementation::pixmapCaching; 0193 0194 /** 0195 * Enables or disables local pixmap caching. If it is anticipated that a pixmap 0196 * will be frequently needed then this can actually save memory overall since the 0197 * X server or graphics card will not have to store duplicate copies of the same 0198 * image. 0199 * 0200 * @param enable Enables pixmap caching if true, disables otherwise. 0201 */ 0202 using KLocalImageCacheImplementation::setPixmapCaching; 0203 0204 /** 0205 * @return The highest memory size in bytes to be used by cached pixmaps. 0206 * @since 4.6 0207 */ 0208 using KLocalImageCacheImplementation::pixmapCacheLimit; 0209 0210 /** 0211 * Sets the highest memory size the pixmap cache should use. 0212 * 0213 * @param size The size in bytes 0214 * @since 4.6 0215 */ 0216 using KLocalImageCacheImplementation::setPixmapCacheLimit; 0217 }; 0218 0219 #endif /* KIMAGECACHE_H */