Subversion Repositories Scribus

Rev

Rev 3830 | Rev 4026 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 paul 1
/*
2
        Scribus font handling code - copyright (C) 2001 by
3
        Alastair M. Robinson
4
 
220 Franz 5
        Based on code by Christian Tpp and Franz Schmid.
3 paul 6
 
7
        Contributed to the Scribus project under the terms of
8
        the GNU General Public License version 2, or any later
9
        version, at your discretion.
10
*/
11
 
1669 craig 12
#include <qglobal.h>
3 paul 13
#include <qapplication.h>
14
#include <qfile.h>
15
#include <qfileinfo.h>
16
#include <qstrlist.h>
17
#include <qstring.h>
18
#include <qtextstream.h>
19
#include <qfont.h>
20
#include <qdict.h>
21
#include <qmap.h>
68 Franz 22
#include <qdir.h>
1669 craig 23
#include <qregexp.h>
24
 
3 paul 25
#include <cstdlib>
26
#include "scfonts.h"
27
#include "scfonts_ttf.h"
2529 craig 28
#include "scfontmetrics.h"
494 fschmid 29
 
2856 cbradney 30
#include "prefsmanager.h"
2510 craig 31
#include "prefsfile.h"
32
#include "prefscontext.h"
33
#include "prefstable.h"
3566 fschmid 34
#include "scribus.h"
2529 craig 35
#ifdef Q_WS_X11
36
#include <X11/X.h>
37
#include <X11/Xlib.h>
38
#endif
39
 
494 fschmid 40
#ifdef HAVE_FONTCONFIG
41
#include <fontconfig/fontconfig.h>
42
#endif
43
 
3794 cbradney 44
#include "scpaths.h"
2534 craig 45
#include "util.h"
46
 
2295 cbradney 47
#include FT_INTERNAL_STREAM_H
48
#include FT_TRUETYPE_TAGS_H
49
#include FT_TRUETYPE_TABLES_H
50
 
3559 fschmid 51
Foi::Foi(QString fam, QString sty, QString alt, QString psname, QString path, int face, bool embedps)
3 paul 52
{
68 Franz 53
        isOTF = false;
54
        Subset = false;
2295 cbradney 55
        typeCode = Foi::UNKNOWN_TYPE;
56
        formatCode = Foi::UNKNOWN_FORMAT;
3559 fschmid 57
        SCName = alt;
58
        Family = fam;
59
        Effect = sty;
60
        cached_RealName = psname;
61
        fontFile = path;
62
        faceIndex_ = face;
63
        EmbedPS = embedps;
64
        Alternative = "";
3 paul 65
}
66
 
3544 avox 67
 
68
FT_Face * ftFace() {
69
        // dummy for now
70
        return NULL;
71
}
72
 
3 paul 73
QString Foi::RealName()
74
{
3559 fschmid 75
        return cached_RealName;
3 paul 76
}
77
 
78
bool Foi::EmbedFont(QString &str)
79
{
80
        str+="Base";
2295 cbradney 81
        return(false);
3 paul 82
}
83
 
84
bool Foi::ReadMetrics()
85
{
86
        HasMetrics=false;
87
        for(int i=0;i<256;++i)
88
                CharWidth[i]=0;
89
        return(false);
90
}
91
 
92
bool Foi::GlNames(QMap<uint, QString> *GList)
93
{
2295 cbradney 94
        return GlyNames(this, GList);
3 paul 95
}
2295 cbradney 96
 
97
void Foi::RawData(QByteArray & bb)
98
{
99
        FT_Library library;
100
        FT_Face    face;
101
        bool       error;
102
 
103
        error = FT_Init_FreeType( &library );
104
        if (error)
3240 fschmid 105
                sDebug(QObject::tr("Freetype2 library not available"));
2295 cbradney 106
        else
3544 avox 107
                error = FT_New_Face( library, fontFile, faceIndex_, &face );
2295 cbradney 108
        if (error)
3544 avox 109
                sDebug(QObject::tr("Font %1 is broken, no embedding").arg(fontFile));
2295 cbradney 110
        else
111
        {
112
                FT_Stream fts = face->stream;
113
                bb.resize(fts->size);
114
                error = FT_Stream_Seek(fts, 0L);
115
                if (!error)
116
                        error = FT_Stream_Read(fts, reinterpret_cast<FT_Byte *>(bb.data()), fts->size);
117
                if (error)
118
                {
3544 avox 119
                        sDebug(QObject::tr("Font %1 is broken (read stream), no embedding").arg(fontFile));
2295 cbradney 120
                        bb.resize(0);
121
                }
122
                /*
123
                if (showFontInformation)
124
                {
3544 avox 125
                        QFile f(fontFile);
126
                        qDebug(QObject::tr("RawData for Font %1(%2): size=%3 filesize=%4").arg(fontFile).arg(faceIndex_).arg(bb.size()).arg(f.size()));
2295 cbradney 127
                }
128
                */
129
        }
130
        FT_Done_Face(face);
131
        FT_Done_FreeType(library);
132
}
133
 
134
 
68 Franz 135
/*
136
void Foi::FontBez()
137
{
138
        FT_Face face;
139
        FT_Library library;
140
        QString ts;
141
        QPixmap pm(200, 100);
142
        bool error;
143
        int  pen_x;
144
        int YPos = qApp->font().pointSize();
145
        uint n;
146
        error = FT_Init_FreeType( &library );
3544 avox 147
        error = FT_New_Face( library, fontFile, 0, &face );
68 Franz 148
        ts = QString(face->family_name) + " " + QString(face->style_name);
149
        pm.fill();
150
        pen_x = 0;
151
        for (n = 0; n < ts.length(); n++)
152
                {
153
                uint dv = ts[n].unicode();
154
                error = FT_Set_Char_Size(       face, 0, qApp->font().pointSize()*64, 72, 72 );
155
                FT_Load_Char(face, dv, FT_LOAD_RENDER | FT_LOAD_NO_BITMAP | FT_LOAD_MONOCHROME);
156
                QByteArray bd(face->glyph->bitmap.rows * face->glyph->bitmap.pitch);
157
                uint yy = 0;
158
                uint adv;
159
                if ((face->glyph->bitmap.width % 8) == 0)
160
                        adv = face->glyph->bitmap.width / 8;
161
                else
162
                        adv = face->glyph->bitmap.width / 8 + 1;
163
                for (int y = 0; y < face->glyph->bitmap.rows; ++y)
164
                        {
165
                        memcpy(bd.data()+yy, face->glyph->bitmap.buffer+(y * face->glyph->bitmap.pitch), adv);
166
                        yy += adv;
167
                        }
168
                QBitmap bb(face->glyph->bitmap.width, face->glyph->bitmap.rows, (uchar*)bd.data(), false);
169
                QPixmap pixm(face->glyph->bitmap.width, face->glyph->bitmap.rows);
170
                if (!pixm.isNull())
171
                        {
172
                        pixm.fill(Qt::black);
173
                        pixm.setMask(bb);
174
                        QPainter p;
175
                        p.begin(&pm);
176
                        p.drawPixmap(pen_x+face->glyph->bitmap_left, YPos-face->glyph->bitmap_top, pixm);
177
                        p.end();
178
                        }
179
                pen_x += face->glyph->advance.x >> 6;
180
                }
181
        int high = qApp->fontMetrics().height();
182
        QPixmap pm2(pen_x, high);
183
        bitBlt(&pm2, 0, 0, &pm, 0, 0, pen_x, high);
184
        Appearance = pm2;
185
        FT_Done_FreeType( library );
186
        return;
187
}    */
3 paul 188
 
