Qt 4.8
qfontdatabase_qpa.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qlibraryinfo.h"
43 #include <QtCore/qsettings.h>
44 
45 #include "qfontengine_qpa_p.h"
46 #include "qplatformdefs.h"
47 
48 #include <QtGui/private/qapplication_p.h>
49 #include <QtGui/qplatformfontdatabase_qpa.h>
50 
51 #include <QtCore/qmath.h>
52 
54 
55 Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &foundryname, int weight,
56  QFont::Style style, int stretch, bool antialiased, bool scalable, int pixelSize,
57  const QSupportedWritingSystems &writingSystems, void *handle)
58 {
59  QFontDatabasePrivate *d = privateDb();
60  // qDebug() << "Adding font" << familyname << weight << italic << pixelSize << file << fileIndex << antialiased;
61  QtFontStyle::Key styleKey;
62  styleKey.style = style;
63  styleKey.weight = weight;
64  styleKey.stretch = stretch;
65  QtFontFamily *f = d->family(familyName, true);
66 
67  for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
68  if (writingSystems.supported(QFontDatabase::WritingSystem(i))) {
70  } else {
72  }
73  }
74 
75  QtFontFoundry *foundry = f->foundry(foundryname, true);
76  QtFontStyle *fontStyle = foundry->style(styleKey, QString(), true);
77  fontStyle->smoothScalable = scalable;
78  fontStyle->antialiased = antialiased;
79  QtFontSize *size = fontStyle->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);
80  size->handle = handle;
81 }
82 
84 {
85  QStringList retList = QApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
86  QFontDatabasePrivate *db = privateDb();
87 
89  for (i = retList.begin(); i != retList.end(); ++i) {
90  bool contains = false;
91  for (int j = 0; j < db->count; j++) {
92  QtFontFamily *qtFamily = db->families[j];
93  if (!(i->compare(qtFamily->name,Qt::CaseInsensitive))) {
94  contains = true;
95  break;
96  }
97  }
98  if (!contains) {
99  i = retList.erase(i);
100  i--;
101  }
102  }
103  return retList;
104 }
105 
107 
108 static void initializeDb()
109 {
110  QFontDatabasePrivate *db = privateDb();
111 
112  // init by asking for the platformfontdb for the first time or after invalidation
113  if (!db->count)
114  QApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
115 
116  if (db->reregisterAppFonts) {
117  for (int i = 0; i < db->applicationFonts.count(); i++) {
118  if (!db->applicationFonts.at(i).families.isEmpty())
120  }
121  db->reregisterAppFonts = false;
122  }
123 }
124 
125 #ifndef QT_NO_SETTINGS
126 // called from qapplication_qws.cpp
128 {
129  initializeDb();
130  QFontDatabasePrivate *db = privateDb();
131  for (int i = 0; i < db->count; ++i) {
132  QtFontFamily *family = db->families[i];
133  if (settings.contains(family->name))
134  family->fallbackFamilies = settings.value(family->name).toStringList();
135  }
136 
137  if (settings.contains(QLatin1String("Global Fallbacks")))
138  db->fallbackFamilies = settings.value(QLatin1String("Global Fallbacks")).toStringList();
139 }
140 #endif // QT_NO_SETTINGS
141 
142 static inline void load(const QString & = QString(), int = -1)
143 {
144  // Only initialize the database if it has been cleared or not initialized yet
145  if (!privateDb()->count)
146  initializeDb();
147 }
148 
149 static
151  const QFontDef &request,
152  QtFontFoundry *foundry,
153  QtFontStyle *style, QtFontSize *size)
154 {
155  Q_UNUSED(foundry);
156 
157  Q_ASSERT(size);
158  int pixelSize = size->pixelSize;
159  if (!pixelSize || (style->smoothScalable && pixelSize == SMOOTH_SCALABLE))
160  pixelSize = request.pixelSize;
161 
162  QFontDef def = request;
163  def.pixelSize = pixelSize;
164 
165  QFontCache::Key key(def,script);
167  if (!engine) {
168  QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase();
169  engine = pfdb->fontEngine(def,QUnicodeTables::Script(script),size->handle);
170  if (engine) {
171  QFontCache::Key key(def,script);
172  QFontCache::instance()->instance()->insertEngine(key,engine);
173  }
174  }
175  return engine;
176 }
177 
178 static
179 QFontEngine *loadEngine(int script, const QFontDef &request,
180  QtFontFamily *family, QtFontFoundry *foundry,
181  QtFontStyle *style, QtFontSize *size)
182 {
183 
184  QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size);
185  //make sure that the db has all fallback families
186  if (engine
187  && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) {
188 
189  if (family && !family->askedForFallback) {
190  QFont::Style fontStyle = QFont::Style(style->key.style);
192  if (styleHint == QFont::AnyStyle && request.fixedPitch)
193  styleHint = QFont::TypeWriter;
194  family->fallbackFamilies = fallbackFamilies(family->name,fontStyle,styleHint,QUnicodeTables::Script(script));
195 
196  family->askedForFallback = true;
197  }
198 
199  QStringList fallbacks = privateDb()->fallbackFamilies;
200  if (family && !family->fallbackFamilies.isEmpty())
201  fallbacks = family->fallbackFamilies;
202 
203  engine = new QFontEngineMultiQPA(engine, script, fallbacks);
204  }
205 
206  return engine;
207 }
208 
210 {
211  QFontDatabasePrivate *db = privateDb();
212 
213  fnt->families = QApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName);
214 
215  db->reregisterAppFonts = true;
216 }
217 
219 {
220  QMutexLocker locker(fontDatabaseMutex());
221 
222  QFontDatabasePrivate *db = privateDb();
223  if (handle < 0 || handle >= db->applicationFonts.count())
224  return false;
225 
227 
228  db->reregisterAppFonts = true;
229  db->invalidate();
230  return true;
231 }
232 
234 {
235  QMutexLocker locker(fontDatabaseMutex());
236 
237  QFontDatabasePrivate *db = privateDb();
238  if (db->applicationFonts.isEmpty())
239  return false;
240 
241  db->applicationFonts.clear();
242  db->invalidate();
243  return true;
244 }
245 
247 {
248  return true;
249 }
250 
254 QFontEngine *
256  const QFontDef &request)
257 {
258  QMutexLocker locker(fontDatabaseMutex());
259 
260  const int force_encoding_id = -1;
261 
262  if (!privateDb()->count)
263  initializeDb();
264 
266  QFontCache::Key key(request, script);
267  engine = QFontCache::instance()->findEngine(key);
268  if (engine) {
269  qDebug() << "Cache hit level 1";
270  return engine;
271  }
272 
273  QString family_name, foundry_name;
274 
275  parseFontName(request.family, foundry_name, family_name);
276 
277  if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) {
278  engine =new QTestFontEngine(request.pixelSize);
279  engine->fontDef = request;
280  }
281 
282  QtFontDesc desc;
283  match(script, request, family_name, foundry_name, force_encoding_id, &desc);
284  if (desc.family != 0 && desc.foundry != 0 && desc.style != 0) {
285  engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size);
286  } else {
287  FM_DEBUG(" NO MATCH FOUND\n");
288  }
289 
290  if (engine) {
291  initFontDef(desc, request, &engine->fontDef);
292 
293  if (fp) {
294  QFontDef def = request;
295  if (def.family.isEmpty()) {
296  def.family = fp->request.family;
297  def.family = def.family.left(def.family.indexOf(QLatin1Char(',')));
298  }
299  }
300  }
301 
302  if (!engine) {
303  if (!request.family.isEmpty()) {
305  for (int i = 0; i < fallbacks.size(); i++) {
306  QFontDef def = request;
307  def.family = fallbacks.at(i);
308  QFontCache::Key key(def,script);
309  engine = QFontCache::instance()->findEngine(key);
310  if (!engine) {
311  QtFontDesc desc;
312  match(script, def, def.family, QLatin1String(""), 0, &desc);
313  if (desc.family == 0 && desc.foundry == 0 && desc.style == 0) {
314  continue;
315  }
316  engine = loadEngine(script, def, desc.family, desc.foundry, desc.style, desc.size);
317  if (engine) {
318  initFontDef(desc, def, &engine->fontDef);
319  break;
320  }
321  }
322  }
323  }
324 
325  if (!engine)
326  engine = new QFontEngineBox(request.pixelSize);
327 
328  FM_DEBUG("returning box engine");
329  }
330 
331  if (fp && fp->dpi > 0) {
332  engine->fontDef.pointSize = qreal(double((engine->fontDef.pixelSize * 72) / fp->dpi));
333  } else {
334  engine->fontDef.pointSize = request.pointSize;
335  }
336 
337  return engine;
338 }
339 
340 void QFontDatabase::load(const QFontPrivate *d, int script)
341 {
342  QFontDef req = d->request;
343 
344  if (req.pixelSize == -1) {
345  req.pixelSize = floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100;
346  req.pixelSize = qRound(req.pixelSize);
347  }
348  if (req.pointSize < 0)
349  req.pointSize = req.pixelSize*72.0/d->dpi;
350  if (req.weight == 0)
351  req.weight = QFont::Normal;
352  if (req.stretch == 0)
353  req.stretch = 100;
354 
355  QFontCache::Key key(req, script);
356 
357  if (!d->engineData)
358  getEngineData(d, key);
359 
360  // the cached engineData could have already loaded the engine we want
361  if (d->engineData->engines[script])
362  return;
363 
365 
366  // list of families to try
367  QStringList family_list;
368 
369  if (!req.family.isEmpty()) {
370  family_list = familyList(req);
371 
372  // add the default family
373  QString defaultFamily = QApplication::font().family();
374  if (! family_list.contains(defaultFamily))
375  family_list << defaultFamily;
376 
377  }
378 
379  // null family means find the first font matching the specified script
380  family_list << QString();
381 
382  QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
383  for (; !fe && it != end; ++it) {
384  req.family = *it;
385 
386  fe = QFontDatabase::findFont(script, d, req);
387  if (fe && (fe->type()==QFontEngine::Box) && !req.family.isEmpty()) {
388  if (fe->ref == 0)
389  delete fe;
390 
391  fe = 0;
392  }
393  }
394 
395  if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
396  for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
397  if (!d->engineData->engines[i]) {
398  d->engineData->engines[i] = fe;
399  fe->ref.ref();
400  }
401  }
402  } else {
403  d->engineData->engines[script] = fe;
404  fe->ref.ref();
405  }
406 }
407 
QAtomicInt ref
uint fixedPitch
Definition: qfont_p.h:96
static bool removeAllApplicationFonts()
Removes all application-local fonts previously added using addApplicationFont() and addApplicationFon...
double d
Definition: qnumeric_p.h:62
unsigned short pixelSize
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Returns the value for setting key.
Definition: qsettings.cpp:3460
double qreal
Definition: qglobal.h:1193
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static void initializeDb()
QtFontStyle * style(const QtFontStyle::Key &, const QString &=QString(), bool=false)
qreal pointSize
Definition: qfont_p.h:89
#define it(className, varName)
The QSettings class provides persistent platform-independent application settings.
Definition: qsettings.h:73
#define Q_GUI_EXPORT
Definition: qglobal.h:1450
QtFontSize * size
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
void insertEngine(const Key &key, QFontEngine *engine)
Definition: qfont.cpp:3073
static bool match(const uchar *found, const char *target, uint len)
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qlist.h:269
QtFontStyle * style
QStringList fallbackFamilies
bool ref()
Atomically increments the value of this QAtomicInt.
static void parseFontName(const QString &name, QString &foundry, QString &family)
The QString class provides a Unicode character string.
Definition: qstring.h:83
static void load(const QFontPrivate *d, int script)
Loads a QFontEngine for the specified script that matches the QFontDef request member variable...
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
virtual Type type() const =0
bool supported(QFontDatabase::WritingSystem) const
Returns true if the writing system given by writingSystem is supported; otherwise returns false...
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
static QFontCache * instance()
Definition: qfont.cpp:2919
static QFont font()
Returns the default application font.
QtFontFoundry * foundry
Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &foundryname, int weight, QFont::Style style, int stretch, bool antialiased, bool scalable, int pixelSize, const QSupportedWritingSystems &writingSystems, void *handle)
Q_CORE_EXPORT void qDebug(const char *,...)
QStringList toStringList() const
Returns the variant as a QStringList if the variant has type() StringList, String ...
Definition: qvariant.cpp:2259
static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
#define SMOOTH_SCALABLE
QStringList fallbackFamilies
static QStringList familyList(const QFontDef &req)
static float pixelSize(const QFontDef &request, int dpi)
Definition: qfont_win.cpp:80
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QtFontFamily ** families
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
QFontDef request
Definition: qfont_p.h:178
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
static QFontEngine * loadEngine(int script, const QFontDef &request, QtFontFamily *family, QtFontFoundry *foundry, QtFontStyle *style, QtFontSize *size)
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
The QSupportedWritingSystems class is used when registering fonts with the internal Qt fontdatabase...
const char * styleHint(const QFontDef &request)
virtual QFontEngine * fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle)
Returns the font engine that can be used to render the font described by the font definition...
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
static bool supportsThreadedFontRendering()
Returns true if font rendering is supported outside the GUI thread, false otherwise.
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
uint weight
Definition: qfont_p.h:95
bool qt_enable_test_font
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
friend class iterator
Definition: qlist.h:226
static QFontEngine * loadSingleEngine(int script, const QFontDef &request, QtFontFoundry *foundry, QtFontStyle *style, QtFontSize *size)
void qt_applyFontDatabaseSettings(const QSettings &settings)
#define FM_DEBUG
Style
This enum describes the different styles of glyphs that are used to display text. ...
Definition: qfont.h:111
static bool removeApplicationFont(int id)
Removes the previously loaded application font identified by id.
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
qreal pixelSize
Definition: qfont_p.h:90
QtFontFamily * family(const QString &f, bool=false)
iterator erase(iterator pos)
Removes the item associated with the iterator pos from the list, and returns an iterator to the next ...
Definition: qlist.h:464
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
static void load(const QString &=QString(), int=-1)
StyleHint
Style hints are used by the font matching algorithm to find an appropriate default family if a select...
Definition: qfont.h:69
unsigned char writingSystems[QFontDatabase::WritingSystemsCount]
QtFontSize * pixelSize(unsigned short size, bool=false)
QString family() const
Returns the requested font family name, i.e.
Definition: qfont.cpp:906
uint style
Definition: qfont_p.h:97
const_iterator ConstIterator
Qt-style synonym for QList::const_iterator.
Definition: qlist.h:279
int key
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
bool contains(const QString &key) const
Returns true if there exists a setting called key; returns false otherwise.
Definition: qsettings.cpp:3394
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
uint stretch
Definition: qfont_p.h:98
QtFontFamily * family
The QPlatformFontDatabase class makes it possible to customize how fonts are discovered and how they ...
QFontEngine * findEngine(const Key &key)
Definition: qfont.cpp:3054
QFontDatabasePrivate * d
QFontDef fontDef
QVector< ApplicationFont > applicationFonts
QtFontFoundry * foundry(const QString &f, bool=false)
QString family
Definition: qfont_p.h:82
static const KeyPair *const end
QFontEngineData * engineData
Definition: qfont_p.h:179
uint styleHint
Definition: qfont_p.h:93
uint styleStrategy
Definition: qfont_p.h:92
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
QFontEngine * engine(int at) const
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:272
static QStringList fallbackFamilies(const QString &family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script)
static QFontEngine * findFont(int script, const QFontPrivate *fp, const QFontDef &request)