~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kcontrol/kfontinst/lib/Fc.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * KFontInst - KDE Font Installer
 
3
 *
 
4
 * Copyright 2003-2007 Craig Drummond <craig@kde.org>
 
5
 *
 
6
 * ----
 
7
 *
 
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.
 
12
 *
 
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.
 
17
 *
 
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.
 
22
 */
 
23
 
 
24
#include "Fc.h"
 
25
#include <QtCore/QTextStream>
 
26
#include <QtCore/QHash>
 
27
 
 
28
//
 
29
// KDE font chooser always seems to use Italic - for both Oblique, and Italic. So I guees
 
30
// the fonts:/ should do too - so as to appear more unified.
 
31
//
 
32
// ditto with respect to Medium/Regular
 
33
#define KFI_HAVE_OBLIQUE         // Do we differentiate between Italic and Oblique when comparing slants?
 
34
#define KFI_DISPLAY_OBLIQUE      // Do we want to list "Oblique"? Or always use Italic?
 
35
#define KFI_HAVE_MEDIUM_WEIGHT   // Do we differentiate between Medium and Regular weights when comparing weights?
 
36
#define KFI_DISPLAY_MEDIUM      // Do we want to list "Medium"? Or always use Regular?
 
37
 
 
38
namespace KFI
 