189
/*
190
        Class Foi_postscript
3142 cbradney 191
        Subclass of Foi, for PostScript fonts that could possibly have a .afm file
3 paul 192
        associated with them for metrics information.
193
*/
194
 
195
class Foi_postscript : public Foi
196
{
197
        public:
3544 avox 198
                Foi_postscript(QString fam, QString sty, QString alt, QString psname, QString path, int face, bool embedps) :
199
                Foi(fam,sty,alt,psname,path,face,embedps), metricsread(false)
3 paul 200
                {
201
                        HasMetrics=false;
202
                        HasKern = false;
203
                        Ascent = "0";
204
                        CapHeight = "0";
205
                        Descender = "0";
206
                        ItalicAngle = "0";
207
                        StdVW = "1";
208
                        FontBBox = "0 0 0 0";
209
                        IsFixedPitch = false;
2295 cbradney 210
                        typeCode = TYPE1;
3 paul 211
                        HasMetrics=true;
212
                }
213
 
214
                virtual QString RealName()
215
                {
3544 avox 216
                        return(Foi::RealName());
3 paul 217
                }
218
 
219
                virtual bool ReadMetrics()  // routine by Franz Schmid - modified by Alastair M. Robinson
220
                {
221
                        if(metricsread)
222
                                return(HasMetrics);
223
                        CharWidth.clear();
68 Franz 224
                        GlyphArray.clear();
84 Franz 225
                        QString tmp, tmp2, tmp3, tmp4;
80 Franz 226
                        double x, y;
68 Franz 227
                        FPointArray outlines;
228
                        struct GlyphR GRec;
3 paul 229
                        bool                    error;
230
                        FT_Library library;
231
                        FT_ULong  charcode;
232
                        FT_UInt   gindex;
233
                        FT_Face   face;
220 Franz 234
                        isStroked = false;
3 paul 235
                        error = FT_Init_FreeType( &library );
236
                        if (error)
391 Franz 237
                        {
3 paul 238
                                UseFont = false;
3500 avox 239
                                sDebug(QObject::tr("Font %1 is broken (FreeType2), discarding it").arg(fontPath()));
3 paul 240
                                return false;
391 Franz 241
                        }
3544 avox 242
                        error = FT_New_Face( library, fontFilePath(), faceIndex(), &face );
3 paul 243
                        if (error)
391 Franz 244
                        {
3 paul 245
                                UseFont = false;
3500 avox 246
                                sDebug(QObject::tr("Font %1 is broken (no Face), discarding it").arg(fontPath()));
2295 cbradney 247
                                FT_Done_FreeType( library );
3 paul 248
                                return false;
391 Franz 249
                        }
80 Franz 250
                        uniEM = static_cast<double>(face->units_per_EM);
3500 avox 251
                        QString afnm = fontFilePath().left(fontFilePath().length()-3);
3 paul 252
                        QFile afm(afnm+"afm");
253
                        if(!(afm.exists()))
391 Franz 254
                        {
3 paul 255
                                afm.setName(afnm+"Afm");
256
                                if(!(afm.exists()))
257
                                        afm.setName(afnm+"AFM");
391 Franz 258
                        }
3 paul 259
                        if (afm.exists())
260
                                error = FT_Attach_File(face, afm.name());
261
                        HasKern = FT_HAS_KERNING(face);
262
                        Ascent = tmp.setNum(face->ascender);
263
                        Descender = tmp.setNum(face->descender);
68 Franz 264
                        numDescender = face->descender / uniEM;
265
                        numAscent = face->ascender / uniEM;
266
                        underline_pos = face->underline_position / uniEM;
267
                        strikeout_pos = numAscent / 3;
268
                        strokeWidth = face->underline_thickness / uniEM;
3 paul 269
                        CapHeight = Ascent;
270
                        ItalicAngle = "0";
271
                        StdVW = "1";
84 Franz 272
                        FontBBox = tmp.setNum(face->bbox.xMin)+" "+tmp2.setNum(face->bbox.yMin)+" "+tmp3.setNum(face->bbox.xMax)+" "+tmp4.setNum(face->bbox.yMax);
3 paul 273
                        IsFixedPitch = face->face_flags & 4;
896 fschmid 274
                        setBestEncoding(face);
3 paul 275
                        gindex = 0;
276
                        charcode = FT_Get_First_Char( face, &gindex );
2295 cbradney 277
                        int goodGlyph = 0;
278
                        int invalidGlyph = 0;
3 paul 279
                        while ( gindex != 0 )
391 Franz 280
                        {
220 Franz 281
                                error = FT_Load_Glyph( face, gindex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP );
282
                                if (error)
391 Franz 283
                                {
2295 cbradney 284
                                        ++invalidGlyph;
3500 avox 285
                                        sDebug(QObject::tr("Font %1 has broken glyph %2 (charcode %3)").arg(fontPath()).arg(gindex).arg(charcode));
2394 cbradney 286
                                        charcode = FT_Get_Next_Char( face, charcode, &gindex );
287
                                        continue;
391 Franz 288
                                }
2295 cbradney 289
                                ++goodGlyph;
220 Franz 290
                                double ww = face->glyph->metrics.horiAdvance / uniEM;
291
                                if (face->glyph->format == FT_GLYPH_FORMAT_PLOTTER)
292
                                        isStroked = true;
293
                                error = false;
294
                                outlines = traceChar(face, charcode, 10, &x, &y, &error);
295
                                if (!error)
391 Franz 296
                                {
220 Franz 297
                                        CharWidth.insert(charcode, ww);
298
                                        GRec.Outlines = outlines.copy();
299
                                        GRec.x = x;
300
                                        GRec.y = y;
301
                                        GlyphArray.insert(charcode, GRec);
391 Franz 302
                                }
3 paul 303
                                charcode = FT_Get_Next_Char( face, charcode, &gindex );
391 Franz 304
                        }
2295 cbradney 305
                        FT_Done_Face( face );
3 paul 306
                        FT_Done_FreeType( library );
2394 cbradney 307
                        if (invalidGlyph > 0) {
308
                                UseFont = false;
3500 avox 309
                                sDebug(QObject::tr("Font %1 is broken and will be discarded").arg(fontPath()));
3240 fschmid 310
                        }
220 Franz 311
                        HasMetrics=UseFont;
312
                        metricsread=UseFont;
3 paul 313
                        return(HasMetrics);
314
                }
315
        private:
316
                bool metricsread;
317
};
318
 
