1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
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 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qplatformfontdatabase.h"
41 #include <QtGui/private/qfontengine_p.h>
42 #include <QtGui/private/qfontengine_qpf2_p.h>
43 #include <QtGui/QGuiApplication>
44 #include <QtGui/QScreen>
45 #include <qpa/qplatformscreen.h>
46 #include <QtCore/QLibraryInfo>
47 #include <QtCore/QDir>
48 #include <QtCore/QMetaEnum>
49 
50 #include <algorithm>
51 #include <iterator>
52 
53 QT_BEGIN_NAMESPACE
54 
55 void qt_registerFont(const QString &familyname, const QString &stylename,
56                      const QString &foundryname, int weight,
57                      QFont::Style style, int stretch, bool antialiased,
58                      bool scalable, int pixelSize, bool fixedPitch,
59                      const QSupportedWritingSystems &writingSystems, void *hanlde);
60 
61 void qt_registerFontFamily(const QString &familyName);
62 void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
63 bool qt_isFontFamilyPopulated(const QString &familyName);
64 
65 /*!
66     Registers the pre-rendered QPF2 font contained in the given \a dataArray.
67 
68     \sa registerFont()
69 */
registerQPF2Font(const QByteArray & dataArray,void * handle)70 void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle)
71 {
72     if (dataArray.size() == 0)
73         return;
74 
75     const uchar *data = reinterpret_cast<const uchar *>(dataArray.constData());
76     if (QFontEngineQPF2::verifyHeader(data, dataArray.size())) {
77         QString fontName = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_FontName).toString();
78         int pixelSize = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_PixelSize).toInt();
79         QVariant weight = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_Weight);
80         QVariant style = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_Style);
81         QByteArray writingSystemBits = QFontEngineQPF2::extractHeaderField(data, QFontEngineQPF2::Tag_WritingSystems).toByteArray();
82 
83         if (!fontName.isEmpty() && pixelSize) {
84             QFont::Weight fontWeight = QFont::Normal;
85             if (weight.userType() == QMetaType::Int || weight.userType() == QMetaType::UInt)
86                 fontWeight = QFont::Weight(weight.toInt());
87 
88             QFont::Style fontStyle = static_cast<QFont::Style>(style.toInt());
89 
90             QSupportedWritingSystems writingSystems;
91             for (int i = 0; i < writingSystemBits.count(); ++i) {
92                 uchar currentByte = writingSystemBits.at(i);
93                 for (int j = 0; j < 8; ++j) {
94                     if (currentByte & 1)
95                         writingSystems.setSupported(QFontDatabase::WritingSystem(i * 8 + j));
96                     currentByte >>= 1;
97                 }
98             }
99             QFont::Stretch stretch = QFont::Unstretched;
100             registerFont(fontName,QString(),QString(),fontWeight,fontStyle,stretch,true,false,pixelSize,false,writingSystems,handle);
101         }
102     } else {
103         qDebug("header verification of QPF2 font failed. maybe it is corrupt?");
104     }
105 }
106 
107 /*!
108     Registers a font with the given set of attributes describing the font's
109     foundry, family name, style and stretch information, pixel size, and
110     supported writing systems. Additional information about whether the font
111     can be scaled and antialiased can also be provided.
112 
113     The foundry name and font family are described by \a foundryName and
114     \a familyName. The font weight (light, normal, bold, etc.), style (normal,
115     oblique, italic) and stretch information (condensed, expanded, unstretched,
116     etc.) are specified by \a weight, \a style and \a stretch.
117 
118     Some fonts can be antialiased and scaled; \a scalable and \a antialiased
119     can be set to true for fonts with these attributes. The intended pixel
120     size of non-scalable fonts is specified by \a pixelSize; this value will be
121     ignored for scalable fonts.
122 
123     The writing systems supported by the font are specified by the
124     \a writingSystems argument.
125 
126     \sa registerQPF2Font(), registerFontFamily()
127 */
registerFont(const QString & familyname,const QString & stylename,const QString & foundryname,QFont::Weight weight,QFont::Style style,QFont::Stretch stretch,bool antialiased,bool scalable,int pixelSize,bool fixedPitch,const QSupportedWritingSystems & writingSystems,void * usrPtr)128 void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &stylename,
129                                          const QString &foundryname, QFont::Weight weight,
130                                          QFont::Style style, QFont::Stretch stretch, bool antialiased,
131                                          bool scalable, int pixelSize, bool fixedPitch,
132                                          const QSupportedWritingSystems &writingSystems, void *usrPtr)
133 {
134     if (scalable)
135         pixelSize = 0;
136 
137     qt_registerFont(familyname, stylename, foundryname, weight, style,
138                     stretch, antialiased, scalable, pixelSize,
139                     fixedPitch, writingSystems, usrPtr);
140 }
141 
142 /*!
143     Registers a font family with the font database. The font will be
144     lazily populated by a callback to populateFamily() when the font
145     database determines that the family needs population.
146 
147     \sa populateFamily(), registerFont()
148 */
registerFontFamily(const QString & familyName)149 void QPlatformFontDatabase::registerFontFamily(const QString &familyName)
150 {
151     qt_registerFontFamily(familyName);
152 }
153 
154 class QWritingSystemsPrivate
155 {
156 public:
QWritingSystemsPrivate()157     QWritingSystemsPrivate()
158         : ref(1)
159         , vector(QFontDatabase::WritingSystemsCount,false)
160     {
161     }
162 
QWritingSystemsPrivate(const QWritingSystemsPrivate * other)163     QWritingSystemsPrivate(const QWritingSystemsPrivate *other)
164         : ref(1)
165         , vector(other->vector)
166     {
167     }
168 
169     QAtomicInt ref;
170     QVector<bool> vector;
171 };
172 
173 /*!
174     Constructs a new object to handle supported writing systems.
175 */
QSupportedWritingSystems()176 QSupportedWritingSystems::QSupportedWritingSystems()
177 {
178     d = new QWritingSystemsPrivate;
179 }
180 
181 /*!
182     Constructs a copy of the \a other writing systems object.
183 */
QSupportedWritingSystems(const QSupportedWritingSystems & other)184 QSupportedWritingSystems::QSupportedWritingSystems(const QSupportedWritingSystems &other)
185 {
186     d = other.d;
187     d->ref.ref();
188 }
189 
190 /*!
191     Constructs a copy of the \a other writing systems object.
192 */
operator =(const QSupportedWritingSystems & other)193 QSupportedWritingSystems &QSupportedWritingSystems::operator=(const QSupportedWritingSystems &other)
194 {
195     if (d != other.d) {
196         other.d->ref.ref();
197         if (!d->ref.deref())
198             delete d;
199         d = other.d;
200     }
201     return *this;
202 }
203 
204 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug debug,const QSupportedWritingSystems & sws)205 QDebug operator<<(QDebug debug, const QSupportedWritingSystems &sws)
206 {
207     QMetaObject mo = QFontDatabase::staticMetaObject;
208     QMetaEnum me = mo.enumerator(mo.indexOfEnumerator("WritingSystem"));
209 
210     QDebugStateSaver saver(debug);
211     debug.nospace() << "QSupportedWritingSystems(";
212     int i = sws.d->vector.indexOf(true);
213     while (i > 0) {
214         debug << me.valueToKey(i);
215         i = sws.d->vector.indexOf(true, i + 1);
216         if (i > 0)
217             debug << ", ";
218     }
219     debug << ")";
220     return debug;
221 }
222 #endif
223 
224 /*!
225     Destroys the supported writing systems object.
226 */
~QSupportedWritingSystems()227 QSupportedWritingSystems::~QSupportedWritingSystems()
228 {
229     if (!d->ref.deref())
230         delete d;
231 }
232 
233 /*!
234     \internal
235 */
detach()236 void QSupportedWritingSystems::detach()
237 {
238     if (d->ref.loadRelaxed() != 1) {
239         QWritingSystemsPrivate *newd = new QWritingSystemsPrivate(d);
240         if (!d->ref.deref())
241             delete d;
242         d = newd;
243     }
244 }
245 
246 /*!
247     Sets or clears support for the specified \a writingSystem based on the
248     value given by \a support.
249 */
setSupported(QFontDatabase::WritingSystem writingSystem,bool support)250 void QSupportedWritingSystems::setSupported(QFontDatabase::WritingSystem writingSystem, bool support)
251 {
252     detach();
253     d->vector[writingSystem] = support;
254 }
255 
256 /*!
257     Returns \c true if the writing system specified by \a writingSystem is
258     supported; otherwise returns \c false.
259 */
supported(QFontDatabase::WritingSystem writingSystem) const260 bool QSupportedWritingSystems::supported(QFontDatabase::WritingSystem writingSystem) const
261 {
262     return d->vector.at(writingSystem);
263 }
264 
265 /*!
266     \class QSupportedWritingSystems
267     \brief The QSupportedWritingSystems class is used when registering fonts with the internal Qt
268     fontdatabase.
269     \ingroup painting
270     \inmodule QtGui
271 
272     Its to provide an easy to use interface for indicating what writing systems a specific font
273     supports.
274 
275 */
276 
277 /*!
278     \internal
279  */
~QPlatformFontDatabase()280 QPlatformFontDatabase::~QPlatformFontDatabase()
281 {
282 }
283 
284 /*!
285   This function is called once at startup by Qt's internal font database.
286   Reimplement this function in a subclass for a convenient place to initialize
287   the internal font database.
288 
289   You may lazily populate the database by calling registerFontFamily() instead
290   of registerFont(), in which case you'll get a callback to populateFamily()
291   when the required family needs population. You then call registerFont() to
292   finish population of the family.
293 
294   The default implementation looks in the fontDir() location and registers all
295   QPF2 fonts.
296 */
populateFontDatabase()297 void QPlatformFontDatabase::populateFontDatabase()
298 {
299     QString fontpath = fontDir();
300     if(!QFile::exists(fontpath)) {
301         qWarning("QFontDatabase: Cannot find font directory '%s' - is Qt installed correctly?",
302                  qPrintable(QDir::toNativeSeparators(fontpath)));
303         return;
304     }
305 
306     QDir dir(fontpath);
307     dir.setNameFilters(QStringList() << QLatin1String("*.qpf2"));
308     dir.refresh();
309     for (int i = 0; i < int(dir.count()); ++i) {
310         const QByteArray fileName = QFile::encodeName(dir.absoluteFilePath(dir[i]));
311         QFile file(QString::fromLocal8Bit(fileName));
312         if (file.open(QFile::ReadOnly)) {
313             const QByteArray fileData = file.readAll();
314             QByteArray *fileDataPtr = new QByteArray(fileData);
315             registerQPF2Font(fileData, fileDataPtr);
316         }
317     }
318 }
319 
320 /*!
321     This function is called whenever a lazily populated family, populated
322     through registerFontFamily(), needs full population.
323 
324     You are expected to fully populate the family by calling registerFont()
325     for each font that matches the family name.
326 */
populateFamily(const QString & familyName)327 void QPlatformFontDatabase::populateFamily(const QString &familyName)
328 {
329     Q_UNUSED(familyName);
330 }
331 
332 /*!
333     This function is called whenever the font database is invalidated.
334 
335     Reimplement this function to clear any internal data structures that
336     will need to be rebuilt at the next call to populateFontDatabase().
337 */
invalidate()338 void QPlatformFontDatabase::invalidate()
339 {
340 }
341 
342 /*!
343     Returns a multi font engine in the specified \a script to encapsulate \a fontEngine with the
344     option to fall back to the fonts given by \a fallbacks if \a fontEngine does not support
345     a certain character.
346 */
fontEngineMulti(QFontEngine * fontEngine,QChar::Script script)347 QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
348 {
349     return new QFontEngineMulti(fontEngine, script);
350 }
351 
352 /*!
353     Returns the font engine that can be used to render the font described by
354     the font definition, \a fontDef, in the specified \a script.
355 */
fontEngine(const QFontDef & fontDef,void * handle)356 QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
357 {
358     QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
359     QFontEngineQPF2 *engine = new QFontEngineQPF2(fontDef,*fileDataPtr);
360     //qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family;
361     return engine;
362 }
363 
fontEngine(const QByteArray & fontData,qreal pixelSize,QFont::HintingPreference hintingPreference)364 QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
365                                                QFont::HintingPreference hintingPreference)
366 {
367     Q_UNUSED(fontData);
368     Q_UNUSED(pixelSize);
369     Q_UNUSED(hintingPreference);
370     qWarning("This plugin does not support font engines created directly from font data");
371     return nullptr;
372 }
373 
374 /*!
375     Adds an application font described by the font contained supplied \a fontData
376     or using the font contained in the file referenced by \a fileName. Returns
377     a list of family names, or an empty list if the font could not be added.
378 
379     \note The default implementation of this function does not add an application
380     font. Subclasses should reimplement this function to perform the necessary
381     loading and registration of fonts.
382 */
addApplicationFont(const QByteArray & fontData,const QString & fileName)383 QStringList QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
384 {
385     Q_UNUSED(fontData);
386     Q_UNUSED(fileName);
387 
388     qWarning("This plugin does not support application fonts");
389     return QStringList();
390 }
391 
392 /*!
393     Releases the specified font \a handle.
394 */
releaseHandle(void * handle)395 void QPlatformFontDatabase::releaseHandle(void *handle)
396 {
397     QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
398     delete fileDataPtr;
399 }
400 
401 /*!
402     Returns the directory containing the fonts used by the database.
403 */
fontDir() const404 QString QPlatformFontDatabase::fontDir() const
405 {
406     QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QPA_FONTDIR"));
407     if (fontpath.isEmpty())
408         fontpath = QLibraryInfo::location(QLibraryInfo::LibrariesPath) + QLatin1String("/fonts");
409 
410     return fontpath;
411 }
412 
413 /*!
414     Returns true if the font family is private. For any given family name,
415     the result is platform dependent.
416 */
isPrivateFontFamily(const QString & family) const417 bool QPlatformFontDatabase::isPrivateFontFamily(const QString &family) const
418 {
419     Q_UNUSED(family);
420     return false;
421 }
422 
423 /*!
424     Returns the default system font.
425 
426     \sa QGuiApplication::font()
427     \since 5.0
428 */
429 
defaultFont() const430 QFont QPlatformFontDatabase::defaultFont() const
431 {
432     return QFont(QLatin1String("Helvetica"));
433 }
434 
435 
436 QString qt_resolveFontFamilyAlias(const QString &alias);
437 
438 /*!
439     Resolve alias to actual font family names.
440 
441     \since 5.0
442  */
resolveFontFamilyAlias(const QString & family) const443 QString QPlatformFontDatabase::resolveFontFamilyAlias(const QString &family) const
444 {
445     return qt_resolveFontFamilyAlias(family);
446 }
447 
448 /*!
449     Return true if all fonts are considered scalable when using this font database.
450     Defaults to false.
451 
452     \since 5.0
453  */
454 
fontsAlwaysScalable() const455 bool QPlatformFontDatabase::fontsAlwaysScalable() const
456 {
457     return false;
458 }
459 
460 /*!
461     Return list of standard font sizes when using this font database.
462 
463     \since 5.0
464  */
465 
standardSizes() const466  QList<int> QPlatformFontDatabase::standardSizes() const
467 {
468     QList<int> ret;
469     static const quint8 standard[] =
470         { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72 };
471     static const int num_standards = int(sizeof standard / sizeof *standard);
472     ret.reserve(num_standards);
473     std::copy(standard, standard + num_standards, std::back_inserter(ret));
474     return ret;
475 }
476 
477 // ### copied to tools/makeqpf/qpf2.cpp
478 
479 // see the Unicode subset bitfields in the MSDN docs
480 static const quint8 requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
481     { 127, 127 }, // Any
482     { 0, 127 },   // Latin
483     { 7, 127 },   // Greek
484     { 9, 127 },   // Cyrillic
485     { 10, 127 },  // Armenian
486     { 11, 127 },  // Hebrew
487     { 13, 127 },  // Arabic
488     { 71, 127 },  // Syriac
489     { 72, 127 },  // Thaana
490     { 15, 127 },  // Devanagari
491     { 16, 127 },  // Bengali
492     { 17, 127 },  // Gurmukhi
493     { 18, 127 },  // Gujarati
494     { 19, 127 },  // Oriya
495     { 20, 127 },  // Tamil
496     { 21, 127 },  // Telugu
497     { 22, 127 },  // Kannada
498     { 23, 127 },  // Malayalam
499     { 73, 127 },  // Sinhala
500     { 24, 127 },  // Thai
501     { 25, 127 },  // Lao
502     { 70, 127 },  // Tibetan
503     { 74, 127 },  // Myanmar
504     { 26, 127 },  // Georgian
505     { 80, 127 },  // Khmer
506     { 126, 127 }, // SimplifiedChinese
507     { 126, 127 }, // TraditionalChinese
508     { 126, 127 }, // Japanese
509     { 56, 127 },  // Korean
510     { 0, 127 },   // Vietnamese (same as latin1)
511     { 126, 127 }, // Other
512     { 78, 127 },  // Ogham
513     { 79, 127 },  // Runic
514     { 14, 127 },  // Nko
515 };
516 
517 enum CsbBits {
518     Latin1CsbBit = 0,
519     CentralEuropeCsbBit = 1,
520     TurkishCsbBit = 4,
521     BalticCsbBit = 7,
522     CyrillicCsbBit = 2,
523     GreekCsbBit = 3,
524     HebrewCsbBit = 5,
525     ArabicCsbBit = 6,
526     VietnameseCsbBit = 8,
527     SimplifiedChineseCsbBit = 18,
528     TraditionalChineseCsbBit = 20,
529     ThaiCsbBit = 16,
530     JapaneseCsbBit = 17,
531     KoreanCsbBit = 19,
532     KoreanJohabCsbBit = 21,
533     SymbolCsbBit = 31
534 };
535 
536 /*!
537     Helper function that determines the writing systems support by a given
538     \a unicodeRange and \a codePageRange.
539 
540     \since 5.1
541 */
writingSystemsFromTrueTypeBits(quint32 unicodeRange[4],quint32 codePageRange[2])542 QSupportedWritingSystems QPlatformFontDatabase::writingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2])
543 {
544     QSupportedWritingSystems writingSystems;
545 
546     bool hasScript = false;
547     for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
548         int bit = requiredUnicodeBits[i][0];
549         int index = bit/32;
550         int flag = 1 << (bit&31);
551         if (bit != 126 && (unicodeRange[index] & flag)) {
552             bit = requiredUnicodeBits[i][1];
553             index = bit/32;
554 
555             flag = 1 << (bit&31);
556             if (bit == 127 || (unicodeRange[index] & flag)) {
557                 writingSystems.setSupported(QFontDatabase::WritingSystem(i));
558                 hasScript = true;
559                 // qDebug("font %s: index=%d, flag=%8x supports script %d", familyName.latin1(), index, flag, i);
560             }
561         }
562     }
563     if (codePageRange[0] & ((1 << Latin1CsbBit) | (1 << CentralEuropeCsbBit) | (1 << TurkishCsbBit) | (1 << BalticCsbBit))) {
564         writingSystems.setSupported(QFontDatabase::Latin);
565         hasScript = true;
566         //qDebug("font %s supports Latin", familyName.latin1());
567     }
568     if (codePageRange[0] & (1 << CyrillicCsbBit)) {
569         writingSystems.setSupported(QFontDatabase::Cyrillic);
570         hasScript = true;
571         //qDebug("font %s supports Cyrillic", familyName.latin1());
572     }
573     if (codePageRange[0] & (1 << GreekCsbBit)) {
574         writingSystems.setSupported(QFontDatabase::Greek);
575         hasScript = true;
576         //qDebug("font %s supports Greek", familyName.latin1());
577     }
578     if (codePageRange[0] & (1 << HebrewCsbBit)) {
579         writingSystems.setSupported(QFontDatabase::Hebrew);
580         hasScript = true;
581         //qDebug("font %s supports Hebrew", familyName.latin1());
582     }
583     if (codePageRange[0] & (1 << ArabicCsbBit)) {
584         writingSystems.setSupported(QFontDatabase::Arabic);
585         hasScript = true;
586         //qDebug("font %s supports Arabic", familyName.latin1());
587     }
588     if (codePageRange[0] & (1 << ThaiCsbBit)) {
589         writingSystems.setSupported(QFontDatabase::Thai);
590         hasScript = true;
591         //qDebug("font %s supports Thai", familyName.latin1());
592     }
593     if (codePageRange[0] & (1 << VietnameseCsbBit)) {
594         writingSystems.setSupported(QFontDatabase::Vietnamese);
595         hasScript = true;
596         //qDebug("font %s supports Vietnamese", familyName.latin1());
597     }
598     if (codePageRange[0] & (1 << SimplifiedChineseCsbBit)) {
599         writingSystems.setSupported(QFontDatabase::SimplifiedChinese);
600         hasScript = true;
601         //qDebug("font %s supports Simplified Chinese", familyName.latin1());
602     }
603     if (codePageRange[0] & (1 << TraditionalChineseCsbBit)) {
604         writingSystems.setSupported(QFontDatabase::TraditionalChinese);
605         hasScript = true;
606         //qDebug("font %s supports Traditional Chinese", familyName.latin1());
607     }
608     if (codePageRange[0] & (1 << JapaneseCsbBit)) {
609         writingSystems.setSupported(QFontDatabase::Japanese);
610         hasScript = true;
611         //qDebug("font %s supports Japanese", familyName.latin1());
612     }
613     if (codePageRange[0] & ((1 << KoreanCsbBit) | (1 << KoreanJohabCsbBit))) {
614         writingSystems.setSupported(QFontDatabase::Korean);
615         hasScript = true;
616         //qDebug("font %s supports Korean", familyName.latin1());
617     }
618     if (codePageRange[0] & (1U << SymbolCsbBit)) {
619         writingSystems = QSupportedWritingSystems();
620         hasScript = false;
621     }
622 
623     if (!hasScript)
624         writingSystems.setSupported(QFontDatabase::Symbol);
625 
626     return writingSystems;
627 }
628 
629 /*!
630     Helper function that returns the Qt font weight matching
631     a given opentype integer value. Converts the integer
632     \a weight (0 ~ 1000) to QFont::Weight and returns it.
633 
634     \since 5.5
635 */
636 
weightFromInteger(int weight)637 QFont::Weight QPlatformFontDatabase::weightFromInteger(int weight)
638 {
639     if (weight < 150)
640         return QFont::Thin;
641     if (weight < 250)
642         return QFont::ExtraLight;
643     if (weight < 350)
644         return QFont::Light;
645     if (weight < 450)
646         return QFont::Normal;
647     if (weight < 550)
648         return QFont::Medium;
649     if (weight < 650)
650         return QFont::DemiBold;
651     if (weight < 750)
652         return QFont::Bold;
653     if (weight < 850)
654         return QFont::ExtraBold;
655     return QFont::Black;
656 }
657 
658 /*!
659     Helper function that register the \a alias for the \a familyName.
660 
661     \since 5.2
662 */
663 
registerAliasToFontFamily(const QString & familyName,const QString & alias)664 void QPlatformFontDatabase::registerAliasToFontFamily(const QString &familyName, const QString &alias)
665 {
666     qt_registerAliasToFontFamily(familyName, alias);
667 }
668 
669 /*!
670     Helper function that returns true if the font family has already been registered and populated.
671 
672     \since 5.14
673 */
isFamilyPopulated(const QString & familyName)674 bool QPlatformFontDatabase::isFamilyPopulated(const QString &familyName)
675 {
676     return qt_isFontFamilyPopulated(familyName);
677 }
678 
679 /*!
680     \class QPlatformFontDatabase
681     \since 5.0
682     \internal
683     \preliminary
684     \ingroup qpa
685     \ingroup painting
686 
687     \brief The QPlatformFontDatabase class makes it possible to customize how fonts
688     are discovered and how they are rendered
689 
690     QPlatformFontDatabase is the superclass which is intended to let platform implementations use
691     native font handling.
692 
693     Qt has its internal font database which it uses to discover available fonts on the
694     user's system. To be able to populate this database subclass this class, and
695     reimplement populateFontDatabase().
696 
697     Use the function registerFont() to populate the internal font database.
698 
699     Sometimes a specified font does not have the required glyphs; in such a case, the
700     fallbackForFamily() function is called automatically to find alternative font
701     families that can supply alternatives to the missing glyphs.
702 
703     \sa QSupportedWritingSystems
704 */
705 QT_END_NAMESPACE
706