~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kcontrol/kfontinst/dbus/FcConfig.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * KFontInst - KDE Font Installer
 
3
 *
 
4
 * Copyright 2003-2009 Craig Drummond <craig@kde.org>
 
5
 *
 
6
 * ----
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; see the file COPYING.  If not, write to
 
20
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
21
 * Boston, MA 02110-1301, USA.
 
22
 */
 
23
 
 
24
#include "FcConfig.h"
 
25
#include "Misc.h"
 
26
#include <QtCore/QRegExp>
 
27
#include <QtCore/QFile>
 
28
#include <QtCore/QDir>
 
29
#include <QtCore/QByteArray>
 
30
#include <QtXml/QDomDocument>
 
31
#include <QtXml/QDomElement>
 
32
#include <QtXml/QDomNode>
 
33
#include <QtXml/QDomText>
 
34
#include <KDebug>
 
35
#include <stdio.h>
 
36
#include <fontconfig/fontconfig.h>
 
37
 
 
38
#define KFI_DBUG kDebug() << time(0L)
 
39
 
 
40
namespace KFI
 
41
{
 
42
 
 
43
namespace FcConfig
 
44
{
 
45
 
 
46
inline QString xDirSyntax(const QString &d) { return Misc::fileSyntax(d); }
 
47
 
 
48
//
 
49
// Obtain location of config file to use.
 
50
//
 
51
// For system, prefer the following:
 
52
//
 
53
//     <...>/config.d/00kde.conf   = preferred method from FCConfig >= 2.3
 
54
//     <...>/local.conf
 
55
//
 
56
// Non-system, prefer:
 
57
//
 
58
//     $HOME/<...>/.fonts.conf
 
59
//     $HOME/<...>/fonts.conf
 
60
//
 
61
QString getConfigFile(bool system)
 
62
{
 
63
#if (FC_VERSION>=20300)
 
64
    static const char constKdeRootFcFile[] = "00kde.conf";
 
65
#endif
 
66
 
 
67
    FcStrList   *list=FcConfigGetConfigFiles(FcConfigGetCurrent());
 
68
    QStringList files;
 
69
    FcChar8     *file;
 
70
    QString     home(Misc::dirSyntax(QDir::homePath()));
 
71
 
 
72
    while((file=FcStrListNext(list)))
 
73
    {
 
74
        QString f((const char *)file);
 
75
 
 
76
        if(Misc::fExists(f))
 
77
        {
 
78
            // For nonsystem, only consider file within $HOME
 
79
            if(system || 0==Misc::fileSyntax(f).indexOf(home))
 
80
                files.append(f);
 
81
        }
 
82
#if (FC_VERSION>=20300)
 
83
        if(system && Misc::dExists(f) && (f.contains(QRegExp("/conf\\.d/?$")) ||
 
84
                                          f.contains(QRegExp("/conf\\.d?$"))) )
 
85
            return Misc::dirSyntax(f)+constKdeRootFcFile;   // This ones good enough for me!
 
86
#endif
 
87
    }
 
88
 
 
89
    //
 
90
    // Go through list of files, looking for the preferred one...
 
91
    if(files.count())
 
92
    {
 
93
        QStringList::const_iterator it(files.begin()),
 
94
                              end(files.end());
 
95
 
 
96
        for(; it!=end; ++it)
 
97
            if(-1!=(*it).indexOf(QRegExp(system ? "/local\\.conf$" : "/\\.?fonts\\.conf$")))
 
98
                return *it;
 
99
        return files.front();  // Just return the 1st one...
 
100
    }
 
101
    else // Hmmm... no known files?
 
102
        return system ? "/etc/fonts/local.conf" : Misc::fileSyntax(home+"/.fonts.conf");
 
103
}
 
104
 
 
105
void addDir(const QString &dir, bool system)
 
106
{
 
107
    QDomDocument doc("fontconfig");
 
108
    QString      fileName=getConfigFile(system);
 
109
    QFile        f(fileName);
 
110
    bool         hasDir(false);
 
111
 
 
112
    KFI_DBUG << "Using fontconfig file:" << fileName;
 
113
 
 
114
    // Load existing file - and check to see whether it has the dir...
 
115
    if(f.open(QIODevice::ReadOnly))
 
116
    {
 
117
        doc.clear();
 
118
 
 
119
        if(doc.setContent(&f))
 
120
        {
 
121
            QDomNode n = doc.documentElement().firstChild();
 
122
 
 
123
            while(!n.isNull() && !hasDir)
 
124
            {
 
125
                QDomElement e = n.toElement();
 
126
 
 
127
                if(!e.isNull() && "dir"==e.tagName())
 
128
                    if(0==Misc::expandHome(Misc::dirSyntax(e.text())).indexOf(dir))
 
129
                        hasDir=true;
 
130
                n=n.nextSibling();
 
131
            }
 
132
        }
 
133
        f.close();
 
134
    }
 
135
 
 
136
    // Add dir, and save, if config does not already have this dir.
 
137
    if(!hasDir)
 
138
    {
 
139
        if(doc.documentElement().isNull())
 
140
            doc.appendChild(doc.createElement("fontconfig"));
 
141
 
 
142
        QDomElement newNode = doc.createElement("dir");
 
143
        QDomText    text    = doc.createTextNode(Misc::contractHome(xDirSyntax(dir)));
 
144
 
 
145
        newNode.appendChild(text);
 
146
        doc.documentElement().appendChild(newNode);
 
147
 
 
148
        FcAtomic *atomic=FcAtomicCreate((const unsigned char *)(QFile::encodeName(fileName).data()));
 
149
 
 
150
        if(atomic)
 
151
        {
 
152
            if(FcAtomicLock(atomic))
 
153
            {
 
154
                FILE *f=fopen((char *)FcAtomicNewFile(atomic), "w");
 
155
 
 
156
                if(f)
 
157
                {
 
158
                    //
 
159
                    // Check document syntax...
 
160
                    static const char qtXmlHeader[]   = "<?xml version = '1.0'?>";
 
161
                    static const char xmlHeader[]     = "<?xml version=\"1.0\"?>";
 
162
                    static const char qtDocTypeLine[] = "<!DOCTYPE fontconfig>";
 
163
                    static const char docTypeLine[]   = "<!DOCTYPE fontconfig SYSTEM "
 
164
                                                        "\"fonts.dtd\">";
 
165
 
 
166
                    QString str(doc.toString());
 
167
                    int     idx;
 
168
 
 
169
                    if(0!=str.indexOf("<?xml"))
 
170
                        str.insert(0, xmlHeader);
 
171
                    else if(0==str.indexOf(qtXmlHeader))
 
172
                        str.replace(0, strlen(qtXmlHeader), xmlHeader);
 
173
 
 
174
                    if(-1!=(idx=str.indexOf(qtDocTypeLine)))
 
175
                        str.replace(idx, strlen(qtDocTypeLine), docTypeLine);
 
176
 
 
177
                    //
 
178
                    // Write to file...
 
179
                    fputs(str.toUtf8(), f);
 
180
                    fclose(f);
 
181
 
 
182
                    if(!FcAtomicReplaceOrig(atomic))
 
183
                        FcAtomicDeleteNew(atomic);
 
184
                }
 
185
                FcAtomicUnlock(atomic);
 
186
            }
 
187
            FcAtomicDestroy(atomic);
 
188
        }
 
189
    }
 
190
}
 
191
 
 
192
}
 
193
 
 
194
}