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:
parent
9d79c3458c
commit
f99fd06d7d
@ -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
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user