File kdm-themer-wallpaper-sizes.diff of Package kdebase4-workspace
--- kdm/kfrontend/themer/kdmpixmap.cpp.sav 2009-08-20 04:42:33.000000000 +0200
+++ kdm/kfrontend/themer/kdmpixmap.cpp 2010-06-21 17:10:42.077788814 +0200
@@ -24,9 +24,12 @@
#include <ksvgrenderer.h>
+#include <QDir>
#include <QPainter>
#include <QSignalMapper>
+#include <math.h>
+
KdmPixmap::KdmPixmap( QObject *parent, const QDomNode &node )
: KdmItem( parent, node )
, qsm( 0 )
@@ -91,11 +94,7 @@ KdmPixmap::loadPixmap( PixmapStruct::Pix
if (pClass.fullpath.isEmpty())
return false;
if (area.isValid()) {
- int dot = pClass.fullpath.lastIndexOf( '.' );
- if (pClass.image.load( pClass.fullpath.left( dot )
- .append( QString( "-%1x%2" )
- .arg( area.width() ).arg( area.height() ) )
- .append( pClass.fullpath.mid( dot ) ) ))
+ if (loadSizedPixmap( pClass, area ))
goto gotit;
}
if (!pClass.image.load( pClass.fullpath )) {
@@ -110,6 +109,60 @@ KdmPixmap::loadPixmap( PixmapStruct::Pix
return true;
}
+bool KdmPixmap::loadSizedPixmap( PixmapStruct::PixmapClass &pClass, QRect area )
+{
+ int dot = pClass.fullpath.lastIndexOf('.');
+ int slash = pClass.fullpath.lastIndexOf('/');
+ QString name = pClass.fullpath.mid(slash + 1, dot < 0 || slash < 0 ? -1 : dot - slash - 1);
+ QString ext = pClass.fullpath.mid(dot);
+ QString directory = pClass.fullpath.left(slash + 1);
+ QStringList images = QDir(directory).entryList(QStringList() << (name + "-*x*" + ext));
+ // choose the nearest resolution
+ float best = 10E30;
+ QString bestImage;
+ QRegExp sizeRegexp(QRegExp::escape(name) + "-([0-9]+)x([0-9]+)" + QRegExp::escape(ext));
+ foreach (const QString &entry, images) {
+ if ( !sizeRegexp.exactMatch(entry))
+ continue;
+ QSize candidate(sizeRegexp.cap(1).toInt(), sizeRegexp.cap(2).toInt());
+ if (candidate == QSize()) {
+ continue;
+ }
+ double dist = distance(candidate, area.size(), pClass);
+ //kDebug() << "candidate" << candidate << "distance" << dist;
+ if (bestImage.isEmpty() || dist < best) {
+ bestImage = entry;
+ best = dist;
+ //kDebug() << "best" << bestImage;
+ if (dist == 0) {
+ break;
+ }
+ }
+ }
+ if (bestImage.isEmpty())
+ return false;
+ return pClass.image.load(directory + bestImage);
+}
+
+float KdmPixmap::distance(const QSize& size, const QSize& desired, PixmapStruct::PixmapClass &pClass) const
+{
+ // compute difference of areas
+ float delta = size.width() * size.height() -
+ desired.width() * desired.height();
+ // scale down to about 1.0
+ delta /= ((desired.width() * desired.height())+(size.width() * size.height()))/2;
+
+ // Consider first the difference in aspect ratio,
+ // then in areas. Prefer scaling down.
+ float deltaRatio = 1.0;
+ if (size.height() > 0 && desired.height() > 0) {
+ deltaRatio = float(size.width()) / float(size.height()) -
+ float(desired.width()) / float(desired.height());
+ }
+ return fabs(deltaRatio) * 3.0 + (delta >= 0.0 ? delta : -delta + 5.0);
+}
+
+
bool
KdmPixmap::loadSvg( PixmapStruct::PixmapClass &pClass )
{
--- kdm/kfrontend/themer/kdmpixmap.h.sav 2009-08-20 04:42:33.000000000 +0200
+++ kdm/kfrontend/themer/kdmpixmap.h 2010-06-21 17:07:10.843787410 +0200
@@ -76,6 +76,8 @@ private:
// Method to load the image given by the theme
void definePixmap( const QDomElement &el, PixmapStruct::PixmapClass &pc );
bool loadPixmap( PixmapStruct::PixmapClass &pc );
+ bool loadSizedPixmap( PixmapStruct::PixmapClass &pClass, QRect area );
+ float distance(const QSize& size, const QSize& desired, PixmapStruct::PixmapClass &pClass) const;
bool loadSvg( PixmapStruct::PixmapClass &pc );
bool calcTargetArea( PixmapStruct::PixmapClass &pClass, const QSize &sh );
void applyTint( PixmapStruct::PixmapClass &pClass, QImage &img );