Enabler: Store more properties of application fonts

The family name of a font is ambiguous and without additional
information there is no way to separate one font from another
inside that family.

In order to make it possible to expose more info about application
fonts from FontLoader in Qt Quick, we need to store them in the font
database.

Task-number: QTBUG-68829
Change-Id: I931e1c2c004437ac0a21d4d88e55d176de676f34
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2020-01-31 09:58:10 +01:00
parent a9caec4a92
commit 8bdbb7f226
19 changed files with 439 additions and 238 deletions

View File

@ -115,7 +115,6 @@ qt_add_module(Gui
painting/qgrayraster.c painting/qgrayraster_p.h painting/qgrayraster.c painting/qgrayraster_p.h
painting/qicc.cpp painting/qicc_p.h painting/qicc.cpp painting/qicc_p.h
painting/qimagescale.cpp painting/qimagescale.cpp
painting/qmatrix.cpp painting/qmatrix.h
painting/qmemrotate.cpp painting/qmemrotate_p.h painting/qmemrotate.cpp painting/qmemrotate_p.h
painting/qoutlinemapper.cpp painting/qoutlinemapper_p.h painting/qoutlinemapper.cpp painting/qoutlinemapper_p.h
painting/qpagedpaintdevice.cpp painting/qpagedpaintdevice.h painting/qpagedpaintdevice_p.h painting/qpagedpaintdevice.cpp painting/qpagedpaintdevice.h painting/qpagedpaintdevice_p.h
@ -161,7 +160,7 @@ qt_add_module(Gui
text/qabstracttextdocumentlayout.cpp text/qabstracttextdocumentlayout.h text/qabstracttextdocumentlayout_p.h text/qabstracttextdocumentlayout.cpp text/qabstracttextdocumentlayout.h text/qabstracttextdocumentlayout_p.h
text/qdistancefield.cpp text/qdistancefield_p.h text/qdistancefield.cpp text/qdistancefield_p.h
text/qfont.cpp text/qfont.h text/qfont_p.h text/qfont.cpp text/qfont.h text/qfont_p.h
text/qfontdatabase.cpp text/qfontdatabase.h text/qfontdatabase.cpp text/qfontdatabase.h text/qfontdatabase_p.h
text/qfontengine.cpp text/qfontengine_p.h text/qfontengine.cpp text/qfontengine_p.h
text/qfontengine_qpf2.cpp text/qfontengine_qpf2.cpp
text/qfontengineglyphcache.cpp text/qfontengineglyphcache_p.h text/qfontengineglyphcache.cpp text/qfontengineglyphcache_p.h

View File

@ -205,7 +205,7 @@ qt_add_module(Gui
text/qabstracttextdocumentlayout.cpp text/qabstracttextdocumentlayout.h text/qabstracttextdocumentlayout_p.h text/qabstracttextdocumentlayout.cpp text/qabstracttextdocumentlayout.h text/qabstracttextdocumentlayout_p.h
text/qdistancefield.cpp text/qdistancefield_p.h text/qdistancefield.cpp text/qdistancefield_p.h
text/qfont.cpp text/qfont.h text/qfont_p.h text/qfont.cpp text/qfont.h text/qfont_p.h
text/qfontdatabase.cpp text/qfontdatabase.h text/qfontdatabase.cpp text/qfontdatabase.h text/qfontdatabase_p.h
text/qfontengine.cpp text/qfontengine_p.h text/qfontengine.cpp text/qfontengine_p.h
text/qfontengine_qpf2.cpp text/qfontengine_qpf2.cpp
text/qfontengineglyphcache.cpp text/qfontengineglyphcache_p.h text/qfontengineglyphcache.cpp text/qfontengineglyphcache_p.h

View File

@ -38,6 +38,7 @@
****************************************************************************/ ****************************************************************************/
#include "qfontdatabase.h" #include "qfontdatabase.h"
#include "qfontdatabase_p.h"
#include "qloggingcategory.h" #include "qloggingcategory.h"
#include "qalgorithms.h" #include "qalgorithms.h"
#include "qguiapplication.h" #include "qguiapplication.h"
@ -173,71 +174,6 @@ static int getFontWeight(const QString &weightString)
} }
struct QtFontSize
{
void *handle;
unsigned short pixelSize : 16;
};
struct QtFontStyle
{
struct Key {
Key(const QString &styleString);
Key() : style(QFont::StyleNormal),
weight(QFont::Normal), stretch(0) { }
Key(const Key &o) : style(o.style), weight(o.weight), stretch(o.stretch) { }
uint style : 2;
signed int weight : 8;
signed int stretch : 12;
bool operator==(const Key & other) {
return (style == other.style && weight == other.weight &&
(stretch == 0 || other.stretch == 0 || stretch == other.stretch));
}
bool operator!=(const Key &other) {
return !operator==(other);
}
bool operator <(const Key &o) {
int x = (style << 12) + (weight << 14) + stretch;
int y = (o.style << 12) + (o.weight << 14) + o.stretch;
return (x < y);
}
};
QtFontStyle(const Key &k)
: key(k), bitmapScalable(false), smoothScalable(false),
count(0), pixelSizes(nullptr)
{
}
~QtFontStyle() {
while (count) {
// bitfield count-- in while condition does not work correctly in mwccsym2
count--;
QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
if (integration) {
integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
}
}
free(pixelSizes);
}
Key key;
bool bitmapScalable : 1;
bool smoothScalable : 1;
signed int count : 30;
QtFontSize *pixelSizes;
QString styleName;
bool antialiased;
QtFontSize *pixelSize(unsigned short size, bool = false);
};
QtFontStyle::Key::Key(const QString &styleString) QtFontStyle::Key::Key(const QString &styleString)
: style(QFont::StyleNormal), weight(QFont::Normal), stretch(0) : style(QFont::StyleNormal), weight(QFont::Normal), stretch(0)
{ {
@ -284,22 +220,6 @@ QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add)
return pixelSizes + (count++); return pixelSizes + (count++);
} }
struct QtFontFoundry
{
QtFontFoundry(const QString &n) : name(n), count(0), styles(nullptr) {}
~QtFontFoundry() {
while (count--)
delete styles[count];
free(styles);
}
QString name;
int count;
QtFontStyle **styles;
QtFontStyle *style(const QtFontStyle::Key &, const QString & = QString(), bool = false);
};
QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &styleName, bool create) QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &styleName, bool create)
{ {
int pos = 0; int pos = 0;
@ -331,46 +251,6 @@ QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &st
return styles[pos]; return styles[pos];
} }
struct QtFontFamily
{
enum WritingSystemStatus {
Unknown = 0,
Supported = 1,
UnsupportedFT = 2,
Unsupported = UnsupportedFT
};
QtFontFamily(const QString &n)
:
populated(false),
fixedPitch(false),
name(n), count(0), foundries(nullptr)
{
memset(writingSystems, 0, sizeof(writingSystems));
}
~QtFontFamily() {
while (count--)
delete foundries[count];
free(foundries);
}
bool populated : 1;
bool fixedPitch : 1;
QString name;
QStringList aliases;
int count;
QtFontFoundry **foundries;
unsigned char writingSystems[QFontDatabase::WritingSystemsCount];
bool matchesFamilyName(const QString &familyName) const;
QtFontFoundry *foundry(const QString &f, bool = false);
void ensurePopulated();
};
QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create) QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
{ {
if (f.isNull() && count == 1) if (f.isNull() && count == 1)
@ -414,85 +294,6 @@ void QtFontFamily::ensurePopulated()
Q_ASSERT_X(populated, Q_FUNC_INFO, qPrintable(name)); Q_ASSERT_X(populated, Q_FUNC_INFO, qPrintable(name));
} }
struct FallbacksCacheKey {
QString family;
QFont::Style style;
QFont::StyleHint styleHint;
QChar::Script script;
};
inline bool operator==(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) noexcept
{
return lhs.script == rhs.script &&
lhs.styleHint == rhs.styleHint &&
lhs.style == rhs.style &&
lhs.family == rhs.family;
}
inline bool operator!=(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) noexcept
{
return !operator==(lhs, rhs);
}
inline uint qHash(const FallbacksCacheKey &key, uint seed = 0) noexcept
{
QtPrivate::QHashCombine hash;
seed = hash(seed, key.family);
seed = hash(seed, int(key.style));
seed = hash(seed, int(key.styleHint));
seed = hash(seed, int(key.script));
return seed;
}
class QFontDatabasePrivate
{
public:
QFontDatabasePrivate()
: count(0), families(nullptr),
fallbacksCache(64)
{ }
~QFontDatabasePrivate() {
free();
}
enum FamilyRequestFlags {
RequestFamily = 0,
EnsureCreated,
EnsurePopulated
};
QtFontFamily *family(const QString &f, FamilyRequestFlags flags = EnsurePopulated);
void free() {
while (count--)
delete families[count];
::free(families);
families = nullptr;
count = 0;
// don't clear the memory fonts!
}
int count;
QtFontFamily **families;
QCache<FallbacksCacheKey, QStringList> fallbacksCache;
struct ApplicationFont {
QString fileName;
QByteArray data;
QStringList families;
};
QVector<ApplicationFont> applicationFonts;
int addAppFont(const QByteArray &fontData, const QString &fileName);
bool isApplicationFont(const QString &fileName);
void invalidate();
};
Q_DECLARE_TYPEINFO(QFontDatabasePrivate::ApplicationFont, Q_MOVABLE_TYPE);
void QFontDatabasePrivate::invalidate() void QFontDatabasePrivate::invalidate()
{ {
QFontCache::instance()->clear(); QFontCache::instance()->clear();
@ -748,6 +549,10 @@ QRecursiveMutex *qt_fontdatabase_mutex()
return fontDatabaseMutex(); return fontDatabaseMutex();
} }
QFontDatabasePrivate *QFontDatabasePrivate::instance()
{
return privateDb();
}
void qt_registerFont(const QString &familyName, const QString &stylename, void qt_registerFont(const QString &familyName, const QString &stylename,
const QString &foundryname, int weight, const QString &foundryname, int weight,
@ -878,7 +683,7 @@ static QStringList fallbacksForFamily(const QString &family, QFont::Style style,
if (!db->count) if (!db->count)
initializeDb(); initializeDb();
const FallbacksCacheKey cacheKey = { family, style, styleHint, script }; const QtFontFallbacksCacheKey cacheKey = { family, style, styleHint, script };
if (const QStringList *fallbacks = db->fallbacksCache.object(cacheKey)) if (const QStringList *fallbacks = db->fallbacksCache.object(cacheKey))
return *fallbacks; return *fallbacks;
@ -922,7 +727,7 @@ static void initializeDb()
if (!db->count) { if (!db->count) {
QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase(); QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
for (int i = 0; i < db->applicationFonts.count(); i++) { for (int i = 0; i < db->applicationFonts.count(); i++) {
if (!db->applicationFonts.at(i).families.isEmpty()) if (!db->applicationFonts.at(i).properties.isEmpty())
registerFont(&db->applicationFonts[i]); registerFont(&db->applicationFonts[i]);
} }
} }
@ -1050,9 +855,22 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
return engine; return engine;
} }
QtFontStyle::~QtFontStyle()
{
while (count) {
// bitfield count-- in while condition does not work correctly in mwccsym2
count--;
QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration();
if (integration)
integration->fontDatabase()->releaseHandle(pixelSizes[count].handle);
}
free(pixelSizes);
}
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
{ {
fnt->families = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data,fnt->fileName); QGuiApplicationPrivate::platformIntegration()->fontDatabase()->addApplicationFont(fnt->data, fnt->fileName, fnt);
} }
static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey, static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey,
@ -2455,7 +2273,7 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
int i; int i;
for (i = 0; i < applicationFonts.count(); ++i) for (i = 0; i < applicationFonts.count(); ++i)
if (applicationFonts.at(i).families.isEmpty()) if (applicationFonts.at(i).properties.isEmpty())
break; break;
if (i >= applicationFonts.count()) { if (i >= applicationFonts.count()) {
applicationFonts.append(ApplicationFont()); applicationFonts.append(ApplicationFont());
@ -2467,7 +2285,7 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
bool wasEmpty = privateDb()->count == 0; bool wasEmpty = privateDb()->count == 0;
registerFont(&font); registerFont(&font);
if (font.families.isEmpty()) if (font.properties.isEmpty())
return -1; return -1;
applicationFonts[i] = font; applicationFonts[i] = font;
@ -2556,7 +2374,14 @@ int QFontDatabase::addApplicationFontFromData(const QByteArray &fontData)
QStringList QFontDatabase::applicationFontFamilies(int id) QStringList QFontDatabase::applicationFontFamilies(int id)
{ {
QMutexLocker locker(fontDatabaseMutex()); QMutexLocker locker(fontDatabaseMutex());
return privateDb()->applicationFonts.value(id).families;
QStringList ret;
ret.reserve(privateDb()->applicationFonts.value(id).properties.size());
for (const auto &properties : privateDb()->applicationFonts.value(id).properties)
ret.append(properties.familyName);
return ret;
} }
/*! /*!

View File

@ -0,0 +1,279 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QFONTDATABASE_P_H
#define QFONTDATABASE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of internal files. This header file may change from version to version
// without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qcache.h>
#include <QtGui/qfontdatabase.h>
QT_BEGIN_NAMESPACE
struct QtFontFallbacksCacheKey
{
QString family;
QFont::Style style;
QFont::StyleHint styleHint;
QChar::Script script;
};
inline bool operator==(const QtFontFallbacksCacheKey &lhs, const QtFontFallbacksCacheKey &rhs) noexcept
{
return lhs.script == rhs.script &&
lhs.styleHint == rhs.styleHint &&
lhs.style == rhs.style &&
lhs.family == rhs.family;
}
inline bool operator!=(const QtFontFallbacksCacheKey &lhs, const QtFontFallbacksCacheKey &rhs) noexcept
{
return !operator==(lhs, rhs);
}
inline uint qHash(const QtFontFallbacksCacheKey &key, uint seed = 0) noexcept
{
QtPrivate::QHashCombine hash;
seed = hash(seed, key.family);
seed = hash(seed, int(key.style));
seed = hash(seed, int(key.styleHint));
seed = hash(seed, int(key.script));
return seed;
}
struct Q_GUI_EXPORT QtFontSize
{
void *handle;
unsigned short pixelSize : 16;
};
struct Q_GUI_EXPORT QtFontStyle
{
struct Key
{
Key(const QString &styleString);
Key()
: style(QFont::StyleNormal)
, weight(QFont::Normal)
, stretch(0)
{}
Key(const Key &o)
: style(o.style)
, weight(o.weight)
, stretch(o.stretch)
{}
uint style : 2;
signed int weight : 8;
signed int stretch : 12;
bool operator==(const Key &other)
{
return (style == other.style && weight == other.weight &&
(stretch == 0 || other.stretch == 0 || stretch == other.stretch));
}
bool operator!=(const Key &other)
{
return !operator==(other);
}
bool operator<(const Key &o)
{
int x = (style << 12) + (weight << 14) + stretch;
int y = (o.style << 12) + (o.weight << 14) + o.stretch;
return (x < y);
}
};
QtFontStyle(const Key &k)
: key(k)
, bitmapScalable(false)
, smoothScalable(false)
, count(0)
, pixelSizes(nullptr)
{
}
~QtFontStyle();
QtFontSize *pixelSize(unsigned short size, bool = false);
Key key;
bool bitmapScalable : 1;
bool smoothScalable : 1;
signed int count : 30;
QtFontSize *pixelSizes;
QString styleName;
bool antialiased;
};
struct Q_GUI_EXPORT QtFontFoundry
{
QtFontFoundry(const QString &n)
: name(n)
, count(0)
, styles(nullptr)
{}
~QtFontFoundry()
{
while (count--)
delete styles[count];
free(styles);
}
QString name;
int count;
QtFontStyle **styles;
QtFontStyle *style(const QtFontStyle::Key &, const QString & = QString(), bool = false);
};
struct Q_GUI_EXPORT QtFontFamily
{
enum WritingSystemStatus {
Unknown = 0,
Supported = 1,
UnsupportedFT = 2,
Unsupported = UnsupportedFT
};
QtFontFamily(const QString &n)
:
populated(false),
fixedPitch(false),
name(n), count(0), foundries(nullptr)
{
memset(writingSystems, 0, sizeof(writingSystems));
}
~QtFontFamily() {
while (count--)
delete foundries[count];
free(foundries);
}
bool populated : 1;
bool fixedPitch : 1;
QString name;
QStringList aliases;
int count;
QtFontFoundry **foundries;
unsigned char writingSystems[QFontDatabase::WritingSystemsCount];
bool matchesFamilyName(const QString &familyName) const;
QtFontFoundry *foundry(const QString &f, bool = false);
void ensurePopulated();
};
class Q_GUI_EXPORT QFontDatabasePrivate
{
public:
QFontDatabasePrivate()
: count(0)
, families(nullptr)
, fallbacksCache(64)
{ }
~QFontDatabasePrivate() {
free();
}
enum FamilyRequestFlags {
RequestFamily = 0,
EnsureCreated,
EnsurePopulated
};
QtFontFamily *family(const QString &f, FamilyRequestFlags flags = EnsurePopulated);
void free() {
while (count--)
delete families[count];
::free(families);
families = nullptr;
count = 0;
// don't clear the memory fonts!
}
int count;
QtFontFamily **families;
QCache<QtFontFallbacksCacheKey, QStringList> fallbacksCache;
struct ApplicationFont {
QString fileName;
QByteArray data;
struct Properties {
QString familyName;
QString styleName;
int weight = 0;
QFont::Style style = QFont::StyleNormal;
int stretch = QFont::Unstretched;
};
QVector<Properties> properties;
};
QVector<ApplicationFont> applicationFonts;
int addAppFont(const QByteArray &fontData, const QString &fileName);
bool isApplicationFont(const QString &fileName);
static QFontDatabasePrivate *instance();
void invalidate();
};
Q_DECLARE_TYPEINFO(QFontDatabasePrivate::ApplicationFont, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
#endif // QFONTDATABASE_P_H

View File

@ -40,6 +40,7 @@
#include "qplatformfontdatabase.h" #include "qplatformfontdatabase.h"
#include <QtGui/private/qfontengine_p.h> #include <QtGui/private/qfontengine_p.h>
#include <QtGui/private/qfontengine_qpf2_p.h> #include <QtGui/private/qfontengine_qpf2_p.h>
#include <QtGui/private/qfontdatabase_p.h>
#include <QtGui/QGuiApplication> #include <QtGui/QGuiApplication>
#include <QtGui/QScreen> #include <QtGui/QScreen>
#include <qpa/qplatformscreen.h> #include <qpa/qplatformscreen.h>
@ -376,16 +377,27 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal
or using the font contained in the file referenced by \a fileName. Returns or using the font contained in the file referenced by \a fileName. Returns
a list of family names, or an empty list if the font could not be added. a list of family names, or an empty list if the font could not be added.
If \a applicationFont is non-null, its \c properties vector should be filled
with information from the loaded fonts. This is exposed through FontLoader in
Qt Quick where it is needed for disambiguating fonts in the same family. When
the function exits, the \a applicationFont should contain an entry of properties
per font in the file, or it should be empty if no font was loaded.
\note The default implementation of this function does not add an application \note The default implementation of this function does not add an application
font. Subclasses should reimplement this function to perform the necessary font. Subclasses should reimplement this function to perform the necessary
loading and registration of fonts. loading and registration of fonts.
*/ */
QStringList QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) QStringList QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{ {
Q_UNUSED(fontData); Q_UNUSED(fontData);
Q_UNUSED(fileName); Q_UNUSED(fileName);
Q_UNUSED(applicationFont);
if (applicationFont != nullptr)
applicationFont->properties.clear();
qWarning("This plugin does not support application fonts"); qWarning("This plugin does not support application fonts");
return QStringList(); return QStringList();
} }

View File

@ -59,6 +59,7 @@
#include <QtGui/QFontDatabase> #include <QtGui/QFontDatabase>
#include <QtGui/private/qfontengine_p.h> #include <QtGui/private/qfontengine_p.h>
#include <QtGui/private/qfont_p.h> #include <QtGui/private/qfont_p.h>
#include <QtGui/private/qfontdatabase_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -111,7 +112,7 @@ public:
virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script); virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
virtual QFontEngine *fontEngine(const QFontDef &fontDef, void *handle); virtual QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const; virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *font = nullptr);
virtual void releaseHandle(void *handle); virtual void releaseHandle(void *handle);
virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);

