CoreText: Order fallback fonts based on writing system support
After we stopped sanitizing the fallback font list (with change
6ca48a847a
), we now need to make
sure it is ordered so that the fonts that support the writing
system in question are always tested first, otherwise we can end up
loading a lot of fonts that will never be used.
Task-number: QTBUG-65605
Change-Id: Id2a65bbff3e64e6d6e6b4f72500778ee3e811e84
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
This commit is contained in:
parent
fcbaa8ec38
commit
12687ccfd5
@ -2837,6 +2837,41 @@ QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
|
||||
return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(family);
|
||||
}
|
||||
|
||||
Q_GUI_EXPORT QStringList qt_sort_families_by_writing_system(QChar::Script script, const QStringList &families)
|
||||
{
|
||||
size_t writingSystem = std::find(scriptForWritingSystem,
|
||||
scriptForWritingSystem + QFontDatabase::WritingSystemsCount,
|
||||
script) - scriptForWritingSystem;
|
||||
if (writingSystem == QFontDatabase::Any
|
||||
|| writingSystem >= QFontDatabase::WritingSystemsCount) {
|
||||
return families;
|
||||
}
|
||||
|
||||
QFontDatabasePrivate *db = privateDb();
|
||||
QMultiMap<uint, QString> supported;
|
||||
for (int i = 0; i < families.size(); ++i) {
|
||||
const QString &family = families.at(i);
|
||||
|
||||
QtFontFamily *testFamily = nullptr;
|
||||
for (int x = 0; x < db->count; ++x) {
|
||||
if (Q_UNLIKELY(matchFamilyName(family, db->families[x]))) {
|
||||
testFamily = db->families[x];
|
||||
testFamily->ensurePopulated();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint order = i;
|
||||
if (testFamily == nullptr
|
||||
|| (testFamily->writingSystems[writingSystem] & QtFontFamily::Supported) == 0) {
|
||||
order |= 1 << 31;
|
||||
}
|
||||
|
||||
supported.insert(order, family);
|
||||
}
|
||||
|
||||
return supported.values();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -544,6 +544,9 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
|
||||
fallbackList.append(QStringLiteral("Arial Unicode MS"));
|
||||
#endif
|
||||
|
||||
extern QStringList qt_sort_families_by_writing_system(QChar::Script, const QStringList &);
|
||||
fallbackList = qt_sort_families_by_writing_system(script, fallbackList);
|
||||
|
||||
return fallbackList;
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,9 @@ private slots:
|
||||
void rawFontFromInvalidData();
|
||||
|
||||
void kernedAdvances();
|
||||
|
||||
void fallbackFontsOrder();
|
||||
|
||||
private:
|
||||
QString testFont;
|
||||
QString testFontBoldItalic;
|
||||
@ -1009,6 +1012,38 @@ void tst_QRawFont::kernedAdvances()
|
||||
QVERIFY(FUZZY_LTEQ(qAbs(advances.at(0).x() - expectedAdvanceWidth), errorMargin));
|
||||
}
|
||||
|
||||
void tst_QRawFont::fallbackFontsOrder()
|
||||
{
|
||||
QFontDatabase fontDatabase;
|
||||
int id = fontDatabase.addApplicationFont(testFont);
|
||||
|
||||
QFont font("QtBidiTestFont");
|
||||
font.setPixelSize(12.0);
|
||||
|
||||
QString arabicText = QFontDatabase::writingSystemSample(QFontDatabase::Arabic);
|
||||
|
||||
// If this fails, then the writing system sample has changed and we need to create
|
||||
// a new text containing both a space and Arabic characters.
|
||||
QVERIFY(arabicText.contains(QLatin1Char(' ')));
|
||||
|
||||
QTextLayout layout;
|
||||
layout.setFont(font);
|
||||
layout.setText(arabicText);
|
||||
layout.setCacheEnabled(true);
|
||||
layout.beginLayout();
|
||||
layout.createLine();
|
||||
layout.endLayout();
|
||||
|
||||
QList<QGlyphRun> glyphRuns = layout.glyphRuns();
|
||||
|
||||
// Since QtBidiTestFont does not support Arabic nor the space, both should map to
|
||||
// the same font. If this fails, it is an indication that the list of fallbacks fonts
|
||||
// is not sorted by writing system support.
|
||||
QCOMPARE(glyphRuns.size(), 1);
|
||||
|
||||
fontDatabase.removeApplicationFont(id);
|
||||
}
|
||||
|
||||
#endif // QT_NO_RAWFONT
|
||||
|
||||
QTEST_MAIN(tst_QRawFont)
|
||||
|
Loading…
Reference in New Issue
Block a user