• 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_currentToken(-1)
00035 {
00036     m_abort = false;
00037     m_restart = false;
00038 }
00039 
00040 WallpaperRenderThread::~WallpaperRenderThread()
00041 {
00042     {
00043         // abort computation
00044         QMutexLocker lock(&m_mutex);
00045         m_abort = true;
00046         m_condition.wakeOne();
00047     }
00048 
00049     wait();
00050 }
00051 
00052 void WallpaperRenderThread::setSize(const QSize& size)
00053 {
00054     QMutexLocker lock(&m_mutex);
00055     m_size = size;
00056 }
00057 
00058 int WallpaperRenderThread::render(const QString &file,
00059                                   const QSize &size,
00060                                   Wallpaper::ResizeMethod method,
00061                                   const QColor &color)
00062 {
00063     int token;
00064     {
00065         QMutexLocker lock(&m_mutex);
00066         m_file = file;
00067         m_color = color;
00068         m_method = method;
00069         m_size = size;
00070         m_restart = true;
00071         token = ++m_currentToken;
00072     }
00073 
00074     if (!isRunning()) {
00075         start();
00076     } else {
00077         m_condition.wakeOne();
00078     }
00079 
00080     return token;
00081 }
00082 
00083 void WallpaperRenderThread::run()
00084 {
00085     QString file;
00086     QColor color;
00087     QSize size;
00088     qreal ratio;
00089     Wallpaper::ResizeMethod method;
00090     int token;
00091 
00092     forever {
00093         {
00094             QMutexLocker lock(&m_mutex);
00095 
00096             while (!m_restart && !m_abort) {
00097                 m_condition.wait(&m_mutex);
00098             }
00099 
00100             if (m_abort) {
00101                 return;
00102             }
00103 
00104             m_restart = false;
00105 
00106             // load all parameters in nonshared variables
00107             token = m_currentToken;
00108             file = m_file;
00109             color = m_color;
00110             size = m_size;
00111             ratio = m_size.width() / qreal(m_size.height());
00112             method = m_method;
00113         }
00114 
00115         QImage result(size, QImage::Format_ARGB32_Premultiplied);
00116         result.fill(color.rgba());
00117 
00118         if (file.isEmpty() || !QFile::exists(file)) {
00119             emit done(token, result, file, size, method, color);
00120             break;
00121         }
00122 
00123         QPoint pos(0, 0);
00124         bool tiled = false;
00125         bool scalable = file.endsWith("svg") || file.endsWith("svgz");
00126         QSize scaledSize;
00127         QImage img;
00128 
00129         // set image size
00130         QSize imgSize;
00131         if (scalable) {
00132             // scalable: image can be of any size
00133             imgSize = size;
00134         } else {
00135             // otherwise, use the natural size of the loaded image
00136             img = QImage(file);
00137             imgSize = img.size();
00138             //kDebug() << "loaded with" << imgSize << ratio;
00139         }
00140 
00141         // if any of them is zero we may run into a div-by-zero below.
00142         if (imgSize.width() < 1) {
00143             imgSize.setWidth(1);
00144         }
00145 
00146         if (imgSize.height() < 1) {
00147             imgSize.setHeight(1);
00148         }
00149 
00150         if (ratio < 1) {
00151             ratio = 1;
00152         }
00153 
00154         // set render parameters according to resize mode
00155         switch (method)
00156         {
00157         case Wallpaper::ScaledResize:
00158             imgSize *= ratio;
00159             scaledSize = size;
00160             break;
00161         case Wallpaper::CenteredResize:
00162             scaledSize = imgSize;
00163             pos = QPoint((size.width() - scaledSize.width()) / 2,
00164                         (size.height() - scaledSize.height()) / 2);
00165 
00166             //If the picture is bigger than the screen, shrink it
00167             if (size.width() < imgSize.width() && imgSize.width() > imgSize.height()) {
00168                 int width = size.width();
00169                 int height = width * scaledSize.height() / imgSize.width();
00170                 scaledSize = QSize(width, height);
00171                 pos = QPoint((size.width() - scaledSize.width()) / 2,
00172                              (size.height() - scaledSize.height()) / 2);
00173             } else if (size.height() < imgSize.height()) {
00174                 int height = size.height();
00175                 int width = height * imgSize.width() / imgSize.height();
00176                 scaledSize = QSize(width, height);
00177                 pos = QPoint((size.width() - scaledSize.width()) / 2,
00178                              (size.height() - scaledSize.height()) / 2);
00179             }
00180 
00181             break;
00182         case Wallpaper::MaxpectResize: {
00183             imgSize *= ratio;
00184             float xratio = (float) size.width() / imgSize.width();
00185             float yratio = (float) size.height() / imgSize.height();
00186             if (xratio > yratio) {
00187                 int height = size.height();
00188                 int width = height * imgSize.width() / imgSize.height();
00189                 scaledSize = QSize(width, height);
00190             } else {
00191                 int width = size.width();
00192                 int height = width * imgSize.height() / imgSize.width();
00193                 scaledSize = QSize(width, height);
00194             }
00195             pos = QPoint((size.width() - scaledSize.width()) / 2,
00196                         (size.height() - scaledSize.height()) / 2);
00197             break;
00198         }
00199         case Wallpaper::ScaledAndCroppedResize: {
00200             imgSize *= ratio;
00201             float xratio = (float) size.width() / imgSize.width();
00202             float yratio = (float) size.height() / imgSize.height();
00203             if (xratio > yratio) {
00204                 int width = size.width();
00205                 int height = width * imgSize.height() / imgSize.width();
00206                 scaledSize = QSize(width, height);
00207             } else {
00208                 int height = size.height();
00209                 int width = height * imgSize.width() / imgSize.height();
00210                 scaledSize = QSize(width, height);
00211             }
00212             pos = QPoint((size.width() - scaledSize.width()) / 2,
00213                         (size.height() - scaledSize.height()) / 2);
00214             break;
00215         }
00216         case Wallpaper::TiledResize:
00217             scaledSize = imgSize;
00218             tiled = true;
00219             break;
00220         case Wallpaper::CenterTiledResize:
00221             scaledSize = imgSize;
00222             pos = QPoint(
00223                 -scaledSize.width() +
00224                     ((size.width() - scaledSize.width()) / 2) % scaledSize.width(),
00225                 -scaledSize.height() +
00226                     ((size.height() - scaledSize.height()) / 2) % scaledSize.height());
00227             tiled = true;
00228             break;
00229         }
00230 
00231         QPainter p(&result);
00232         //kDebug() << token << scalable << scaledSize << imgSize;
00233         if (scalable) {
00234             // tiling is ignored for scalable wallpapers
00235             QSvgRenderer svg(file);
00236             if (m_restart) {
00237                 continue;
00238             }
00239             svg.render(&p);
00240         } else {
00241             if (scaledSize != imgSize) {
00242                 img = img.scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
00243             }
00244 
00245             if (m_restart) {
00246                 continue;
00247             }
00248 
00249             if (tiled) {
00250                 for (int x = pos.x(); x < size.width(); x += scaledSize.width()) {
00251                     for (int y = pos.y(); y < size.height(); y += scaledSize.height()) {
00252                         p.drawImage(QPoint(x, y), img);
00253                         if (m_restart) {
00254                             continue;
00255                         }
00256                     }
00257                 }
00258             } else {
00259                 p.drawImage(pos, img);
00260             }
00261         }
00262 
00263         // signal we're done
00264         emit done(token, result, file, size, method, color);
00265         break;
00266     }
00267 }
00268 
00269 } // namespace Plasma
00270 
00271 #include "wallpaperrenderthread_p.moc"
00272 

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