Merge qfontdatabase_qpa.cpp with qfontdatabase.cpp

There's no point in separating them anymore, and it just makes editing
and reasoning about the QFontDatabase code harder.

Change-Id: I6bc8cb5e5daac26293e75553639e4a4d34eba3bd
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
This commit is contained in:
Tor Arne Vestbø 2014-03-04 14:39:36 +01:00 committed by The Qt Project
parent 9d79c3458c
commit f99fd06d7d
2 changed files with 416 additions and 475 deletions

View File

@ -55,6 +55,8 @@
#include <qpa/qplatformfontdatabase.h>
#include <qpa/qplatformtheme.h>
#include <QtCore/qmath.h>
#include <stdlib.h>
#include <limits.h>
#include <algorithm>
@ -654,9 +656,200 @@ QMutex *qt_fontdatabase_mutex()
return fontDatabaseMutex();
}
QT_BEGIN_INCLUDE_NAMESPACE
# include "qfontdatabase_qpa.cpp"
QT_END_INCLUDE_NAMESPACE
void qt_registerFont(const QString &familyName, const QString &stylename,
const QString &foundryname, int weight,
QFont::Style style, int stretch, bool antialiased,
bool scalable, int pixelSize, bool fixedPitch,
const QSupportedWritingSystems &writingSystems, void *handle)
{
QFontDatabasePrivate *d = privateDb();
// qDebug() << "Adding font" << familyName << weight << style << pixelSize << antialiased;
QtFontStyle::Key styleKey;
styleKey.style = style;
styleKey.weight = weight;
styleKey.stretch = stretch;
QtFontFamily *f = d->family(familyName, true);
f->fixedPitch = fixedPitch;
for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
if (writingSystems.supported(QFontDatabase::WritingSystem(i)))
f->writingSystems[i] = QtFontFamily::Supported;
}
QtFontFoundry *foundry = f->foundry(foundryname, true);
QtFontStyle *fontStyle = foundry->style(styleKey, stylename, true);
fontStyle->smoothScalable = scalable;
fontStyle->antialiased = antialiased;
QtFontSize *size = fontStyle->pixelSize(pixelSize ? pixelSize : SMOOTH_SCALABLE, true);
if (size->handle) {
QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
if (integration)
integration->fontDatabase()->releaseHandle(size->handle);
}
size->handle = handle;
}
void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias)
{
if (alias.isEmpty())
return;
QFontDatabasePrivate *d = privateDb();
QtFontFamily *f = d->family(familyName, false);
if (!f)
return;
if (f->aliases.contains(alias, Qt::CaseInsensitive))
return;
f->aliases.push_back(alias);
}
QString qt_resolveFontFamilyAlias(const QString &alias)
{
if (!alias.isEmpty()) {
const QFontDatabasePrivate *d = privateDb();
for (int i = 0; i < d->count; ++i)
if (d->families[i]->matchesFamilyName(alias))
return d->families[i]->name;
}
return alias;
}
static QStringList fallbackFamilies(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script)
{
QStringList retList = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
QFontDatabasePrivate *db = privateDb();
QStringList::iterator i;
for (i = retList.begin(); i != retList.end(); ++i) {
bool contains = false;
for (int j = 0; j < db->count; j++) {
if (db->families[j]->matchesFamilyName(*i)) {
contains = true;
break;
}
}
if (!contains) {
i = retList.erase(i);
i--;
}
}
return retList;
}
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt);
static void initializeDb()
{
QFontDatabasePrivate *db = privateDb();
// init by asking for the platformfontdb for the first time or after invalidation
if (!db->count)
QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
if (db->reregisterAppFonts) {
for (int i = 0; i < db->applicationFonts.count(); i++) {
if (!db->applicationFonts.at(i).families.isEmpty())
registerFont(&db->applicationFonts[i]);
}
db->reregisterAppFonts = false;
}
}
static inline void load(const QString & = QString(), int = -1)
{
// Only initialize the database if it has been cleared or not initialized yet
if (!privateDb()->count)
initializeDb();
}
static
QFontEngine *loadSingleEngine(int script,
const QFontDef &request,
QtFontFoundry *foundry,
QtFontStyle *style, QtFontSize *size)
{
Q_UNUSED(foundry);
Q_ASSERT(size);
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
int pixelSize = size->pixelSize;
if (!pixelSize || (style->smoothScalable && pixelSize == SMOOTH_SCALABLE)
|| pfdb->fontsAlwaysScalable()) {
pixelSize = request.pixelSize;
}
QFontDef def = request;
def.pixelSize = pixelSize;
QFontCache::Key key(def,script);
QFontEngine *engine = QFontCache::instance()->findEngine(key);
if (!engine) {
engine = pfdb->fontEngine(def, size->handle);
if (engine) {
// Also check for OpenType tables when using complex scripts
if (!engine->supportsScript(QChar::Script(script))) {
qWarning(" OpenType support missing for script %d", script);
if (engine->ref.load() == 0)
delete engine;
return 0;
}
QFontCache::instance()->insertEngine(key, engine);
}
}
return engine;
}
static
QFontEngine *loadEngine(int script, const QFontDef &request,
QtFontFamily *family, QtFontFoundry *foundry,
QtFontStyle *style, QtFontSize *size)
{
QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size);
//make sure that the db has all fallback families
if (engine && engine->type() != QFontEngine::Multi
&& !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) {
if (family && !family->askedForFallback) {
QFont::Style fontStyle = QFont::Style(style->key.style);
QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
if (styleHint == QFont::AnyStyle && request.fixedPitch)
styleHint = QFont::TypeWriter;
family->fallbackFamilies = fallbackFamilies(family->name, fontStyle, styleHint, QChar::Script(script));
family->askedForFallback = true;
}
QStringList fallbacks = privateDb()->fallbackFamilies;
if (family && !family->fallbackFamilies.isEmpty())
fallbacks = family->fallbackFamilies;
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script));
pfMultiEngine->setFallbackFamiliesList(fallbacks);
engine = pfMultiEngine;
// Cache Multi font engine as well in case we got the single
// font engine when we are actually looking for a Multi one
QFontCache::Key key(request, script, 1);
QFontCache::instance()->insertEngine(key, engine);
}
return engine;
}
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
QFontDatabasePrivate *db = privateDb();
fnt->families = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName);
db->reregisterAppFonts = true;
}
static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey,
const QString &styleName = QString())
@ -2146,6 +2339,20 @@ QFont QFontDatabase::systemFont(QFontDatabase::SystemFont type)
\sa removeAllApplicationFonts(), addApplicationFont(),
addApplicationFontFromData()
*/
bool QFontDatabase::removeApplicationFont(int handle)
{
QMutexLocker locker(fontDatabaseMutex());
QFontDatabasePrivate *db = privateDb();
if (handle < 0 || handle >= db->applicationFonts.count())
return false;
db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
db->reregisterAppFonts = true;
db->invalidate();
return true;
}
/*!
\fn bool QFontDatabase::removeAllApplicationFonts()
@ -2159,6 +2366,18 @@ QFont QFontDatabase::systemFont(QFontDatabase::SystemFont type)
\sa removeApplicationFont(), addApplicationFont(), addApplicationFontFromData()
*/
bool QFontDatabase::removeAllApplicationFonts()
{
QMutexLocker locker(fontDatabaseMutex());
QFontDatabasePrivate *db = privateDb();
if (db->applicationFonts.isEmpty())
return false;
db->applicationFonts.clear();
db->invalidate();
return true;
}
/*!
\fn bool QFontDatabase::supportsThreadedFontRendering()
@ -2174,6 +2393,200 @@ QFont QFontDatabase::systemFont(QFontDatabase::SystemFont type)
\sa {Thread-Support in Qt Modules#Painting In Threads}{Painting In Threads}
*/
// QT_DEPRECATED_SINCE(5, 2)
bool QFontDatabase::supportsThreadedFontRendering()
{
return true;
}
/*!
\internal
*/
QFontEngine *
QFontDatabase::findFont(int script, const QFontPrivate *fp,
const QFontDef &request, bool multi)
{
QMutexLocker locker(fontDatabaseMutex());
const int force_encoding_id = -1;
if (!privateDb()->count)
initializeDb();
QFontEngine *engine;
QFontCache::Key key(request, script, multi ? 1 : 0);
engine = QFontCache::instance()->findEngine(key);
if (engine) {
FM_DEBUG("Cache hit level 1");
return engine;
}
QString family_name, foundry_name;
parseFontName(request.family, foundry_name, family_name);
if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) {
engine =new QTestFontEngine(request.pixelSize);
engine->fontDef = request;
}
QtFontDesc desc;
QList<int> blackListed;
int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed);
if (index >= 0) {
engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size);
if (!engine)
blackListed.append(index);
} else {
FM_DEBUG(" NO MATCH FOUND\n");
}
if (engine && engine->type() != QFontEngine::TestFontEngine) {
initFontDef(desc, request, &engine->fontDef, engine->type() == QFontEngine::Multi);
if (fp) {
QFontDef def = request;
if (def.family.isEmpty()) {
def.family = fp->request.family;
def.family = def.family.left(def.family.indexOf(QLatin1Char(',')));
}
}
}
if (!engine) {
if (!request.family.isEmpty()) {
QStringList fallbacks = request.fallBackFamilies
+ fallbackFamilies(request.family,
QFont::Style(request.style),
QFont::StyleHint(request.styleHint),
QChar::Script(script));
if (script > QChar::Script_Common)
fallbacks += QString(); // Find the first font matching the specified script.
for (int i = 0; !engine && i < fallbacks.size(); i++) {
QFontDef def = request;
def.family = fallbacks.at(i);
QFontCache::Key key(def, script, multi ? 1 : 0);
engine = QFontCache::instance()->findEngine(key);
if (!engine) {
QtFontDesc desc;
do {
index = match(script, def, def.family, QLatin1String(""), 0, &desc, blackListed);
if (index >= 0) {
QFontDef loadDef = def;
if (loadDef.family.isEmpty())
loadDef.family = desc.family->name;
engine = loadEngine(script, loadDef, desc.family, desc.foundry, desc.style, desc.size);
if (engine)
initFontDef(desc, loadDef, &engine->fontDef, engine->type() == QFontEngine::Multi);
else
blackListed.append(index);
}
} while (index >= 0 && !engine);
}
}
}
if (!engine)
engine = new QFontEngineBox(request.pixelSize);
FM_DEBUG("returning box engine");
}
if (fp && fp->dpi > 0) {
engine->fontDef.pointSize = qreal(double((engine->fontDef.pixelSize * 72) / fp->dpi));
} else {
engine->fontDef.pointSize = request.pointSize;
}
return engine;
}
void QFontDatabase::load(const QFontPrivate *d, int script)
{
QFontDef req = d->request;
if (req.pixelSize == -1) {
req.pixelSize = floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100;
req.pixelSize = qRound(req.pixelSize);
}
if (req.pointSize < 0)
req.pointSize = req.pixelSize*72.0/d->dpi;
if (req.weight == 0)
req.weight = QFont::Normal;
if (req.stretch == 0)
req.stretch = 100;
// Until we specifically asked not to, try looking for Multi font engine
// first, the last '1' indicates that we want Multi font engine instead
// of single ones
bool multi = !(req.styleStrategy & QFont::NoFontMerging);
QFontCache::Key key(req, script, multi ? 1 : 0);
if (!d->engineData)
getEngineData(d, req);
// the cached engineData could have already loaded the engine we want
if (d->engineData->engines[script])
return;
QFontEngine *fe = QFontCache::instance()->findEngine(key);
// list of families to try
QStringList family_list;
if (!req.family.isEmpty()) {
QStringList familiesForRequest = familyList(req);
// Add primary selection
family_list << familiesForRequest.takeFirst();
// Fallbacks requested in font request
req.fallBackFamilies = familiesForRequest;
// add the default family
QString defaultFamily = QGuiApplication::font().family();
if (! family_list.contains(defaultFamily))
family_list << defaultFamily;
}
// null family means find the first font matching the specified script
family_list << QString();
QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
for (; !fe && it != end; ++it) {
req.family = *it;
fe = QFontDatabase::findFont(script, d, req, multi);
if (fe && (fe->type()==QFontEngine::Box) && !req.family.isEmpty()) {
if (fe->ref.load() == 0)
delete fe;
fe = 0;
}
// No need to check requested fallback families again
req.fallBackFamilies.clear();
}
if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
for (int i = 0; i < QChar::ScriptCount; ++i) {
if (!d->engineData->engines[i]) {
d->engineData->engines[i] = fe;
fe->ref.ref();
}
}
} else {
d->engineData->engines[script] = fe;
fe->ref.ref();
}
}
QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
{
return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(family);
}
QT_END_NAMESPACE

