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