summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp232
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp15
4 files changed, 154 insertions, 114 deletions
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 8f48efc7f9..b397b12311 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -675,6 +675,8 @@ static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned c
#ifndef Q_OS_WINCE
const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags);
#else
+// Under Windows CE we don't use ChildWindowFromPointEx as it's not available
+// and ChildWindowFromPoint does not work properly.
Q_UNUSED(cwexFlags)
const HWND child = WindowFromPoint(point);
#endif
@@ -683,7 +685,13 @@ static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned c
if (QWindowsWindow *window = context->findPlatformWindow(child)) {
*result = window;
*hwnd = child;
+#ifndef Q_OS_WINCE
return true;
+#else
+// WindowFromPoint does not return same handle in two sequential calls, which leads
+// to an endless loop, but calling WindowFromPoint once is good enough.
+ return false;
+#endif
}
#ifndef Q_OS_WINCE // Does not have WS_EX_TRANSPARENT .
// QTBUG-40555: despite CWP_SKIPINVISIBLE, it is possible to hit on invisible
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index ef74ef35f5..56adae8ffb 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -1674,8 +1674,10 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request,
HFONT hfont = 0;
hfont = CreateFontIndirect(&lf);
- if (!hfont)
+ if (!hfont) {
qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__);
+ hfont = QWindowsFontDatabase::systemFont();
+ }
bool ttf = false;
int avWidth = 0;
@@ -1689,18 +1691,17 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request,
SelectObject(data->hdc, oldObj);
if (!useDirectWrite) {
- if (hfont && (!ttf || request.stretch != 100)) {
+ if (!ttf || request.stretch != 100) {
DeleteObject(hfont);
if (!res)
qErrnoWarning("%s: GetTextMetrics failed", __FUNCTION__);
lf.lfWidth = avWidth * request.stretch/100;
hfont = CreateFontIndirect(&lf);
- if (!hfont)
+ if (!hfont) {
qErrnoWarning("%s: CreateFontIndirect with stretch failed", __FUNCTION__);
+ hfont = QWindowsFontDatabase::systemFont();
+ }
}
-
- if (!hfont)
- hfont = QWindowsFontDatabase::systemFont();
}
#if !defined(QT_NO_DIRECTWRITE)
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index 0c294c2727..d1ea8a798f 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -41,6 +41,7 @@
#include <QtCore/QDir>
#include <QtCore/QDirIterator>
#include <QtCore/QSettings>
+#include <QtCore/QRegularExpression>
#include <QtGui/private/qfontengine_ft_p.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QFontDatabase>
@@ -101,7 +102,67 @@ static FontFile * createFontFile(const QString &fileName, int index)
extern bool localizedName(const QString &name);
extern QString getEnglishName(const QString &familyName);
-#ifdef Q_OS_WINCE
+#ifndef Q_OS_WINCE
+
+namespace {
+struct FontKey
+{
+ QString fileName;
+ QStringList fontNames;
+};
+} // namespace
+
+typedef QVector<FontKey> FontKeys;
+
+static FontKeys &fontKeys()
+{
+ static FontKeys result;
+ if (result.isEmpty()) {
+ const QSettings fontRegistry(QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"),
+ QSettings::NativeFormat);
+ const QStringList allKeys = fontRegistry.allKeys();
+ const QString trueType = QStringLiteral("(TrueType)");
+ const QRegularExpression sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+"));
+ Q_ASSERT(sizeListMatch.isValid());
+ const int size = allKeys.size();
+ result.reserve(size);
+ for (int i = 0; i < size; ++i) {
+ FontKey fontKey;
+ const QString &registryFontKey = allKeys.at(i);
+ fontKey.fileName = fontRegistry.value(registryFontKey).toString();
+ QString realKey = registryFontKey;
+ realKey.remove(trueType);
+ realKey.remove(sizeListMatch);
+ const QStringList fontNames = realKey.trimmed().split(QLatin1Char('&'));
+ fontKey.fontNames.reserve(fontNames.size());
+ foreach (const QString &fontName, fontNames)
+ fontKey.fontNames.append(fontName.trimmed());
+ result.append(fontKey);
+ }
+ }
+ return result;
+}
+
+static const FontKey *findFontKey(const QString &name, int *indexIn = Q_NULLPTR)
+{
+ typedef FontKeys::ConstIterator ConstIt;
+
+ const FontKeys &keys = fontKeys();
+ for (ConstIt it = keys.constBegin(), cend = keys.constEnd(); it != cend; ++it) {
+ const int index = it->fontNames.indexOf(name);
+ if (index >= 0) {
+ if (indexIn)
+ *indexIn = index;
+ return &(*it);
+ }
+ }
+ if (indexIn)
+ *indexIn = -1;
+ return Q_NULLPTR;
+}
+
+#else // Q_OS_WINCE
+
typedef struct {
quint16 majorVersion;
quint16 minorVersion;
@@ -220,24 +281,67 @@ static QString fontNameFromTTFile(const QString &filename)
}
return retVal;
}
+
+static inline QString fontSettingsOrganization() { return QStringLiteral("Qt-Project"); }
+static inline QString fontSettingsApplication() { return QStringLiteral("Qtbase"); }
+static inline QString fontSettingsGroup() { return QStringLiteral("CEFontCache"); }
+
+static QString findFontFile(const QString &faceName)
+{
+ static QHash<QString, QString> fontCache;
+
+ if (fontCache.isEmpty()) {
+ QSettings settings(QSettings::SystemScope, fontSettingsOrganization(), fontSettingsApplication());
+ settings.beginGroup(fontSettingsGroup());
+ foreach (const QString &fontName, settings.allKeys())
+ fontCache.insert(fontName, settings.value(fontName).toString());
+ settings.endGroup();
+ }
+
+ QString value = fontCache.value(faceName);
+
+ //Fallback if we haven't cached the font yet or the font got removed/renamed iterate again over all fonts
+ if (value.isEmpty() || !QFile::exists(value)) {
+ QSettings settings(QSettings::SystemScope, fontSettingsOrganization(), fontSettingsApplication());
+ settings.beginGroup(fontSettingsGroup());
+
+ //empty the cache first, as it seems that it is dirty
+ settings.remove(QString());
+
+ QDirIterator it(QStringLiteral("/Windows"), QStringList(QStringLiteral("*.ttf")), QDir::Files | QDir::Hidden | QDir::System);
+
+ while (it.hasNext()) {
+ const QString fontFile = it.next();
+ const QString fontName = fontNameFromTTFile(fontFile);
+ if (fontName.isEmpty())
+ continue;
+ fontCache.insert(fontName, fontFile);
+ settings.setValue(fontName, fontFile);
+
+ if (localizedName(fontName)) {
+ QString englishFontName = getEnglishName(fontName);
+ fontCache.insert(englishFontName, fontFile);
+ settings.setValue(englishFontName, fontFile);
+ }
+ }
+ settings.endGroup();
+ value = fontCache.value(faceName);
+ }
+ return value;
+}
#endif // Q_OS_WINCE
-static bool addFontToDatabase(const QString &familyName, uchar charSet,
+static bool addFontToDatabase(const QString &faceName,
+ const QString &fullName,
+ uchar charSet,
const TEXTMETRIC *textmetric,
const FONTSIGNATURE *signature,
int type)
{
- typedef QPair<QString, QStringList> FontKey;
-
// the "@family" fonts are just the same as "family". Ignore them.
- if (familyName.isEmpty() || familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QLatin1String("WST_")))
+ if (faceName.isEmpty() || faceName.at(0) == QLatin1Char('@') || faceName.startsWith(QLatin1String("WST_")))
return false;
- const int separatorPos = familyName.indexOf(QStringLiteral("::"));
- const QString faceName =
- separatorPos != -1 ? familyName.left(separatorPos) : familyName;
- const QString fullName =
- separatorPos != -1 ? familyName.mid(separatorPos + 2) : QString();
static const int SMOOTH_SCALABLE = 0xffff;
const QString foundryName; // No such concept.
const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric;
@@ -254,7 +358,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
if (QWindowsContext::verbose > 2) {
QString message;
QTextStream str(&message);
- str << __FUNCTION__ << ' ' << familyName << ' ' << charSet << " TTF=" << ttf;
+ str << __FUNCTION__ << ' ' << faceName << "::" << fullName << ' ' << charSet << " TTF=" << ttf;
if (type & DEVICE_FONTTYPE)
str << " DEVICE";
if (type & RASTER_FONTTYPE)
@@ -297,93 +401,19 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
writingSystems.setSupported(ws);
}
-#ifndef Q_OS_WINCE
- const QSettings fontRegistry(QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"),
- QSettings::NativeFormat);
-
- static QVector<FontKey> allFonts;
- if (allFonts.isEmpty()) {
- const QStringList allKeys = fontRegistry.allKeys();
- allFonts.reserve(allKeys.size());
- const QString trueType = QStringLiteral("(TrueType)");
- const QRegExp sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+"));
- foreach (const QString &key, allKeys) {
- QString realKey = key;
- realKey.remove(trueType);
- realKey.remove(sizeListMatch);
- QStringList fonts;
- const QStringList fontNames = realKey.trimmed().split(QLatin1Char('&'));
- foreach (const QString &fontName, fontNames)
- fonts.push_back(fontName.trimmed());
- allFonts.push_back(FontKey(key, fonts));
- }
- }
-
- QString value;
int index = 0;
- for (int k = 0; k < allFonts.size(); ++k) {
- const FontKey &fontKey = allFonts.at(k);
- for (int i = 0; i < fontKey.second.length(); ++i) {
- const QString &font = fontKey.second.at(i);
- if (font == faceName || fullName == font || englishName == font) {
- value = fontRegistry.value(fontKey.first).toString();
- index = i;
- break;
- }
- }
- if (!value.isEmpty())
- break;
+#ifndef Q_OS_WINCE
+ const FontKey *key = findFontKey(faceName, &index);
+ if (!key) {
+ key = findFontKey(fullName, &index);
+ if (!key && !englishName.isEmpty())
+ key = findFontKey(englishName, &index);
+ if (!key)
+ return false;
}
+ QString value = key->fileName;
#else
- QString value;
- int index = 0;
-
- static QHash<QString, QString> fontCache;
-
- if (fontCache.isEmpty()) {
- QSettings settings(QSettings::SystemScope, QStringLiteral("Qt-Project"), QStringLiteral("Qtbase"));
- settings.beginGroup(QStringLiteral("CEFontCache"));
-
- foreach (const QString &fontName, settings.allKeys()) {
- const QString fontFileName = settings.value(fontName).toString();
- fontCache.insert(fontName, fontFileName);
- }
-
- settings.endGroup(); // CEFontCache
- }
-
- value = fontCache.value(faceName);
-
- //Fallback if we haven't cached the font yet or the font got removed/renamed iterate again over all fonts
- if (value.isEmpty() || !QFile::exists(value)) {
- QSettings settings(QSettings::SystemScope, QStringLiteral("Qt-Project"), QStringLiteral("Qtbase"));
- settings.beginGroup(QStringLiteral("CEFontCache"));
-
- //empty the cache first, as it seems that it is dirty
- foreach (const QString &fontName, settings.allKeys())
- settings.remove(fontName);
-
- QDirIterator it(QStringLiteral("/Windows"), QStringList(QStringLiteral("*.ttf")), QDir::Files | QDir::Hidden | QDir::System);
-
- while (it.hasNext()) {
- const QString fontFile = it.next();
- const QString fontName = fontNameFromTTFile(fontFile);
- if (fontName.isEmpty())
- continue;
- fontCache.insert(fontName, fontFile);
- settings.setValue(fontName, fontFile);
-
- if (localizedName(fontName)) {
- QString englishFontName = getEnglishName(fontName);
- fontCache.insert(englishFontName, fontFile);
- settings.setValue(englishFontName, fontFile);
- }
- }
-
- value = fontCache.value(faceName);
-
- settings.endGroup(); // CEFontCache
- }
+ QString value = findFontFile(faceName);
#endif
if (value.isEmpty())
@@ -440,9 +470,9 @@ static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetr
int type, LPARAM namesSetIn)
{
typedef QSet<QString> StringSet;
- const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName)
- + QStringLiteral("::")
- + QString::fromWCharArray(f->elfFullName);
+
+ const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
+ const QString fullName = QString::fromWCharArray(f->elfFullName);
const uchar charSet = f->elfLogFont.lfCharSet;
#ifndef Q_OS_WINCE
@@ -476,8 +506,10 @@ static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetr
// 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
// anyway
- if (addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type))
- reinterpret_cast<StringSet *>(namesSetIn)->insert(familyName);
+ if (addFontToDatabase(faceName, fullName,
+ charSet, (TEXTMETRIC *)textmetric, &signature, type)) {
+ reinterpret_cast<StringSet *>(namesSetIn)->insert(faceName + QStringLiteral("::") + fullName);
+ }
// keep on enumerating
return 1;
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index db89402c05..0e26a17223 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -567,16 +567,15 @@ static inline int toKeyOrUnicode(int vk, int scancode, unsigned char *kbdBuffer,
Q_ASSERT(vk > 0 && vk < 256);
int code = 0;
QChar unicodeBuffer[5];
- // While key combinations containing alt and ctrl might trigger the third assignment of a key
- // (for example "alt+ctrl+q" causes '@' on a German layout), ToUnicode often does not return the
- // wanted character if only the ctrl modifier is used. Thus we unset this modifier temporarily
- // if it is not used together with alt.
- const unsigned char controlState = kbdBuffer[VK_MENU] ? 0 : kbdBuffer[VK_CONTROL];
- if (controlState)
- kbdBuffer[VK_CONTROL] = 0;
int res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
- if (controlState)
+ // When Ctrl modifier is used ToUnicode does not return correct values. In order to assign the
+ // right key the control modifier is removed for just that function if the previous call failed.
+ if (res == 0 && kbdBuffer[VK_CONTROL]) {
+ const unsigned char controlState = kbdBuffer[VK_CONTROL];
+ kbdBuffer[VK_CONTROL] = 0;
+ res = ToUnicode(vk, scancode, kbdBuffer, reinterpret_cast<LPWSTR>(unicodeBuffer), 5, 0);
kbdBuffer[VK_CONTROL] = controlState;
+ }
if (res)
code = unicodeBuffer[0].toUpper().unicode();