cache on disk rects of elements and the not-existence of them

should avoid some calls of createRenderer() the second time it's queried

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=872250
This commit is contained in:
Marco Martin 2008-10-16 18:25:20 +00:00
parent 7b201201b0
commit 089fb6ea94
3 changed files with 76 additions and 18 deletions

51
svg.cpp
View File

@ -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

View File

@ -110,6 +110,8 @@ public:
int defaultWallpaperWidth;
int defaultWallpaperHeight;
KPixmapCache pixmapCache;
KSharedConfigPtr svgElementsCache;
QHash<QString, QList<QString> > 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 <theme.moc>

View File

@ -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