2
* KFontInst - KDE Font Installer
4
* Copyright 2003-2007 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.
24
#include "FontThroughAnalyzer.h"
26
#define STRIGI_IMPORT_API
27
#include <strigi/streamthroughanalyzer.h>
28
#include <strigi/analyzerplugin.h>
29
#include <strigi/fieldtypes.h>
30
#include <strigi/analysisresult.h>
32
#include "KfiConstants.h"
34
#include "FontEngine.h"
35
#include <QtCore/QByteArray>
36
#include <QtCore/QFile>
37
#include <KDE/KIO/NetAccess>
40
using namespace Strigi;
44
class FontThroughAnalyzerFactory : public StreamThroughAnalyzerFactory
46
friend class FontThroughAnalyzer;
50
const RegisteredField * constFamilyNameField;
51
const RegisteredField * constFoundryField;
52
const RegisteredField * constWeightField;
53
const RegisteredField * constWidthField;
54
const RegisteredField * constSpacingField;
55
const RegisteredField * constSlantField;
56
const RegisteredField * constVersionField;
58
const char * name() const
60
return "FontThroughAnalyzer";
63
StreamThroughAnalyzer * newInstance() const
65
return new FontThroughAnalyzer(this);
68
void registerFields(FieldRegister ®);
71
void FontThroughAnalyzerFactory::registerFields(FieldRegister ®)
73
constFamilyNameField=reg.registerField("font.family", FieldRegister::stringType, 1, 0);
74
constWeightField=reg.registerField("font.weight", FieldRegister::stringType, 1, 0);
75
constSlantField=reg.registerField("font.slant", FieldRegister::stringType, 1, 0);
76
constWidthField=reg.registerField("font.width", FieldRegister::stringType, 1, 0);
77
constSpacingField=reg.registerField("font.spacing", FieldRegister::stringType, 1, 0);
78
constFoundryField=reg.registerField("font.foundry", FieldRegister::stringType, 1, 0);
79
constVersionField=reg.registerField("content.version", FieldRegister::stringType, 1, 0);
82
class Factory : public AnalyzerFactoryFactory
86
list<StreamThroughAnalyzerFactory *> streamThroughAnalyzerFactories() const
88
list<StreamThroughAnalyzerFactory *> af;
90
af.push_back(new FontThroughAnalyzerFactory());
95
// macro that initializes the Factory when the plugin is loaded
96
STRIGI_ANALYZER_FACTORY(Factory)
98
static QString getFamily(const QString &font)
100
int commaPos=font.lastIndexOf(',');
101
return -1==commaPos ? font : font.left(commaPos);
104
static QString toMime(CFontEngine::EType type)
108
case CFontEngine::TYPE_OTF:
109
return "application/x-font-otf";
110
case CFontEngine::TYPE_TTF:
111
case CFontEngine::TYPE_TTC:
112
return "application/x-font-ttf";
113
case CFontEngine::TYPE_TYPE1:
114
return "application/x-font-type1";
115
case CFontEngine::TYPE_PCF:
116
return "application/x-font-pcf";
117
case CFontEngine::TYPE_BDF:
118
return "application/x-font-bdf";
119
case CFontEngine::TYPE_AFM:
120
return "application/x-font-afm";
128
FontThroughAnalyzer::FontThroughAnalyzer(const FontThroughAnalyzerFactory *f)
133
InputStream * FontThroughAnalyzer::connectInputStream(InputStream *in)
135
KUrl url(analysisResult->path().c_str());
136
bool fontsProt = KFI_KIO_FONTS_PROTOCOL == url.protocol(),
137
fileProt = "file" == url.protocol() || url.protocol().isEmpty();
142
// OK, it is a fonts:/ url - stat to get appropriate info
146
quint32 styleInfo=KFI_NO_STYLE_INFO;
147
KIO::UDSEntry udsEntry;
149
if(KIO::NetAccess::stat(url, udsEntry, NULL))
151
if(udsEntry.numberValue(KIO::UDSEntry::UDS_HIDDEN, 0))
153
path=udsEntry.stringValue(UDS_EXTRA_FILE_NAME);
154
face=udsEntry.numberValue(UDS_EXTRA_FILE_FACE, 0);
156
name=udsEntry.stringValue(KIO::UDSEntry::UDS_NAME);
157
styleInfo=udsEntry.numberValue(UDS_EXTRA_FC_STYLE);
158
mime=udsEntry.stringValue(KIO::UDSEntry::UDS_MIME_TYPE);
166
int weight, width, slant;
168
FC::decomposeStyleVal(styleInfo, weight, width, slant);
169
name=getFamily(name);
171
FcObjectSet *os = FcObjectSetBuild(FC_SPACING, FC_FOUNDRY, FC_FONTVERSION, (void *)0);
172
FcPattern *pat = FcPatternBuild(NULL,
173
FC_FAMILY, FcTypeString,
174
(const FcChar8 *)(name.toUtf8().data()),
175
FC_WEIGHT, FcTypeInteger, weight,
176
FC_SLANT, FcTypeInteger, slant,
177
#ifndef KFI_FC_NO_WIDTHS
178
FC_WIDTH, FcTypeInteger, width,
182
FcFontSet *set = FcFontList(0, pat, os);
184
FcPatternDestroy(pat);
185
FcObjectSetDestroy(os);
187
if(set && set->nfont)
191
QString foundry(FC::getFcString(set->fonts[0], FC_FOUNDRY, 0)),
194
FcPatternGetInteger(set->fonts[0], FC_SPACING, 0, &spacing);
195
FcPatternGetInteger(set->fonts[0], FC_FONTVERSION, 0, &version);
198
versionStr.setNum(CFontEngine::decodeFixed(version));
200
result(name, CFontEngine::fixFoundry(foundry),
201
KFI::FC::weightStr(weight, false), KFI::FC::widthStr(width, false),
202
KFI::FC::spacingStr(spacing), KFI::FC::slantStr(slant, false),
207
else // It is a disabled font, so read file...
212
if(fe.openFont(CFontEngine::TYPE_UNKNOWN, data,
213
QFile::encodeName(path).constData(), face) &&
214
!fe.getFamilyName().isEmpty())
215
result(fe.getFamilyName(), fe.getFoundry(),
216
KFI::FC::weightStr(fe.getWeight(), false),
217
KFI::FC::widthStr(fe.getWidth(), false),
218
KFI::FC::spacingStr(fe.getSpacing()),
219
KFI::FC::slantStr(fe.getItalic(), false), fe.getVersion(), mime);
223
if( in != 0 && fileProt)
225
CFontEngine::EType type(CFontEngine::getType(analysisResult->path().c_str(), in));
227
if(CFontEngine::TYPE_UNKNOWN!=type)
229
// For some reason, when called vie KFileMetaInfo in->size() is 0. So, set a maximum
230
// size that we want to read in...
231
static const int constMaxFileSize=30*1024*1024;
233
int size=in->size()>0 ? in->size() : constMaxFileSize;
235
int n=in->read(d, size, -1);
242
QByteArray data=QByteArray::fromRawData(d, n);
244
face=Misc::getIntQueryVal(url, KFI_KIO_FACE, 0);
246
if(fe.openFont(type, data, analysisResult->path().c_str(), face) &&
247
!fe.getFamilyName().isEmpty())
248
result(fe.getFamilyName(), fe.getFoundry(),
249
KFI::FC::weightStr(fe.getWeight(), false),
250
KFI::FC::widthStr(fe.getWidth(), false),
251
KFI::FC::spacingStr(fe.getSpacing()),
252
KFI::FC::slantStr(fe.getItalic(), false),
253
fe.getVersion(), toMime(type));
260
void FontThroughAnalyzer::result(const QString &family, const QString &foundry, const QString &weight,
261
const QString &width, const QString &spacing, const QString &slant,
262
const QString &version, const QString &mime)
264
analysisResult->addValue(factory->constFamilyNameField, (const char *)family.toUtf8());
265
analysisResult->addValue(factory->constWeightField, (const char *)weight.toUtf8());
266
analysisResult->addValue(factory->constSlantField, (const char *)slant.toUtf8());
267
analysisResult->addValue(factory->constWidthField, (const char *)width.toUtf8());
268
analysisResult->addValue(factory->constSpacingField, (const char *)spacing.toUtf8());
269
analysisResult->addValue(factory->constFoundryField, foundry.isEmpty()
270
? (const char *)i18n(KFI_UNKNOWN_FOUNDRY).toUtf8()
271
: (const char *)foundry.toUtf8());
272
if(!version.isEmpty())
273
analysisResult->addValue(factory->constVersionField, (const char *)version.toUtf8());
275
analysisResult->setMimeType((const char *)mime.toUtf8());