mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 19:02:51 +00:00
194 lines
5.8 KiB
C++
194 lines
5.8 KiB
C++
/*
|
|
* 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/QDomDocument>
|
|
#include <QtXml/QDomElement>
|
|
#include <QtXml/QDomNode>
|
|
#include <QtXml/QDomText>
|
|
#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);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|