source: trunk/src/gui/text/qfontdatabase_pm.cpp@ 342

Last change on this file since 342 was 319, checked in by Dmitry A. Kuminov, 16 years ago

gui/text: Leftovers after r318 (note that this revision also removed most Workplace Sans hacks since v0.6 of the font doesn't need them any longer).

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Date Revision Author Id
File size: 26.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** Copyright (C) 2009 netlabs.org. OS/2 parts.
7**
8** This file is part of the QtGui module of the Qt Toolkit.
9**
10** $QT_BEGIN_LICENSE:LGPL$
11** Commercial Usage
12** Licensees holding valid Qt Commercial licenses may use this file in
13** accordance with the Qt Commercial License Agreement provided with the
14** Software or, alternatively, in accordance with the terms contained in
15** a written agreement between you and Nokia.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Nokia gives you certain
26** additional rights. These rights are described in the Nokia Qt LGPL
27** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
28** package.
29**
30** GNU General Public License Usage
31** Alternatively, this file may be used under the terms of the GNU
32** General Public License version 3.0 as published by the Free Software
33** Foundation and appearing in the file LICENSE.GPL included in the
34** packaging of this file. Please review the following information to
35** ensure the GNU General Public License version 3.0 requirements will be
36** met: http://www.gnu.org/copyleft/gpl.html.
37**
38** If you are unsure which license is appropriate for your use, please
39** contact the sales department at [email protected].
40** $QT_END_LICENSE$
41**
42****************************************************************************/
43
44#include "qabstractfileengine.h"
45
46#include "qfontengine_pm_p.h"
47
48#include "qsettings.h"
49#include "qfileinfo.h"
50#include "qdatetime.h"
51#include "qhash.h"
52
53#include <ft2build.h>
54#include FT_FREETYPE_H
55#include FT_TYPES_H
56#include FT_TRUETYPE_TABLES_H
57#include FT_LCD_FILTER_H
58
59QT_BEGIN_NAMESPACE
60
61struct FaceData
62{
63 int index;
64 QString familyName;
65 QtFontStyle::Key styleKey;
66 QList<QFontDatabase::WritingSystem> systems;
67 bool fixedPitch;
68 bool smoothScalable;
69 QList<unsigned short> pixelSizes;
70};
71
72static QDataStream &operator<<(QDataStream &data, const QFontDatabase::WritingSystem &ws)
73{
74 data << (int)ws;
75 return data;
76}
77
78static QDataStream &operator>>(QDataStream &data, QFontDatabase::WritingSystem &ws)
79{
80 data >> (int&)ws;
81 return data;
82}
83
84static QDataStream &operator<<(QDataStream &data, const FaceData &cached)
85{
86 data << cached.familyName;
87 data << cached.styleKey.style << cached.styleKey.weight
88 << cached.styleKey.stretch;
89 data << cached.systems;
90 data << cached.fixedPitch << cached.smoothScalable;
91 data << cached.pixelSizes;
92 return data;
93}
94
95static QDataStream &operator>>(QDataStream &data, FaceData &cached)
96{
97 data >> cached.familyName;
98 uint style;
99 int weight, stretch;
100 data >> style; cached.styleKey.style = style;
101 data >> weight; cached.styleKey.weight = weight;
102 data >> stretch; cached.styleKey.stretch = stretch;
103 data >> cached.systems;
104 data >> cached.fixedPitch >> cached.smoothScalable;
105 data >> cached.pixelSizes;
106 return data;
107}
108
109struct FileData
110{
111 FileData() : seen(false) {}
112 FileData(const QFileInfo &fi, bool s) : fileInfo(fi), seen(s) {}
113
114 QFileInfo fileInfo;
115 bool seen;
116};
117
118typedef QHash<QString, FileData> FontFileHash;
119static FontFileHash knownFontFiles;
120static bool knownFontFilesInitialized = false;
121
122static void populateDatabase(const QString& fam)
123{
124 QFontDatabasePrivate *db = privateDb();
125 if (!db)
126 return;
127
128 QtFontFamily *family = 0;
129 if(!fam.isEmpty()) {
130 family = db->family(fam);
131 if(family)
132 return;
133 } else if (db->count) {
134 return;
135 }
136
137 // we don't recognize foundries on OS/2, use an empty one
138 const QString foundryName;
139
140#ifdef QFONTDATABASE_DEBUG
141 QTime timer;
142 timer.start();
143#endif
144
145 QSettings fontCache(QSettings::UserScope, QLatin1String("Trolltech"));
146 fontCache.beginGroup(QLatin1String("Qt/Fonts/Cache 1.0"));
147
148 if (!knownFontFilesInitialized) {
149 // get the initial list of know font files from the cache (necessary to
150 // detect deleted font files)
151 knownFontFilesInitialized = true;
152 QStringList files = fontCache.childGroups();
153 foreach(QString file, files) {
154 file.replace("|", "/");
155 knownFontFiles.insert(file, FileData());
156 // note that QFileInfo is empty so the file will be considered as
157 // NEW which is necessary for the font to get into the database
158 }
159 } else {
160 // reset the 'seen' flag
161 for (FontFileHash::iterator it = knownFontFiles.begin();
162 it != knownFontFiles.end(); ++it)
163 it.value().seen = false;
164 }
165
166 QList<QFileInfo> fontFiles;
167
168 ULONG bufSize = 0;
169 BOOL ok = PrfQueryProfileSize(HINI_USERPROFILE, "PM_Fonts", 0, &bufSize);
170 Q_ASSERT(ok);
171 if (ok) {
172 char *buffer = new char[bufSize + 1 /*terminating NULL*/];
173 Q_ASSERT(buffer);
174 if (buffer) {
175 ULONG bufLen = PrfQueryProfileString(HINI_USERPROFILE, "PM_Fonts", 0, 0,
176 buffer, bufSize);
177 if (bufLen) {
178 char *key = buffer;
179 while (*key) {
180 ULONG keySize = 0;
181 ok = PrfQueryProfileSize(HINI_USERPROFILE, "PM_Fonts", key,
182 &keySize);
183 if (ok) {
184 QByteArray file(keySize, 0);
185 ULONG keyLen =
186 PrfQueryProfileString(HINI_USERPROFILE, "PM_Fonts", key, 0,
187 file.data(), file.size());
188 file.truncate(keyLen - 1 /*terminating NULL*/);
189 if (!file.isEmpty()) {
190 // FreeType doesn't understand .OFM but understands .PFB
191 if (file.toUpper().endsWith(".OFM")) {
192 file.chop(4);
193 file.append(".PFB");
194 }
195 QFileInfo fileInfo(QFile::decodeName(file));
196 QString fileName = fileInfo.canonicalFilePath().toLower();
197 if (!fileName.isEmpty()) { // file may have been deleted
198 fileInfo.setFile(fileName);
199 // check the in-process file name cache
200 FileData &cached = knownFontFiles[fileName];
201 if (cached.fileInfo.filePath().isEmpty() ||
202 cached.fileInfo.lastModified() != fileInfo.lastModified() ||
203 cached.fileInfo.size() != fileInfo.size()) {
204 // no cache entry or outdated, process it
205 cached.fileInfo = fileInfo;
206 cached.seen = true;
207 fontFiles << fileInfo;
208 FD_DEBUG("populateDatabase: NEW/UPDATED font file %s",
209 qPrintable(fileName));
210 } else {
211 // just set the 'seen' flag and skip this font
212 // (it's already in the database)
213 knownFontFiles[fileName].seen = true;
214 FD_DEBUG("populateDatabase: UNCHANGED font file %s",
215 qPrintable(fileName));
216 }
217 }
218 }
219 }
220 key += strlen(key) + 1;
221 }
222 }
223 delete buffer;
224 }
225 }
226
227 extern FT_Library qt_getFreetype(); // qfontengine_ft.cpp
228 FT_Library lib = qt_getFreetype();
229
230 // go through each font file and get available faces
231 foreach(const QFileInfo &fileInfo, fontFiles) {
232 QString fileKey = fileInfo.absoluteFilePath().toLower();
233 QByteArray file = QFile::encodeName(fileKey);
234
235 // QSettings uses / for splitting into groups, suppress it
236 fileKey.replace("/", "|");
237
238 QList<FaceData> cachedFaces;
239
240 // first, look up the cached data
241 fontCache.beginGroup(fileKey);
242
243 if (fontCache.value(QLatin1String("DateTime")).toDateTime() != fileInfo.lastModified() ||
244 fontCache.value(QLatin1String("Size")).toUInt() != fileInfo.size()) {
245 // the cache is outdated or doesn't exist, query the font file
246
247 FT_Long numFaces = 0;
248 FT_Face face;
249
250 FT_Error rc = FT_New_Face(lib, file, -1, &face);
251 if (rc == 0) {
252 numFaces = face->num_faces;
253 FT_Done_Face(face);
254 } else {
255 // invalid/unsupported font file, numFaces is left 0 so that
256 // only DateTime and Size will be cached indicating that this
257 // file is not recognized
258 }
259
260 FD_DEBUG("populateDatabase: Font file %s: FT error %d, has %ld faces",
261 file.constData(), (int) rc, numFaces);
262
263 // go throuhg each face
264 for (FT_Long idx = 0; idx < numFaces; ++idx) {
265 rc = FT_New_Face(lib, file, idx, &face);
266 if (rc != 0)
267 continue;
268
269 FaceData cached;
270
271 cached.index = idx;
272 cached.familyName = QString::fromLatin1(face->family_name);
273
274 // familyName may contain extra spaces (at least this is true for
275 // TNR.PFB that is reported as "Times New Roman ". Trim them.
276 cached.familyName = cached.familyName.trimmed();
277
278 cached.styleKey.style = face->style_flags & FT_STYLE_FLAG_ITALIC ?
279 QFont::StyleItalic : QFont::StyleNormal;
280
281 TT_OS2 *os2_table = 0;
282 if (face->face_flags & FT_FACE_FLAG_SFNT) {
283 os2_table = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
284 }
285 if (os2_table) {
286 // map weight and width values
287 if (os2_table->usWeightClass < 400)
288 cached.styleKey.weight = QFont::Light;
289 else if (os2_table->usWeightClass < 600)
290 cached.styleKey.weight = QFont::Normal;
291 else if (os2_table->usWeightClass < 700)
292 cached.styleKey.weight = QFont::DemiBold;
293 else if (os2_table->usWeightClass < 800)
294 cached.styleKey.weight = QFont::Bold;
295 else
296 cached.styleKey.weight = QFont::Black;
297
298 switch (os2_table->usWidthClass) {
299 case 1: cached.styleKey.stretch = QFont::UltraCondensed; break;
300 case 2: cached.styleKey.stretch = QFont::ExtraCondensed; break;
301 case 3: cached.styleKey.stretch = QFont::Condensed; break;
302 case 4: cached.styleKey.stretch = QFont::SemiCondensed; break;
303 case 5: cached.styleKey.stretch = QFont::Unstretched; break;
304 case 6: cached.styleKey.stretch = QFont::SemiExpanded; break;
305 case 7: cached.styleKey.stretch = QFont::Expanded; break;
306 case 8: cached.styleKey.stretch = QFont::ExtraExpanded; break;
307 case 9: cached.styleKey.stretch = QFont::UltraExpanded; break;
308 default: cached.styleKey.stretch = QFont::Unstretched; break;
309 }
310
311 quint32 unicodeRange[4] = {
312 os2_table->ulUnicodeRange1, os2_table->ulUnicodeRange2,
313 os2_table->ulUnicodeRange3, os2_table->ulUnicodeRange4
314 };
315 quint32 codePageRange[2] = {
316 os2_table->ulCodePageRange1, os2_table->ulCodePageRange2
317 };
318 cached.systems =
319 determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
320 } else {
321 // we've only got simple weight information and no stretch
322 cached.styleKey.weight = face->style_flags & FT_STYLE_FLAG_BOLD ?
323 QFont::Bold : QFont::Normal;
324 cached.styleKey.stretch = QFont::Unstretched;
325 }
326
327 cached.fixedPitch = face->face_flags & FT_FACE_FLAG_FIXED_WIDTH;
328
329 cached.smoothScalable = face->face_flags & FT_FACE_FLAG_SCALABLE;
330
331 // the font may both be scalable and contain fixed size bitmaps
332 if (face->face_flags & FT_FACE_FLAG_FIXED_SIZES) {
333 for (FT_Int i = 0; i < face->num_fixed_sizes; ++i) {
334 cached.pixelSizes << face->available_sizes[i].height;
335 }
336 }
337
338 cachedFaces << cached;
339
340 FT_Done_Face(face);
341 }
342
343 // store the data into the cache
344 fontCache.setValue(QLatin1String("DateTime"), fileInfo.lastModified());
345 fontCache.setValue(QLatin1String("Size"), fileInfo.size());
346 foreach(FaceData cached, cachedFaces) {
347 QByteArray rawData;
348 QDataStream data(&rawData, QIODevice::WriteOnly);
349 data << cached;
350
351 QString face = QString::number(cached.index);
352 fontCache.beginGroup(face);
353 fontCache.setValue(QLatin1String("Info"), rawData);
354 fontCache.endGroup();
355 }
356 } else {
357 // take the face data from the cache
358
359 QStringList faces = fontCache.childGroups();
360
361 FD_DEBUG("populateDatabase: Font file %s: IN CACHE, has %d faces",
362 file.constData(), faces.count());
363
364 foreach(QString face, faces) {
365 bool ok = false;
366 FaceData cached;
367 cached.index = face.toInt(&ok);
368 if (!ok || cached.index < 0) // not a valid index
369 continue;
370
371 fontCache.beginGroup(face);
372 QByteArray rawData =
373 fontCache.value(QLatin1String("Info")).toByteArray();
374 QDataStream data(rawData);
375 data >> cached;
376 fontCache.endGroup();
377
378 cachedFaces << cached;
379 }
380 }
381
382 fontCache.endGroup();
383
384 // go throuhg each cached face and add it to the database
385 foreach(FaceData cached, cachedFaces) {
386
387 QtFontFamily *family = privateDb()->family(cached.familyName, true);
388
389 // @todo is it possible that the same family is both fixed and not?
390 Q_ASSERT(!family->fixedPitch || cached.fixedPitch);
391 family->fixedPitch = cached.fixedPitch;
392
393 if (cached.systems.isEmpty()) {
394 // it was hard or impossible to determine the actual writing system
395 // of the font (as in case of OS/2 bitmap and PFB fonts for which it is
396 // usually simply reported that they support standard/system codepages).
397 // Pretend that we support all writing systems to not miss the one.
398 //
399 // @todo find a proper way to detect actual supported scripts to make
400 // sure these fonts are not matched for scripts they don't support.
401 for (int ws = 0; ws < QFontDatabase::WritingSystemsCount; ++ws)
402 family->writingSystems[ws] = QtFontFamily::Supported;
403 } else {
404 for (int i = 0; i < cached.systems.count(); ++i)
405 family->writingSystems[cached.systems.at(i)] = QtFontFamily::Supported;
406 }
407
408 QtFontFoundry *foundry = family->foundry(foundryName, true);
409 QtFontStyle *style = foundry->style(cached.styleKey, true);
410
411 // so far, all recognized fonts are antialiased
412 style->antialiased = true;
413
414 if (cached.smoothScalable && !style->smoothScalable) {
415 // add new scalable style only if it hasn't been already added --
416 // the first one of two duplicate (in Qt terms) non-bitmap font
417 // styles wins.
418 style->smoothScalable = true;
419 QtFontSize *size =
420 style->pixelSize(SMOOTH_SCALABLE, true);
421 size->fileName = file;
422 size->fileIndex = cached.index;
423 size->systems = cached.systems;
424 }
425
426 foreach(unsigned short pixelSize, cached.pixelSizes) {
427 QtFontSize *size = style->pixelSize(pixelSize, true);
428 // the first bitmap style with a given pixel and point size wins
429 if (!size->fileName.isEmpty())
430 continue;
431 size->fileName = file;
432 size->fileIndex = cached.index;
433 size->systems = cached.systems;
434 }
435 }
436 }
437
438 // go through the known file list to detect what files have been removed
439 for (FontFileHash::iterator it = knownFontFiles.begin();
440 it != knownFontFiles.end();) {
441 if (!it.value().seen) {
442 FD_DEBUG("populateDatabase: DELETED font file %s",
443 qPrintable(it.key()));
444 // remove from the both caches
445 QString fileKey = it.key();
446 fileKey.replace("/", "|");
447 fontCache.remove(fileKey);
448 it = knownFontFiles.erase(it);
449 // @todo should we remove all references to this file from the
450 // font database? My concern is that this font may be in use by Qt
451 // and its glyphs may be still cached when file deletion happens
452 } else {
453 ++it;
454 }
455 }
456
457#ifdef QFONTDATABASE_DEBUG
458 FD_DEBUG("populateDatabase: took %d ms", timer.elapsed());
459#endif
460}
461
462static void initializeDb()
463{
464 QFontDatabasePrivate *db = privateDb();
465 if (!db || db->count)
466 return;
467
468 populateDatabase(QString());
469
470#ifdef QFONTDATABASE_DEBUG
471 // print the database
472 qDebug("initializeDb:");
473 for (int f = 0; f < db->count; f++) {
474 QtFontFamily *family = db->families[f];
475 qDebug(" %s: %p", qPrintable(family->name), family);
476 populateDatabase(family->name);
477#if 1
478 qDebug(" writing systems supported:");
479 QStringList systems;
480 for (int ws = 0; ws < QFontDatabase::WritingSystemsCount; ++ws)
481 if (family->writingSystems[ws] & QtFontFamily::Supported)
482 systems << QFontDatabase::writingSystemName((QFontDatabase::WritingSystem)ws);
483 qDebug() << " " << systems;
484 for (int fd = 0; fd < family->count; fd++) {
485 QtFontFoundry *foundry = family->foundries[fd];
486 qDebug(" %s", foundry->name.isEmpty() ? "(empty foundry)" :
487 qPrintable(foundry->name));
488 for (int s = 0; s < foundry->count; s++) {
489 QtFontStyle *style = foundry->styles[s];
490 qDebug(" style: style=%d weight=%d smooth=%d", style->key.style,
491 style->key.weight, style->smoothScalable);
492 for(int i = 0; i < style->count; ++i) {
493 if (style->pixelSizes[i].pixelSize == SMOOTH_SCALABLE)
494 qDebug(" smooth %s:%d",
495 style->pixelSizes[i].fileName.constData(),
496 style->pixelSizes[i].fileIndex);
497 else
498 qDebug(" %d px %s:%d", style->pixelSizes[i].pixelSize,
499 style->pixelSizes[i].fileName.constData(),
500 style->pixelSizes[i].fileIndex);
501 }
502 }
503 }
504#endif
505 }
506#endif // QFONTDATABASE_DEBUG
507}
508
509static inline void load(const QString &family = QString(), int = -1)
510{
511 populateDatabase(family);
512}
513
514static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
515{
516 // @todo implement
517}
518
519static QFontDef fontDescToFontDef(const QFontDef &req, const QtFontDesc &desc)
520{
521 static LONG dpi = -1;
522 if (dpi == -1) {
523 // PM cannot change resolutions on the fly so cache it
524 int hps = qt_display_ps();
525 DevQueryCaps(GpiQueryDevice(hps), CAPS_HORIZONTAL_FONT_RES, 1, &dpi);
526 }
527
528 QFontDef fontDef;
529
530 fontDef.family = desc.family->name;
531
532 if (desc.size->pixelSize == SMOOTH_SCALABLE) {
533 // scalable font matched, calculate the missing size (points or pixels)
534 fontDef.pointSize = req.pointSize;
535 fontDef.pixelSize = req.pixelSize;
536 if (req.pointSize < 0) {
537 fontDef.pointSize = req.pixelSize * 72. / dpi;
538 } else if (req.pixelSize == -1) {
539 fontDef.pixelSize = qRound(req.pointSize * dpi / 72.);
540 }
541 } else {
542 // non-scalable font matched, calculate both point and pixel size
543 fontDef.pixelSize = desc.size->pixelSize;
544 fontDef.pointSize = desc.size->pixelSize * 72. / dpi;
545 }
546
547 fontDef.styleStrategy = req.styleStrategy;
548 fontDef.styleHint = req.styleHint;
549
550 fontDef.weight = desc.style->key.weight;
551 fontDef.fixedPitch = desc.family->fixedPitch;
552 fontDef.style = desc.style->key.style;
553 fontDef.stretch = desc.style->key.stretch;
554
555 return fontDef;
556}
557
558static QFontEngine *loadEngine(const QFontDef &req, const QtFontDesc &desc)
559{
560 // @todo all these fixed so far; make configurable through the Registry
561 // on per-family basis
562 QFontEnginePMFT::HintStyle hintStyle = QFontEnginePMFT::HintFull;
563 bool autoHint = true;
564 QFontEngineFT::SubpixelAntialiasingType subPixel = QFontEngineFT::Subpixel_None;
565 int lcdFilter = FT_LCD_FILTER_DEFAULT;
566 bool useEmbeddedBitmap = true;
567
568 QFontEngine::FaceId faceId;
569 faceId.filename = desc.size->fileName;
570 faceId.index = desc.size->fileIndex;
571
572 QFontEngineFT *fe = new QFontEnginePMFT(fontDescToFontDef(req, desc), faceId,
573 desc.style->antialiased, hintStyle,
574 autoHint, subPixel, lcdFilter,
575 useEmbeddedBitmap);
576 Q_ASSERT(fe);
577 if (fe && fe->invalid()) {
578 FM_DEBUG(" --> invalid!\n");
579 delete fe;
580 fe = 0;
581 }
582 return fe;
583}
584
585static QFontEngine *loadPM(const QFontPrivate *d, int script, const QFontDef &req)
586{
587 // list of families to try
588 QStringList families = familyList(req);
589
590 const char *styleHint = qt_fontFamilyFromStyleHint(d->request);
591 if (styleHint)
592 families << QLatin1String(styleHint);
593
594 // add the default family
595 QString defaultFamily = QApplication::font().family();
596 if (! families.contains(defaultFamily))
597 families << defaultFamily;
598
599 // add QFont::defaultFamily() to the list, for compatibility with
600 // previous versions
601 families << QApplication::font().defaultFamily();
602
603 // null family means find the first font matching the specified script
604 families << QString();
605
606 QtFontDesc desc;
607 QFontEngine *fe = 0;
608 QList<int> blacklistedFamilies;
609
610 while (!fe) {
611 for (int i = 0; i < families.size(); ++i) {
612 QString family, foundry;
613 parseFontName(families.at(i), foundry, family);
614 FM_DEBUG("loadPM: >>>>>>>>>>>>>> trying to match '%s'", qPrintable(family));
615 QT_PREPEND_NAMESPACE(match)(script, req, family, foundry, -1, &desc, blacklistedFamilies);
616 if (desc.family)
617 break;
618 }
619 if (!desc.family)
620 break;
621 FM_DEBUG("loadPM: ============== matched '%s'", qPrintable(desc.family->name));
622 fe = loadEngine(req, desc);
623 if (!fe)
624 blacklistedFamilies.append(desc.familyIndex);
625 }
626 return fe;
627}
628
629void QFontDatabase::load(const QFontPrivate *d, int script)
630{
631 Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
632
633 // normalize the request to get better caching
634 QFontDef req = d->request;
635 if (req.pixelSize <= 0)
636 req.pixelSize = qMax(1, qRound(req.pointSize * d->dpi / 72.));
637 req.pointSize = 0;
638 if (req.weight == 0)
639 req.weight = QFont::Normal;
640 if (req.stretch == 0)
641 req.stretch = 100;
642
643 // @todo a hack to substitute "WarpSans" with "Workplace Sans". Remove this
644 // when we start supporting OS/2 bitmap fonts.
645 if (req.family == QLatin1String("WarpSans"))
646 req.family = QLatin1String("Workplace Sans");
647
648 QFontCache::Key key(req, d->rawMode ? QUnicodeTables::Common : script, d->screen);
649 if (!d->engineData)
650 getEngineData(d, key);
651
652 // the cached engineData could have already loaded the engine we want
653 if (d->engineData->engines[script])
654 return;
655
656 // set it to the actual pointsize, so QFontInfo will do the right thing
657 req.pointSize = req.pixelSize * 72. / d->dpi;
658
659 QFontEngine *fe = QFontCache::instance()->findEngine(key);
660
661 if (!fe) {
662 if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) {
663 fe = new QTestFontEngine(req.pixelSize);
664 fe->fontDef = req;
665 } else {
666 QMutexLocker locker(fontDatabaseMutex());
667 if (!privateDb()->count)
668 initializeDb();
669 fe = loadPM(d, script, req);
670 }
671 if (!fe) {
672 fe = new QFontEngineBox(req.pixelSize);
673 fe->fontDef = QFontDef();
674 }
675 }
676 if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
677 for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
678 if (!d->engineData->engines[i]) {
679 d->engineData->engines[i] = fe;
680 fe->ref.ref();
681 }
682 }
683 } else {
684 d->engineData->engines[script] = fe;
685 fe->ref.ref();
686 }
687 QFontCache::instance()->insertEngine(key, fe);
688}
689
690bool QFontDatabase::removeApplicationFont(int handle)
691{
692 // @todo implement
693 return false;
694}
695
696bool QFontDatabase::removeAllApplicationFonts()
697{
698 // @todo implement
699 return false;
700}
701
702bool QFontDatabase::supportsThreadedFontRendering()
703{
704 // @todo implement
705 return false;
706}
707
708QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.