• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Plasma

wallpaperrenderthread.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
00003  *   Copyright (c) 2009 Aaron Seigo <aseigo@kde.org>
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU Library General Public License as
00007  *   published by the Free Software Foundation; either version 2, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details
00014  *
00015  *   You should have received a copy of the GNU Library General Public
00016  *   License along with this program; if not, write to the
00017  *   Free Software Foundation, Inc.,
00018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019  */
00020 
00021 #include "plasma/private/wallpaperrenderthread_p.h"
00022 
00023 #include <QPainter>
00024 #include <QFile>
00025 #include <QSvgRenderer>
00026 
00027 #include <kdebug.h>
00028 
00029 namespace Plasma
00030 {
00031 
00032 WallpaperRenderThread::WallpaperRenderThread(QObject *parent)
00033     : QThread(parent),
00034       m_lastToken(-1)
00035 {
00036     m_abort = false;
00037 }
00038 
00039 WallpaperRenderThread::~WallpaperRenderThread()
00040 {
00041     {
00042         // abort computation
00043         QMutexLocker lock(&m_mutex);
00044         m_abort = true;
00045     }
00046 
00047     wait();
00048 }
00049 
00050 int WallpaperRenderThread::render(const QString &file,
00051                                   const QSize &size,
00052                                   Wallpaper::ResizeMethod method,
00053                                   const QColor &color)
00054 {
00055     int token;
00056     RenderTask task;
00057     task.file = file;
00058     task.color = color;
00059     task.resizeMethod = method;
00060     task.size = size;
00061     {
00062         QMutexLocker lock(&m_mutex);
00063         task.token = ++m_lastToken;
00064         m_tasks.enqueue(task);
00065     }
00066 
00067     if (!isRunning()) {
00068         start();
00069     }
00070 
00071     return token;
00072 }
00073 
00074 void WallpaperRenderThread::run()
00075 {
00076     qreal ratio;
00077     RenderTask task;
00078 
00079     forever {
00080         {
00081             QMutexLocker lock(&m_mutex);
00082 
00083             if (m_tasks.isEmpty() || m_abort) {
00084                 return;
00085             }
00086 
00087             // load all parameters in nonshared variables
00088             task = m_tasks.dequeue();
00089             ratio = task.size.width() / qreal(task.size.height());
00090         }
00091 
00092         QImage result(task.size, QImage::Format_ARGB32_Premultiplied);
00093         result.fill(task.color.rgba());
00094 
00095         if (task.file.isEmpty() || !QFile::exists(task.file)) {
00096             emit done(task.token, result, task.file, task.size, task.resizeMethod, task.color);
00097             break;
00098         }
00099 
00100         QPoint pos(0, 0);
00101         bool tiled = false;
00102         bool scalable = task.file.endsWith("svg") || task.file.endsWith("svgz");
00103         QSize scaledSize;
00104         QImage img;
00105 
00106         // set image size
00107         QSize imgSize;
00108         if (scalable) {
00109             // scalable: image can be of any size
00110             imgSize = task.size;
00111         } else {
00112             // otherwise, use the natural size of the loaded image
00113             img = QImage(task.file);
00114             imgSize = img.size();
00115             //kDebug() << "loaded with" << imgSize << ratio;
00116         }
00117 
00118         // if any of them is zero we may run into a div-by-zero below.
00119         if (imgSize.width() < 1) {
00120             imgSize.setWidth(1);
00121         }
00122 
00123         if (imgSize.height() < 1) {
00124             imgSize.setHeight(1);
00125         }
00126 
00127         if (ratio < 1) {
00128             ratio = 1;
00129         }
00130 
00131         // set render parameters according to resize mode
00132         switch (task.resizeMethod)
00133         {
00134         case Wallpaper::ScaledResize:
00135             imgSize *= ratio;
00136             scaledSize = task.size;
00137             break;
00138         case Wallpaper::CenteredResize:
00139             scaledSize = imgSize;
00140             pos = QPoint((task.size.width() - scaledSize.width()) / 2,
00141                         (task.size.height() - scaledSize.height()) / 2);
00142 
00143             //If the picture is bigger than the screen, shrink it
00144             if (task.size.width() < imgSize.width() && imgSize.width() > imgSize.height()) {
00145                 int width = task.size.width();
00146                 int height = width * scaledSize.height() / imgSize.width();
00147                 scaledSize = QSize(width, height);
00148                 pos = QPoint((task.size.width() - scaledSize.width()) / 2,
00149                              (task.size.height() - scaledSize.height()) / 2);
00150             } else if (task.size.height() < imgSize.height()) {
00151                 int height = task.size.height();
00152                 int width = height * imgSize.width() / imgSize.height();
00153                 scaledSize = QSize(width, height);
00154                 pos = QPoint((task.size.width() - scaledSize.width()) / 2,
00155                              (task.size.height() - scaledSize.height()) / 2);
00156             }
00157 
00158             break;
00159         case Wallpaper::MaxpectResize: {
00160             imgSize *= ratio;
00161             float xratio = (float) task.size.width() / imgSize.width();
00162             float yratio = (float) task.size.height() / imgSize.height();
00163             if (xratio > yratio) {
00164                 int height = task.size.height();
00165                 int width = height * imgSize.width() / imgSize.height();
00166                 scaledSize = QSize(width, height);
00167             } else {
00168                 int width = task.size.width();
00169                 int height = width * imgSize.height() / imgSize.width();
00170                 scaledSize = QSize(width, height);
00171             }
00172             pos = QPoint((task.size.width() - scaledSize.width()) / 2,
00173                         (task.size.height() - scaledSize.height()) / 2);
00174             break;
00175         }
00176         case Wallpaper::ScaledAndCroppedResize: {
00177             imgSize *= ratio;
00178             float xratio = (float) task.size.width() / imgSize.width();
00179             float yratio = (float) task.size.height() / imgSize.height();
00180             if (xratio > yratio) {
00181                 int width = task.size.width();
00182                 int height = width * imgSize.height() / imgSize.width();
00183                 scaledSize = QSize(width, height);
00184             } else {
00185                 int height = task.size.height();
00186                 int width = height * imgSize.width() / imgSize.height();
00187                 scaledSize = QSize(width, height);
00188             }
00189             pos = QPoint((task.size.width() - scaledSize.width()) / 2,
00190                         (task.size.height() - scaledSize.height()) / 2);
00191             break;
00192         }
00193         case Wallpaper::TiledResize:
00194             scaledSize = imgSize;
00195             tiled = true;
00196             break;
00197         case Wallpaper::CenterTiledResize:
00198             scaledSize = imgSize;
00199             pos = QPoint(
00200                 -scaledSize.width() +
00201                     ((task.size.width() - scaledSize.width()) / 2) % scaledSize.width(),
00202                 -scaledSize.height() +
00203                     ((task.size.height() - scaledSize.height()) / 2) % scaledSize.height());
00204             tiled = true;
00205             break;
00206         }
00207 
00208         QPainter p(&result);
00209         //kDebug() << token << scalable << scaledSize << imgSize;
00210         if (scalable) {
00211             // tiling is ignored for scalable wallpapers
00212             QSvgRenderer svg(task.file);
00213             if (m_abort) {
00214                 return;
00215             }
00216             svg.render(&p);
00217         } else {
00218             if (scaledSize != imgSize) {
00219                 img = img.scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
00220             }
00221 
00222             if (m_abort) {
00223                 return;
00224             }
00225 
00226             if (tiled) {
00227                 for (int x = pos.x(); x < task.size.width(); x += scaledSize.width()) {
00228                     for (int y = pos.y(); y < task.size.height(); y += scaledSize.height()) {
00229                         p.drawImage(QPoint(x, y), img);
00230                         if (m_abort) {
00231                             return;
00232                         }
00233                     }
00234                 }
00235             } else {
00236                 p.drawImage(pos, img);
00237             }
00238         }
00239 
00240         // signal we're done
00241         emit done(task.token, result, task.file, task.size, task.resizeMethod, task.color);
00242     }
00243 }
00244 
00245 } // namespace Plasma
00246 
00247 #include "wallpaperrenderthread_p.moc"
00248 

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal