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

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
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
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