319
/*
320
        Class Foi_pfb
321
        Subclass of Foi, specifically for Adobe type 1 .pfb fonts.
322
        Implements: RealName() and EmbedFont().
323
*/
324
 
325
class Foi_pfb : public Foi_postscript
326
{
327
        public:
3544 avox 328
                Foi_pfb(QString fam, QString sty, QString alt, QString psname, QString path, int face, bool embedps) :
329
                Foi_postscript(fam,sty,alt,psname,path,face,embedps)
3 paul 330
                {
2295 cbradney 331
                        formatCode = PFB;
3 paul 332
                }
333
 
334
                virtual bool EmbedFont(QString &str)
335
                {
2295 cbradney 336
                        QByteArray bb;
337
                        RawData(bb);
3 paul 338
                        QString tmp2 = "";
2295 cbradney 339
                        if ((bb.size() > 2) &&  (bb[0] == char(0x80)) && (static_cast<int>(bb[1]) == 1))
3 paul 340
                        {
2295 cbradney 341
                                QString tmp3="";
342
                                QString tmp4 = "";
343
                                uint posi,cxxc=0;
344
                                for (posi = 6; posi < bb.size(); ++posi)
3 paul 345
                                {
2295 cbradney 346
                                        if ((bb[posi] == char(0x80)) && (posi+1 < bb.size()) && (static_cast<int>(bb[posi+1]) == 2))
347
                                                break;
348
                                        str += bb[posi];
349
                                }
350
                                uint ulen;
351
                                if (posi+6 < bb.size())
352
                                {
3 paul 353
                                        ulen = bb[posi+2] & 0xff;
354
                                        ulen |= (bb[posi+3] << 8) & 0xff00;
355
                                        ulen |= (bb[posi+4] << 16) & 0xff0000;
356
                                        ulen |= (bb[posi+5] << 24) & 0xff000000;
357
                                        posi += 6;
2295 cbradney 358
                                        if (posi + ulen > bb.size())
359
                                                ulen = bb.size() - posi - 1;
3 paul 360
                                        char linebuf[80];
361
                                        cxxc=0;
362
                                        for (uint j = 0; j < ulen; ++j)
363
                                        {
364
                                                unsigned char u=bb[posi];
365
                                                linebuf[cxxc]=((u >> 4) & 15) + '0';
366
                                                if(u>0x9f) linebuf[cxxc]+='a'-':';
367
                                                ++cxxc;
368
                                                u&=15; linebuf[cxxc]=u + '0';
369
                                                if(u>0x9) linebuf[cxxc]+='a'-':';
370
                                                ++posi;
371
                                                ++cxxc;
372
                                                if (cxxc > 72)
373
                                                {
374
                                                        linebuf[cxxc++]='\n';
375
                                                        linebuf[cxxc++]=0;
376
                                                        str += linebuf;
377
                                                        cxxc = 0;
378
                                                }
379
                                        }
380
                                        linebuf[cxxc]=0;
381
                                        str += linebuf;
382
                                        str += "\n";
383
                                }
2295 cbradney 384
                                posi += 6;
385
                                for (uint j = posi; j < bb.size(); ++j)
386
                                {
387
                                        if ((bb[j] == static_cast<char>(0x80)) && (j+1 < bb.size()) && (static_cast<int>(bb[j+1]) == 3))
388
                                                break;
389
                                        if(bb[j]=='\r')
390
                                                str+="\n";
391
                                        else
392
                                                str += bb[j];
393
                                }
394
                                str += "\n";
395
                                cxxc = 0;
396
                                return true;
3 paul 397
                        }
2295 cbradney 398
                        else
399
                        {
3500 avox 400
                                sDebug(QObject::tr("Font %1 cannot be read, no embedding").arg(fontPath()));
2295 cbradney 401
                                return false;
402
                        }
3 paul 403
                }
404
};
405
 
406
/*
407
        Class Foi_pfa
408
        Subclass of Foi, specifically for Adobe type 1 and type 3 .pfa fonts.
409
        Implements: RealName() and EmbedFont().
410
*/
411
 
412
class Foi_pfa : public Foi_postscript
413
{
414
        public:
3544 avox 415
                Foi_pfa(QString fam, QString sty, QString alt, QString psname, QString path, int face, bool embedps) :
416
                Foi_postscript(fam,sty,alt,psname,path,face,embedps)
3 paul 417
                {
2295 cbradney 418
                        formatCode = PFA;
3 paul 419
                }
420
                virtual bool EmbedFont(QString &str)
421
                {
2295 cbradney 422
                        QByteArray bb;
423
                        RawData(bb);
424
                        if (bb.size() > 2 && bb[0] == '%' && bb[1] == '!')
425
                        {
426
                                // this is ok since bb will not contain '\0'
427
                                str.append(bb);
428
                                return true;
429
                        }
430
                        return false;
3 paul 431
                }
432
};
433
 
434
 
2295 cbradney 435
 
3 paul 436
/***************************************************************************/
437
 
3559 fschmid 438
SCFonts::SCFonts() : QDict<Foi>(), FontPath(true)
439
{
440
        setAutoDelete(true);
441
        showFontInformation=false;
442
        checkedFonts.clear();
443
}
444
 
3 paul 445
SCFonts::~SCFonts()
446
{
447
}
448
 
