File indexing completed on 2024-04-28 17:04:38

0001 /*****************************************************************************
0002  *   Copyright 2007 - 2010 Craig Drummond <craig.p.drummond@gmail.com>       *
0003  *   Copyright 2013 - 2015 Yichao Yu <yyc1992@gmail.com>                     *
0004  *                                                                           *
0005  *   This program is free software; you can redistribute it and/or modify    *
0006  *   it under the terms of the GNU Lesser General Public License as          *
0007  *   published by the Free Software Foundation; either version 2.1 of the    *
0008  *   License, or (at your option) version 3, or any later version accepted   *
0009  *   by the membership of KDE e.V. (or its successor approved by the         *
0010  *   membership of KDE e.V.), which shall act as a proxy defined in          *
0011  *   Section 6 of version 3 of the license.                                  *
0012  *                                                                           *
0013  *   This program is distributed in the hope that it will be useful,         *
0014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
0015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       *
0016  *   Lesser General Public License for more details.                         *
0017  *                                                                           *
0018  *   You should have received a copy of the GNU Lesser General Public        *
0019  *   License along with this library. If not,                                *
0020  *   see <http://www.gnu.org/licenses/>.                                     *
0021  *****************************************************************************/
0022 
0023 #ifndef __QTCURVESHADOWCACHE_H__
0024 #define __QTCURVESHADOWCACHE_H__
0025 
0026 //////////////////////////////////////////////////////////////////////////////
0027 // Taken from: oxygenshadowcache.h
0028 // handles caching of TileSet objects to draw shadows
0029 // -------------------
0030 //
0031 // Copyright (c) 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0032 //
0033 // Permission is hereby granted, free of charge, to any person obtaining a copy
0034 // of this software and associated documentation files (the "Software"), to
0035 // deal in the Software without restriction, including without limitation the
0036 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
0037 // sell copies of the Software, and to permit persons to whom the Software is
0038 // furnished to do so, subject to the following conditions:
0039 //
0040 // The above copyright notice and this permission notice shall be included in
0041 // all copies or substantial portions of the Software.
0042 //
0043 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0044 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0045 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0046 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0047 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0048 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0049 // IN THE SOFTWARE.
0050 //////////////////////////////////////////////////////////////////////////////
0051 
0052 //#define NEW_SHADOWS
0053 
0054 #include "qtcurveshadowconfiguration.h"
0055 #include "tileset.h"
0056 
0057 #include <qtcurve-utils/number.h>
0058 
0059 #include <QCache>
0060 #include <QRadialGradient>
0061 
0062 #include <cmath>
0063 
0064 class QtCurveHelper;
0065 
0066 namespace QtCurve {
0067 namespace KWin {
0068 
0069 class QtCurveClient;
0070 
0071 class QtCurveShadowCache {
0072 public:
0073     QtCurveShadowCache();
0074 
0075     const QColor&
0076     color(bool active)
0077     {
0078         return (active ? m_activeShadowConfig.color() :
0079                 m_inactiveShadowConfig.color());
0080     }
0081 
0082     void
0083     invalidateCaches()
0084     {
0085         m_shadowCache.clear();
0086     }
0087 
0088     //! returns true if provided shadow configuration changes with respect to
0089     //  stored
0090     /*!
0091      * use ShadowConfig::colorRole() to decide whether it should be stored
0092      * as active or inactive
0093      */
0094     bool shadowConfigChanged(const ShadowConfig &other) const;
0095 
0096     //! set shadowConfiguration
0097     /*!
0098      * use ShadowConfig::colorRole() to decide whether it should be stored
0099      * as active or inactive
0100      */
0101     void setShadowConfig(const ShadowConfig &other);
0102 
0103     //! shadow size
0104     qreal
0105     shadowSize() const
0106     {
0107         qreal size(qMax(m_activeShadowConfig.shadowSize(),
0108                         m_inactiveShadowConfig.shadowSize()));
0109 
0110         // even if shadows are disabled, you need a minimum size to allow
0111         // corner rendering
0112         return qMax(size, 5.0);
0113     }
0114 
0115     TileSet *tileSet(const QtCurveClient *client, bool roundAllCorners);
0116 
0117     //! Key class to be used into QCache
0118     /*! class is entirely inline for optimization */
0119     class Key {
0120     public:
0121         explicit Key() : active(false), isShade(false) {}
0122         Key(const QtCurveClient *client);
0123         Key(int hash) : active((hash >> 1) & 1), isShade(hash & 1) {}
0124 
0125         int hash() const
0126         {
0127             return (active << 1) | isShade;
0128         }
0129 
0130         const bool active;
0131         const bool isShade;
0132     };
0133 
0134     class Parabolic {
0135     public:
0136         //! constructor
0137         Parabolic(qreal amplitude, qreal width)
0138             : m_amplitude(amplitude), m_width(width) {}
0139         //! value
0140         qreal
0141         operator() (qreal x) const
0142         {
0143             return qMax(0.0, m_amplitude * (1.0 - qtcSquare(x / m_width)));
0144         }
0145     private:
0146         const qreal m_amplitude;
0147         const qreal m_width;
0148     };
0149 
0150     class Gaussian {
0151     public:
0152         Gaussian(qreal amplitude, qreal width)
0153             : m_amplitude(amplitude), m_width(width) {}
0154         //! value
0155         qreal
0156         operator() (qreal x) const
0157         {
0158             return qMax(0.0, m_amplitude *
0159                         (std::exp(-qtcSquare(x / m_width) - 0.05)));
0160         }
0161     private:
0162         const qreal m_amplitude;
0163         const qreal m_width;
0164     };
0165 
0166     //! complex pixmap (when needed)
0167     QPixmap shadowPixmap(const QtCurveClient *client, bool active,
0168                          bool roundAllCorners) const;
0169 
0170     //! simple pixmap
0171     QPixmap simpleShadowPixmap(const QColor &color, bool active,
0172                                bool roundAllCorners) const;
0173 
0174     void reset() { m_shadowCache.clear(); }
0175 
0176 private:
0177     //! draw gradient into rect
0178     /*! a separate method is used in order to properly account for corners */
0179     void renderGradient(QPainter &p, const QRectF &rect,
0180                         const QRadialGradient &rg, bool hasBorder) const;
0181 
0182     typedef QCache<int, TileSet> TileSetCache;
0183 
0184     ShadowConfig m_activeShadowConfig;
0185     ShadowConfig m_inactiveShadowConfig;
0186     TileSetCache m_shadowCache;
0187 };
0188 
0189 }
0190 }
0191 
0192 #endif