Windows: Rewrite font database to use delayed population.
Task-number: QTBUG-43774 Change-Id: I3b0b0ead0953b3b88a6d0092c694a2a00f70acf7 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com> Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
This commit is contained in:
parent
10c62c894c
commit
c88e354993
@ -946,9 +946,8 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
|
static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
|
||||||
int type, LPARAM namesSetIn)
|
int type, LPARAM)
|
||||||
{
|
{
|
||||||
typedef QSet<QString> StringSet;
|
|
||||||
const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
|
const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
|
||||||
const uchar charSet = f->elfLogFont.lfCharSet;
|
const uchar charSet = f->elfLogFont.lfCharSet;
|
||||||
|
|
||||||
@ -957,53 +956,71 @@ static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetr
|
|||||||
// NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
|
// NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
|
||||||
// identical to a TEXTMETRIC except for the last four members, which we don't use
|
// identical to a TEXTMETRIC except for the last four members, which we don't use
|
||||||
// anyway
|
// anyway
|
||||||
if (addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type))
|
addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type);
|
||||||
reinterpret_cast<StringSet *>(namesSetIn)->insert(familyName);
|
|
||||||
|
|
||||||
// keep on enumerating
|
// keep on enumerating
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWindowsFontDatabase::populateFontDatabase()
|
void QWindowsFontDatabase::populateFamily(const QString &familyName)
|
||||||
{
|
{
|
||||||
m_families.clear();
|
qCDebug(lcQpaFonts) << familyName;
|
||||||
removeApplicationFonts();
|
if (familyName.size() >= LF_FACESIZE) {
|
||||||
populate(); // Called multiple times.
|
qCWarning(lcQpaFonts) << "Unable to enumerate family '" << familyName << '\'';
|
||||||
// Work around EnumFontFamiliesEx() not listing the system font, see below.
|
return;
|
||||||
const QString sysFontFamily = QGuiApplication::font().family();
|
}
|
||||||
if (!m_families.contains(sysFontFamily))
|
|
||||||
populate(sysFontFamily);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Populate font database using EnumFontFamiliesEx().
|
|
||||||
|
|
||||||
Normally, leaving the name empty should enumerate
|
|
||||||
all fonts, however, system fonts like "MS Shell Dlg 2"
|
|
||||||
are only found when specifying the name explicitly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void QWindowsFontDatabase::populate(const QString &family)
|
|
||||||
{
|
|
||||||
|
|
||||||
qCDebug(lcQpaFonts) << __FUNCTION__ << m_families.size() << family;
|
|
||||||
|
|
||||||
HDC dummy = GetDC(0);
|
HDC dummy = GetDC(0);
|
||||||
LOGFONT lf;
|
LOGFONT lf;
|
||||||
lf.lfCharSet = DEFAULT_CHARSET;
|
lf.lfCharSet = DEFAULT_CHARSET;
|
||||||
if (family.size() >= LF_FACESIZE) {
|
familyName.toWCharArray(lf.lfFaceName);
|
||||||
qWarning("%s: Unable to enumerate family '%s'.",
|
lf.lfFaceName[familyName.size()] = 0;
|
||||||
__FUNCTION__, qPrintable(family));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wmemcpy(lf.lfFaceName, reinterpret_cast<const wchar_t*>(family.utf16()),
|
|
||||||
family.size() + 1);
|
|
||||||
lf.lfPitchAndFamily = 0;
|
lf.lfPitchAndFamily = 0;
|
||||||
EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont,
|
EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, 0, 0);
|
||||||
(LPARAM)&m_families, 0);
|
|
||||||
ReleaseDC(0, dummy);
|
ReleaseDC(0, dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// Context for enumerating system fonts, records whether the default font has been encountered,
|
||||||
|
// which is normally not enumerated by EnumFontFamiliesEx().
|
||||||
|
struct PopulateFamiliesContext
|
||||||
|
{
|
||||||
|
PopulateFamiliesContext(const QString &f) : systemDefaultFont(f), seenSystemDefaultFont(false) {}
|
||||||
|
|
||||||
|
QString systemDefaultFont;
|
||||||
|
bool seenSystemDefaultFont;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *, int, LPARAM lparam)
|
||||||
|
{
|
||||||
|
// the "@family" fonts are just the same as "family". Ignore them.
|
||||||
|
const wchar_t *faceNameW = f->elfLogFont.lfFaceName;
|
||||||
|
if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) {
|
||||||
|
const QString faceName = QString::fromWCharArray(faceNameW);
|
||||||
|
QPlatformFontDatabase::registerFontFamily(faceName);
|
||||||
|
PopulateFamiliesContext *context = reinterpret_cast<PopulateFamiliesContext *>(lparam);
|
||||||
|
if (!context->seenSystemDefaultFont && faceName == context->systemDefaultFont)
|
||||||
|
context->seenSystemDefaultFont = true;
|
||||||
|
}
|
||||||
|
return 1; // continue
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWindowsFontDatabase::populateFontDatabase()
|
||||||
|
{
|
||||||
|
removeApplicationFonts();
|
||||||
|
HDC dummy = GetDC(0);
|
||||||
|
LOGFONT lf;
|
||||||
|
lf.lfCharSet = DEFAULT_CHARSET;
|
||||||
|
lf.lfFaceName[0] = 0;
|
||||||
|
lf.lfPitchAndFamily = 0;
|
||||||
|
PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family());
|
||||||
|
EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0);
|
||||||
|
ReleaseDC(0, dummy);
|
||||||
|
// Work around EnumFontFamiliesEx() not listing the system font.
|
||||||
|
if (!context.seenSystemDefaultFont)
|
||||||
|
QPlatformFontDatabase::registerFontFamily(context.systemDefaultFont);
|
||||||
|
}
|
||||||
|
|
||||||
typedef QSharedPointer<QWindowsFontEngineData> QWindowsFontEngineDataPtr;
|
typedef QSharedPointer<QWindowsFontEngineData> QWindowsFontEngineDataPtr;
|
||||||
|
|
||||||
#ifndef QT_NO_THREAD
|
#ifndef QT_NO_THREAD
|
||||||
@ -1365,7 +1382,7 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
|
|||||||
|
|
||||||
// Fonts based on files are added via populate, as they will show up in font enumeration.
|
// Fonts based on files are added via populate, as they will show up in font enumeration.
|
||||||
for (int j = 0; j < families.count(); ++j)
|
for (int j = 0; j < families.count(); ++j)
|
||||||
populate(families.at(j));
|
populateFamily(families.at(j));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_applicationFonts << font;
|
m_applicationFonts << font;
|
||||||
@ -1645,7 +1662,7 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFon
|
|||||||
result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
|
result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
|
||||||
|
|
||||||
qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
|
qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
|
||||||
<< script << result << m_families.size();
|
<< script << result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ public:
|
|||||||
~QWindowsFontDatabase();
|
~QWindowsFontDatabase();
|
||||||
|
|
||||||
void populateFontDatabase() Q_DECL_OVERRIDE;
|
void populateFontDatabase() Q_DECL_OVERRIDE;
|
||||||
|
void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
|
||||||
QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) Q_DECL_OVERRIDE;
|
QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) Q_DECL_OVERRIDE;
|
||||||
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
|
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
|
||||||
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) Q_DECL_OVERRIDE;
|
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) Q_DECL_OVERRIDE;
|
||||||
@ -99,9 +100,7 @@ public:
|
|||||||
static QString familyForStyleHint(QFont::StyleHint styleHint);
|
static QString familyForStyleHint(QFont::StyleHint styleHint);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void populate(const QString &family = QString());
|
|
||||||
void removeApplicationFonts();
|
void removeApplicationFonts();
|
||||||
QSet<QString> m_families;
|
|
||||||
|
|
||||||
struct WinApplicationFont {
|
struct WinApplicationFont {
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user