2508 fschmid 449
void SCFonts::updateFontMap()
450
{
451
        fontMap.clear();
452
        SCFontsIterator it( *this );
453
        for ( ; it.current(); ++it)
454
        {
455
                if (it.current()->UseFont)
456
                {
3544 avox 457
                        if (fontMap.contains(it.current()->family()))
2508 fschmid 458
                        {
459
                                QStringList effect;
3544 avox 460
                                if (!fontMap[it.current()->family()].contains(it.current()->style()))
2508 fschmid 461
                                {
3544 avox 462
                                        fontMap[it.current()->family()].append(it.current()->style());
2508 fschmid 463
                                }
464
                        }
465
                        else
466
                        {
467
                                QStringList effect;
3544 avox 468
                                effect.append(it.current()->style());
469
                                fontMap.insert(it.current()->family(), effect);
2508 fschmid 470
                        }
471
                }
472
        }
473
}
474
 
3 paul 475
/* Add a path to the list of fontpaths, ensuring that
476
   a trailing slash is present.
477
   Checks to make sure this path is not already present
478
   before adding.
479
*/
480
void SCFonts::AddPath(QString p)
481
{
482
        if(p.right(1) != "/")
483
          p += "/";
484
        if(FontPath.find(p)==-1)
485
                FontPath.insert(FontPath.count(),p);
486
}
487
 
494 fschmid 488
void SCFonts::AddScalableFonts(const QString &path, QString DocName)
3 paul 489
{
3831 cbradney 490
        //Make sure this is not empty or we will scan the whole drive on *nix
491
        //QString::null+/ is / of course.
492
        if (path.isEmpty())
493
                return;
494 fschmid 494
        FT_Library library = NULL;
495
        QString pathfile;
68 Franz 496
        bool error;
3566 fschmid 497
        error = FT_Init_FreeType( &library );
3831 cbradney 498
        QString pathname(path);
3830 cbradney 499
        if ( !pathname.endsWith("/") )
500
                pathname += "/";
501
        pathname=QDir::convertSeparators(pathname);
502
        QDir d(pathname, "*", QDir::Name, QDir::Dirs | QDir::Files | QDir::Readable);
68 Franz 503
        if ((d.exists()) && (d.count() != 0))
494 fschmid 504
        {
505
                for (uint dc = 0; dc < d.count(); ++dc)
3 paul 506
                {
2919 craig 507
                        // readdir may return . or .., which we don't want to recurse
508
                        // over. Skip 'em.
509
                        if (d[dc] == "." || d[dc] == "..")
510
                                continue;
3830 cbradney 511
                        QFileInfo fi(pathname+d[dc]);
84 Franz 512
                        if (!fi.exists())      // Sanity check for broken Symlinks
513
                                continue;
2295 cbradney 514
 
515
                        qApp->processEvents();
516
 
84 Franz 517
                        if (fi.isSymLink())
494 fschmid 518
                        {
84 Franz 519
                                QFileInfo fi3(fi.readLink());
520
                                if (fi3.isRelative())
3830 cbradney 521
                                        pathfile = pathname+fi.readLink();
84 Franz 522
                                else
523
                                        pathfile = fi3.absFilePath();
494 fschmid 524
                        }
84 Franz 525
                        else
3830 cbradney 526
                                pathfile = pathname+d[dc];
84 Franz 527
                        QFileInfo fi2(pathfile);
2295 cbradney 528
                        if (fi2.isDir())
529
                        {
2877 cbradney 530
                                if (DocName.isEmpty())
2295 cbradney 531
                                        AddScalableFonts(pathfile);
532
                                continue;
533
                        }
504 cbradney 534
                        QString ext = fi.extension(false).lower();
535
                        QString ext2 = fi2.extension(false).lower();
2877 cbradney 536
                        if ((ext != ext2) && (ext.isEmpty()))
537
                                ext = ext2;
2295 cbradney 538
                        if ((ext == "ttc") || (ext == "dfont") || (ext == "pfa") || (ext == "pfb") || (ext == "ttf") || (ext == "otf"))
414 Franz 539
                        {
2295 cbradney 540
                                error = AddScalableFont(pathfile, library, DocName);
72 Franz 541
                                if (error)
3240 fschmid 542
                                        sDebug(QObject::tr("Font %1 is broken, discarding it").arg(pathfile));
414 Franz 543
                        }
2295 cbradney 544
#ifdef FT_MACINTOSH
2877 cbradney 545
                        else if (ext.isEmpty() && DocName.isEmpty())
2295 cbradney 546
                        {
547
                                error = AddScalableFont(pathfile, library, DocName);
548
                                if (error)
549
                                        error = AddScalableFont(pathfile + "/rsrc",library, DocName);
550
                                if (error)
3240 fschmid 551
                                        sDebug(QObject::tr("Font %1 is broken, discarding it").arg(pathfile));
2295 cbradney 552
                        }
553
#endif                          
3 paul 554
                }
494 fschmid 555
        }
68 Franz 556
        FT_Done_FreeType( library );
3 paul 557
}
558
 
2295 cbradney 559
/**
560
 * tests magic words to determine the fontformat and preliminary fonttype
561
 */