View File

@ -3,6 +3,7 @@
HEADERS += \ HEADERS += \
text/qfont.h \ text/qfont.h \
text/qfontdatabase.h \ text/qfontdatabase.h \
text/qfontdatabase_p.h \
text/qfontengine_p.h \ text/qfontengine_p.h \
text/qfontengineglyphcache_p.h \ text/qfontengineglyphcache_p.h \
text/qfontinfo.h \ text/qfontinfo.h \

View File

@ -392,7 +392,7 @@ static inline bool requiresOpenType(int writingSystem)
|| writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko); || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
} }
static void populateFromPattern(FcPattern *pattern) static void populateFromPattern(FcPattern *pattern, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr)
{ {
QString familyName; QString familyName;
QString familyNameLang; QString familyNameLang;
@ -502,6 +502,18 @@ static void populateFromPattern(FcPattern *pattern)
// Note: stretch should really be an int but registerFont incorrectly uses an enum // Note: stretch should really be an int but registerFont incorrectly uses an enum
QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value)); QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString(); QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
if (applicationFont != nullptr) {
QFontDatabasePrivate::ApplicationFont::Properties properties;
properties.familyName = familyName;
properties.styleName = styleName;
properties.weight = weight;
properties.style = style;
properties.stretch = stretch;
applicationFont->properties.append(properties);
}
QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile); QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size; // qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
@ -523,6 +535,16 @@ static void populateFromPattern(FcPattern *pattern)
altFamilyNameLang = familyNameLang; altFamilyNameLang = familyNameLang;
if (familyNameLang == altFamilyNameLang && altStyleName != styleName) { if (familyNameLang == altFamilyNameLang && altStyleName != styleName) {
if (applicationFont != nullptr) {
QFontDatabasePrivate::ApplicationFont::Properties properties;
properties.familyName = altFamilyName;
properties.styleName = altStyleName;
properties.weight = weight;
properties.style = style;
properties.stretch = stretch;
applicationFont->properties.append(properties);
}
FontFile *altFontFile = new FontFile(*fontFile); FontFile *altFontFile = new FontFile(*fontFile);
QPlatformFontDatabase::registerFont(altFamilyName, altStyleName, QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile); QPlatformFontDatabase::registerFont(altFamilyName, altStyleName, QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile);
} else { } else {
@ -827,10 +849,13 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
#endif #endif
} }
QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{ {
QStringList families; QStringList families;
if (applicationFont != nullptr)
applicationFont->properties.clear();
FcFontSet *set = FcConfigGetFonts(nullptr, FcSetApplication); FcFontSet *set = FcConfigGetFonts(nullptr, FcSetApplication);
if (!set) { if (!set) {
FcConfigAppFontAddFile(nullptr, (const FcChar8 *)":/non-existent"); FcConfigAppFontAddFile(nullptr, (const FcChar8 *)":/non-existent");
@ -855,7 +880,7 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam)); QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
families << family; families << family;
} }
populateFromPattern(pattern); populateFromPattern(pattern, applicationFont);
FcFontSetAdd(set, pattern); FcFontSetAdd(set, pattern);

