2
* KFontInst - KDE Font Installer
4
* Copyright 2003-2009 Craig Drummond <craig@kde.org>
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.
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.
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.
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>
36
#include <fontconfig/fontconfig.h>
38
#define KFI_DBUG kDebug() << time(0L)
46
inline QString xDirSyntax(const QString &d) { return Misc::fileSyntax(d); }
49
// Obtain location of config file to use.
51
// For system, prefer the following:
53
// <...>/config.d/00kde.conf = preferred method from FCConfig >= 2.3
56
// Non-system, prefer:
58
// $HOME/<...>/.fonts.conf
59
// $HOME/<...>/fonts.conf
61
QString getConfigFile(bool system)
63
#if (FC_VERSION>=20300)
64
static const char constKdeRootFcFile[] = "00kde.conf";
67
FcStrList *list=FcConfigGetConfigFiles(FcConfigGetCurrent());
70
QString home(Misc::dirSyntax(QDir::homePath()));
72
while((file=FcStrListNext(list)))
74
QString f((const char *)file);
78
// For nonsystem, only consider file within $HOME
79
if(system || 0==Misc::fileSyntax(f).indexOf(home))
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!
90
// Go through list of files, looking for the preferred one...
93
QStringList::const_iterator it(files.begin()),
97
if(-1!=(*it).indexOf(QRegExp(system ? "/local\\.conf$" : "/\\.?fonts\\.conf$")))
99
return files.front(); // Just return the 1st one...
101
else // Hmmm... no known files?
102
return system ? "/etc/fonts/local.conf" : Misc::fileSyntax(home+"/.fonts.conf");
105
void addDir(const QString &dir, bool system)
107
QDomDocument doc("fontconfig");
108
QString fileName=getConfigFile(system);
112
KFI_DBUG << "Using fontconfig file:" << fileName;
114
// Load existing file - and check to see whether it has the dir...
115
if(f.open(QIODevice::ReadOnly))
119
if(doc.setContent(&f))
121
QDomNode n = doc.documentElement().firstChild();
123
while(!n.isNull() && !hasDir)
125
QDomElement e = n.toElement();
127
if(!e.isNull() && "dir"==e.tagName())
128
if(0==Misc::expandHome(Misc::dirSyntax(e.text())).indexOf(dir))
136
// Add dir, and save, if config does not already have this dir.
139
if(doc.documentElement().isNull())
140
doc.appendChild(doc.createElement("fontconfig"));
142
QDomElement newNode = doc.createElement("dir");
143
QDomText text = doc.createTextNode(Misc::contractHome(xDirSyntax(dir)));
145
newNode.appendChild(text);
146
doc.documentElement().appendChild(newNode);
148
FcAtomic *atomic=FcAtomicCreate((const unsigned char *)(QFile::encodeName(fileName).data()));
152
if(FcAtomicLock(atomic))
154
FILE *f=fopen((char *)FcAtomicNewFile(atomic), "w");
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 "
166
QString str(doc.toString());
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);
174
if(-1!=(idx=str.indexOf(qtDocTypeLine)))
175
str.replace(idx, strlen(qtDocTypeLine), docTypeLine);
179
fputs(str.toUtf8(), f);
182
if(!FcAtomicReplaceOrig(atomic))
183
FcAtomicDeleteNew(atomic);
185
FcAtomicUnlock(atomic);
187
FcAtomicDestroy(atomic);