562
void getFontFormat(FT_Face face, Foi::FontFormat & fmt, Foi::FontType & type)
494 fschmid 563
{
2295 cbradney 564
        static const char* T42_HEAD      = "%!PS-TrueTypeFont";
565
        static const char* T1_HEAD      = "%!FontType1";
566
        static const char* T1_ADOBE_HEAD = "%!PS-AdobeFont-1";
567
        static const char* PSFONT_ADOBE2_HEAD  = "%!PS-Adobe-2.0 Font";
568
        static const char* PSFONT_ADOBE21_HEAD  = "%!PS-Adobe-2.1 Font";
569
        static const char* PSFONT_ADOBE3_HEAD  = "%!PS-Adobe-3.0 Resource-Font";
2730 cbradney 570
        static const int   FONT_NO_ERROR = 0;
2295 cbradney 571
 
572
        const FT_Stream fts = face->stream;
573
        char buf[128];
574
 
575
        fmt = Foi::UNKNOWN_FORMAT;
576
        type = Foi::UNKNOWN_TYPE;
2730 cbradney 577
        if (FT_Stream_Seek(fts, 0L) == FONT_NO_ERROR && FT_Stream_Read(fts, reinterpret_cast<FT_Byte *>(buf), 128) == FONT_NO_ERROR)
494 fschmid 578
        {
2295 cbradney 579
                if(strncmp(buf,T42_HEAD,strlen(T42_HEAD)) == 0)
1321 fschmid 580
                {
2295 cbradney 581
                        fmt = Foi::TYPE42;
582
                        type = Foi::TTF;
1321 fschmid 583
                }
2295 cbradney 584
                else if(strncmp(buf,T1_HEAD,strlen(T1_HEAD)) == 0 ||
585
                            strncmp(buf,T1_ADOBE_HEAD,strlen(T1_ADOBE_HEAD)) == 0)
1321 fschmid 586
                {
2295 cbradney 587
                        fmt = Foi::PFA;
588
                        type = Foi::TYPE1;
1321 fschmid 589
                }
2295 cbradney 590
                else if(strncmp(buf,PSFONT_ADOBE2_HEAD,strlen(PSFONT_ADOBE2_HEAD)) == 0 ||
591
                            strncmp(buf,PSFONT_ADOBE21_HEAD,strlen(PSFONT_ADOBE21_HEAD)) == 0 ||
592
                            strncmp(buf,PSFONT_ADOBE3_HEAD,strlen(PSFONT_ADOBE3_HEAD)) ==0)
1321 fschmid 593
                {
2295 cbradney 594
                        // Type2(CFF), Type0(Composite/CID), Type 3, Type 14 etc would end here
595
                        fmt = Foi::PFA;
596
                        type = Foi::UNKNOWN_TYPE;
1321 fschmid 597
                }
2295 cbradney 598
                else if(buf[0] == '\200' && buf[1] == '\1')
1321 fschmid 599
                {
2295 cbradney 600
                        fmt = Foi::PFB;
601
                        type = Foi::TYPE1;
1321 fschmid 602
                }
2295 cbradney 603
                else if(buf[0] == '\0' && buf[1] == '\1'
604
                                && buf[2] == '\0' && buf[3] == '\0')
494 fschmid 605
                {
2295 cbradney 606
                        fmt = Foi::SFNT;
607
                        type = Foi::TTF;
608
                }
609
                else if(strncmp(buf,"true",4) == 0)
610
                {
611
                        fmt = Foi::SFNT;
612
                        type = Foi::TTF;
613
                }
614
                else if(strncmp(buf,"ttcf",4) == 0)
615
                {
616
                        fmt = Foi::TTCF;
617
                        type = Foi::OTF;
618
                }
619
                else if(strncmp(buf,"OTTO",4) == 0)
620
                {
621
                        fmt = Foi::SFNT;
622
                        type = Foi::OTF;
623
                }
624
                // missing: raw CFF
625
        }
626
}
627
 
628
/**
629
 * Checks face, which must be sfnt based, for the subtype.
630
 * Possible values: TTF, CFF, OTF
631
 */
632
void getSFontType(FT_Face face, Foi::FontType & type)
633
{
634
        if (FT_IS_SFNT(face))
635
        {
636
                FT_ULong ret = 0;
637
                bool hasGlyph = ! FT_Load_Sfnt_Table(face, TTAG_glyf, 0, NULL,  &ret);
638
                hasGlyph &= ret > 0;
639
                bool hasCFF = ! FT_Load_Sfnt_Table(face, TTAG_CFF, 0, NULL,  &ret);
640
                hasCFF &= ret > 0;
641
                if (hasGlyph)
642
                        type = Foi::TTF;
643
                else if (hasCFF)
644
                        type = Foi::OTF;
645
                // TODO: CID or no
646
        }
647
}
648
 
