kde-workspace/kcontrol/kfontinst/dbus/FcConfig.cpp

195 lines
5.8 KiB
C++
Raw Normal View History

2014-11-13 19:30:51 +02:00
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2009 Craig Drummond <craig@kde.org>
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "FcConfig.h"
#include "Misc.h"
#include <QtCore/QRegExp>
#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtCore/QByteArray>
#include <QtXml/qdom.h>
#include <QtXml/qdom.h>
#include <QtXml/qdom.h>
#include <QtXml/qdom.h>
2014-11-13 19:30:51 +02:00
#include <KDebug>
#include <stdio.h>
#include <fontconfig/fontconfig.h>
#define KFI_DBUG kDebug() << time(0L)
namespace KFI
{
namespace FcConfig
{
inline QString xDirSyntax(const QString &d) { return Misc::fileSyntax(d); }
//
// Obtain location of config file to use.
//
// For system, prefer the following:
//
// <...>/config.d/00kde.conf = preferred method from FCConfig >= 2.3
// <...>/local.conf
//
// Non-system, prefer:
//
// $HOME/<...>/.fonts.conf
// $HOME/<...>/fonts.conf
//
QString getConfigFile(bool system)
{
#if (FC_VERSION>=20300)
static const char constKdeRootFcFile[] = "00kde.conf";
#endif
FcStrList *list=FcConfigGetConfigFiles(FcConfigGetCurrent());
QStringList files;
FcChar8 *file;
QString home(Misc::dirSyntax(QDir::homePath()));
while((file=FcStrListNext(list)))
{
QString f((const char *)file);
if(Misc::fExists(f))
{
// For nonsystem, only consider file within $HOME
if(system || 0==Misc::fileSyntax(f).indexOf(home))
files.append(f);
}
#if (FC_VERSION>=20300)
if(system && Misc::dExists(f) && (f.contains(QRegExp("/conf\\.d/?$")) ||
f.contains(QRegExp("/conf\\.d?$"))) )
return Misc::dirSyntax(f)+constKdeRootFcFile; // This ones good enough for me!
#endif
}
//
// Go through list of files, looking for the preferred one...
if(files.count())
{
QStringList::const_iterator it(files.begin()),
end(files.end());
for(; it!=end; ++it)
if(-1!=(*it).indexOf(QRegExp(system ? "/local\\.conf$" : "/\\.?fonts\\.conf$")))
return *it;
return files.front(); // Just return the 1st one...
}
else // Hmmm... no known files?
return system ? "/etc/fonts/local.conf" : Misc::fileSyntax(home+"/.fonts.conf");
}
void addDir(const QString &dir, bool system)
{
QDomDocument doc("fontconfig");
QString fileName=getConfigFile(system);
QFile f(fileName);
bool hasDir(false);
KFI_DBUG << "Using fontconfig file:" << fileName;
// Load existing file - and check to see whether it has the dir...
if(f.open(QIODevice::ReadOnly))
{
doc.clear();
if(doc.setContent(&f))
{
QDomNode n = doc.documentElement().firstChild();
while(!n.isNull() && !hasDir)
{
QDomElement e = n.toElement();
if(!e.isNull() && "dir"==e.tagName())
if(0==Misc::expandHome(Misc::dirSyntax(e.text())).indexOf(dir))
hasDir=true;
n=n.nextSibling();
}
}
f.close();
}
// Add dir, and save, if config does not already have this dir.
if(!hasDir)
{
if(doc.documentElement().isNull())
doc.appendChild(doc.createElement("fontconfig"));
QDomElement newNode = doc.createElement("dir");
QDomText text = doc.createTextNode(Misc::contractHome(xDirSyntax(dir)));
newNode.appendChild(text);
doc.documentElement().appendChild(newNode);
FcAtomic *atomic=FcAtomicCreate((const unsigned char *)(QFile::encodeName(fileName).data()));
if(atomic)
{
if(FcAtomicLock(atomic))
{
FILE *f=fopen((char *)FcAtomicNewFile(atomic), "w");
if(f)
{
//
// Check document syntax...
static const char qtXmlHeader[] = "<?xml version = '1.0'?>";
static const char xmlHeader[] = "<?xml version=\"1.0\"?>";
static const char qtDocTypeLine[] = "<!DOCTYPE fontconfig>";
static const char docTypeLine[] = "<!DOCTYPE fontconfig SYSTEM "
"\"fonts.dtd\">";
QString str(doc.toString());
int idx;
if(0!=str.indexOf("<?xml"))
str.insert(0, xmlHeader);
else if(0==str.indexOf(qtXmlHeader))
str.replace(0, strlen(qtXmlHeader), xmlHeader);
if(-1!=(idx=str.indexOf(qtDocTypeLine)))
str.replace(idx, strlen(qtDocTypeLine), docTypeLine);
//
// Write to file...
fputs(str.toUtf8(), f);
fclose(f);
if(!FcAtomicReplaceOrig(atomic))
FcAtomicDeleteNew(atomic);
}
FcAtomicUnlock(atomic);
}
FcAtomicDestroy(atomic);
}
}
}
}
}