View File

@ -67,7 +67,7 @@ public:
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override; QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override; QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override; QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
QString resolveFontFamilyAlias(const QString &family) const override; QString resolveFontFamilyAlias(const QString &family) const override;
QFont defaultFont() const override; QFont defaultFont() const override;

View File

@ -98,9 +98,9 @@ QFontEngine *QFreeTypeFontDatabase::fontEngine(const QByteArray &fontData, qreal
return QFontEngineFT::create(fontData, pixelSize, hintingPreference); return QFontEngineFT::create(fontData, pixelSize, hintingPreference);
} }
QStringList QFreeTypeFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) QStringList QFreeTypeFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{ {
return QFreeTypeFontDatabase::addTTFile(fontData, fileName.toLocal8Bit()); return QFreeTypeFontDatabase::addTTFile(fontData, fileName.toLocal8Bit(), applicationFont);
} }
void QFreeTypeFontDatabase::releaseHandle(void *handle) void QFreeTypeFontDatabase::releaseHandle(void *handle)
@ -111,7 +111,7 @@ void QFreeTypeFontDatabase::releaseHandle(void *handle)
extern FT_Library qt_getFreetype(); extern FT_Library qt_getFreetype();
QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file) QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file, QFontDatabasePrivate::ApplicationFont *applicationFont)
{ {
FT_Library library = qt_getFreetype(); FT_Library library = qt_getFreetype();
@ -199,9 +199,20 @@ QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const Q
fontFile->indexValue = index; fontFile->indexValue = index;
QFont::Stretch stretch = QFont::Unstretched; QFont::Stretch stretch = QFont::Unstretched;
QString styleName = QString::fromLatin1(face->style_name);
registerFont(family,QString::fromLatin1(face->style_name),QString(),weight,style,stretch,true,true,0,fixedPitch,writingSystems,fontFile); if (applicationFont != nullptr) {
QFontDatabasePrivate::ApplicationFont::Properties properties;
properties.familyName = family;
properties.styleName = styleName;
properties.weight = weight;
properties.stretch = stretch;
properties.style = style;
applicationFont->properties.append(properties);
}
registerFont(family, styleName, QString(), weight, style, stretch, true, true, 0, fixedPitch, writingSystems, fontFile);
families.append(family); families.append(family);
FT_Done_Face(face); FT_Done_Face(face);

View File

@ -69,10 +69,10 @@ public:
void populateFontDatabase() override; void populateFontDatabase() override;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override; QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override; QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
void releaseHandle(void *handle) override; void releaseHandle(void *handle) override;
static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file); static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr);
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -322,7 +322,7 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
} }
} }
void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName) void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{ {
FontDescription fd; FontDescription fd;
getFontDescription(font, &fd); getFontDescription(font, &fd);
@ -332,6 +332,17 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, con
// fonts if a font family does not have any fonts available on the system. // fonts if a font family does not have any fonts available on the system.
QString family = !familyName.isNull() ? familyName : static_cast<QString>(fd.familyName); QString family = !familyName.isNull() ? familyName : static_cast<QString>(fd.familyName);
if (applicationFont != nullptr) {
QFontDatabasePrivate::ApplicationFont::Properties properties;
properties.familyName = family;
properties.styleName = fd.styleName;
properties.weight = fd.weight;
properties.stretch = fd.stretch;
properties.style = fd.style;
applicationFont->properties.append(properties);
}
CFRetain(font); CFRetain(font);
QPlatformFontDatabase::registerFont(family, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch, QPlatformFontDatabase::registerFont(family, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch,
true /* antialiased */, true /* scalable */, 0 /* pixelSize, ignored as font is scalable */, true /* antialiased */, true /* scalable */, 0 /* pixelSize, ignored as font is scalable */,
@ -570,7 +581,7 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
return fallbackList; return fallbackList;
} }
QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{ {
QCFType<CFArrayRef> fonts; QCFType<CFArrayRef> fonts;
@ -597,7 +608,7 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
const int numFonts = CFArrayGetCount(fonts); const int numFonts = CFArrayGetCount(fonts);
for (int i = 0; i < numFonts; ++i) { for (int i = 0; i < numFonts; ++i) {
CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i)); CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i));
populateFromDescriptor(fontDescriptor); populateFromDescriptor(fontDescriptor, QString(), applicationFont);
QCFType<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute)); QCFType<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute));
families.append(QString::fromCFString(familyName)); families.append(QString::fromCFString(familyName));
} }