649
// Load a single font into the library from the passed filename. Returns true on error.
650
bool SCFonts::AddScalableFont(QString filename, FT_Library &library, QString DocName)
651
{
3566 fschmid 652
        static bool firstRun;
3633 fschmid 653
        bool Subset = false;
654
        char *buf[50];
655
        QString glyName = "";
2295 cbradney 656
        Foi::FontFormat format;
657
        Foi::FontType   type;
658
        FT_Face         face = NULL;
3559 fschmid 659
        struct testCache foCache;
660
        QFileInfo fic(filename);
661
        foCache.isOK = false;
662
        foCache.isChecked = true;
663
        foCache.lastMod = fic.lastModified();
3566 fschmid 664
        if (checkedFonts.count() == 0)
665
        {
666
                firstRun = true;
667
                ScApp->setSplashStatus( QObject::tr("Creating Font Cache") );
668
        }
2295 cbradney 669
        bool error = FT_New_Face( library, filename, 0, &face );
670
        if (error)
671
        {
672
                if (face != NULL)
673
                        FT_Done_Face( face );
3559 fschmid 674
                checkedFonts.insert(filename, foCache);
2295 cbradney 675
                return true;
676
        }
677
        getFontFormat(face, format, type);
678
        if (format == Foi::UNKNOWN_FORMAT)
679
        {
3474 cbradney 680
                if (showFontInformation)
681
                        sDebug(QObject::tr("Failed to load font %1 - font type unknown").arg(filename));
3559 fschmid 682
                checkedFonts.insert(filename, foCache);
2295 cbradney 683
                error = true;
684
        }
3633 fschmid 685
        bool HasNames = FT_HAS_GLYPH_NAMES(face);
3469 fschmid 686
        if (!error)
687
        {
3559 fschmid 688
                if (!checkedFonts.contains(filename))
3469 fschmid 689
                {
3566 fschmid 690
                        if (!firstRun)
691
                                ScApp->setSplashStatus( QObject::tr("New Font found, checking...") );
3559 fschmid 692
                        FT_UInt gindex = 0;
693
                        FT_ULong charcode = FT_Get_First_Char( face, &gindex );
694
                        while ( gindex != 0 )
3469 fschmid 695
                        {
3559 fschmid 696
                                error = FT_Load_Glyph( face, gindex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP );
697
                                if (error)
698
                                {
699
                                        if (showFontInformation)
700
                                                sDebug(QObject::tr("Font %1 has broken glyph %2 (charcode %3)").arg(filename).arg(gindex).arg(charcode));
701
                                        if (face != NULL)
702
                                                FT_Done_Face( face );
703
                                        checkedFonts.insert(filename, foCache);
704
                                        return true;
705
                                }
3633 fschmid 706
                                FT_Get_Glyph_Name(face, gindex, buf, 50);
707
                                QString newName = QString(reinterpret_cast<char*>(buf));
708
                                if (newName == glyName)
709
                                {
710
                                        HasNames = false;
711
                                        Subset = true;
712
                                }
713
                                glyName = newName;
3559 fschmid 714
                                charcode = FT_Get_Next_Char( face, charcode, &gindex );
715
                        }
716
                        foCache.isOK = true;
717
                        checkedFonts.insert(filename, foCache);
718
                }
719
                else
720
                {
721
                        if (!checkedFonts[filename].isOK)
722
                        {
723
                                checkedFonts[filename].isChecked = true;
3469 fschmid 724
                                return true;
725
                        }
3559 fschmid 726
                        if (checkedFonts[filename].lastMod != fic.lastModified())
727
                        {
3566 fschmid 728
                                ScApp->setSplashStatus( QObject::tr("Modified Font found, checking...") );
3559 fschmid 729
                                FT_UInt gindex = 0;
730
                                FT_ULong charcode = FT_Get_First_Char( face, &gindex );
731
                                while ( gindex != 0 )
732
                                {
733
                                        error = FT_Load_Glyph( face, gindex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP );
734
                                        if (error)
735
                                        {
736
                                                if (showFontInformation)
737
                                                        sDebug(QObject::tr("Font %1 has broken glyph %2 (charcode %3)").arg(filename).arg(gindex).arg(charcode));
738
                                                if (face != NULL)
739
                                                        FT_Done_Face( face );
740
                                                checkedFonts.insert(filename, foCache);
741
                                                return true;
742
                                        }
3633 fschmid 743
                                        FT_Get_Glyph_Name(face, gindex, buf, 50);
744
                                        QString newName = QString(reinterpret_cast<char*>(buf));
745
                                        if (newName == glyName)
746
                                        {
747
                                                HasNames = false;
748
                                                Subset = true;
749
                                        }
750
                                        glyName = newName;
3559 fschmid 751
                                        charcode = FT_Get_Next_Char( face, charcode, &gindex );
752
                                }
753
                                foCache.isOK = true;
754
                                checkedFonts[filename] = foCache;
755
                        }
756
                        else
757
                        {
758
                                checkedFonts[filename].isOK = true;
759
                                checkedFonts[filename].isChecked = true;
760
                        }
3469 fschmid 761
                }
762
        }
763
        int faceindex=0;
2295 cbradney 764
        while (!error)
765
        {
3460 fschmid 766
                QString fam = QString(face->family_name);
767
                QString sty = QString(face->style_name);
768
                if (sty == "Regular")
769
                {
770
                        switch (face->style_flags)
771
                        {
772
                                case 0:
773
                                        break;
774
                                case 1:
775
                                        sty = "Italic";
776
                                        break;
777
                                case 2:
778
                                        sty = "Bold";
779
                                        break;
780
                                case 3:
781
                                        sty = "Bold Italic";
782
                                        break;
783
                                default:
784
                                        break;
785
                        }
786
                }
787
                QString ts = fam + " " + sty;
3544 avox 788
                QString alt = "";
3460 fschmid 789
                const char* psName = FT_Get_Postscript_Name(face);
790
                QString qpsName;
791
                if (psName)
792
                        qpsName = QString(psName);
793
                else
794
                        qpsName = ts;
2295 cbradney 795
                Foi *t = find(ts);
3460 fschmid 796
                if (t)
797
                {
3544 avox 798
                        if (t->RealName() != qpsName)
3460 fschmid 799
                        {
3544 avox 800
                                alt = " ("+qpsName+")";
801
                                ts += alt;
802
                                sty += alt;
3460 fschmid 803
                        }
804
                }
805
                t = find(ts);
2295 cbradney 806
                if (!t)
807
                {
808
                        switch (format)
809
                        {
810
                                case Foi::PFA:
3559 fschmid 811
                                        t = new Foi_pfa(fam, sty, ts, qpsName, filename, faceindex, true);
3633 fschmid 812
                                        t->Subset = Subset;
2295 cbradney 813
                                        break;
2508 fschmid 814
                                case Foi::PFB:
3559 fschmid 815
                                        t = new Foi_pfb(fam, sty, ts, qpsName, filename, faceindex, true);
3633 fschmid 816
                                        t->Subset = Subset;
2295 cbradney 817
                                        break;
818
                                case Foi::SFNT:
3559 fschmid 819
                                        t = new Foi_ttf(fam, sty, ts, qpsName, filename, faceindex, true);
2295 cbradney 820
                                        getSFontType(face, t->typeCode);
821
                                        if (t->typeCode == Foi::OTF)
822
                                        {
823
                                                t->isOTF = true;
824
                                                t->Subset = true;
825
                                        }
3633 fschmid 826
                                        else
827
                                                t->Subset = Subset;
2295 cbradney 828
                                        break;
829
                                case Foi::TTCF:
3559 fschmid 830
                                        t = new Foi_ttf(fam, sty, ts, qpsName, filename, faceindex, true);
2295 cbradney 831
                                        t->formatCode = Foi::TTCF;
832
                                        t->typeCode = Foi::TTF;
833
                                        //getSFontType(face, t->typeCode);
834
                                        if (t->typeCode == Foi::OTF)
835
                                        {
836
                                                t->isOTF = true;
837
                                                t->Subset = true;
838
                                        }
3633 fschmid 839
                                        else
840
                                                t->Subset = Subset;
2295 cbradney 841
                                        break;
842
                                case Foi::TYPE42:
3559 fschmid 843
                                        t = new Foi_ttf(fam, sty, ts, qpsName, filename, faceindex, true);
2295 cbradney 844
                                        getSFontType(face, t->typeCode);
845
                                        if (t->typeCode == Foi::OTF)
846
                                        {
847
                                                t->isOTF = true;
848
                                                t->Subset = true;
849
                                        }
3633 fschmid 850
                                        else
851
                                                t->Subset = Subset;
2295 cbradney 852
                                        break;
853
                        }
494 fschmid 854
                        insert(ts,t);
3633 fschmid 855
                        t->HasNames = HasNames;
494 fschmid 856
                        t->EmbedPS = true;
857
                        t->UseFont = true;
858
                        t->CharWidth[13] = 0;
859
                        t->CharWidth[28] = 0;
860
                        t->CharWidth[9] = 1;
861
                        t->PrivateFont = DocName;
2633 cbradney 862
                        //setBestEncoding(face); //AV
2295 cbradney 863
                        switch (face->charmap? face->charmap->encoding : -1)
864
                        {
865
                                case     FT_ENCODING_ADOBE_STANDARD:
866
                                        t->FontEnc = QString("StandardEncoding");
867
                                        break;
868
                                case     FT_ENCODING_APPLE_ROMAN:
869
                                        t->FontEnc = QString("MacRomanEncoding");
870
                                        break;
871
                                case     FT_ENCODING_ADOBE_EXPERT:
872
                                        t->FontEnc = QString("MacExpertEncoding");
873
                                        break;
874
                                case     FT_ENCODING_ADOBE_LATIN_1:
875
                                        t->FontEnc = QString("WinAnsiEncoding");
876
                                        break;
877
                                case     FT_ENCODING_UNICODE:
878
                                        t->FontEnc = QString("Unicode");
879
                                        break;
880
                                default:
881
                                        t->FontEnc = QString();
882
                        }
883
                        if (showFontInformation)
3544 avox 884
                                sDebug(QObject::tr("Font %1 loaded from %2(%3)").arg(t->RealName()).arg(filename).arg(faceindex+1));
2295 cbradney 885
 
886
/*
887
//debug
888
                        QByteArray bb;
889
                        t->RawData(bb);
890
                        QFile dump(QString("/tmp/fonts/%1-%2").arg(ts).arg(psName));
891
                        dump.open(IO_WriteOnly);
892
                        QDataStream os(&dump);
893
                        os.writeRawBytes(bb.data(), bb.size());
894
                        dump.close();
895
*/
896
                        FT_Done_Face(face);
2542 cbradney 897
                        face=NULL;
2295 cbradney 898
                        ++faceindex;
899
                        error = FT_New_Face( library, filename, faceindex, &face );
494 fschmid 900
                }
2295 cbradney 901
                else
902
                {
903
                        if (showFontInformation)
3240 fschmid 904
                                sDebug(QObject::tr("Font %1(%2) is duplicate of %3").arg(filename).arg(faceindex+1).arg(t->fontPath()));
2295 cbradney 905
                        // this is needed since eg. AppleSymbols will happily return a face for *any* face_index
906
                        error = true;
907
                }
908
        } //while
909
 
494 fschmid 910
        if (face != 0)
911
                FT_Done_Face( face );
912
        return false;
913
}
914
 
