From 9e99dba4a22bbf212b3e6d1e2607a16dbbd04d90 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 11 Dec 2017 11:14:22 +0100 Subject: Windows: Add font fallback for EUDC glyphs EUDC, or "End-User Defined Characters", is a concept in Windows, where the end-user can create a local fallback font of default glyphs for the PUA (Private Use Area, a range of Unicode not reserved to any writing system), and these glyphs will be used when displaying the character using a font which does not itself support the code point. To support this in Qt we look up the default EUDC font in the registry and add it to the fallback fonts if it is available. We use the font for code page 1252. This has been tested on a couple of systems, and appears to always be present. The font is added to the front of all fallback lists, so that it will override other fallbacks, such as Segoe UI Symbol, which happens to assign glyphs to the PUA. If there is no end-user defined fallback, then Segoe UI Symbol will still be used as before. Note that this required a small change in the code to get canonical font names. The EUDC font that Windows generates will only have a name set for the current locale, and we expected all fonts to have an English name. Instead, the code has now been changed to prefer the English name if one is present, but accept any other name if there is nothing in English. [ChangeLog][Windows][Text] Added support for End-User Defined Characters in Qt. Task-number: QTBUG-44594 Change-Id: I83ae68b6d16e9b50e990dfb3ac3d294b7b2a5113 Reviewed-by: Lars Knoll --- .../fontdatabases/windows/qwindowsfontdatabase.cpp | 48 ++++++++++++++++++++-- .../fontdatabases/windows/qwindowsfontdatabase_p.h | 2 + 2 files changed, 47 insertions(+), 3 deletions(-) (limited to 'src/platformsupport/fontdatabases') diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index def67c6199..9d86f461e9 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -872,8 +872,8 @@ FontNames qt_getCanonicalFontNames(const uchar *table, quint32 bytes) if ((platform_id == PlatformId_Microsoft && (encoding_id == 0 || encoding_id == 1)) - && (language_id & 0x3ff) == MS_LangIdEnglish - && *idType < Microsoft) { + && ((language_id & 0x3ff) == MS_LangIdEnglish + || *idType < Microsoft)) { *id = i; *idType = Microsoft; } @@ -1172,6 +1172,46 @@ static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TE return 1; // continue } +void QWindowsFontDatabase::addDefaultEUDCFont() +{ + QString path; + { + HKEY key; + if (RegOpenKeyEx(HKEY_CURRENT_USER, + L"EUDC\\1252", + 0, + KEY_READ, + &key) != ERROR_SUCCESS) { + return; + } + + WCHAR value[MAX_PATH]; + DWORD bufferSize = sizeof(value); + ZeroMemory(value, bufferSize); + + if (RegQueryValueEx(key, + L"SystemDefaultEUDCFont", + nullptr, + nullptr, + reinterpret_cast(value), + &bufferSize) == ERROR_SUCCESS) { + path = QString::fromWCharArray(value); + } + + RegCloseKey(key); + } + + if (!path.isEmpty()) { + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) { + qCWarning(lcQpaFonts) << "Unable to open default EUDC font:" << path; + return; + } + + m_eudcFonts = addApplicationFont(file.readAll(), path); + } +} + void QWindowsFontDatabase::populateFontDatabase() { removeApplicationFonts(); @@ -1186,6 +1226,7 @@ void QWindowsFontDatabase::populateFontDatabase() QString systemDefaultFamily = QWindowsFontDatabase::systemDefaultFont().family(); if (QPlatformFontDatabase::resolveFontFamilyAlias(systemDefaultFamily) == systemDefaultFamily) QPlatformFontDatabase::registerFontFamily(systemDefaultFamily); + addDefaultEUDCFont(); } typedef QSharedPointer QWindowsFontEngineDataPtr; @@ -1583,6 +1624,7 @@ void QWindowsFontDatabase::removeApplicationFonts() } } m_applicationFonts.clear(); + m_eudcFonts.clear(); } void QWindowsFontDatabase::releaseHandle(void *handle) @@ -1842,7 +1884,7 @@ QString QWindowsFontDatabase::familyForStyleHint(QFont::StyleHint styleHint) QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const { - QStringList result; + QStringList result = m_eudcFonts; result.append(QWindowsFontDatabase::familyForStyleHint(styleHint)); result.append(QWindowsFontDatabase::extraTryFontsForFamily(family)); result.append(QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script)); diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h index bbdb90f70a..c01a03c7b4 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h @@ -134,6 +134,7 @@ public: private: void removeApplicationFonts(); + void addDefaultEUDCFont(); struct WinApplicationFont { HANDLE handle; @@ -150,6 +151,7 @@ private: QMap m_uniqueFontData; static unsigned m_fontOptions; + QStringList m_eudcFonts; }; #ifndef QT_NO_DEBUG_STREAM -- cgit v1.2.3