View File

@ -1,472 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qlibraryinfo.h"
#include <QtCore/qsettings.h>
#include "qfontengine_qpa_p.h"
#include "qplatformdefs.h"
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformfontdatabase.h>
#include <QtCore/qmath.h>
QT_BEGIN_NAMESPACE
void qt_registerFont(const QString &familyName, const QString &stylename,
const QString &foundryname, int weight,
QFont::Style style, int stretch, bool antialiased,
bool scalable, int pixelSize, bool fixedPitch,
const QSupportedWritingSystems &writingSystems, void *handle)
{
QFontDatabasePrivate *d = privateDb();
// qDebug() << "Adding font" << familyName << weight << style << pixelSize << antialiased;
QtFontStyle::Key styleKey;
styleKey.style = style;
styleKey.weight = weight;
styleKey.stretch = stretch;
QtFontFamily *f = d->family(familyName, true);
f->fixedPitch = fixedPitch;
for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
if (writingSystems.supported(QFontDatabase::WritingSystem(i)))
f->writingSystems[i] = QtFontFamily::Supported;
}
QtFontFoundry *foundry = f->foundry(foundryname, true);
QtFontStyle *fontStyle = foundry->style(styleKey, stylename, true);
fontStyle->smoothScalable = scalable;
fontStyle->antialiased = antialiased;
QtFontSize *size = fontStyle->pixelSize(pixelSize ? pixelSize : SMOOTH_SCALABLE, true);
if (size->handle) {
QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
if (integration)
integration->fontDatabase()->releaseHandle(size->handle);
}
size->handle = handle;
}
void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias)
{
if (alias.isEmpty())
return;
QFontDatabasePrivate *d = privateDb();
QtFontFamily *f = d->family(familyName, false);
if (!f)
return;
if (f->aliases.contains(alias, Qt::CaseInsensitive))
return;
f->aliases.push_back(alias);
}
QString qt_resolveFontFamilyAlias(const QString &alias)
{
if (!alias.isEmpty()) {
const QFontDatabasePrivate *d = privateDb();
for (int i = 0; i < d->count; ++i)
if (d->families[i]->matchesFamilyName(alias))
return d->families[i]->name;
}
return alias;
}
static QStringList fallbackFamilies(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script)
{
QStringList retList = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script);
QFontDatabasePrivate *db = privateDb();
QStringList::iterator i;
for (i = retList.begin(); i != retList.end(); ++i) {
bool contains = false;
for (int j = 0; j < db->count; j++) {
if (db->families[j]->matchesFamilyName(*i)) {
contains = true;
break;
}
}
if (!contains) {
i = retList.erase(i);
i--;
}
}
return retList;
}
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt);
static void initializeDb()
{
QFontDatabasePrivate *db = privateDb();
// init by asking for the platformfontdb for the first time or after invalidation
if (!db->count)
QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
if (db->reregisterAppFonts) {
for (int i = 0; i < db->applicationFonts.count(); i++) {
if (!db->applicationFonts.at(i).families.isEmpty())
registerFont(&db->applicationFonts[i]);
}
db->reregisterAppFonts = false;
}
}
static inline void load(const QString & = QString(), int = -1)
{
// Only initialize the database if it has been cleared or not initialized yet
if (!privateDb()->count)
initializeDb();
}
static
QFontEngine *loadSingleEngine(int script,
const QFontDef &request,
QtFontFoundry *foundry,
QtFontStyle *style, QtFontSize *size)
{
Q_UNUSED(foundry);
Q_ASSERT(size);
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
int pixelSize = size->pixelSize;
if (!pixelSize || (style->smoothScalable && pixelSize == SMOOTH_SCALABLE)
|| pfdb->fontsAlwaysScalable()) {
pixelSize = request.pixelSize;
}
QFontDef def = request;
def.pixelSize = pixelSize;
QFontCache::Key key(def,script);
QFontEngine *engine = QFontCache::instance()->findEngine(key);
if (!engine) {
engine = pfdb->fontEngine(def, size->handle);
if (engine) {
// Also check for OpenType tables when using complex scripts
if (!engine->supportsScript(QChar::Script(script))) {
qWarning(" OpenType support missing for script %d", script);
if (engine->ref.load() == 0)
delete engine;
return 0;
}
QFontCache::instance()->insertEngine(key, engine);
}
}
return engine;
}
static
QFontEngine *loadEngine(int script, const QFontDef &request,
QtFontFamily *family, QtFontFoundry *foundry,
QtFontStyle *style, QtFontSize *size)
{
QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size);
//make sure that the db has all fallback families
if (engine && engine->type() != QFontEngine::Multi
&& !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) {
if (family && !family->askedForFallback) {
QFont::Style fontStyle = QFont::Style(style->key.style);
QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
if (styleHint == QFont::AnyStyle && request.fixedPitch)
styleHint = QFont::TypeWriter;
family->fallbackFamilies = fallbackFamilies(family->name, fontStyle, styleHint, QChar::Script(script));
family->askedForFallback = true;
}
QStringList fallbacks = privateDb()->fallbackFamilies;
if (family && !family->fallbackFamilies.isEmpty())
fallbacks = family->fallbackFamilies;
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script));
pfMultiEngine->setFallbackFamiliesList(fallbacks);
engine = pfMultiEngine;
// Cache Multi font engine as well in case we got the single
// font engine when we are actually looking for a Multi one
QFontCache::Key key(request, script, 1);
QFontCache::instance()->insertEngine(key, engine);
}
return engine;
}
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{
QFontDatabasePrivate *db = privateDb();
fnt->families = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName);
db->reregisterAppFonts = true;
}
bool QFontDatabase::removeApplicationFont(int handle)
{
QMutexLocker locker(fontDatabaseMutex());
QFontDatabasePrivate *db = privateDb();
if (handle < 0 || handle >= db->applicationFonts.count())
return false;
db->applicationFonts[handle] = QFontDatabasePrivate::ApplicationFont();
db->reregisterAppFonts = true;
db->invalidate();
return true;
}
bool QFontDatabase::removeAllApplicationFonts()
{
QMutexLocker locker(fontDatabaseMutex());
QFontDatabasePrivate *db = privateDb();
if (db->applicationFonts.isEmpty())
return false;
db->applicationFonts.clear();
db->invalidate();
return true;
}
// QT_DEPRECATED_SINCE(5, 2)
bool QFontDatabase::supportsThreadedFontRendering()
{
return true;
}
/*!
\internal
*/
QFontEngine *
QFontDatabase::findFont(int script, const QFontPrivate *fp,
const QFontDef &request, bool multi)
{
QMutexLocker locker(fontDatabaseMutex());
const int force_encoding_id = -1;
if (!privateDb()->count)
initializeDb();
QFontEngine *engine;
QFontCache::Key key(request, script, multi ? 1 : 0);
engine = QFontCache::instance()->findEngine(key);
if (engine) {
FM_DEBUG("Cache hit level 1");
return engine;
}
QString family_name, foundry_name;
parseFontName(request.family, foundry_name, family_name);
if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) {
engine =new QTestFontEngine(request.pixelSize);
engine->fontDef = request;
}
QtFontDesc desc;
QList<int> blackListed;
int index = match(script, request, family_name, foundry_name, force_encoding_id, &desc, blackListed);
if (index >= 0) {
engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size);
if (!engine)
blackListed.append(index);
} else {
FM_DEBUG(" NO MATCH FOUND\n");
}
if (engine && engine->type() != QFontEngine::TestFontEngine) {
initFontDef(desc, request, &engine->fontDef, engine->type() == QFontEngine::Multi);
if (fp) {
QFontDef def = request;
if (def.family.isEmpty()) {
def.family = fp->request.family;
def.family = def.family.left(def.family.indexOf(QLatin1Char(',')));
}
}
}
if (!engine) {
if (!request.family.isEmpty()) {
QStringList fallbacks = request.fallBackFamilies
+ fallbackFamilies(request.family,
QFont::Style(request.style),
QFont::StyleHint(request.styleHint),
QChar::Script(script));
if (script > QChar::Script_Common)
fallbacks += QString(); // Find the first font matching the specified script.
for (int i = 0; !engine && i < fallbacks.size(); i++) {
QFontDef def = request;
def.family = fallbacks.at(i);
QFontCache::Key key(def, script, multi ? 1 : 0);
engine = QFontCache::instance()->findEngine(key);
if (!engine) {
QtFontDesc desc;
do {
index = match(script, def, def.family, QLatin1String(""), 0, &desc, blackListed);
if (index >= 0) {
QFontDef loadDef = def;
if (loadDef.family.isEmpty())
loadDef.family = desc.family->name;
engine = loadEngine(script, loadDef, desc.family, desc.foundry, desc.style, desc.size);
if (engine)
initFontDef(desc, loadDef, &engine->fontDef, engine->type() == QFontEngine::Multi);
else
blackListed.append(index);
}
} while (index >= 0 && !engine);
}
}
}
if (!engine)
engine = new QFontEngineBox(request.pixelSize);
FM_DEBUG("returning box engine");
}
if (fp && fp->dpi > 0) {
engine->fontDef.pointSize = qreal(double((engine->fontDef.pixelSize * 72) / fp->dpi));
} else {
engine->fontDef.pointSize = request.pointSize;
}
return engine;
}
void QFontDatabase::load(const QFontPrivate *d, int script)
{
QFontDef req = d->request;
if (req.pixelSize == -1) {
req.pixelSize = floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100;
req.pixelSize = qRound(req.pixelSize);
}
if (req.pointSize < 0)
req.pointSize = req.pixelSize*72.0/d->dpi;
if (req.weight == 0)
req.weight = QFont::Normal;
if (req.stretch == 0)
req.stretch = 100;
// Until we specifically asked not to, try looking for Multi font engine
// first, the last '1' indicates that we want Multi font engine instead
// of single ones
bool multi = !(req.styleStrategy & QFont::NoFontMerging);
QFontCache::Key key(req, script, multi ? 1 : 0);
if (!d->engineData)
getEngineData(d, req);
// the cached engineData could have already loaded the engine we want
if (d->engineData->engines[script])
return;
QFontEngine *fe = QFontCache::instance()->findEngine(key);
// list of families to try
QStringList family_list;
if (!req.family.isEmpty()) {
QStringList familiesForRequest = familyList(req);
// Add primary selection
family_list << familiesForRequest.takeFirst();
// Fallbacks requested in font request
req.fallBackFamilies = familiesForRequest;
// add the default family
QString defaultFamily = QGuiApplication::font().family();
if (! family_list.contains(defaultFamily))
family_list << defaultFamily;
}
// null family means find the first font matching the specified script
family_list << QString();
QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
for (; !fe && it != end; ++it) {
req.family = *it;
fe = QFontDatabase::findFont(script, d, req, multi);
if (fe && (fe->type()==QFontEngine::Box) && !req.family.isEmpty()) {
if (fe->ref.load() == 0)
delete fe;
fe = 0;
}
// No need to check requested fallback families again
req.fallBackFamilies.clear();
}
if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) {
for (int i = 0; i < QChar::ScriptCount; ++i) {
if (!d->engineData->engines[i]) {
d->engineData->engines[i] = fe;
fe->ref.ref();
}
}
} else {
d->engineData->engines[script] = fe;
fe->ref.ref();
}
}
QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
{
return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(family);
}
QT_END_NAMESPACE