reference the font engines from QFontPrivate

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2021-12-30 03:08:24 +02:00
parent 1a038d23d5
commit cf94e3ffdd
7 changed files with 35 additions and 147 deletions

View file

@ -111,44 +111,36 @@ bool QFontDef::exactMatch(const QFontDef &other) const
}
QFontPrivate::QFontPrivate()
: engineData(0), dpi(QX11Info::appDpiY()), screen(QX11Info::appScreen()),
: engine(nullptr), dpi(QX11Info::appDpiY()), screen(QX11Info::appScreen()),
underline(false), overline(false), strikeOut(false), kerning(true),
letterSpacingIsAbsolute(false)
{
}
QFontPrivate::QFontPrivate(const QFontPrivate &other)
: request(other.request), engineData(0), dpi(other.dpi), screen(other.screen),
: request(other.request), engine(other.engine), dpi(other.dpi), screen(other.screen),
underline(other.underline), overline(other.overline),
strikeOut(other.strikeOut), kerning(other.kerning),
letterSpacingIsAbsolute(other.letterSpacingIsAbsolute),
letterSpacing(other.letterSpacing), wordSpacing(other.wordSpacing)
{
if (engine) {
engine->ref.ref();
}
}
QFontPrivate::~QFontPrivate()
{
if (engineData && !engineData->ref.deref())
delete engineData;
engineData = 0;
if (engine) {
engine->ref.deref();
}
}
extern std::recursive_mutex &qt_fontdatabase_mutex();
QFontEngine *QFontPrivate::engineForScript(QUnicodeTables::Script script) const
{
std::lock_guard<std::recursive_mutex> locker(qt_fontdatabase_mutex());
if (script > QUnicodeTables::ScriptCount)
script = QUnicodeTables::Common;
if (engineData && engineData->fontCache != QFontCache::instance()) {
// throw out engineData that came from a different thread
if (!engineData->ref.deref())
delete engineData;
engineData = 0;
}
if (!engineData || !engineData->engines[script])
QFontDatabase::load(this, script);
return engineData->engines[script];
return QFontDatabase::load(this, script);
}
void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
@ -209,27 +201,6 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
wordSpacing = other->wordSpacing;
}
QFontEngineData::QFontEngineData()
: ref(1), fontCache(QFontCache::instance())
{
memset(engines, 0, QUnicodeTables::ScriptCount * sizeof(QFontEngine *));
}
QFontEngineData::~QFontEngineData()
{
for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
if (engines[i] && !engines[i]->ref.deref())
delete engines[i];
engines[i] = 0;
}
}
/*!
\class QFont
\reentrant
@ -509,9 +480,6 @@ QFont::QFont(QFontPrivate *data)
void QFont::detach()
{
if (d->ref == 1) {
if (d->engineData && !d->engineData->ref.deref())
delete d->engineData;
d->engineData = 0;
return;
}
@ -1950,8 +1918,8 @@ QFontCache::~QFontCache()
{
clear();
{
EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
end = engineDataCache.constEnd();
EngineCache::ConstIterator it = engineCache.constBegin(),
end = engineCache.constEnd();
while (it != end) {
if (!it.value()->ref.deref())
delete it.value();
@ -1965,20 +1933,6 @@ QFontCache::~QFontCache()
void QFontCache::clear()
{
{
EngineDataCache::Iterator it = engineDataCache.begin(),
end = engineDataCache.end();
while (it != end) {
QFontEngineData *data = it.value();
for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) {
if (data->engines[i] && !data->engines[i]->ref.deref())
delete data->engines[i];
data->engines[i] = 0;
}
++it;
}
}
for (EngineCache::Iterator it = engineCache.begin(), end = engineCache.end();
it != end; ++it) {
QFontEngine *engine = it.value();
@ -1990,28 +1944,6 @@ void QFontCache::clear()
engineCache.clear();
}
QFontEngineData *QFontCache::findEngineData(const Key &key) const
{
EngineDataCache::ConstIterator it = engineDataCache.find(key),
end = engineDataCache.end();
if (it == end) {
return nullptr;
}
// found
return it.value();
}
void QFontCache::insertEngineData(const Key &key, QFontEngineData *engineData)
{
FC_DEBUG("QFontCache: inserting new engine data %p", engineData);
Q_ASSERT(!engineDataCache.contains(key));
engineData->ref.ref(); // the cache has a reference
engineDataCache.insert(key, engineData);
}
QFontEngine *QFontCache::findEngine(const Key &key)
{
EngineCache::Iterator it = engineCache.find(key),
@ -2031,11 +1963,6 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine)
{
FC_DEBUG("QFontCache: inserting new engine %p", engine);
QFontEngine *oldEngine = engineCache.value(key);
engine->ref.ref(); // the cache has a reference
if (oldEngine && !oldEngine->ref.deref())
delete oldEngine;
engineCache.insert(key, engine);
}

View file

@ -102,19 +102,6 @@ struct QFontDef
}
};
class QFontEngineData
{
public:
QFontEngineData();
~QFontEngineData();
QAtomicInt ref;
QFontCache *fontCache;
QFontEngine *engines[QUnicodeTables::ScriptCount];
};
class Q_GUI_EXPORT QFontPrivate
{
public:
@ -130,7 +117,7 @@ public:
QAtomicInt ref;
QFontDef request;
mutable QFontEngineData *engineData;
mutable QFontEngine *engine;
int dpi;
int screen;
@ -165,8 +152,7 @@ public:
~QFontCache();
void clear();
// universal key structure. QFontEngineDatas and QFontEngines are cached using
// the same keys
// QFontEngines are cached using the same keys
struct Key {
Key() : script(0), screen(0) { }
Key(const QFontDef &d, int c, int s = 0)
@ -186,13 +172,6 @@ public:
{ return def == other.def && script == other.script && screen == other.screen; }
};
// QFontEngineData cache
typedef QMap<Key,QFontEngineData*> EngineDataCache;
EngineDataCache engineDataCache;
QFontEngineData *findEngineData(const Key &key) const;
void insertEngineData(const Key &key, QFontEngineData *engineData);
// QFontEngine cache
typedef QMap<Key,QFontEngine *> EngineCache;
EngineCache engineCache;

View file

@ -467,21 +467,6 @@ struct QtFontDesc
static void match(int script, const QFontDef &request, const QString &family_name,
const QString &foundry_name, QtFontDesc *desc);
#if defined(Q_WS_X11)
static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key)
{
// look for the requested font in the engine data cache
d->engineData = QFontCache::instance()->findEngineData(key);
if (!d->engineData) {
// create a new one
d->engineData = new QFontEngineData;
QFontCache::instance()->insertEngineData(key, d->engineData);
} else {
d->engineData->ref.ref();
}
}
#endif
static QStringList familyList(const QFontDef &req)
{
// list of families to try
@ -1349,7 +1334,9 @@ void QFontDatabase::parseFontName(const QString &name, QString &foundry, QString
}
void QFontDatabase::createDatabase()
{ initializeFontDb(); }
{
initializeFontDb();
}
// used from qfontengine_ft.cpp
Q_GUI_EXPORT QByteArray qt_fontdata_from_index(int index)

View file

@ -32,7 +32,6 @@ QT_BEGIN_NAMESPACE
class QFontInfo;
class QStringList;
template <class T> class QList;
struct QFontDef;
class QFontEngine;
class QFontDatabasePrivate;
@ -76,7 +75,7 @@ private:
static void createDatabase();
static void parseFontName(const QString &name, QString &foundry, QString &family);
static QString resolveFontFamilyAlias(const QString &family);
static void load(const QFontPrivate *d, int script);
static QFontEngine* load(const QFontPrivate *d, int script);
friend struct QFontDef;
friend class QFontPrivate;

View file

@ -1066,34 +1066,31 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
Loads a QFontEngine for the specified \a script that matches the
QFontDef \e request member variable.
*/
void QFontDatabase::load(const QFontPrivate *d, int script)
QFontEngine* QFontDatabase::load(const QFontPrivate *d, int script)
{
Q_ASSERT(script >= 0 && script < QUnicodeTables::ScriptCount);
// normalize the request to get better caching
QFontDef req = d->request;
if (req.pixelSize <= 0)
if (req.pixelSize <= 0) {
req.pixelSize = qFloor(qt_pixelSize(req.pointSize, d->dpi) * 100.0 + 0.5) * 0.01;
if (req.pixelSize < 1)
}
if (req.pixelSize < 1) {
req.pixelSize = 1;
}
if (req.weight == 0)
if (req.weight == 0) {
req.weight = QFont::Normal;
if (req.stretch == 0)
}
if (req.stretch == 0) {
req.stretch = 100;
}
QFontCache::Key key(req, script, d->screen);
if (!d->engineData)
getEngineData(d, key);
// the cached engineData could have already loaded the engine we want
if (d->engineData->engines[script])
return;
// set it to the actual pointsize, so QFontInfo will do the right thing
if (req.pointSize < 0)
if (req.pointSize < 0) {
req.pointSize = qt_pointSize(req.pixelSize, d->dpi);
}
QFontEngine *fe = QFontCache::instance()->findEngine(key);
@ -1112,9 +1109,8 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
fe->fontDef = QFontDef();
}
}
d->engineData->engines[script] = fe;
fe->ref.ref();
QFontCache::instance()->insertEngine(key, fe);
return fe;
}
static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)

View file

@ -137,7 +137,7 @@ static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB
QFontEngine::QFontEngine()
: QObject(),
ref(0)
ref(1)
{
fsType = 0;
memset(&hbFont, 0, sizeof(hbFont));

View file

@ -509,17 +509,17 @@ bool QFontEngineFT::getSfntTableData(uint tag, uchar *buffer, uint *length) cons
int QFontEngineFT::synthesized() const
{
int s = 0;
int result = 0;
if (oblique) {
s = SynthesizedItalic;
result = SynthesizedItalic;
}
if (embolden) {
s |= SynthesizedBold;
result |= SynthesizedBold;
}
if (fontDef.stretch != 100) {
s |= SynthesizedStretch;
result |= SynthesizedStretch;
}
return s;
return result;
}
QFixed QFontEngineFT::ascent() const