diff --git a/svg.cpp b/svg.cpp index 9759cffaa..bbbdcd1c1 100644 --- a/svg.cpp +++ b/svg.cpp @@ -81,6 +81,12 @@ class SvgPrivate { bool isThemed = !QDir::isAbsolutePath(imagePath); + if (isThemed == themed && + ((themed && themePath == imagePath) || + (!themed && path == imagePath))) { + return false; + } + // lets check to see if we're already set to this file if (isThemed == themed && ((themed && themePath == imagePath) || @@ -218,32 +224,31 @@ class SvgPrivate QSize elementSize(const QString &elementId) { - createRenderer(); - - if (!renderer->elementExists(elementId)) { - return QSize(0, 0); - } - - QSizeF elementSize = renderer->boundsOnElement(elementId).size(); - QSizeF naturalSize = renderer->defaultSize(); - qreal dx = size.width() / naturalSize.width(); - qreal dy = size.height() / naturalSize.height(); - elementSize.scale(elementSize.width() * dx, elementSize.height() * dy, - Qt::IgnoreAspectRatio); - - return elementSize.toSize(); + return elementRect(elementId).size().toSize(); } QRectF elementRect(const QString &elementId) { + QRectF rect; + bool found = Theme::defaultTheme()->findInRectsCache(themePath, elementId, rect); + + if (found && !rect.isValid()) { + return QRect(); + } else if (rect.isValid()) { + return rect; + } + createRenderer(); QRectF elementRect = renderer->boundsOnElement(elementId); QSizeF naturalSize = renderer->defaultSize(); qreal dx = size.width() / naturalSize.width(); qreal dy = size.height() / naturalSize.height(); - return QRectF(elementRect.x() * dx, elementRect.y() * dy, - elementRect.width() * dx, elementRect.height() * dy); + elementRect = QRectF(elementRect.x() * dx, elementRect.y() * dy, + elementRect.width() * dx, elementRect.height() * dy); + Theme::defaultTheme()->insertIntoRectsCache(themePath, elementId, elementRect); + + return elementRect; } QMatrix matrixForElement(const QString &elementId) @@ -376,11 +381,14 @@ void Svg::resize(qreal width, qreal height) void Svg::resize(const QSizeF &size) { + Theme::defaultTheme()->invalidateRectsCache(d->themePath); d->size = size; } void Svg::resize() { + Theme::defaultTheme()->invalidateRectsCache(d->themePath); + if (d->renderer) { d->size = d->renderer->defaultSize(); } else { @@ -404,8 +412,15 @@ bool Svg::hasElement(const QString &elementId) const return false; } - d->createRenderer(); - return d->renderer->elementExists(elementId); + QRectF elementRect; + bool found = Theme::defaultTheme()->findInRectsCache(d->themePath, elementId, elementRect); + + if (found && elementRect.isValid()) { + return false; + } else { + d->createRenderer(); + return d->renderer->elementExists(elementId); + } } QString Svg::elementAtPoint(const QPoint &point) const diff --git a/theme.cpp b/theme.cpp index 1a9556ed7..6056e3f46 100644 --- a/theme.cpp +++ b/theme.cpp @@ -110,6 +110,8 @@ public: int defaultWallpaperWidth; int defaultWallpaperHeight; KPixmapCache pixmapCache; + KSharedConfigPtr svgElementsCache; + QHash > invalidElements; #ifdef Q_WS_X11 KSelectionWatcher *compositeWatch; @@ -297,6 +299,11 @@ void Theme::setThemeName(const QString &themeName) } } + + QString svgElementsFile = KStandardDirs::locateLocal("cache", "plasma-svgelements-"+themeName); + d->invalidElements.clear(); + d->svgElementsCache = KSharedConfig::openConfig(svgElementsFile); + emit themeChanged(); } @@ -492,6 +499,38 @@ void Theme::insertIntoCache(const QString& key, const QPixmap& pix) d->pixmapCache.insert(key, pix); } +bool Theme::findInRectsCache(const QString &image, const QString &element, QRectF &rect) const +{ + KConfigGroup imageGroup(d->svgElementsCache, image); + rect = imageGroup.readEntry(element, QRectF()); + + if (!d->invalidElements.contains(image)) { + d->invalidElements[image] = imageGroup.readEntry("invalidGroups", QStringList()); + } + + return d->invalidElements[image].contains(element) || rect.isValid(); +} + +void Theme::insertIntoRectsCache(const QString& image, const QString &element, const QRectF &rect) +{ + KConfigGroup imageGroup(d->svgElementsCache, image); + if (rect.isValid()) { + imageGroup.writeEntry(element, rect); + } else { + d->invalidElements[image].append(element); + if (d->invalidElements[image].count() > 1000) { + d->invalidElements[image].pop_front(); + } + imageGroup.writeEntry("invalidElements", d->invalidElements[image]); + } +} + +void Theme::invalidateRectsCache(const QString& image) +{ + KConfigGroup imageGroup(d->svgElementsCache, image); + imageGroup.deleteGroup(); +} + } #include diff --git a/theme.h b/theme.h index f61d6e784..0f0749590 100644 --- a/theme.h +++ b/theme.h @@ -192,6 +192,10 @@ class PLASMA_EXPORT Theme : public QObject **/ void insertIntoCache(const QString& key, const QPixmap& pix); + bool findInRectsCache(const QString &image, const QString &element, QRectF &rect) const; + void insertIntoRectsCache(const QString& image, const QString &element, const QRectF &rect); + void invalidateRectsCache(const QString& image); + Q_SIGNALS: /** * Emitted when the user changes the theme. SVGs should be reloaded at