915
void SCFonts::removeFont(QString name)
916
{
917
        remove(name);
2508 fschmid 918
        updateFontMap();
494 fschmid 919
}
920
 
776 fschmid 921
#ifdef HAVE_FONTCONFIG
922
// Use Fontconfig to locate and load fonts.
923
void SCFonts::AddFontconfigFonts()
924
{
2295 cbradney 925
        // All-in-one library setup. Perhaps this should be in
926
        // the SCFonts constructor.
927
        FcConfig* FcInitLoadConfigAndFonts();
928
        // The pattern controls what fonts to match. In this case we want to
929
        // match all scalable fonts, but ignore bitmap fonts.
930
        FcPattern* pat = FcPatternBuild(NULL,
931
                                                                        FC_SCALABLE, FcTypeBool, true,
932
                                                                        NULL);
933
        // The ObjectSet tells FontConfig what information about each match to return.
934
        // We currently just need FC_FILE, but other info like font family and style
935
        // is availible - see "man fontconfig".
936
        FcObjectSet* os = FcObjectSetBuild (FC_FILE, (char *) 0);
937
        // Now ask fontconfig to retrieve info as specified in 'os' about fonts
938
        // matching pattern 'pat'.
939
        FcFontSet* fs = FcFontList(0, pat, os);
940
        FcObjectSetDestroy(os);
941
        FcPatternDestroy(pat);
942
        // Create the Freetype library
943
        bool error;
944
        FT_Library library = NULL;
945
        error = FT_Init_FreeType( &library );
946
        // Now iterate over the font files and load them
947
        int i;
948
        for (i = 0; i < fs->nfont; i++)
949
        {
950
                FcChar8 *file = NULL;
951
                if (FcPatternGetString (fs->fonts[i], FC_FILE, 0, &file) == FcResultMatch)
952
                {
953
                        if (showFontInformation)
3240 fschmid 954
                                sDebug(QObject::tr("Loading font %1 (found using fontconfig)").arg(QString((char*)file)));
2295 cbradney 955
                        error = AddScalableFont(QString((char*)file), library, "");
3476 cbradney 956
                        if (showFontInformation && error)
3240 fschmid 957
                                sDebug(QObject::tr("Font %1 (found using fontconfig) is broken, discarding it").arg(QString((char*)file)));
2295 cbradney 958
                }
959
                else
960
                        if (showFontInformation)
3240 fschmid 961
                                sDebug(QObject::tr("Failed to load a font - freetype2 couldn't find the font file"));
2295 cbradney 962
        }
963
        FT_Done_FreeType( library );
776 fschmid 964
}
965
 
966
#else
3794 cbradney 967
#if !defined(QT_MAC) && !defined(_WIN32)
776 fschmid 968
 
3 paul 969
void SCFonts::AddXFontPath()
970
{
971
        int pathcount,i;
972
        Display *display=XOpenDisplay(NULL);
973
        char **fontpath=XGetFontPath(display,&pathcount);
974
        for(i=0; i<pathcount; ++i)
975
                AddPath(fontpath[i]);
976
        XFreeFontPath(fontpath);
977
}
978
 
979
/* replacement for AddXFontServerPath() for correctly parsing
980
 * RedHad-Style /etc/X11/fs/config files */
981
 
982
void SCFonts::AddXFontServerPath()
983
{
984
        QFile fs("/etc/X11/fs/config");
985
        if(!(fs.exists()))
986
        {
987
                fs.setName("/usr/X11R6/lib/X11/fs/config");
988
                if(!(fs.exists()))
989
                {
990
                        fs.setName("/usr/X11/lib/X11/fs/config");
991
                        if(!(fs.exists()))
992
                                return;
993
                }
994
        }
995
 
996
        if (fs.open(IO_ReadOnly))
997
        {
998
                QString fsconfig,paths,tmp;
999
                QTextStream tsx(&fs);
1000
                fsconfig = tsx.read();
1001
                fs.close();
1002
 
1003
                int pos = fsconfig.find("catalogue");
1004
                paths = fsconfig.mid(pos);
1005
                paths = paths.mid(paths.find("=")+1);
1006
 
1007
                pos=0;
1008
                do {
1009
                        pos = paths.find("\n",pos+1);
1010
                } while (pos > -1 && paths.mid(pos-1, 1) == ",");
1011
 
1012
                if(pos<0) pos=paths.length();
1013
                paths = paths.left(pos);
1014
                paths = paths.simplifyWhiteSpace();
1015
                paths.replace(QRegExp(" "), "");
1016
                paths.replace(QRegExp(","), "\n");
1017
                paths += "\n";
1018
                paths = paths.stripWhiteSpace();
1019
 
1020
                pos=-1;
1021
                do {
1022
                        int pos2;
1023
                        pos2 = paths.find("\n",pos+1);
1024
                        tmp = paths.mid(pos+1,(pos2-pos)-1);
1025
                        pos=pos2;
1026
 
1027
                        AddPath(tmp);
1028
 
1029
                } while (pos > -1);
1030
        }
1031
}
776 fschmid 1032
#endif
2295 cbradney 1033
#endif
3 paul 1034
 