View File

@ -76,7 +76,7 @@ public:
void invalidate() override; void invalidate() override;
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override; QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override; QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
void releaseHandle(void *handle) override; void releaseHandle(void *handle) override;
bool isPrivateFontFamily(const QString &family) const override; bool isPrivateFontFamily(const QString &family) const override;
QFont defaultFont() const override; QFont defaultFont() const override;
@ -91,7 +91,7 @@ protected:
mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors; mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors;
private: private:
void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString()); void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString(), QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr);
static CFArrayRef fallbacksForFamily(const QString &family); static CFArrayRef fallbacksForFamily(const QString &family);
mutable QString defaultFontName; mutable QString defaultFontName;

View File

@ -283,7 +283,7 @@ QStringList QWindowsDirectWriteFontDatabase::fallbacksForFamily(const QString &f
return result; return result;
} }
QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{ {
qCDebug(lcQpaFonts) << "Adding application font" << fileName; qCDebug(lcQpaFonts) << "Adding application font" << fileName;
@ -354,12 +354,30 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray
<< ", fixed:" << fixed; << ", fixed:" << fixed;
if (!englishLocaleFamilyName.isEmpty()) { if (!englishLocaleFamilyName.isEmpty()) {
if (applicationFont != nullptr) {
QFontDatabasePrivate::ApplicationFont::Properties properties;
properties.style = style;
properties.weight = weight;
properties.familyName = englishLocaleFamilyName;
properties.styleName = englishLocaleStyleName;
applicationFont->properties.append(properties);
}
ret.append(englishLocaleFamilyName); ret.append(englishLocaleFamilyName);
QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face); QPlatformFontDatabase::registerFont(englishLocaleFamilyName, englishLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
face->AddRef(); face->AddRef();
} }
if (!defaultLocaleFamilyName.isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) { if (!defaultLocaleFamilyName.isEmpty() && defaultLocaleFamilyName != englishLocaleFamilyName) {
if (applicationFont != nullptr) {
QFontDatabasePrivate::ApplicationFont::Properties properties;
properties.style = style;
properties.weight = weight;
properties.familyName = englishLocaleFamilyName;
properties.styleName = englishLocaleStyleName;
applicationFont->properties.append(properties);
}
ret.append(defaultLocaleFamilyName); ret.append(defaultLocaleFamilyName);
QPlatformFontDatabase::registerFont(defaultLocaleFamilyName, defaultLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face); QPlatformFontDatabase::registerFont(defaultLocaleFamilyName, defaultLocaleStyleName, QString(), weight, style, stretch, antialias, scalable, size, fixed, writingSystems, face);
face->AddRef(); face->AddRef();

View File

@ -76,7 +76,7 @@ public:
void populateFamily(const QString &familyName) override; void populateFamily(const QString &familyName) override;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override; QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override; QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *font = nullptr) override;
void releaseHandle(void *handle) override; void releaseHandle(void *handle) override;
QFont defaultFont() const override; QFont defaultFont() const override;

View File

@ -949,7 +949,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
} }
} }
QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont)
{ {
WinApplicationFont font; WinApplicationFont font;
font.fileName = fileName; font.fileName = fileName;
@ -992,6 +992,16 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
HFONT hfont = CreateFontIndirect(&lf); HFONT hfont = CreateFontIndirect(&lf);
HGDIOBJ oldobj = SelectObject(hdc, hfont); HGDIOBJ oldobj = SelectObject(hdc, hfont);
if (applicationFont != nullptr) {
QFontDatabasePrivate::ApplicationFont::Properties properties;
properties.style = values.isItalic ? QFont::StyleItalic : QFont::StyleNormal;
properties.weight = QPlatformFontDatabase::weightFromInteger(values.weight);
properties.familyName = familyName;
properties.styleName = styleName;
applicationFont->properties.append(properties);
}
TEXTMETRIC textMetrics; TEXTMETRIC textMetrics;
GetTextMetrics(hdc, &textMetrics); GetTextMetrics(hdc, &textMetrics);
@ -1010,7 +1020,9 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
QByteArray data = f.readAll(); QByteArray data = f.readAll();
f.close(); f.close();
getFamiliesAndSignatures(data, &families, nullptr, nullptr);
getFamiliesAndSignatures(data, &families, nullptr, applicationFont != nullptr ? &fontValues : nullptr);
if (families.isEmpty()) if (families.isEmpty())
return QStringList(); return QStringList();
@ -1023,6 +1035,20 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
for (int j = 0; j < families.count(); ++j) { for (int j = 0; j < families.count(); ++j) {
const QString familyName = families.at(j).name; const QString familyName = families.at(j).name;
familyNames << familyName; familyNames << familyName;
if (applicationFont != nullptr) {
const QString &styleName = families.at(j).style;
const QFontValues &values = fontValues.at(j);
QFontDatabasePrivate::ApplicationFont::Properties properties;
properties.style = values.isItalic ? QFont::StyleItalic : QFont::StyleNormal;
properties.weight = QPlatformFontDatabase::weightFromInteger(values.weight);
properties.familyName = familyName;
properties.styleName = styleName;
applicationFont->properties.append(properties);
}
populateFamily(familyName); populateFamily(familyName);
} }
} }

