diff options
Diffstat (limited to 'kcontrol/kfontinst/kfontinst/Fontmap.cpp')
-rw-r--r-- | kcontrol/kfontinst/kfontinst/Fontmap.cpp | 596 |
1 files changed, 0 insertions, 596 deletions
diff --git a/kcontrol/kfontinst/kfontinst/Fontmap.cpp b/kcontrol/kfontinst/kfontinst/Fontmap.cpp deleted file mode 100644 index 2c8b80201..000000000 --- a/kcontrol/kfontinst/kfontinst/Fontmap.cpp +++ /dev/null @@ -1,596 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Namespae : KFI::Fontmap -// Author : Craig Drummond -// Project : K Font Installer -// Creation Date : 06/06/2003 -// Version : $Revision$ $Date$ -// -//////////////////////////////////////////////////////////////////////////////// -// -// 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; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -//////////////////////////////////////////////////////////////////////////////// -// (C) Craig Drummond, 2003, 2004 -//////////////////////////////////////////////////////////////////////////////// - -#include "Fontmap.h" -#include "FontEngine.h" -#include "XConfig.h" -#include "FcEngine.h" -#include "KfiConstants.h" -#include <ksavefile.h> -#include <tqtextstream.h> -#include <tqdir.h> -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <tqregexp.h> -#include <fstream> -#include <unistd.h> - -using namespace std; - -static const char * findSpace(const char *str) -{ - while(str && *str!=' ' && *str!='\t') - str++; - - return str; -} - -static bool parseLine(const char *line, TQString &ps, TQString &fname, bool &isAlias) -{ - static const int constMaxLen = 127; - static const int constFileMaxLen = 1023; - - // - // Format: - // "/<psname> (<filename>) ; " - // "/<psname> /real ; " - - char a[constMaxLen+1], - b[constFileMaxLen+1]; - - char *slash1=const_cast<char*>(strchr(line, '/')), - *space1=slash1 ? (char*)findSpace(slash1) : NULL, //strchr(slash1, ' ') : NULL, - *ob=slash1 ? strchr(slash1, '(') : NULL, - *cb=ob ? strchr(ob, ')') : NULL, - *slash2=space1 && !ob && !cb ? strchr(space1, '/') : NULL, - *space2=slash2 ? (char*)findSpace(slash2) : NULL, // strchr(slash2, ' ') : NULL, - *semic=cb || space2 ? strchr(cb ? cb : space2, ';') : NULL; - - if(semic && space1-slash1<constMaxLen) - { - slash1++; - memcpy(a, slash1, space1-slash1); - a[space1-slash1]='\0'; - - if(cb && cb-ob<constFileMaxLen) // Then found a file entry... - { - ob++; - memcpy(b, ob, cb-ob); - b[cb-ob]='\0'; - ps=a; - fname=b; - isAlias=false; - return true; - } - else if(space2 && space2-slash2<constMaxLen) // Then found an alias... - { - slash2++; - memcpy(b, slash2, space2-slash2); - b[space2-slash2]='\0'; - ps=a; - fname=b; - isAlias=true; - return true; - } - } - - return false; -} - -// -// Returns a PS name from an X family name... -// e.g. "Times New Roman" -> "TimesNewRoman" -static TQString createX11PsName(const TQString &font) -{ - TQString newName(font); - unsigned int ch; - bool newWord=true; - - newName.replace(TQRegExp("\\-"), "_"); - - for(ch=0; ch<newName.length(); ++ch) - { - if(newName[ch].isSpace()) - newWord=true; - else - { - if(newName[ch]==newName[ch].upper()) - { - if(!newWord) - newName[ch]=newName[ch].lower(); - } - else - if(newName[ch]==newName[ch].lower()) - { - if(newWord) - newName[ch]=newName[ch].upper(); - } - newWord=false; - } - } - - newName.replace(" ", TQString()); - return newName; -} - -static const char * getItalicStr(KFI::CFontEngine::EItalic it) -{ - switch(it) - { - default: - case KFI::CFontEngine::ITALIC_NONE: - return NULL; - case KFI::CFontEngine::ITALIC_ITALIC: - return "Italic"; - case KFI::CFontEngine::ITALIC_OBLIQUE: - return "Oblique"; - } -} - -// -// Create a full Ps name -static TQString createName(const TQString &family, const TQString &weight, const char *italic) -{ - TQString name; - TQTextOStream str(&name); - - str << family; - if(!weight.isEmpty() || NULL!=italic) - { - str << '-'; - if(!weight.isEmpty()) - str << weight; - if(NULL!=italic) - str << italic; - } - - return name; -} - -static TQString getEntry(TQStringList &list, const TQString &name) -{ - TQStringList::Iterator it(list.begin()), - end(list.end()); - - for( ; it!=end; ++it) - if(0==(*it).find('/'+name+' ')) - return *it; - - return TQString::null; -} - -inline bool isAlias(const TQString &entry) -{ - return -1==entry.findRev(TQRegExp(")\\s*;\\s*$")); -} - -static void addEntry(TQStringList &list, const TQString &name, const TQString &file, const TQString &fmapDir) -{ - TQString existing(getEntry(list, name)); - bool insert=true; - - if(!existing.isEmpty()) - if(isAlias(existing)) - list.remove(existing); - else - insert=false; - - if(insert) - { - TQString entry; - TQTextOStream str(&entry); - - str << '/' << name << " ("; - - if(0==file.find(fmapDir)) - str << file.mid(fmapDir.length()); - else - str << file; - - str << ") ;"; - list.append(entry); - } -} - -static void addAliasEntry(TQStringList &list, const TQString &x11Name, const TQString &psName) -{ - if(x11Name!=psName) - { - TQString existing(getEntry(list, x11Name)); - - if(existing.isEmpty()) - { - TQString entry; - TQTextOStream str(&entry); - - str << '/' << x11Name << " /" << psName << " ;"; - list.append(entry); - } - } -} - -static TQString locateFile(const char *dir, const char *file, int level=0) -{ - if(level<5) - { - TQDir d(dir); - - if(d.isReadable()) - { - const TQFileInfoList *fList=d.entryInfoList(); - - if(fList) - { - TQFileInfoListIterator it(*fList); - TQFileInfo *fInfo; - TQString str; - - for(; NULL!=(fInfo=it.current()); ++it) - if("."!=fInfo->fileName() && ".."!=fInfo->fileName()) - if(fInfo->isDir()) - { - if(!(str=locateFile(TQFile::encodeName(fInfo->filePath()+"/"), file, level+1)).isEmpty()) - return str; - } - else - if(fInfo->fileName()==file) - return fInfo->filePath(); - } - } - } - - return TQString(); -} - -static TQString locateFile(const char *file, const char **dirs) -{ - int d; - TQString str; - - for(d=0; dirs[d]; ++d) - if(!(str=locateFile(dirs[d], file)).isEmpty()) - return str; - - return TQString::null; -} - -#define FONTMAP "Fontmap" - -namespace KFI -{ - -namespace Fontmap -{ - -bool create(const TQString &dir, CFontEngine &fe) -{ - bool root(Misc::root()), - added=false; - TQString fmapDir(Misc::dirSyntax(root ? KFI_ROOT_CFG_DIR : dir)); - CFile old(fmapDir); - TQStringList entries; - int i; - FcPattern *pat = FcPatternCreate(); - FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SCALABLE, (void*)0); - FcFontSet *fs = FcFontList(0, pat, os); - - FcPatternDestroy(pat); - FcObjectSetDestroy(os); - - for (i = 0; i<fs->nfont; i++) - { - TQString fName(Misc::fileSyntax(CFcEngine::getFcString(fs->fonts[i], FC_FILE))); - FcBool scalable=FcFalse; - - if(!fName.isEmpty() && (root || dir.isEmpty() || 0==fName.find(dir)) && - FcResultMatch==FcPatternGetBool(fs->fonts[i], FC_SCALABLE, 0, &scalable) && scalable) - { - const TQStringList *existing=old.getEntries(fName); - - if(existing && existing->count()) - entries+=(*existing); - else - { - int face=0, - numFaces=0; - - do - { - if(fe.openFont(fName, face)) - { - if(fe.hasPsInfo()) - { - if(0==numFaces) - numFaces=fe.getNumFaces(); // Only really for TTC files... - - // - // Add real - addEntry(entries, fe.getPsName(), fName, fmapDir); - added=true; - - // - // Add fake entries for X11 generated names - switch(fe.getWeight()) - { - case CFontEngine::WEIGHT_MEDIUM: - case CFontEngine::WEIGHT_REGULAR: - { - TQString x11Ps(createX11PsName(fe.getFamilyName())); - - if(CFontEngine::ITALIC_ITALIC!=fe.getItalic() && - CFontEngine::ITALIC_OBLIQUE!=fe.getItalic()) - addAliasEntry(entries, - createName(x11Ps, "Roman", - getItalicStr(fe.getItalic())), - fe.getPsName()); - addAliasEntry(entries, - createName(x11Ps, NULL, getItalicStr(fe.getItalic())), - fe.getPsName()); - break; - } - case CFontEngine::WEIGHT_UNKNOWN: - break; - default: - addAliasEntry(entries, - createName(createX11PsName(fe.getFamilyName()), - CFontEngine::weightStr(fe.getWeight()), - getItalicStr(fe.getItalic())), - fe.getPsName()); - } - } - fe.closeFont(); - } - } - while(++face<numFaces); - } - } - } - - bool status=true; - - if(added || entries.count()!=old.getLineCount()) - { - KSaveFile out(fmapDir+FONTMAP); - TQTextStream *stream=out.textStream(); - - if(stream) - { - TQStringList::Iterator it; - - for(it=entries.begin(); it!=entries.end(); ++it) - *stream << *it << endl; - } - else - status=false; - } - - // - // Ensure GS's main Fontmap references our file... - if(root && status) - { - static const char * constGhostscriptDirs[]= - { - "/usr/share/ghostscript/", - "/usr/local/share/ghostscript/", - "/usr/share/gs-esp/", - NULL - }; - - TQString gsFile=locateFile(FONTMAP, constGhostscriptDirs); - - if(!gsFile.isEmpty()) - { - const int constMaxLineLen=1024; - const char *constRLF=".runlibfile"; - - char line[constMaxLineLen]; - ifstream in(TQFile::encodeName(gsFile)); - - if(in) - { - TQCString fmap(TQFile::encodeName(fmapDir+FONTMAP)); - int lineNum=0, - kfiLine=-1, - gsLine=-1, - ncLine=-1; - - do - { - in.getline(line, constMaxLineLen); - - if(in.good()) - { - line[constMaxLineLen-1]='\0'; - - if(strstr(line, fmap.data())!=NULL && strstr(line, constRLF)!=NULL) - kfiLine=lineNum; - else if(strstr(line, FONTMAP".GS")!=NULL && strstr(line, constRLF)!=NULL) - gsLine=lineNum; - if(-1==ncLine && '%'!=line[0]) - ncLine=lineNum; - lineNum++; - } - } - while(!in.eof() && (-1==kfiLine || -1==gsLine)); - - // - // If the file doesn't already say to use our Fontmap file, then tell it to! - // Also, ensure ours is .runlibfile'd before the main GS one - else problems can occur - if(-1==kfiLine || kfiLine>gsLine) - { - in.clear(); - in.seekg(0, ios::end); - int size= (streamoff) in.tellg(); - in.seekg(0, ios::beg); - - char *buffer=new char[size+strlen(fmap)+strlen(constRLF)+5]; - - if(buffer) - { - bool added=false; - - buffer[0]='\0'; - lineNum=0; - - do - { - in.getline(line, constMaxLineLen); - - if(in.good()) - { - line[constMaxLineLen-1]='\0'; - - if(lineNum>=ncLine && !added) - { - strcat(buffer, "("); - strcat(buffer, fmap); - strcat(buffer, ") "); - strcat(buffer, constRLF); - strcat(buffer, "\n"); - added=true; - } - - if(lineNum!=kfiLine) - { - strcat(buffer, line); - strcat(buffer, "\n"); - } - lineNum++; - } - } - while(!in.eof()); - - in.close(); - - if(added) // Don't re-write GS's Fontmap unless we've actually added something... - { - KSaveFile out(gsFile); - TQTextStream *stream=out.textStream(); - - if(stream) - *stream << buffer; - } - delete [] buffer; - } - } - } - } - } - - return status; -} - -CFile::CFile(const TQString &dir) - : itsDir(dir), - itsLineCount(0) -{ - ifstream f(TQFile::encodeName(dir+FONTMAP)); - - itsEntries.setAutoDelete(true); - - if(f) - { - static const int constMaxLine=512; - - char line[constMaxLine+1]; - TEntry *current=NULL; - - while(!f.eof()) - { - f.getline(line, constMaxLine); - - if(!f.eof()) - { - TQString ps, - fname; - bool isAlias; - - if(parseLine(line, ps, fname, isAlias)) - { - itsLineCount++; - - TEntry *entry=getEntry(¤t, fname, isAlias); - - if(!isAlias && entry && entry->psName.isEmpty()) - entry->psName=ps; - - if(entry) - entry->entries.append(line); - } - } - } - f.close(); - } -} - -const TQStringList * CFile::getEntries(const TQString &fname) -{ - TEntry *entry=findEntry(0==fname.find(itsDir) ? fname.mid(itsDir.length()) : fname, false); - - return entry ? &entry->entries : NULL; -} - -CFile::TEntry * CFile::findEntry(const TQString &fname, bool isAlias) -{ - TEntry *entry=NULL; - - for(entry=itsEntries.first(); entry; entry=itsEntries.next()) - if(isAlias ? entry->psName==fname : entry->filename==fname) - break; - - return entry; -} - -CFile::TEntry * CFile::getEntry(TEntry **current, const TQString &fname, bool isAlias) -{ - // - // See if its the current one... - if(*current && (isAlias ? (*current)->psName==fname : (*current)->filename==fname)) - return *current; - - // - // See if its already known... - TEntry *entry=findEntry(fname, isAlias); - - // - // If not found, then create a new entry - if(!entry) - { - entry=new TEntry(fname); - itsEntries.append(entry); - } - - *current=entry; - return entry; -} - -} - -} |