LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File kdm-themer-wallpaper-sizes.diff of Package kdebase4-workspace (Project openSUSE:11.4)

--- 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 );