summaryrefslogtreecommitdiffstats
path: root/kcontrol/kfontinst/kfile-plugin/KFileFont.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kcontrol/kfontinst/kfile-plugin/KFileFont.cpp')
-rw-r--r--kcontrol/kfontinst/kfile-plugin/KFileFont.cpp422
1 files changed, 422 insertions, 0 deletions
diff --git a/kcontrol/kfontinst/kfile-plugin/KFileFont.cpp b/kcontrol/kfontinst/kfile-plugin/KFileFont.cpp
new file mode 100644
index 000000000..31fbaa83e
--- /dev/null
+++ b/kcontrol/kfontinst/kfile-plugin/KFileFont.cpp
@@ -0,0 +1,422 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Class Name : KFI::KFileFont
+// Author : Craig Drummond
+// Project : K Font Installer
+// Creation Date : 20/03/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 "KFileFont.h"
+#include "KfiConstants.h"
+#include <qfile.h>
+#include <qtextstream.h>
+#include <kgenericfactory.h>
+#include <kio/netaccess.h>
+
+static void addEntry(int face, QString &existing, const QString &add)
+{
+ if(face>0)
+ existing.append(", ");
+ existing.append(add);
+}
+
+static int strToWeight(const QString &str)
+{
+ if(NULL==str)
+ return FC_WEIGHT_MEDIUM;
+ else if(str.contains("Bold", false))
+ return FC_WEIGHT_BOLD;
+ else if(str.contains("Heavy", false))
+ return FC_WEIGHT_HEAVY;
+ else if(str.contains("Black", false))
+ return FC_WEIGHT_BLACK;
+ else if(str.contains("ExtraBold", false))
+ return FC_WEIGHT_EXTRABOLD;
+ else if(str.contains("UltraBold", false))
+ return FC_WEIGHT_ULTRABOLD;
+ else if(str.contains("ExtraLight", false))
+ return FC_WEIGHT_EXTRALIGHT;
+ else if(str.contains("UltraLight", false))
+ return FC_WEIGHT_ULTRALIGHT;
+ else if(str.contains("Light", false))
+ return FC_WEIGHT_LIGHT;
+ else if(str.contains("Medium", false) || str.contains("Normal", false) || str.contains("Roman", false))
+ return FC_WEIGHT_MEDIUM;
+ else if(str.contains("Regular", false))
+ return FC_WEIGHT_REGULAR;
+ else if(str.contains("SemiBold", false))
+ return FC_WEIGHT_SEMIBOLD;
+ else if(str.contains("DemiBold", false))
+ return FC_WEIGHT_DEMIBOLD;
+ else if(str.contains("Thin", false))
+ return FC_WEIGHT_THIN;
+ else if(str.contains("Book", false))
+ return FC_WEIGHT_NORMAL;
+ else if(str.contains("Demi", false))
+ return FC_WEIGHT_NORMAL;
+ else
+ return FC_WEIGHT_MEDIUM;
+}
+
+#ifndef KFI_FC_NO_WIDTHS
+static int strToWidth(const QString &str)
+{
+ if(str.isEmpty())
+ return FC_WIDTH_NORMAL;
+ else if(str.contains("UltraCondensed", false))
+ return FC_WIDTH_ULTRACONDENSED;
+ else if(str.contains("ExtraCondensed", false))
+ return FC_WIDTH_EXTRACONDENSED;
+ else if(str.contains("SemiCondensed", false))
+ return FC_WIDTH_SEMICONDENSED;
+ else if(str.contains("Condensed", false))
+ return FC_WIDTH_CONDENSED;
+ else if(str.contains("SemiExpanded", false))
+ return FC_WIDTH_SEMIEXPANDED;
+ else if(str.contains("UltraExpanded", false))
+ return FC_WIDTH_ULTRAEXPANDED;
+ else if(str.contains("ExtraExpanded", false))
+ return FC_WIDTH_EXTRAEXPANDED;
+ else if(str.contains("Expanded", false))
+ return FC_WIDTH_EXPANDED;
+ else
+ return FC_WIDTH_NORMAL;
+}
+#endif
+
+struct FoundryMap
+{
+ const char *noticeStr,
+ *foundry;
+ unsigned short len;
+};
+
+static const FoundryMap map[]= // These are (mainly) taken from type1inst
+{
+ { "Bigelow", "B&H", 3},
+ { "Adobe", "Adobe", 5},
+ { "Bitstream", "Bitstream", 9},
+ { "Monotype", "Monotype", 8},
+ { "Linotype", "Linotype", 8},
+ { "LINOTYPE-HELL", "Linotype", 0},
+ { "IBM", "IBM", 3},
+ { "URW", "URW", 3},
+ { "International Typeface Corporation", "ITC", 3},
+ { "Tiro Typeworks", "Tiro", 4},
+ { "XFree86", "XFree86", 7},
+ { "Microsoft", "Microsoft", 9},
+ { "Omega", "Omega", 5},
+ { "Font21", "Hwan", 4},
+ { "HanYang System", "Hanyang", 7},
+ { "Richard Mitchell", "Mitchell", 8},
+ { "Doug Miles", "Miles", 5},
+ { "Hank Gillette", "Gillette", 8},
+ { "Three Islands Press", "3ip", 3},
+ { "MacroMind", "Macromind", 9},
+ { "MWSoft", "MWSoft", 6},
+ { "Digiteyes Multimedia", "DigitEyes", 9},
+ { "ZSoft", "ZSoft", 5},
+ { "Title Wave", "Titlewave", 9},
+ { "Southern Software", "Southern", 8},
+ { "Reasonable Solutions", "Reasonable", 10},
+ { "David Rakowski", "Rakowski", 8},
+ { "D. Rakowski", "Rakowski", 0},
+ { "S. G. Moye", "Moye", 4},
+ { "S.G. Moye", "Moye", 0},
+ { "Andrew s. Meit", "Meit", 4},
+ { "A.S.Meit", "Meit", 0},
+ { "Hershey", "Hershey", 7},
+ { "FontBank", "FontBank", 8},
+ { "A. Carr", "Carr", 4},
+ { "Brendel Informatik", "Brendel", 7},
+ { "Jonathan Brecher", "Brecher", 7},
+ { "SoftMaker", "Softmaker", 9},
+ { "LETRASET", "Letraset", 8},
+ { "Corel Corp", "Corel", 5},
+ { "PUBLISHERS PARADISE", "Paradise", 8},
+ { "Publishers Paradise", "Paradise", 0},
+ { "Allied Corporation", "Allied", 6},
+ { NULL, NULL, 0}
+};
+
+static const char * getFoundry(const char *notice)
+{
+ const FoundryMap *entry;
+
+ if(notice)
+ for(entry=map; NULL!=entry->foundry; entry++)
+ if(NULL!=strstr(notice, entry->noticeStr))
+ return entry->foundry;
+
+ return NULL;
+}
+
+static bool readAfm(const QString &file, QString &full, QString &family, QString &foundry, QString &weight,
+#ifndef KFI_FC_NO_WIDTHS
+ QString &width,
+#endif
+ QString &spacing, QString &slant)
+{
+ QFile f(file);
+ bool foundName=false,
+ foundFamily=false;
+ int intSpacing=FC_PROPORTIONAL,
+#ifndef KFI_FC_NO_WIDTHS
+ intWidth=FC_WIDTH_NORMAL,
+#endif
+ intWeight=FC_WEIGHT_NORMAL,
+ intSlant=FC_SLANT_ROMAN,
+ intItalic=FC_SLANT_ROMAN;
+
+ if(f.open(IO_ReadOnly))
+ {
+ QTextStream stream(&f);
+ QString line;
+ bool inMetrics=false;
+
+ while(!stream.atEnd())
+ {
+ line=stream.readLine();
+ line=line.simplifyWhiteSpace();
+
+ if(inMetrics)
+ {
+ if(0==line.find("FullName "))
+ {
+ full=line.mid(9);
+#ifndef KFI_FC_NO_WIDTHS
+ intWidth=strToWidth(full);
+#endif
+ foundName=true;
+ }
+ else if(0==line.find("FamilyName "))
+ {
+ family=line.mid(11);
+ foundFamily=true;
+ }
+ else if(0==line.find("Weight "))
+ intWeight=strToWeight(line.mid(7));
+ else if(0==line.find("ItalicAngle "))
+ intSlant=0.0f==line.mid(12).toFloat() ? FC_SLANT_ROMAN : FC_SLANT_ITALIC;
+ else if(0==line.find("IsFixedPitch "))
+ intSpacing=0==line.mid(13).find("false", 0, false) ? FC_PROPORTIONAL : FC_MONO;
+ else if(0==line.find("Notice "))
+ foundry=getFoundry(line.mid(7).latin1());
+ else if(0==line.find("StartCharMetrics"))
+ break;
+ }
+ else
+ if(0==line.find("StartFontMetrics"))
+ inMetrics=true;
+ };
+ f.close();
+
+ if(!foundFamily && foundName)
+ {
+ family=full;
+ foundFamily=true;
+ }
+
+ if(foundName && FC_SLANT_ITALIC==intItalic && (-1!=full.find("Oblique") || -1!=full.find("Slanted")))
+ intItalic=FC_SLANT_OBLIQUE;
+ }
+
+ if(foundName && foundFamily)
+ {
+ weight=KFI::CFcEngine::weightStr(intWeight, false);
+#ifndef KFI_FC_NO_WIDTHS
+ width=KFI::CFcEngine::widthStr(intWidth, false);
+#endif
+ slant=KFI::CFcEngine::slantStr(intSlant, false);
+ spacing=KFI::CFcEngine::spacingStr(intSpacing);
+
+ if(foundry.isEmpty())
+ foundry=i18n(KFI_UNKNOWN_FOUNDRY);
+
+ return true;
+ }
+
+ return false;
+}
+
+typedef KGenericFactory<KFI::KFileFontPlugin> KFileFontPluginFactory;
+K_EXPORT_COMPONENT_FACTORY(kfile_font, KFileFontPluginFactory("kfontinst"))
+
+namespace KFI
+{
+
+KFileFontPlugin::KFileFontPlugin(QObject *parent, const char *name, const QStringList& args)
+ : KFilePlugin(parent, name, args)
+{
+ KGlobal::locale()->insertCatalogue(KFI_CATALOGUE);
+
+ addMimeType("application/x-font-ttf"),
+ addMimeType("application/x-font-type1");
+ //addMimeType("application/x-font-speedo");
+ addMimeType("application/x-font-bdf");
+ addMimeType("application/x-font-pcf");
+ //addMimeType("application/x-font-snf");
+ addMimeType("application/x-font-otf");
+ addMimeType("application/x-font-ttc");
+ addMimeType("application/x-afm");
+}
+
+void KFileFontPlugin::addMimeType(const char *mime)
+{
+ KFileMimeTypeInfo *info=addMimeTypeInfo(mime);
+ KFileMimeTypeInfo::GroupInfo *group=addGroupInfo(info, "General", i18n("General"));
+
+ addItemInfo(group, "Full", i18n("Full Name"), QVariant::String);
+ addItemInfo(group, "Family", i18n("Family"), QVariant::String);
+ addItemInfo(group, "Foundry", i18n("Foundry"), QVariant::String);
+ addItemInfo(group, "Weight", i18n("Weight"), QVariant::String);
+#ifndef KFI_FC_NO_WIDTHS
+ addItemInfo(group, "Width", i18n("Width"), QVariant::String);
+#endif
+ addItemInfo(group, "Spacing", i18n("Spacing"), QVariant::String);
+ addItemInfo(group, "Slant", i18n("Slant"), QVariant::String);
+}
+
+bool KFileFontPlugin::readInfo(KFileMetaInfo& info, uint what)
+{
+ QString full,
+ lastFull,
+ family,
+ foundry,
+ weight,
+#ifndef KFI_FC_NO_WIDTHS
+ width,
+#endif
+ spacing,
+ slant,
+ fullAll,
+ familyAll,
+ foundryAll,
+ weightAll,
+#ifndef KFI_FC_NO_WIDTHS
+ widthAll,
+#endif
+ spacingAll,
+ slantAll;
+ KURL url(info.url());
+ QString fName;
+ bool fontsProt = KFI_KIO_FONTS_PROTOCOL == url.protocol(),
+ fileProt = "file" == url.protocol(),
+ downloaded = false,
+ status = false;
+
+ what=0;
+
+ if(!fontsProt && !fileProt && KIO::NetAccess::download(url, fName, NULL))
+ {
+ downloaded=true;
+ url=KURL(fName);
+ }
+
+ if(downloaded || fontsProt || fileProt)
+ {
+ if("application/x-afm"==info.mimeType()) // Then fontconfig can't give us the data :-(
+ status=readAfm(url.path(), fullAll, familyAll, foundryAll, weightAll,
+#ifndef KFI_FC_NO_WIDTHS
+ widthAll,
+#endif
+ spacingAll, slantAll);
+ else
+ for(int face=0; face<10; ++face) // How to get num faces from fontconfig? don't know - so just try 1st 10...
+ {
+ if(itsEngine.getInfo(url, face, full, family, foundry, weight,
+#ifndef KFI_FC_NO_WIDTHS
+ width,
+#endif
+ spacing, slant) &&
+ !full.isEmpty() && full!=lastFull)
+ {
+ addEntry(face, fullAll, full);
+ lastFull=full;
+
+ if(KFileMetaInfo::Fastest!=what)
+ {
+ addEntry(face, familyAll, family);
+ if(0==face)
+ {
+ foundryAll=foundry;
+
+ if(foundryAll.isEmpty())
+ foundryAll=i18n(KFI_UNKNOWN_FOUNDRY);
+ else
+ {
+ // Try to make sure foundry is capitalised, and looks the same as that of
+ // any AFM.
+ foundryAll[0]=foundryAll[0].upper();
+
+ const FoundryMap *entry;
+
+ for(entry=map; NULL!=entry->foundry; entry++)
+ if(foundryAll.length()==entry->len && foundryAll.contains(entry->foundry, false))
+ {
+ foundryAll=entry->foundry;
+ break;
+ }
+ }
+ }
+ addEntry(face, weightAll, weight);
+#ifndef KFI_FC_NO_WIDTHS
+ addEntry(face, widthAll, width);
+#endif
+ addEntry(face, spacingAll, spacing);
+ addEntry(face, slantAll, slant);
+ }
+ status=true;
+ }
+ else
+ break;
+ }
+
+ if(status)
+ {
+ KFileMetaInfoGroup group;
+
+ group=appendGroup(info, "General");
+ appendItem(group, "Full", fullAll);
+
+ if(KFileMetaInfo::Fastest!=what)
+ {
+ appendItem(group, "Family", familyAll);
+ appendItem(group, "Foundry", foundryAll);
+ appendItem(group, "Weight", weightAll);
+#ifndef KFI_FC_NO_WIDTHS
+ appendItem(group, "Width", widthAll);
+#endif
+ appendItem(group, "Spacing", spacingAll);
+ appendItem(group, "Slant", slantAll);
+ }
+ }
+
+ if(downloaded)
+ KIO::NetAccess::removeTempFile(fName);
+ }
+
+ return status;
+}
+
+}