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

Plasma

renderthread.cpp

Go to the documentation of this file.
00001 /*
00002   Copyright (c) 2007 Paolo Capriotti <p.capriotti@gmail.com>
00003 
00004   This program is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008 */
00009 
00010 #include "renderthread.h"
00011 
00012 #include <QPainter>
00013 #include <QFile>
00014 #include <KDebug>
00015 #include <KSvgRenderer>
00016 
00017 RenderThread::RenderThread(const QSize &size, float ratio)
00018 : m_current_token(-1)
00019 , m_size(size)
00020 , m_ratio(ratio)
00021 {
00022     m_abort = false;
00023     m_restart = false;
00024 }
00025 
00026 RenderThread::~RenderThread()
00027 {
00028     {
00029         // abort computation
00030         QMutexLocker lock(&m_mutex);
00031         m_abort = true;
00032         m_condition.wakeOne();
00033     }
00034     
00035     wait();
00036 }
00037 
00038 void RenderThread::setSize(const QSize& size)
00039 {
00040     QMutexLocker lock(&m_mutex);
00041     m_size = size;
00042 }
00043 
00044 int RenderThread::render(const QString &file,
00045                           const QColor &color,
00046                           Background::ResizeMethod method,
00047                           Qt::TransformationMode mode)
00048 {
00049     int token;
00050     {
00051         QMutexLocker lock(&m_mutex);
00052         m_file = file;
00053         m_color = color;
00054         m_method = method;
00055         m_mode = mode;
00056         m_restart = true;
00057         token = ++m_current_token;
00058     }
00059     
00060     if (!isRunning()) {
00061         start();
00062     }
00063     else {
00064         m_condition.wakeOne();
00065     }
00066     
00067     return token;
00068 }
00069 
00070 void RenderThread::run()
00071 {
00072     QString file;
00073     QColor color;
00074     QSize size;
00075     float ratio;
00076     Background::ResizeMethod method;
00077     Qt::TransformationMode mode;
00078     int token;
00079     
00080     forever {
00081         {
00082             QMutexLocker lock(&m_mutex);
00083             while (!m_restart && !m_abort) {
00084                 m_condition.wait(&m_mutex);
00085             }
00086             if (m_abort) {
00087                 return;
00088             }
00089             m_restart = false;
00090             
00091             // load all parameters in nonshared variables
00092             token = m_current_token;
00093             file = m_file;
00094             color = m_color;
00095             size = m_size;
00096             ratio = m_ratio;
00097             method = m_method;
00098             mode = m_mode;
00099         }
00100         
00101         QImage result(size, QImage::Format_ARGB32_Premultiplied);
00102         result.fill(color.rgba());
00103 
00104         if (file.isEmpty() || !QFile::exists(file)) {
00105             emit done(token, result);
00106             continue;
00107         }
00108         
00109         QPoint pos(0, 0);
00110         bool tiled = false;
00111         bool scalable = file.endsWith("svg") || file.endsWith("svgz");
00112         QSize scaledSize;
00113         QImage img;
00114         
00115         // load nonscalable image
00116         if (!scalable) {
00117             img = QImage(file);
00118         }
00119         
00120         // set image size
00121         QSize imgSize;
00122         if (scalable) {
00123             // scalable: image can be of any size
00124             imgSize = size; 
00125         }
00126         else {
00127             // otherwise, use the natural size of the loaded image
00128             imgSize = img.size();
00129         }
00130         imgSize *= ratio;
00131         
00132         // if any of them is zero we may run into a div-by-zero below.
00133         if (imgSize.width() == 0) {
00134             imgSize.setWidth(1);
00135         }
00136         if (imgSize.height() == 0) {
00137             imgSize.setHeight(1);
00138         }
00139 
00140         // set render parameters according to resize mode
00141         switch (method)
00142         {
00143         case Background::Scale:
00144             scaledSize = size;
00145             break;
00146         case Background::Center:
00147             scaledSize = imgSize;
00148             pos = QPoint((size.width() - scaledSize.width()) / 2,
00149                         (size.height() - scaledSize.height()) / 2);
00150             
00151         //If the picture is bigger than the screen, shrink it
00152             if( size.width() < imgSize.width() && imgSize.width() > imgSize.height() )
00153         {
00154                 int width = size.width();
00155                 int height = width * scaledSize.height() / imgSize.width();
00156                 scaledSize = QSize(width, height);
00157         pos = QPoint((size.width() - scaledSize.width()) / 2,
00158                 (size.height() - scaledSize.height()) / 2);
00159         } 
00160         else if( size.height() < imgSize.height() )
00161         {
00162                 int height = size.height();
00163                 int width = height * imgSize.width() / imgSize.height();
00164                 scaledSize = QSize(width, height);
00165         pos = QPoint((size.width() - scaledSize.width()) / 2,
00166                 (size.height() - scaledSize.height()) / 2);
00167         }
00168         
00169             break;
00170         case Background::ScaleCrop: {
00171             float xratio = (float) size.width() / imgSize.width();
00172             float yratio = (float) size.height() / imgSize.height();
00173             if (xratio > yratio) {
00174                 int width = size.width();
00175                 int height = width * imgSize.height() / imgSize.width();
00176                 scaledSize = QSize(width, height);
00177             }
00178             else {
00179                 int height = size.height();
00180                 int width = height * imgSize.width() / imgSize.height();
00181                 scaledSize = QSize(width, height);
00182             }
00183             pos = QPoint((size.width() - scaledSize.width()) / 2,
00184                         (size.height() - scaledSize.height()) / 2);
00185             break;
00186         }
00187         case Background::Tiled:
00188             scaledSize = imgSize;
00189             tiled = true;
00190             break;
00191         case Background::CenterTiled:
00192             scaledSize = imgSize;
00193             pos = QPoint(
00194                 -scaledSize.width() + 
00195                     ((size.width() - scaledSize.width()) / 2) % scaledSize.width(),
00196                 -scaledSize.height() + 
00197                     ((size.height() - scaledSize.height()) / 2) % scaledSize.height());
00198             tiled = true;
00199             break;
00200         }
00201         
00202         QPainter p(&result);
00203         if (scalable) {
00204             // tiling is ignored for scalable wallpapers
00205             KSvgRenderer svg(file);
00206             if (m_restart) {
00207                 continue;
00208             }
00209             svg.render(&p);
00210         }
00211         else {
00212             QImage scaled = img.scaled(scaledSize, Qt::IgnoreAspectRatio, mode);
00213             if (m_restart) {
00214                 continue;
00215             }
00216             if (tiled) {
00217                 for (int x = pos.x(); x < size.width(); x += scaledSize.width()) {
00218                     for (int y = pos.y(); y < size.height(); y += scaledSize.height()) {
00219                         p.drawImage(QPoint(x, y), scaled);
00220                         if (m_restart) {
00221                             goto endLoop;
00222                         }
00223                     }
00224                 }
00225             }
00226             else {
00227                 p.drawImage(pos, scaled);
00228             }
00229         }
00230 
00231         // signal we're done
00232         emit done(token, result);
00233         
00234         endLoop: continue;
00235     }
00236 }

Plasma

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

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
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