View File

@ -80,7 +80,7 @@ public:
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override; QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override; QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override; QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName, QFontDatabasePrivate::ApplicationFont *applicationFont = nullptr) override;
void releaseHandle(void *handle) override; void releaseHandle(void *handle) override;
QString fontDir() const override; QString fontDir() const override;

View File

@ -74,12 +74,6 @@ QStringList QWasmFontDatabase::fallbacksForFamily(const QString &family, QFont::
return fallbacks; return fallbacks;
} }
QStringList QWasmFontDatabase::addApplicationFont(const QByteArray &fontData,
const QString &fileName)
{
return QFreeTypeFontDatabase::addApplicationFont(fontData, fileName);
}
void QWasmFontDatabase::releaseHandle(void *handle) void QWasmFontDatabase::releaseHandle(void *handle)
{ {
QFreeTypeFontDatabase::releaseHandle(handle); QFreeTypeFontDatabase::releaseHandle(handle);

View File

@ -42,7 +42,6 @@ public:
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QStringList fallbacksForFamily(const QString &family, QFont::Style style,
QFont::StyleHint styleHint, QFont::StyleHint styleHint,
QChar::Script script) const override; QChar::Script script) const override;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override;
void releaseHandle(void *handle) override; void releaseHandle(void *handle) override;
QFont defaultFont() const override; QFont defaultFont() const override;
}; };