1
/****************************************************************************************
2
 * Copyright (c) 2007 Nikolaj Hald Nielsen <nhn@kde.org>                                *
3
 * Copyright (c) 2007 Mark Kretschmann <kretschmann@kde.org>                            *
4
 *                                                                                      *
5
 * This program is free software; you can redistribute it and/or modify it under        *
6
 * the terms of the GNU General Public License as published by the Free Software        *
7
 * Foundation; either version 2 of the License, or (at your option) any later           *
8
 * version.                                                                             *
9
 *                                                                                      *
10
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
11
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
12
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
13
 *                                                                                      *
14
 * You should have received a copy of the GNU General Public License along with         *
15
 * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
16
 ****************************************************************************************/
17
18
#include "SvgTinter.h"
19
20
#include "App.h"
21
#include "core/support/Debug.h"
22
23
#include <QBuffer>
24
#include <KFilterDev>
25
26
SvgTinter * SvgTinter::s_instance = 0;
27
28
SvgTinter::SvgTinter()
29
    : m_firstRun( true )
30
{
31
    init();
32
    m_firstRun = false;
33
}
34
35
36
SvgTinter::~SvgTinter()
37
{}
38
39
QString
40
SvgTinter::tint(QString filename)
41
{
42
    QFile file( filename );
43
    if ( !file.open( QIODevice::ReadOnly ) )
44
    {
45
        error() << "Unable to open file: " << filename;
46
        return QString();
47
    }
48
49
    QByteArray svg_source( file.readAll() );
50
51
    // Copied from KSvgrenderer.cpp as we don't load it directly.
52
    if (!svg_source.startsWith("<?xml"))
53
    {
54
        QBuffer buf( &svg_source );
55
        QIODevice *flt = KFilterDev::device( &buf, QString::fromLatin1("application/x-gzip"), false );
56
        if (!flt)
57
            return QString();
58
        if (!flt->open(QIODevice::ReadOnly))
59
        {
60
            delete flt;
61
            return QString();
62
        }
63
        svg_source = flt->readAll();
64
        delete flt;
65
    }
66
67
    QString svg_string( svg_source );
68
    const QStringList tintKeys = m_tintMap.keys();
69
    foreach ( const QString &colorName, tintKeys ) {
70
        //debug() << "replace " <<  colorName << " with " << m_tintMap.value( colorName );
71
        svg_string.replace( colorName, m_tintMap.value( colorName ) );
72
    }
73
74
    return svg_string;
75
}
76
77
void
78
SvgTinter::init()
79
{
80
    if ( m_lastPalette != App::instance()->palette() || m_firstRun ) {
81
        m_tintMap.insert( "#666765", App::instance()->palette().window().color().name() );
82
        //insert a color for bright ( highlight color )
83
        m_tintMap.insert( "#66ffff", App::instance()->palette().highlight().color().name() );
84
        //a slightly lighter than window color:
85
        m_tintMap.insert( "#e8e8e8", blendColors( App::instance()->palette().window().color(), "#ffffff", 90 ).name() );
86
        //a slightly darker than window color:
87
        m_tintMap.insert( "#565755", blendColors( App::instance()->palette().window().color(), "#000000", 90 ).name() );
88
89
        //list background:
90
    #ifdef Q_WS_MAC 
91
        m_tintMap.insert( "#f0f0f0", blendColors( App::instance()->palette().window().color(), "#000000", 90 ).name() );
92
        m_tintMap.insert( "#ffffff", blendColors( App::instance()->palette().window().color(), "#000000", 98 ).name() );
93
    #else
94
       m_tintMap.insert( "#f0f0f0", App::instance()->palette().base().color().name() );
95
    #endif
96
97
        //alternate list background:
98
        m_tintMap.insert( "#e0e0e0", App::instance()->palette().alternateBase().color().name() );
99
100
        //highlight/window mix:
101
        m_tintMap.insert( "#123456", blendColors( App::instance()->palette().window().color(), App::instance()->palette().highlight().color().name(), 80 ).name() );
102
103
        //text color, useful for adding contrast
104
        m_tintMap.insert( "#010101", App::instance()->palette().text().color().name() );
105
106
        m_lastPalette = App::instance()->palette();
107
    }
108
}
109
110
QColor
111
SvgTinter::blendColors( const QColor& color1, const QColor& color2, int percent )
112
{
113
    const float factor1 = ( float ) percent / 100;
114
    const float factor2 = ( 100 - ( float ) percent ) / 100;
115
116
    const int r = static_cast<int>( color1.red() * factor1 + color2.red() * factor2 );
117
    const int g = static_cast<int>( color1.green() * factor1 + color2.green() * factor2 );
118
    const int b = static_cast<int>( color1.blue() * factor1 + color2.blue() * factor2 );
119
120
    QColor result;
121
    result.setRgb( r, g, b );
122
123
    return result;
124
}
125
126
namespace The {
127
    SvgTinter*
128
    svgTinter()
129
    {
130
        if ( SvgTinter::s_instance == 0 )
131
            SvgTinter::s_instance = new SvgTinter();
132
133
        return SvgTinter::s_instance;
134
    }
135
}