2510 craig 1035
/* Add an extra path to our font search path,
1036
 * allowing a user to have extra fonts installed
1037
 * only for this user. Can also be used also as an emergency
1038
 * fallback if no suitable fonts are found elsewere */
3240 fschmid 1039
void SCFonts::AddUserPath(QString )
3 paul 1040
{
2856 cbradney 1041
        PrefsContext *pc = PrefsManager::instance()->prefsFile->getContext("Fonts");
2510 craig 1042
        PrefsTable *extraDirs = pc->getTable("ExtraFontDirs");
1043
        for (int i = 0; i < extraDirs->getRowCount(); ++i)
1044
                AddPath(extraDirs->get(i, 0));
3 paul 1045
}
1046
 
3559 fschmid 1047
void SCFonts::ReadCacheList(QString pf)
1048
{
3633 fschmid 1049
        QFile fr(pf + "/cfonts.xml");
1050
        QFileInfo fir(fr);
1051
        if (fir.exists())
1052
                fr.remove();
3559 fschmid 1053
        checkedFonts.clear();
1054
        struct testCache foCache;
1055
        QDomDocument docu("fontcacherc");
3633 fschmid 1056
        QFile f(pf + "/checkfonts.xml");
3559 fschmid 1057
        if(!f.open(IO_ReadOnly))
1058
                return;
3566 fschmid 1059
        ScApp->setSplashStatus( QObject::tr("Reading Font Cache") );
3559 fschmid 1060
        QTextStream ts(&f);
1061
        ts.setEncoding(QTextStream::UnicodeUTF8);
1062
        QString errorMsg;
1063
        int errorLine = 0, errorColumn = 0;
1064
        if( !docu.setContent(ts.read(), &errorMsg, &errorLine, &errorColumn) )
1065
        {
1066
                f.close();
1067
                return;
1068
        }
1069
        f.close();
1070
        QDomElement elem = docu.documentElement();
1071
        if (elem.tagName() != "CachedFonts")
1072
                return;
1073
        QDomNode DOC = elem.firstChild();
1074
        while(!DOC.isNull())
1075
        {
1076
                QDomElement dc = DOC.toElement();
1077
                if (dc.tagName()=="Font")
1078
                {
1079
                        foCache.isChecked = false;
1080
                        foCache.isOK = static_cast<bool>(QStoInt(dc.attribute("Status","1")));
1081
                        foCache.lastMod = QDateTime::fromString(dc.attribute("Modified"), Qt::ISODate);
1082
                        checkedFonts.insert(dc.attribute("File"), foCache);
1083
                }
1084
                DOC = DOC.nextSibling();
1085
        }
1086
}
1087
 
1088
void SCFonts::WriteCacheList(QString pf)
1089
{
1090
        QDomDocument docu("fontcacherc");
1091
        QString st="<CachedFonts></CachedFonts>";
1092
        docu.setContent(st);
1093
        QDomElement elem = docu.documentElement();
1094
        QMap<QString, testCache>::Iterator it;
1095
        for (it = checkedFonts.begin(); it != checkedFonts.end(); ++it)
1096
        {
1097
                if (it.data().isChecked)
1098
                {
1099
                        QDomElement fosu = docu.createElement("Font");
1100
                        fosu.setAttribute("File",it.key());
1101
                        fosu.setAttribute("Status",static_cast<int>(it.data().isOK));
1102
                        fosu.setAttribute("Modified",it.data().lastMod.toString(Qt::ISODate));
1103
                        elem.appendChild(fosu);
1104
                }
1105
        }
3566 fschmid 1106
        ScApp->setSplashStatus( QObject::tr("Writing updated Font Cache") );
3633 fschmid 1107
        QFile f(pf + "/checkfonts.xml");
3559 fschmid 1108
        if(f.open(IO_WriteOnly))
1109
        {
1110
                QTextStream s(&f);
1111
                s.setEncoding(QTextStream::UnicodeUTF8);
1112
                s<<docu.toString();
1113
                f.close();
1114
        }
1115
        checkedFonts.clear();
1116
}
1117
 
2295 cbradney 1118
void SCFonts::GetFonts(QString pf, bool showFontInfo)
3 paul 1119
{
2295 cbradney 1120
        showFontInformation=showFontInfo;
3 paul 1121
        FontPath.clear();
3559 fschmid 1122
        ReadCacheList(pf);
3566 fschmid 1123
        ScApp->setSplashStatus( QObject::tr("Searching for Fonts") );
3 paul 1124
        AddUserPath(pf);
3794 cbradney 1125
        // Search the system paths
1126
        QStringList ftDirs = ScPaths::getSystemFontDirs();
1127
        for (unsigned int i = 0; i < ftDirs.count(); i++)
1128
                AddScalableFonts( ftDirs[i] );
1129
        // Search Scribus font path
3831 cbradney 1130
        if (!ScPaths::instance().fontDir().isEmpty() && QDir(ScPaths::instance().fontDir()).exists())
3794 cbradney 1131
                AddScalableFonts( ScPaths::instance().fontDir() );
2295 cbradney 1132
// if fontconfig is there, it does all the work
1133
#if HAVE_FONTCONFIG
3794 cbradney 1134
        // Search fontconfig paths
776 fschmid 1135
        for(QStrListIterator fpi(FontPath) ; fpi.current() ; ++fpi)
1136
                AddScalableFonts(fpi.current());
1137
        AddFontconfigFonts();
1138
#else
2295 cbradney 1139
// on X11 look there:
1140
#ifdef Q_WS_X11
3 paul 1141
        AddXFontPath();
1142
        AddXFontServerPath();
2295 cbradney 1143
#endif
1144
// add user and X11 fonts:
1145
        for(QStrListIterator fpi(FontPath) ; fpi.current() ; ++fpi)
3 paul 1146
                AddScalableFonts(fpi.current());
494 fschmid 1147
#endif
2508 fschmid 1148
        updateFontMap();
3559 fschmid 1149
        WriteCacheList(pf);
494 fschmid 1150
}