on disk pixmap cache, and use it agressively for svg's. first step towards "no svg parsing on second run"!
svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=871870
This commit is contained in:
parent
047c0dde89
commit
6374635bf3
120
svg.cpp
120
svg.cpp
@ -22,15 +22,15 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QMatrix>
|
#include <QMatrix>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPixmapCache>
|
|
||||||
#include <QSharedData>
|
#include <QSharedData>
|
||||||
|
|
||||||
#include <KDebug>
|
|
||||||
#include <KSharedPtr>
|
|
||||||
#include <KSvgRenderer>
|
|
||||||
#include <KColorScheme>
|
#include <KColorScheme>
|
||||||
|
#include <KConfigGroup>
|
||||||
|
#include <KDebug>
|
||||||
#include <KIconEffect>
|
#include <KIconEffect>
|
||||||
#include <KGlobalSettings>
|
#include <KGlobalSettings>
|
||||||
|
#include <KSharedPtr>
|
||||||
|
#include <KSvgRenderer>
|
||||||
|
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
|
|
||||||
@ -77,8 +77,21 @@ class SvgPrivate
|
|||||||
eraseRenderer();
|
eraseRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setImagePath(const QString &imagePath, Svg *q)
|
bool setImagePath(const QString &imagePath, Svg *q)
|
||||||
{
|
{
|
||||||
|
bool isThemed = !QDir::isAbsolutePath(imagePath);
|
||||||
|
|
||||||
|
// lets check to see if we're already set to this file
|
||||||
|
if (isThemed == themed &&
|
||||||
|
((themed && themePath == imagePath) ||
|
||||||
|
(!themed && path == imagePath))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we don't have any path right now and are going to set one,
|
||||||
|
// then lets not schedule a repaint because we are just initializing!
|
||||||
|
bool updateNeeded = true; //!path.isEmpty() || !themePath.isEmpty();
|
||||||
|
|
||||||
if (themed) {
|
if (themed) {
|
||||||
QObject::disconnect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
|
QObject::disconnect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
|
||||||
q, SLOT(themeChanged()));
|
q, SLOT(themeChanged()));
|
||||||
@ -86,7 +99,7 @@ class SvgPrivate
|
|||||||
q, SLOT(colorsChanged()));
|
q, SLOT(colorsChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
themed = !QDir::isAbsolutePath(imagePath);
|
themed = isThemed;
|
||||||
path.clear();
|
path.clear();
|
||||||
themePath.clear();
|
themePath.clear();
|
||||||
|
|
||||||
@ -96,38 +109,22 @@ class SvgPrivate
|
|||||||
q, SLOT(themeChanged()));
|
q, SLOT(themeChanged()));
|
||||||
|
|
||||||
// check if svg wants colorscheme applied
|
// check if svg wants colorscheme applied
|
||||||
createRenderer();
|
checkApplyColorHint();
|
||||||
applyColors = renderer->elementExists("hint-apply-color-scheme");
|
|
||||||
if (applyColors && !Theme::defaultTheme()->colorScheme()) {
|
if (applyColors && !Theme::defaultTheme()->colorScheme()) {
|
||||||
QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
|
QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
|
||||||
q, SLOT(colorsChanged()));
|
q, SLOT(colorsChanged()));
|
||||||
}
|
}
|
||||||
|
} else if (QFile::exists(imagePath)) {
|
||||||
} else {
|
|
||||||
path = imagePath;
|
path = imagePath;
|
||||||
|
} else {
|
||||||
if (!QFile::exists(path)) {
|
|
||||||
kDebug() << "file '" << path << "' does not exist!";
|
kDebug() << "file '" << path << "' does not exist!";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeFromCache() {
|
return updateNeeded;
|
||||||
if (ids.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (const QString &id, ids) {
|
|
||||||
QPixmapCache::remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
ids.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap findInCache(const QString &elementId, const QSizeF &s = QSizeF())
|
QPixmap findInCache(const QString &elementId, const QSizeF &s = QSizeF())
|
||||||
{
|
{
|
||||||
createRenderer();
|
|
||||||
|
|
||||||
QSize size;
|
QSize size;
|
||||||
if (elementId.isEmpty() || multipleImages) {
|
if (elementId.isEmpty() || multipleImages) {
|
||||||
size = s.toSize();
|
size = s.toSize();
|
||||||
@ -145,16 +142,14 @@ class SvgPrivate
|
|||||||
if (!elementId.isEmpty()) {
|
if (!elementId.isEmpty()) {
|
||||||
id.append(elementId);
|
id.append(elementId);
|
||||||
}
|
}
|
||||||
|
|
||||||
//kDebug() << "id is " << id;
|
//kDebug() << "id is " << id;
|
||||||
|
|
||||||
if (!ids.contains(id)) {
|
Theme *theme = Theme::defaultTheme();
|
||||||
ids.append(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmap p;
|
QPixmap p;
|
||||||
|
|
||||||
if (QPixmapCache::find(id, p)) {
|
if (theme->findInCache(id, p)) {
|
||||||
//kDebug() << "found cached version of " << id;
|
//kDebug() << "found cached version of " << id << p.size();
|
||||||
return p;
|
return p;
|
||||||
} else {
|
} else {
|
||||||
//kDebug() << "didn't find cached version of " << id << ", so re-rendering";
|
//kDebug() << "didn't find cached version of " << id << ", so re-rendering";
|
||||||
@ -168,6 +163,7 @@ class SvgPrivate
|
|||||||
p.fill(Qt::transparent);
|
p.fill(Qt::transparent);
|
||||||
QPainter renderPainter(&p);
|
QPainter renderPainter(&p);
|
||||||
|
|
||||||
|
createRenderer();
|
||||||
if (elementId.isEmpty()) {
|
if (elementId.isEmpty()) {
|
||||||
renderer->render(&renderPainter);
|
renderer->render(&renderPainter);
|
||||||
} else {
|
} else {
|
||||||
@ -179,15 +175,11 @@ class SvgPrivate
|
|||||||
// Apply current color scheme if the svg asks for it
|
// Apply current color scheme if the svg asks for it
|
||||||
if (applyColors) {
|
if (applyColors) {
|
||||||
QImage itmp = p.toImage();
|
QImage itmp = p.toImage();
|
||||||
KIconEffect::colorize(
|
KIconEffect::colorize(itmp, theme->color(Theme::BackgroundColor), 1.0);
|
||||||
itmp, Theme::defaultTheme()->color(Theme::BackgroundColor), 1.0);
|
|
||||||
p = p.fromImage(itmp);
|
p = p.fromImage(itmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QPixmapCache::insert(id, p)) {
|
theme->insertIntoCache(id, p);
|
||||||
//kDebug() << "pixmap cache is too small for inserting" << id << "of size" << s;
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,14 +193,14 @@ class SvgPrivate
|
|||||||
path = Plasma::Theme::defaultTheme()->imagePath(themePath);
|
path = Plasma::Theme::defaultTheme()->imagePath(themePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<QString, SharedSvgRenderer::Ptr>::const_iterator it = renderers.find(path);
|
QHash<QString, SharedSvgRenderer::Ptr>::const_iterator it = s_renderers.find(path);
|
||||||
|
|
||||||
if (it != renderers.end()) {
|
if (it != s_renderers.end()) {
|
||||||
//kDebug() << "gots us an existing one!";
|
//kDebug() << "gots us an existing one!";
|
||||||
renderer = it.value();
|
renderer = it.value();
|
||||||
} else {
|
} else {
|
||||||
renderer = new SharedSvgRenderer(path);
|
renderer = new SharedSvgRenderer(path);
|
||||||
renderers[path] = renderer;
|
s_renderers[path] = renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = renderer->defaultSize();
|
size = renderer->defaultSize();
|
||||||
@ -218,7 +210,7 @@ class SvgPrivate
|
|||||||
{
|
{
|
||||||
if (renderer && renderer.count() == 2) {
|
if (renderer && renderer.count() == 2) {
|
||||||
// this and the cache reference it; and boy is this not thread safe ;)
|
// this and the cache reference it; and boy is this not thread safe ;)
|
||||||
renderers.erase(renderers.find(path));
|
s_renderers.erase(s_renderers.find(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer = 0;
|
renderer = 0;
|
||||||
@ -260,6 +252,19 @@ class SvgPrivate
|
|||||||
return renderer->matrixForElement(elementId);
|
return renderer->matrixForElement(elementId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void checkApplyColorHint()
|
||||||
|
{
|
||||||
|
KConfigGroup cg(KGlobal::config(), "SvgHints");
|
||||||
|
QString cgKey = themePath + "-hint-apply-color-scheme";
|
||||||
|
if (cg.hasKey(cgKey)) {
|
||||||
|
applyColors = cg.readEntry(cgKey, false);
|
||||||
|
} else {
|
||||||
|
createRenderer();
|
||||||
|
applyColors = renderer->elementExists("hint-apply-color-scheme");
|
||||||
|
cg.writeEntry(cgKey, applyColors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void themeChanged()
|
void themeChanged()
|
||||||
{
|
{
|
||||||
if (!themed) {
|
if (!themed) {
|
||||||
@ -272,22 +277,24 @@ class SvgPrivate
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFromCache();
|
|
||||||
path = newPath;
|
path = newPath;
|
||||||
//delete d->renderer; we're a KSharedPtr
|
//delete d->renderer; we're a KSharedPtr
|
||||||
eraseRenderer();
|
eraseRenderer();
|
||||||
|
|
||||||
// check if new theme svg wants colorscheme applied
|
// check if new theme svg wants colorscheme applied
|
||||||
createRenderer();
|
bool wasApplyColors = applyColors;
|
||||||
applyColors = renderer->elementExists("hint-apply-color-scheme");
|
checkApplyColorHint();
|
||||||
if (applyColors && !Theme::defaultTheme()->colorScheme()) {
|
if (applyColors && !Theme::defaultTheme()->colorScheme()) {
|
||||||
|
if (!wasApplyColors) {
|
||||||
QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
|
QObject::connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
|
||||||
q, SLOT(colorsChanged()));
|
q, SLOT(colorsChanged()));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
QObject::disconnect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
|
QObject::disconnect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
|
||||||
q, SLOT(colorsChanged()));
|
q, SLOT(colorsChanged()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//kDebug() << themePath << ">>>>>>>>>>>>>>>>>> theme changed";
|
||||||
emit q->repaintNeeded();
|
emit q->repaintNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,24 +304,22 @@ class SvgPrivate
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFromCache();
|
|
||||||
eraseRenderer();
|
eraseRenderer();
|
||||||
emit q->repaintNeeded();
|
emit q->repaintNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
Svg *q;
|
Svg *q;
|
||||||
static QHash<QString, SharedSvgRenderer::Ptr> renderers;
|
static QHash<QString, SharedSvgRenderer::Ptr> s_renderers;
|
||||||
SharedSvgRenderer::Ptr renderer;
|
SharedSvgRenderer::Ptr renderer;
|
||||||
QString themePath;
|
QString themePath;
|
||||||
QString path;
|
QString path;
|
||||||
QList<QString> ids;
|
|
||||||
QSizeF size;
|
QSizeF size;
|
||||||
bool multipleImages;
|
bool multipleImages;
|
||||||
bool themed;
|
bool themed;
|
||||||
bool applyColors;
|
bool applyColors;
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash<QString, SharedSvgRenderer::Ptr> SvgPrivate::renderers;
|
QHash<QString, SharedSvgRenderer::Ptr> SvgPrivate::s_renderers;
|
||||||
|
|
||||||
Svg::Svg(QObject *parent)
|
Svg::Svg(QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
@ -371,14 +376,16 @@ void Svg::resize(qreal width, qreal height)
|
|||||||
|
|
||||||
void Svg::resize(const QSizeF &size)
|
void Svg::resize(const QSizeF &size)
|
||||||
{
|
{
|
||||||
d->createRenderer();
|
|
||||||
d->size = size;
|
d->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Svg::resize()
|
void Svg::resize()
|
||||||
{
|
{
|
||||||
d->createRenderer();
|
if (d->renderer) {
|
||||||
d->size = d->renderer->defaultSize();
|
d->size = d->renderer->defaultSize();
|
||||||
|
} else {
|
||||||
|
d->size = QSizeF();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize Svg::elementSize(const QString &elementId) const
|
QSize Svg::elementSize(const QString &elementId) const
|
||||||
@ -393,6 +400,10 @@ QRectF Svg::elementRect(const QString &elementId) const
|
|||||||
|
|
||||||
bool Svg::hasElement(const QString &elementId) const
|
bool Svg::hasElement(const QString &elementId) const
|
||||||
{
|
{
|
||||||
|
if (d->path.isNull() && d->themePath.isNull()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
d->createRenderer();
|
d->createRenderer();
|
||||||
return d->renderer->elementExists(elementId);
|
return d->renderer->elementExists(elementId);
|
||||||
}
|
}
|
||||||
@ -415,6 +426,10 @@ FIXME: implement when Qt can support us!
|
|||||||
|
|
||||||
bool Svg::isValid() const
|
bool Svg::isValid() const
|
||||||
{
|
{
|
||||||
|
if (d->path.isNull() && d->themePath.isNull()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
d->createRenderer();
|
d->createRenderer();
|
||||||
return d->renderer->isValid();
|
return d->renderer->isValid();
|
||||||
}
|
}
|
||||||
@ -431,7 +446,8 @@ bool Svg::containsMultipleImages() const
|
|||||||
|
|
||||||
void Svg::setImagePath(const QString &svgFilePath)
|
void Svg::setImagePath(const QString &svgFilePath)
|
||||||
{
|
{
|
||||||
d->setImagePath(svgFilePath, this);
|
if (d->setImagePath(svgFilePath, this)) {
|
||||||
|
}
|
||||||
d->eraseRenderer();
|
d->eraseRenderer();
|
||||||
emit repaintNeeded();
|
emit repaintNeeded();
|
||||||
}
|
}
|
||||||
|
30
theme.cpp
30
theme.cpp
@ -25,15 +25,17 @@
|
|||||||
#include <QX11Info>
|
#include <QX11Info>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <KWindowSystem>
|
|
||||||
#include <KColorScheme>
|
#include <KColorScheme>
|
||||||
|
#include <KComponentData>
|
||||||
#include <KConfigGroup>
|
#include <KConfigGroup>
|
||||||
#include <KDebug>
|
#include <KDebug>
|
||||||
#include <KGlobal>
|
#include <KGlobal>
|
||||||
|
#include <KGlobalSettings>
|
||||||
|
#include <KPixmapCache>
|
||||||
#include <KSelectionWatcher>
|
#include <KSelectionWatcher>
|
||||||
#include <KSharedConfig>
|
#include <KSharedConfig>
|
||||||
#include <KStandardDirs>
|
#include <KStandardDirs>
|
||||||
#include <KGlobalSettings>
|
#include <KWindowSystem>
|
||||||
|
|
||||||
#include "private/packages_p.h"
|
#include "private/packages_p.h"
|
||||||
|
|
||||||
@ -56,6 +58,7 @@ public:
|
|||||||
defaultWallpaperSuffix(DEFAULT_WALLPAPER_SUFFIX),
|
defaultWallpaperSuffix(DEFAULT_WALLPAPER_SUFFIX),
|
||||||
defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH),
|
defaultWallpaperWidth(DEFAULT_WALLPAPER_WIDTH),
|
||||||
defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT),
|
defaultWallpaperHeight(DEFAULT_WALLPAPER_HEIGHT),
|
||||||
|
pixmapCache(KGlobal::mainComponent().componentName()),
|
||||||
locolor(false),
|
locolor(false),
|
||||||
compositingActive(KWindowSystem::compositingActive()),
|
compositingActive(KWindowSystem::compositingActive()),
|
||||||
isDefault(false),
|
isDefault(false),
|
||||||
@ -65,6 +68,10 @@ public:
|
|||||||
generalFont = QApplication::font();
|
generalFont = QApplication::font();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~ThemePrivate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
KConfigGroup &config()
|
KConfigGroup &config()
|
||||||
{
|
{
|
||||||
if (!cfg.isValid()) {
|
if (!cfg.isValid()) {
|
||||||
@ -102,6 +109,7 @@ public:
|
|||||||
QString defaultWallpaperSuffix;
|
QString defaultWallpaperSuffix;
|
||||||
int defaultWallpaperWidth;
|
int defaultWallpaperWidth;
|
||||||
int defaultWallpaperHeight;
|
int defaultWallpaperHeight;
|
||||||
|
KPixmapCache pixmapCache;
|
||||||
|
|
||||||
#ifdef Q_WS_X11
|
#ifdef Q_WS_X11
|
||||||
KSelectionWatcher *compositeWatch;
|
KSelectionWatcher *compositeWatch;
|
||||||
@ -232,6 +240,14 @@ void Theme::setThemeName(const QString &themeName)
|
|||||||
theme = ThemePrivate::defaultTheme;
|
theme = ThemePrivate::defaultTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (d->themeName == theme) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!d->themeName.isEmpty()) {
|
||||||
|
d->pixmapCache.discard();
|
||||||
|
}
|
||||||
|
|
||||||
d->themeName = theme;
|
d->themeName = theme;
|
||||||
|
|
||||||
// load the color scheme config
|
// load the color scheme config
|
||||||
@ -466,6 +482,16 @@ bool Theme::useGlobalSettings() const
|
|||||||
return d->useGlobal;
|
return d->useGlobal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Theme::findInCache(const QString &key, QPixmap &pix)
|
||||||
|
{
|
||||||
|
return d->pixmapCache.find(key, pix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Theme::insertIntoCache(const QString& key, const QPixmap& pix)
|
||||||
|
{
|
||||||
|
d->pixmapCache.insert(key, pix);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <theme.moc>
|
#include <theme.moc>
|
||||||
|
13
theme.h
13
theme.h
@ -179,6 +179,19 @@ class PLASMA_EXPORT Theme : public QObject
|
|||||||
*/
|
*/
|
||||||
bool useGlobalSettings() const;
|
bool useGlobalSettings() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to load pixmap with the specified key from cache.
|
||||||
|
* @return true when pixmap was found and loaded from cache, false otherwise
|
||||||
|
**/
|
||||||
|
bool findInCache(const QString &key, QPixmap &pix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert specified pixmap into the cache.
|
||||||
|
* If the cache already contains pixmap with the specified key then it is
|
||||||
|
* overwritten.
|
||||||
|
**/
|
||||||
|
void insertIntoCache(const QString& key, const QPixmap& pix);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* Emitted when the user changes the theme. SVGs should be reloaded at
|
* Emitted when the user changes the theme. SVGs should be reloaded at
|
||||||
|
Loading…
Reference in New Issue
Block a user