39
{
 
40
 
 
41
namespace FC
 
42
{
 
43
 
 
44
#define FC_PROTOCOL    QString::fromLatin1("fontconfig")
 
45
#define FC_STYLE_QUERY QString::fromLatin1("style")
 
46
#define FC_FILE_QUERY  QString::fromLatin1("file")
 
47
#define FC_INDEX_QUERY QString::fromLatin1("index")
 
48
 
 
49
KUrl encode(const QString &name, quint32 style, const QString &file, int index)
 
50
{
 
51
    KUrl url(KUrl::fromPath(name));
 
52
 
 
53
    url.setProtocol(FC_PROTOCOL);
 
54
    url.addQueryItem(FC_STYLE_QUERY, QString::number(style));
 
55
    if(!file.isEmpty())
 
56
        url.addQueryItem(FC_FILE_QUERY, file);
 
57
    if(index>0)
 
58
        url.addQueryItem(FC_INDEX_QUERY, QString::number(index));
 
59
    return url;
 
60
}
 
61
 
 
62
Misc::TFont decode(const KUrl &url)
 
63
{
 
64
    return FC_PROTOCOL==url.protocol()
 
65
                ? Misc::TFont(url.path(), url.queryItem(FC_STYLE_QUERY).toUInt())
 
66
                : Misc::TFont(QString(), 0);
 
67
}
 
68
 
 
69
QString getFile(const KUrl &url)
 
70
{
 
71
    return FC_PROTOCOL==url.protocol() ? url.queryItem(FC_FILE_QUERY) : QString();
 
72
}
 
73
 
 
74
int getIndex(const KUrl &url)
 
75
{
 
76
    return FC_PROTOCOL==url.protocol() ? url.queryItem(FC_INDEX_QUERY).toInt() : 0;
 
77
}
 
78
 
 
79
int weight(int w)
 
80
{
 
81
    if(KFI_NULL_SETTING==w)
 
82
#ifdef KFI_HAVE_MEDIUM_WEIGHT
 
83
        return FC_WEIGHT_MEDIUM;
 
84
#else
 
85
        return FC_WEIGHT_REGULAR;
 
86
#endif
 
87
 
 
88
    if(w<FC_WEIGHT_EXTRALIGHT)
 
89
        return FC_WEIGHT_THIN;
 
90
 
 
91
    if(w<(FC_WEIGHT_EXTRALIGHT+FC_WEIGHT_LIGHT)/2)
 
92
        return FC_WEIGHT_EXTRALIGHT;
 
93
 
 
94
    if(w<(FC_WEIGHT_LIGHT+FC_WEIGHT_REGULAR)/2)
 
95
        return FC_WEIGHT_LIGHT;
 
96
 
 
97
#ifdef KFI_HAVE_MEDIUM_WEIGHT
 
98
    if(w<(FC_WEIGHT_REGULAR+FC_WEIGHT_MEDIUM)/2)
 
99
        return FC_WEIGHT_REGULAR;
 
100
 
 
101
    if(w<(FC_WEIGHT_MEDIUM+FC_WEIGHT_DEMIBOLD)/2)
 
102
        return FC_WEIGHT_MEDIUM;
 
103
#else
 
104
    if(w<(FC_WEIGHT_REGULAR+FC_WEIGHT_DEMIBOLD)/2)
 
105
        return FC_WEIGHT_REGULAR;
 
106
#endif
 
107
 
 
108
    if(w<(FC_WEIGHT_DEMIBOLD+FC_WEIGHT_BOLD)/2)
 
109
        return FC_WEIGHT_DEMIBOLD;
 
110
 
 
111
    if(w<(FC_WEIGHT_BOLD+FC_WEIGHT_EXTRABOLD)/2)
 
112
        return FC_WEIGHT_BOLD;
 
113
 
 
114
    if(w<(FC_WEIGHT_EXTRABOLD+FC_WEIGHT_BLACK)/2)
 
115
        return FC_WEIGHT_EXTRABOLD;
 
116
 
 
117
    return FC_WEIGHT_BLACK;
 
118
}
 
119
 
 
120
int width(int w)
 
121
{
 
122
    if(KFI_NULL_SETTING==w)
 
123
        return KFI_FC_WIDTH_NORMAL;
 
124
 
 
125
    if(w<KFI_FC_WIDTH_EXTRACONDENSED)
 
126
        return KFI_FC_WIDTH_EXTRACONDENSED;
 
127
 
 
128
    if(w<(KFI_FC_WIDTH_EXTRACONDENSED+KFI_FC_WIDTH_CONDENSED)/2)
 
129
        return KFI_FC_WIDTH_EXTRACONDENSED;
 
130
 
 
131
    if(w<(KFI_FC_WIDTH_CONDENSED+KFI_FC_WIDTH_SEMICONDENSED)/2)
 
132
        return KFI_FC_WIDTH_CONDENSED;
 
133
 
 
134
    if(w<(KFI_FC_WIDTH_SEMICONDENSED+KFI_FC_WIDTH_NORMAL)/2)
 
135
        return KFI_FC_WIDTH_SEMICONDENSED;
 
136
 
 
137
    if(w<(KFI_FC_WIDTH_NORMAL+KFI_FC_WIDTH_SEMIEXPANDED)/2)
 
138
        return KFI_FC_WIDTH_NORMAL;
 
139
 
 
140
    if(w<(KFI_FC_WIDTH_SEMIEXPANDED+KFI_FC_WIDTH_EXPANDED)/2)
 
141
        return KFI_FC_WIDTH_SEMIEXPANDED;
 
142
 
 
143
    if(w<(KFI_FC_WIDTH_EXPANDED+KFI_FC_WIDTH_EXTRAEXPANDED)/2)
 
144
        return KFI_FC_WIDTH_EXPANDED;
 
145
 
 
146
    if(w<(KFI_FC_WIDTH_EXTRAEXPANDED+KFI_FC_WIDTH_ULTRAEXPANDED)/2)
 
147
        return KFI_FC_WIDTH_EXTRAEXPANDED;
 
148
 
 
149
    return KFI_FC_WIDTH_ULTRAEXPANDED;
 
150
}
 
151
 
 
152
int slant(int s)
 
153
{
 
154
    if(KFI_NULL_SETTING==s || s<FC_SLANT_ITALIC)
 
155
        return FC_SLANT_ROMAN;
 
156
 
 
157
#ifdef KFI_HAVE_OBLIQUE
 
158
    if(s<(FC_SLANT_ITALIC+FC_SLANT_OBLIQUE)/2)
 
159
        return FC_SLANT_ITALIC;
 
160
 
 
161
    return FC_SLANT_OBLIQUE;
 
162
#else
 
163
    return FC_SLANT_ITALIC;
 
164
#endif
 
165
}
 
166
 
 
167
int spacing(int s)
 
168
{
 
169
    if(s<FC_MONO)
 
170
        return FC_PROPORTIONAL;
 
171
 
 
172
    if(s<(FC_MONO+FC_CHARCELL)/2)
 
173
        return FC_MONO;
 
174
 
 
175
    return FC_CHARCELL;
 
176
}
 
177
 
 
178
int strToWeight(const QString &str, QString &newStr)
 
179
{
 
180
    if(0==str.indexOf(i18n(KFI_WEIGHT_THIN), 0, Qt::CaseInsensitive))
 
181
    {
 
182
        newStr=str.mid(i18n(KFI_WEIGHT_THIN).length());
 
183
        return FC_WEIGHT_THIN;
 
184
    }
 
185
    if(0==str.indexOf(i18n(KFI_WEIGHT_EXTRALIGHT), 0, Qt::CaseInsensitive))
 
186
    {
 
187
        newStr=str.mid(i18n(KFI_WEIGHT_EXTRALIGHT).length());
 
188
        return FC_WEIGHT_EXTRALIGHT;
 
189
    }
 
190
    //if(0==str.indexOf(i18n(KFI_WEIGHT_ULTRALIGHT), 0, Qt::CaseInsensitive))
 
191
    //{
 
192
    //    newStr=str.mid(i18n(KFI_WEIGHT_ULTRALIGHT).length());
 
193
    //    return FC_WEIGHT_ULTRALIGHT;
 
194
    //}
 
195
    if(0==str.indexOf(i18n(KFI_WEIGHT_LIGHT), 0, Qt::CaseInsensitive))
 
196
    {
 
197
        newStr=str.mid(i18n(KFI_WEIGHT_LIGHT).length());
 
198
        return FC_WEIGHT_LIGHT;
 
199
    }
 
200
    if(0==str.indexOf(i18n(KFI_WEIGHT_REGULAR), 0, Qt::CaseInsensitive))
 
201
    {
 
202
        newStr=str.mid(i18n(KFI_WEIGHT_REGULAR).length());
 
203
        return FC_WEIGHT_REGULAR;
 
204
    }
 
205
    //if(0==str.indexOf(i18n(KFI_WEIGHT_NORMAL), 0, Qt::CaseInsensitive))
 
206
    //{
 
207
    //    newStr=str.mid(i18n(KFI_WEIGHT_NORMAL).length());
 
208
    //    return FC_WEIGHT_NORMAL;
 
209
    //}
 
210
    if(0==str.indexOf(i18n(KFI_WEIGHT_MEDIUM), 0, Qt::CaseInsensitive))
 
211
    {
 
212
        newStr=str.mid(i18n(KFI_WEIGHT_MEDIUM).length());
 
213
        return FC_WEIGHT_MEDIUM;
 
214
    }
 
215
    if(0==str.indexOf(i18n(KFI_WEIGHT_DEMIBOLD), 0, Qt::CaseInsensitive))
 
216
    {
 
217
        newStr=str.mid(i18n(KFI_WEIGHT_DEMIBOLD).length());
 
218
        return FC_WEIGHT_DEMIBOLD;
 
219
    }
 
220
    //if(0==str.indexOf(i18n(KFI_WEIGHT_SEMIBOLD), 0, Qt::CaseInsensitive))
 
221
    //{
 
222
    //    newStr=str.mid(i18n(KFI_WEIGHT_SEMIBOLD).length());
 
223
    //    return FC_WEIGHT_SEMIBOLD;
 
224
    //}
 
225
    if(0==str.indexOf(i18n(KFI_WEIGHT_BOLD), 0, Qt::CaseInsensitive))
 
226
    {
 
227
        newStr=str.mid(i18n(KFI_WEIGHT_BOLD).length());
 
228
        return FC_WEIGHT_BOLD;
 
229
    }
 
230
    if(0==str.indexOf(i18n(KFI_WEIGHT_EXTRABOLD), 0, Qt::CaseInsensitive))
 
231
    {
 
232
        newStr=str.mid(i18n(KFI_WEIGHT_EXTRABOLD).length());
 
233
        return FC_WEIGHT_EXTRABOLD;
 
234
    }
 
235
    //if(0==str.indexOf(i18n(KFI_WEIGHT_ULTRABOLD), 0, Qt::CaseInsensitive))
 
236
    //{
 
237
    //    newStr=str.mid(i18n(KFI_WEIGHT_ULTRABOLD).length());
 
238
    //    return FC_WEIGHT_ULTRABOLD;
 
239
    //}
 
240
    if(0==str.indexOf(i18n(KFI_WEIGHT_BLACK), 0, Qt::CaseInsensitive))
 
241
    {
 
242
        newStr=str.mid(i18n(KFI_WEIGHT_BLACK).length());
 
243
        return FC_WEIGHT_BLACK;
 
244
    }
 
245
    if(0==str.indexOf(i18n(KFI_WEIGHT_BLACK), 0, Qt::CaseInsensitive))
 
246
    {
 
247
        newStr=str.mid(i18n(KFI_WEIGHT_BLACK).length());
 
248
        return FC_WEIGHT_BLACK;
 
249
    }
 
250
 
 
251
    newStr=str;
 
252
    return FC_WEIGHT_REGULAR;
 
253
}
 
254
 
 
255
int strToWidth(const QString &str, QString &newStr)
 
256
{
 
257
    if(0==str.indexOf(i18n(KFI_WIDTH_ULTRACONDENSED), 0, Qt::CaseInsensitive))
 
258
    {
 
259
        newStr=str.mid(i18n(KFI_WIDTH_ULTRACONDENSED).length());
 
260
        return KFI_FC_WIDTH_ULTRACONDENSED;
 
261
    }
 
262
    if(0==str.indexOf(i18n(KFI_WIDTH_EXTRACONDENSED), 0, Qt::CaseInsensitive))
 
263
    {
 
264
        newStr=str.mid(i18n(KFI_WIDTH_EXTRACONDENSED).length());
 
265
        return KFI_FC_WIDTH_EXTRACONDENSED;
 
266
    }
 
267
    if(0==str.indexOf(i18n(KFI_WIDTH_CONDENSED), 0, Qt::CaseInsensitive))
 
268
    {
 
269
        newStr=str.mid(i18n(KFI_WIDTH_CONDENSED).length());
 
270
        return KFI_FC_WIDTH_CONDENSED;
 
271
    }
 
272
    if(0==str.indexOf(i18n(KFI_WIDTH_SEMICONDENSED), 0, Qt::CaseInsensitive))
 
273
    {
 
274
        newStr=str.mid(i18n(KFI_WIDTH_SEMICONDENSED).length());
 
275
        return KFI_FC_WIDTH_SEMICONDENSED;
 
276
    }
 
277
    if(0==str.indexOf(i18n(KFI_WIDTH_NORMAL), 0, Qt::CaseInsensitive))
 
278
    {
 
279
        newStr=str.mid(i18n(KFI_WIDTH_NORMAL).length());
 
280
        return KFI_FC_WIDTH_NORMAL;
 
281
    }
 
282
    if(0==str.indexOf(i18n(KFI_WIDTH_SEMIEXPANDED), 0, Qt::CaseInsensitive))
 
283
    {
 
284
        newStr=str.mid(i18n(KFI_WIDTH_SEMIEXPANDED).length());
 
285
        return KFI_FC_WIDTH_SEMIEXPANDED;
 
286
    }
 
287
    if(0==str.indexOf(i18n(KFI_WIDTH_EXPANDED), 0, Qt::CaseInsensitive))
 
288
    {
 
289
        newStr=str.mid(i18n(KFI_WIDTH_EXPANDED).length());
 
290
        return KFI_FC_WIDTH_EXPANDED;
 
291
    }
 
292
    if(0==str.indexOf(i18n(KFI_WIDTH_EXTRAEXPANDED), 0, Qt::CaseInsensitive))
 
293
    {
 
294
        newStr=str.mid(i18n(KFI_WIDTH_EXTRAEXPANDED).length());
 
295
        return KFI_FC_WIDTH_EXTRAEXPANDED;
 
296
    }
 
297
    if(0==str.indexOf(i18n(KFI_WIDTH_ULTRAEXPANDED), 0, Qt::CaseInsensitive))
 
298
    {
 
299
        newStr=str.mid(i18n(KFI_WIDTH_ULTRAEXPANDED).length());
 
300
        return KFI_FC_WIDTH_ULTRAEXPANDED;
 
301
    }
 
302
 
 
303
    newStr=str;
 
304
    return KFI_FC_WIDTH_NORMAL;
 
305
}
 
306
 
 
307
int strToSlant(const QString &str)
 
308
{
 
309
    if(-1!=str.indexOf(i18n(KFI_SLANT_ITALIC)))
 
310
        return FC_SLANT_ITALIC;
 
311
    if(-1!=str.indexOf(i18n(KFI_SLANT_OBLIQUE)))
 
312
        return FC_SLANT_OBLIQUE;
 
313
    return FC_SLANT_ROMAN;
 
314
}
 
315
 
 
316
quint32 createStyleVal(const QString &name)
 
317
{
 
318
    int pos;
 
319
 
 
320
    if(-1==(pos=name.indexOf(", ")))   // No style information...
 
321
        return createStyleVal(FC_WEIGHT_REGULAR,
 
322
#ifdef KFI_FC_NO_WIDTHS
 
323
                              KFI_NULL_SETTING
 
324
#else
 
325
                              KFI_FC_WIDTH_NORMAL
 
326
#endif
 
327
                              , FC_SLANT_ROMAN);
 
328
    else
 
329
    {
 
330
        QString style(name.mid(pos+2));
 
331
 
 
332
        return createStyleVal(strToWeight(style, style),
 
333
#ifdef KFI_FC_NO_WIDTHS
 
334
                              KFI_NULL_SETTING
 
335
#else
 
336
                              strToWidth(style, style)
 
337
#endif
 
338
                              , strToSlant(style));
 
339
    }
 
340
}
 
341
 
 
342
QString styleValToStr(quint32 style)
 
343
{
 
344
    QString str;
 
345
    int     weight, width, slant;
 
346
 
 
347
    decomposeStyleVal(style, weight, width, slant);
 
348
    str.sprintf("0X%02X%02X%02X\n", weight, width, slant);
 
349
    return str;
 
350
}
 
351
 
 
352
void decomposeStyleVal(quint32 styleInfo, int &weight, int &width, int &slant)
 
353
{
 
354
    weight=(styleInfo&0xFF0000)>>16;
 
355
    width=(styleInfo&0x00FF00)>>8;
 
356
    slant=(styleInfo&0x0000FF);
 
357
}
 
358
 
 
359
quint32 styleValFromStr(const QString &style)
 
360
{
 
361
    if(style.isEmpty())
 
362
        return KFI_NO_STYLE_INFO;
 
363
    else
 
364
    {
 
365
        quint32 val;
 
366
 
 
367
        QTextStream(const_cast<QString *>(&style), QIODevice::ReadOnly) >> val;
 
368
        return val;
 
369
    }
 
370
}
 
371
 
 
372
QString getFcString(FcPattern *pat, const char *val, int index)
 
373
{
 
374
    QString rv;
 
375
    FcChar8 *fcStr;
 
376
 
 
377
    if(FcResultMatch==FcPatternGetString(pat, val, index, &fcStr))
 
378
        rv=QString::fromUtf8((char *)fcStr);
 
379
 
 
380
    return rv;
 
381
}
 
382
 
 
383
//
 
384
// TODO: How correct is this?
 
385
// Qt/Gtk seem to prefer font family names with FAMILY_LANG=="en"
 
386
// ...so if possible, use that. Else, use the first non "xx" lang.
 
387
QString getFcLangString(FcPattern *pat, const char *val, const char *valLang)
 
388
{
 
389
    QString rv;
 
390
    int     langIndex=-1;
 
391
 
 
392
    for(int i=0; true; ++i)
 
393
    {
 
394
        QString lang=getFcString(pat, valLang, i);
 
395
 
 
396
        if(lang.isEmpty())
 
397
            break;
 
398
        else if(QString::fromLatin1("en")==lang)
 
399
            return getFcString(pat, val, i);
 
400
        else if(QString::fromLatin1("xx")!=lang && -1==langIndex)
 
401
            langIndex=i;
 
402
    }
 
403
 
 
404
    return getFcString(pat, val, langIndex>0 ? langIndex : 0);
 
405
}
 
406
 
 
407
int getFcInt(FcPattern *pat, const char *val, int index, int def)
 
408
{
 
409
    int rv;
 
410
 
 
411
    if (FcResultMatch==FcPatternGetInteger(pat, val, index, &rv))
 
412
        return rv;
 
413
    return def;
 
414
}
 
415
 
 
416
QString getName(const QString &file)
 
417
{
 
418
    int       count=0;
 
419
    FcPattern *pat=FcFreeTypeQuery((const FcChar8 *)(QFile::encodeName(file).constData()), 0, NULL,
 
420
                                    &count);
 
421
    QString   name(i18n("Unknown"));
 
422
 
 
423
    if(pat)
 
424
    {
 
425
        name=FC::createName(pat);
 
426
        FcPatternDestroy(pat);
 
427
    }
 
428
 
 
429
    return name;
 
430
}
 
431
 
 
432
void getDetails(FcPattern *pat, QString &family, quint32 &styleVal, int &index, QString &foundry)
 
433
{
 
434
    int weight=getFcInt(pat,  FC_WEIGHT, 0, KFI_NULL_SETTING),
 
435
        width=
 
436
#ifdef KFI_FC_NO_WIDTHS
 
437
               KFI_NULL_SETTING,
 
438
#else
 
439
               getFcInt(pat,  FC_WIDTH, 0, KFI_NULL_SETTING),
 
440
#endif
 
441
        slant=getFcInt(pat,  FC_SLANT, 0, KFI_NULL_SETTING);
 
442
 
 
443
    index=getFcInt(pat,  FC_INDEX, 0, 0);
 
444
// #ifdef KFI_USE_TRANSLATED_FAMILY_NAME
 
445
    family=getFcLangString(pat, FC_FAMILY, FC_FAMILYLANG);
 
446
// #else
 
447
//     family=getFcString(pat, FC_FAMILY, 0);
 
448
// #endif
 
449
    styleVal=createStyleVal(weight, width, slant);
 
450
    foundry=getFcString(pat, FC_FOUNDRY, 0);
 
451
}
 
452
 
 
453
QString createName(FcPattern *pat)
 
454
{
 
455
    QString family,
 
456
            foundry;
 
457
    quint32 styleVal;
 
458
    int     index;
 
459
           
 
460
    getDetails(pat, family, styleVal, index, foundry);
 
461
    return createName(family, styleVal);
 
462
}
 
463
 
 
464
QString createName(const QString &family, quint32 styleInfo)
 
465
{
 
466
    int weight, width, slant;
 
467
 
 
468
    decomposeStyleVal(styleInfo, weight, width, slant);
 
469
    return createName(family, weight, width, slant);
 
470
}
 
471
 
 
472
QString createName(const QString &family, int weight, int width, int slant)
 
473
{
 
474
    return family+QString::fromLatin1(", ")+createStyleName(weight, width, slant);
 
475
}
 
476
 
 
477
QString createStyleName(quint32 styleInfo)
 
478
{
 
479
    int weight, width, slant;
 
480
 
 
481
    decomposeStyleVal(styleInfo, weight, width, slant);
 
482
    return createStyleName(weight, width, slant);
 
483
}
 
484
 
 
485
QString createStyleName(int weight, int width, int slant)
 
486
{
 
487
//
 
488
//CPD: TODO: the names *need* to match up with kfontchooser's...
 
489
//         : Removing KFI_DISPLAY_OBLIQUE and KFI_DISPLAY_MEDIUM help this.
 
490
//           However, I have at least one bad font:
 
491
//               Rockwell Extra Bold. Both fontconfig, and kcmshell fonts list family
 
492
//               as "Rockwell Extra Bold" -- good (well at least they match). *But* fontconfig
 
493
//               is returning the weight "Extra Bold", and kcmshell fonts is using "Bold" :-(
 
494
//
 
495
    QString name,
 
496
            weightString,
 
497
            widthString,
 
498
            slantString;
 
499
 
 
500
#ifndef KFI_FC_NO_WIDTHS
 
501
    if(KFI_NULL_SETTING!=width)
 
502
        widthString=widthStr(width);
 
503
#endif
 
504
 
 
505
    if(KFI_NULL_SETTING!=slant)
 
506
        slantString=slantStr(slant);
 
507
 
 
508
    //
 
509
    // If weight is "Regular", we only want to display it if slant and width are empty.
 
510
    if(KFI_NULL_SETTING!=weight)
 
511
    {
 
512
        weightString=weightStr(weight, !slantString.isEmpty() || !widthString.isEmpty());
 
513
 
 
514
        if(!weightString.isEmpty())
 
515
            name=weightString;
 
516
    }
 
517
 
 
518
#ifndef KFI_FC_NO_WIDTHS
 
519
    if(!widthString.isEmpty())
 
520
    {
 
521
        if(!name.isEmpty())
 
522
            name+=QChar(' ');
 
523
        name+=widthString;
 
524
    }
 
525
#endif
 
526
 
 
527
    if(!slantString.isEmpty())
 
528
    {
 
529
        if(!name.isEmpty())
 
530
            name+=QChar(' ');
 
531
        name+=slantString;
 
532
    }
 
533
    return name;
 
534
}
 
535
 
 
536
QString weightStr(int w, bool emptyNormal)
 
537
{
 
538
    switch(weight(w))
 
539
    {
 
540
        case FC_WEIGHT_THIN:
 
541
            return i18n(KFI_WEIGHT_THIN);
 
542
        case FC_WEIGHT_EXTRALIGHT:
 
543
            return i18n(KFI_WEIGHT_EXTRALIGHT);
 
544
        case FC_WEIGHT_LIGHT:
 
545
            return i18n(KFI_WEIGHT_LIGHT);
 
546
        case FC_WEIGHT_MEDIUM:
 
547
#ifdef KFI_DISPLAY_MEDIUM
 
548
            return i18n(KFI_WEIGHT_MEDIUM);
 
549
#endif
 
550
        case FC_WEIGHT_REGULAR:
 
551
            return emptyNormal ? QString() : i18n(KFI_WEIGHT_REGULAR);
 
552
        case FC_WEIGHT_DEMIBOLD:
 
553
            return i18n(KFI_WEIGHT_DEMIBOLD);
 
554
        case FC_WEIGHT_BOLD:
 
555
            return i18n(KFI_WEIGHT_BOLD);
 
556
        case FC_WEIGHT_EXTRABOLD:
 
557
            return i18n(KFI_WEIGHT_EXTRABOLD);
 
558
        default:
 
559
            return i18n(KFI_WEIGHT_BLACK);
 
560
    }
 
561
}
 
562
 
 
563
QString widthStr(int w, bool emptyNormal)
 
564
{
 
565
    switch(width(w))
 
566
    {
 
567
        case KFI_FC_WIDTH_ULTRACONDENSED:
 
568
            return i18n(KFI_WIDTH_ULTRACONDENSED);
 
569
        case KFI_FC_WIDTH_EXTRACONDENSED:
 
570
            return i18n(KFI_WIDTH_EXTRACONDENSED);
 
571
        case KFI_FC_WIDTH_CONDENSED:
 
572
            return i18n(KFI_WIDTH_CONDENSED);
 
573
        case KFI_FC_WIDTH_SEMICONDENSED:
 
574
            return i18n(KFI_WIDTH_SEMICONDENSED);
 
575
        case KFI_FC_WIDTH_NORMAL:
 
576
            return emptyNormal ? QString() : i18n(KFI_WIDTH_NORMAL);
 
577
        case KFI_FC_WIDTH_SEMIEXPANDED:
 
578
            return i18n(KFI_WIDTH_SEMIEXPANDED);
 
579
        case KFI_FC_WIDTH_EXPANDED:
 
580
            return i18n(KFI_WIDTH_EXPANDED);
 
581
        case KFI_FC_WIDTH_EXTRAEXPANDED:
 
582
            return i18n(KFI_WIDTH_EXTRAEXPANDED);
 
583
        default:
 
584
            return i18n(KFI_WIDTH_ULTRAEXPANDED);
 
585
    }
 
586
}
 
587
 
 
588
QString slantStr(int s, bool emptyNormal)
 
589
{
 
590
    switch(slant(s))
 
591
    {
 
592
        case FC_SLANT_OBLIQUE:
 
593
#ifdef KFI_DISPLAY_OBLIQUE
 
594
            return i18n(KFI_SLANT_OBLIQUE);
 
595
#endif
 
596
        case FC_SLANT_ITALIC:
 
597
            return i18n(KFI_SLANT_ITALIC);
 
598
        default:
 
599
            return emptyNormal ? QString() : i18n(KFI_SLANT_ROMAN);
 
600
    }
 
601
}
 
602
 
 
603
QString spacingStr(int s)
 
604
{
 
605
    switch(spacing(s))
 
606
    {
 
607
        case FC_MONO:
 
608
            return i18n(KFI_SPACING_MONO);
 
609
        case FC_CHARCELL:
 
610
            return i18n(KFI_SPACING_CHARCELL);
 
611
        default:
 
612
            return i18n(KFI_SPACING_PROPORTIONAL);
 
613
    }
 
614
}
 
615
 
 
616
bool bitmapsEnabled()
 
617
{
 
618
    //
 
619
    // On some systems, such as KUbuntu, fontconfig is configured to ignore all bitmap fonts.
 
620
    // The following check tries to get a list of installed bitmaps, if it an empty list is returned
 
621
    // it is assumed that bitmaps are disabled.
 
622
 
 
623
    static bool enabled(false);
 
624
    static bool checked(false); // Do not keep on checking!
 
625
 
 
626
    if(!checked)
 
627
    {
 
628
        FcObjectSet *os  = FcObjectSetBuild(FC_FAMILY, (void *)0);
 
629
        FcPattern   *pat = FcPatternBuild(NULL, FC_SCALABLE, FcTypeBool, FcFalse, NULL);
 
630
        FcFontSet   *set = FcFontList(0, pat, os);
 
631
 
 
632
        FcPatternDestroy(pat);
 
633
        FcObjectSetDestroy(os);
 
634
 
 
635
        if (set)
 
636
        {
 
637
            if(set->nfont)
 
638
                enabled=true;
 
639
 
 
640
            FcFontSetDestroy(set);
 
641
        }
 
642
        checked=true;
 
643
    }
 
644
 
 
645
    return enabled;
 
646
}
 
647
 
 
648
}
 
649
 
 
650
}