Fix font lookup.

Change match() to return an index and use that to reintroduce
the blacklist bookkeeping for fonts for which font engine
creation fails (for example, due to missing open type support).
Change the algorithm to retry search if that happens.
Add empty string as fallback for non-common scripts indicating
'try to find any font matching the script' as is done in Qt 4.

Task-number: QTBUG-34908
Change-Id: I9ac81ff1c275ebb635675dc26b52394789fca60c
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Friedemann Kleint 2013-11-27 16:32:28 +01:00 committed by The Qt Project
parent dc80838a37
commit f29e38f9a4
2 changed files with 29 additions and 16 deletions

View File

@ -562,9 +562,9 @@ struct QtFontDesc
int familyIndex; int familyIndex;
}; };
static void match(int script, const QFontDef &request, static int match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id, const QString &family_name, const QString &foundry_name, int force_encoding_id,
QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>()); QtFontDesc *desc, const QList<int> &blacklisted);
static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi) static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef, bool multi)
{ {
@ -846,11 +846,12 @@ static bool matchFamilyName(const QString &familyName, QtFontFamily *f)
Tries to find the best match for a given request and family/foundry Tries to find the best match for a given request and family/foundry
*/ */
static void match(int script, const QFontDef &request, static int match(int script, const QFontDef &request,
const QString &family_name, const QString &foundry_name, int force_encoding_id, const QString &family_name, const QString &foundry_name, int force_encoding_id,
QtFontDesc *desc, const QList<int> &blacklistedFamilies) QtFontDesc *desc, const QList<int> &blacklistedFamilies)
{ {
Q_UNUSED(force_encoding_id); Q_UNUSED(force_encoding_id);
int result = -1;
QtFontStyle::Key styleKey; QtFontStyle::Key styleKey;
styleKey.style = request.style; styleKey.style = request.style;
@ -925,12 +926,14 @@ static void match(int script, const QFontDef &request,
newscore += score_adjust; newscore += score_adjust;
if (newscore < score) { if (newscore < score) {
result = x;
score = newscore; score = newscore;
*desc = test; *desc = test;
} }
if (newscore < 10) // xlfd instead of FT... just accept it if (newscore < 10) // xlfd instead of FT... just accept it
break; break;
} }
return result;
} }
static QString styleStringHelper(int weight, QFont::Style style) static QString styleStringHelper(int weight, QFont::Style style)

View File

@ -306,9 +306,12 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp,
} }
QtFontDesc desc; QtFontDesc desc;
match(script, request, family_name, foundry_name, force_encoding_id, &desc); QList<int> blackListed;
if (desc.family != 0 && desc.foundry != 0 && desc.style != 0) { 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); engine = loadEngine(script, request, desc.family, desc.foundry, desc.style, desc.size);
if (!engine)
blackListed.append(index);
} else { } else {
FM_DEBUG(" NO MATCH FOUND\n"); FM_DEBUG(" NO MATCH FOUND\n");
} }
@ -332,6 +335,8 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp,
QFont::Style(request.style), QFont::Style(request.style),
QFont::StyleHint(request.styleHint), QFont::StyleHint(request.styleHint),
QChar::Script(script)); 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++) { for (int i = 0; !engine && i < fallbacks.size(); i++) {
QFontDef def = request; QFontDef def = request;
@ -340,14 +345,19 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp,
engine = QFontCache::instance()->findEngine(key); engine = QFontCache::instance()->findEngine(key);
if (!engine) { if (!engine) {
QtFontDesc desc; QtFontDesc desc;
match(script, def, def.family, QLatin1String(""), 0, &desc); do {
if (desc.family == 0 && desc.foundry == 0 && desc.style == 0) { index = match(script, def, def.family, QLatin1String(""), 0, &desc, blackListed);
continue; if (index >= 0) {
} QFontDef loadDef = def;
engine = loadEngine(script, def, desc.family, desc.foundry, desc.style, desc.size); if (loadDef.family.isEmpty())
if (engine) { loadDef.family = desc.family->name;
initFontDef(desc, def, &engine->fontDef, engine->type() == QFontEngine::Multi); 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);
} }
} }
} }