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/accessible/iaccessible2.cpp2
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp24
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp1
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json12
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h1
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp1952
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.h133
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp438
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.h68
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp1328
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h187
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp992
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h143
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h6
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.cpp150
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.h78
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp7
-rw-r--r--src/plugins/platforms/windows/windows.pri26
-rw-r--r--src/plugins/platforms/windows/windows.pro7
26 files changed, 45 insertions, 5531 deletions
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index 5ba49a8a98..d5cd9ac6db 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -41,7 +41,7 @@
#include "iaccessible2.h"
#include "qwindowsaccessibility.h"
-#include <QtPlatformSupport/private/qaccessiblebridgeutils_p.h>
+#include <QtAccessibilitySupport/private/qaccessiblebridgeutils_p.h>
#include <QtGui/qaccessible.h>
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
index 7cf24421f8..aed9c94003 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
@@ -47,13 +47,13 @@
#include <QtCore/qmap.h>
#include <QtCore/qpair.h>
#include <QtCore/qpointer.h>
-#include <QtCore/qsettings.h>
#include <QtGui/qaccessible.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformintegration.h>
#include <QtGui/qwindow.h>
#include <QtGui/qguiapplication.h>
+#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h> // registry helper
#include "qwindowsaccessibility.h"
#ifdef Q_CC_MINGW
@@ -114,6 +114,14 @@ static inline QString messageBoxAlertSound(const QObject *messageBox)
return QString();
}
+static QString soundFileName(const QString &soundName)
+{
+ const QString key = QStringLiteral("AppEvents\\Schemes\\Apps\\.Default\\")
+ + soundName + QStringLiteral("\\.Current");
+ return QWindowsFontDatabase::readRegistryString(HKEY_CURRENT_USER,
+ reinterpret_cast<const wchar_t *>(key.utf16()), L"");
+}
+
void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
{
QString soundName;
@@ -134,17 +142,9 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
break;
}
- if (!soundName.isEmpty()) {
-#ifndef QT_NO_SETTINGS
- QSettings settings(QLatin1String("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\") + soundName,
- QSettings::NativeFormat);
- QString file = settings.value(QLatin1String(".Current/.")).toString();
-#else
- QString file;
-#endif
- if (!file.isEmpty()) {
- PlaySound(reinterpret_cast<const wchar_t *>(soundName.utf16()), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT);
- }
+ if (!soundName.isEmpty() && !soundFileName(soundName).isEmpty()) {
+ PlaySound(reinterpret_cast<const wchar_t *>(soundName.utf16()), 0,
+ SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT);
}
// An event has to be associated with a window,
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index 5d4afe8fb2..06d481b3af 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -50,7 +50,6 @@
#include <QtCore/qdebug.h>
#include <QtCore/qmap.h>
#include <QtCore/qpair.h>
-#include <QtCore/qsettings.h>
#include <QtGui/qaccessible.h>
#include <QtGui/qguiapplication.h>
#include <qpa/qplatformnativeinterface.h>
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index 1e00da52eb..dd99e674ec 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -102,6 +102,18 @@
"features": [
"disable_desktopgl", "disable_d3d11", "disable_d3d9"
]
+ },
+ {
+ "id": 9,
+ "description": "Intel 945 crash (QTBUG-40991)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x27A2" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl"
+ ]
}
]
}
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 3b7374dc92..49c7144221 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -39,11 +39,11 @@
#include "qwindowsbackingstore.h"
#include "qwindowswindow.h"
-#include "qwindowsnativeimage.h"
#include "qwindowscontext.h"
#include <QtGui/QWindow>
#include <QtGui/QPainter>
+#include <QtFontDatabaseSupport/private/qwindowsnativeimage_p.h>
#include <private/qhighdpiscaling_p.h>
#include <private/qimage_p.h>
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index 21bc9d7377..d4a7e27762 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -53,7 +53,7 @@
#include <QtCore/QVariant>
#include <QtCore/QUrl>
-#include <QtPlatformSupport/private/qwindowsguieventdispatcher_p.h>
+#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 10d38f2a0c..40d4cb1497 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -73,7 +73,7 @@
#include <QtCore/QScopedArrayPointer>
#include <QtCore/private/qsystemlibrary_p.h>
-#include <QtPlatformSupport/private/qwindowsguieventdispatcher_p.h>
+#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
#include <stdlib.h>
#include <stdio.h>
@@ -85,7 +85,6 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows")
Q_LOGGING_CATEGORY(lcQpaBackingStore, "qt.qpa.backingstore")
Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
-Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
Q_LOGGING_CATEGORY(lcQpaGl, "qt.qpa.gl")
Q_LOGGING_CATEGORY(lcQpaMime, "qt.qpa.mime")
Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods")
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 843f7e2ad6..9dfde67797 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -59,7 +59,6 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaWindows)
Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStore)
Q_DECLARE_LOGGING_CATEGORY(lcQpaEvents)
-Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts)
Q_DECLARE_LOGGING_CATEGORY(lcQpaGl)
Q_DECLARE_LOGGING_CATEGORY(lcQpaMime)
Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods)
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
deleted file mode 100644
index 4f022141cf..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ /dev/null
@@ -1,1952 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsfontdatabase.h"
-#include "qwindowsfontdatabase_ft.h" // for default font
-#include "qwindowscontext.h"
-#include "qwindowsintegration.h"
-#include "qwindowsfontengine.h"
-#include "qwindowsfontenginedirectwrite.h"
-#include <QtCore/qt_windows.h>
-
-#include <QtGui/QFont>
-#include <QtGui/QGuiApplication>
-#include <QtGui/private/qhighdpiscaling_p.h>
-
-#include <QtCore/qmath.h>
-#include <QtCore/QDebug>
-#include <QtCore/QFile>
-#include <QtCore/QtEndian>
-#include <QtCore/QThreadStorage>
-#include <QtCore/private/qsystemlibrary_p.h>
-
-#include <wchar.h>
-
-#if !defined(QT_NO_DIRECTWRITE)
-# if defined(QT_USE_DIRECTWRITE2)
-# include <dwrite_2.h>
-# else
-# include <dwrite.h>
-# endif
-# include <d2d1.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_DIRECTWRITE
-// ### fixme: Consider direct linking of dwrite.dll once Windows Vista pre SP2 is dropped (QTBUG-49711)
-
-typedef HRESULT (WINAPI *DWriteCreateFactoryType)(DWRITE_FACTORY_TYPE, const IID &, IUnknown **);
-
-static inline DWriteCreateFactoryType resolveDWriteCreateFactory()
-{
- if (QSysInfo::windowsVersion() < QSysInfo::WV_VISTA)
- return Q_NULLPTR;
- QSystemLibrary library(QStringLiteral("dwrite"));
- QFunctionPointer result = library.resolve("DWriteCreateFactory");
- if (Q_UNLIKELY(!result)) {
- qWarning("Unable to load dwrite.dll");
- return Q_NULLPTR;
- }
- return reinterpret_cast<DWriteCreateFactoryType>(result);
-}
-
-static void createDirectWriteFactory(IDWriteFactory **factory)
-{
- *factory = Q_NULLPTR;
-
- static const DWriteCreateFactoryType dWriteCreateFactory = resolveDWriteCreateFactory();
- if (!dWriteCreateFactory)
- return;
-
- IUnknown *result = NULL;
-#if defined(QT_USE_DIRECTWRITE2)
- dWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory2), &result);
-#endif
-
- if (result == NULL) {
- if (FAILED(dWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &result))) {
- qErrnoWarning("DWriteCreateFactory failed");
- return;
- }
- }
-
- *factory = static_cast<IDWriteFactory *>(result);
-}
-
-static inline bool useDirectWrite(QFont::HintingPreference hintingPreference, bool isColorFont = false)
-{
- const unsigned options = QWindowsIntegration::instance()->options();
- if (Q_UNLIKELY(options & QWindowsIntegration::DontUseDirectWriteFonts))
- return false;
- if (isColorFont)
- return (options & QWindowsIntegration::DontUseColorFonts) == 0;
- return hintingPreference == QFont::PreferNoHinting
- || hintingPreference == QFont::PreferVerticalHinting
- || (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting);
-}
-#endif // !QT_NO_DIRECTWRITE
-
-// Helper classes for creating font engines directly from font data
-namespace {
-
-# pragma pack(1)
-
- // Common structure for all formats of the "name" table
- struct NameTable
- {
- quint16 format;
- quint16 count;
- quint16 stringOffset;
- };
-
- struct NameRecord
- {
- quint16 platformID;
- quint16 encodingID;
- quint16 languageID;
- quint16 nameID;
- quint16 length;
- quint16 offset;
- };
-
- struct OffsetSubTable
- {
- quint32 scalerType;
- quint16 numTables;
- quint16 searchRange;
- quint16 entrySelector;
- quint16 rangeShift;
- };
-
- struct TableDirectory
- {
- quint32 identifier;
- quint32 checkSum;
- quint32 offset;
- quint32 length;
- };
-
- struct OS2Table
- {
- quint16 version;
- qint16 avgCharWidth;
- quint16 weightClass;
- quint16 widthClass;
- quint16 type;
- qint16 subscriptXSize;
- qint16 subscriptYSize;
- qint16 subscriptXOffset;
- qint16 subscriptYOffset;
- qint16 superscriptXSize;
- qint16 superscriptYSize;
- qint16 superscriptXOffset;
- qint16 superscriptYOffset;
- qint16 strikeOutSize;
- qint16 strikeOutPosition;
- qint16 familyClass;
- quint8 panose[10];
- quint32 unicodeRanges[4];
- quint8 vendorID[4];
- quint16 selection;
- quint16 firstCharIndex;
- quint16 lastCharIndex;
- qint16 typoAscender;
- qint16 typoDescender;
- qint16 typoLineGap;
- quint16 winAscent;
- quint16 winDescent;
- quint32 codepageRanges[2];
- qint16 height;
- qint16 capHeight;
- quint16 defaultChar;
- quint16 breakChar;
- quint16 maxContext;
- };
-
-# pragma pack()
-
- class EmbeddedFont
- {
- public:
- EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) {}
-
- QString changeFamilyName(const QString &newFamilyName);
- QByteArray data() const { return m_fontData; }
- TableDirectory *tableDirectoryEntry(const QByteArray &tagName);
- QString familyName(TableDirectory *nameTableDirectory = 0);
-
- private:
- QByteArray m_fontData;
- };
-
- TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName)
- {
- Q_ASSERT(tagName.size() == 4);
- quint32 tagId = *(reinterpret_cast<const quint32 *>(tagName.constData()));
- const size_t fontDataSize = m_fontData.size();
- if (Q_UNLIKELY(fontDataSize < sizeof(OffsetSubTable)))
- return 0;
-
- OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data());
- TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1);
-
- const size_t tableCount = qFromBigEndian<quint16>(offsetSubTable->numTables);
- if (Q_UNLIKELY(fontDataSize < sizeof(OffsetSubTable) + sizeof(TableDirectory) * tableCount))
- return 0;
-
- TableDirectory *tableDirectoryEnd = tableDirectory + tableCount;
- for (TableDirectory *entry = tableDirectory; entry < tableDirectoryEnd; ++entry) {
- if (entry->identifier == tagId)
- return entry;
- }
-
- return 0;
- }
-
- QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry)
- {
- QString name;
-
- if (nameTableDirectoryEntry == 0)
- nameTableDirectoryEntry = tableDirectoryEntry("name");
-
- if (nameTableDirectoryEntry != 0) {
- quint32 offset = qFromBigEndian<quint32>(nameTableDirectoryEntry->offset);
- if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameTable)))
- return QString();
-
- NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data() + offset);
- NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
-
- quint16 nameTableCount = qFromBigEndian<quint16>(nameTable->count);
- if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameRecord) * nameTableCount))
- return QString();
-
- for (int i = 0; i < nameTableCount; ++i, ++nameRecord) {
- if (qFromBigEndian<quint16>(nameRecord->nameID) == 1
- && qFromBigEndian<quint16>(nameRecord->platformID) == 3 // Windows
- && qFromBigEndian<quint16>(nameRecord->languageID) == 0x0409) { // US English
- quint16 stringOffset = qFromBigEndian<quint16>(nameTable->stringOffset);
- quint16 nameOffset = qFromBigEndian<quint16>(nameRecord->offset);
- quint16 nameLength = qFromBigEndian<quint16>(nameRecord->length);
-
- if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + stringOffset + nameOffset + nameLength))
- return QString();
-
- const void *ptr = reinterpret_cast<const quint8 *>(nameTable)
- + stringOffset
- + nameOffset;
-
- const quint16 *s = reinterpret_cast<const quint16 *>(ptr);
- const quint16 *e = s + nameLength / sizeof(quint16);
- while (s != e)
- name += QChar( qFromBigEndian<quint16>(*s++));
- break;
- }
- }
- }
-
- return name;
- }
-
- QString EmbeddedFont::changeFamilyName(const QString &newFamilyName)
- {
- TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name");
- if (nameTableDirectoryEntry == 0)
- return QString();
-
- QString oldFamilyName = familyName(nameTableDirectoryEntry);
-
- // Reserve size for name table header, five required name records and string
- const int requiredRecordCount = 5;
- quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 };
-
- int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount;
- int newFamilyNameSize = newFamilyName.size() * int(sizeof(quint16));
-
- const QString regularString = QString::fromLatin1("Regular");
- int regularStringSize = regularString.size() * int(sizeof(quint16));
-
- // Align table size of table to 32 bits (pad with 0)
- int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4;
-
- QByteArray newNameTable(fullSize, char(0));
-
- {
- NameTable *nameTable = reinterpret_cast<NameTable *>(newNameTable.data());
- nameTable->count = qbswap<quint16>(requiredRecordCount);
- nameTable->stringOffset = qbswap<quint16>(sizeOfHeader);
-
- NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
- for (int i = 0; i < requiredRecordCount; ++i, nameRecord++) {
- nameRecord->nameID = qbswap<quint16>(nameIds[i]);
- nameRecord->encodingID = qbswap<quint16>(1);
- nameRecord->languageID = qbswap<quint16>(0x0409);
- nameRecord->platformID = qbswap<quint16>(3);
- nameRecord->length = qbswap<quint16>(newFamilyNameSize);
-
- // Special case for sub-family
- if (nameIds[i] == 4) {
- nameRecord->offset = qbswap<quint16>(newFamilyNameSize);
- nameRecord->length = qbswap<quint16>(regularStringSize);
- }
- }
-
- // nameRecord now points to string data
- quint16 *stringStorage = reinterpret_cast<quint16 *>(nameRecord);
- const quint16 *sourceString = newFamilyName.utf16();
- for (int i = 0; i < newFamilyName.size(); ++i)
- stringStorage[i] = qbswap<quint16>(sourceString[i]);
- stringStorage += newFamilyName.size();
-
- sourceString = regularString.utf16();
- for (int i = 0; i < regularString.size(); ++i)
- stringStorage[i] = qbswap<quint16>(sourceString[i]);
- }
-
- quint32 *p = reinterpret_cast<quint32 *>(newNameTable.data());
- quint32 *tableEnd = reinterpret_cast<quint32 *>(newNameTable.data() + fullSize);
-
- quint32 checkSum = 0;
- while (p < tableEnd)
- checkSum += qFromBigEndian<quint32>(*(p++));
-
- nameTableDirectoryEntry->checkSum = qbswap<quint32>(checkSum);
- nameTableDirectoryEntry->offset = qbswap<quint32>(m_fontData.size());
- nameTableDirectoryEntry->length = qbswap<quint32>(fullSize);
-
- m_fontData.append(newNameTable);
-
- return oldFamilyName;
- }
-
-#if !defined(QT_NO_DIRECTWRITE)
-
- class DirectWriteFontFileStream: public IDWriteFontFileStream
- {
- public:
- DirectWriteFontFileStream(const QByteArray &fontData)
- : m_fontData(fontData)
- , m_referenceCount(0)
- {
- }
- virtual ~DirectWriteFontFileStream()
- {
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset,
- UINT64 fragmentSize, OUT void **fragmentContext);
- void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext);
- HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize);
- HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime);
-
- private:
- QByteArray m_fontData;
- ULONG m_referenceCount;
- };
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object)
- {
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
- *object = this;
- AddRef();
- return S_OK;
- } else {
- *object = NULL;
- return E_NOINTERFACE;
- }
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef()
- {
- return InterlockedIncrement(&m_referenceCount);
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release()
- {
- ULONG newCount = InterlockedDecrement(&m_referenceCount);
- if (newCount == 0)
- delete this;
- return newCount;
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment(
- const void **fragmentStart,
- UINT64 fileOffset,
- UINT64 fragmentSize,
- OUT void **fragmentContext)
- {
- *fragmentContext = NULL;
- if (fileOffset + fragmentSize <= quint64(m_fontData.size())) {
- *fragmentStart = m_fontData.data() + fileOffset;
- return S_OK;
- } else {
- *fragmentStart = NULL;
- return E_FAIL;
- }
- }
-
- void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *)
- {
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize)
- {
- *fileSize = m_fontData.size();
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime)
- {
- *lastWriteTime = 0;
- return E_NOTIMPL;
- }
-
- class DirectWriteFontFileLoader: public IDWriteFontFileLoader
- {
- public:
- DirectWriteFontFileLoader() : m_referenceCount(0) {}
- virtual ~DirectWriteFontFileLoader()
- {
- }
-
- inline void addKey(const void *key, const QByteArray &fontData)
- {
- Q_ASSERT(!m_fontDatas.contains(key));
- m_fontDatas.insert(key, fontData);
- }
-
- inline void removeKey(const void *key)
- {
- m_fontDatas.remove(key);
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- OUT IDWriteFontFileStream **fontFileStream);
-
- private:
- ULONG m_referenceCount;
- QHash<const void *, QByteArray> m_fontDatas;
- };
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid,
- void **object)
- {
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
- *object = this;
- AddRef();
- return S_OK;
- } else {
- *object = NULL;
- return E_NOINTERFACE;
- }
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef()
- {
- return InterlockedIncrement(&m_referenceCount);
- }
-
- ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release()
- {
- ULONG newCount = InterlockedDecrement(&m_referenceCount);
- if (newCount == 0)
- delete this;
- return newCount;
- }
-
- HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey(
- void const *fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- IDWriteFontFileStream **fontFileStream)
- {
- Q_UNUSED(fontFileReferenceKeySize);
-
- if (fontFileReferenceKeySize != sizeof(const void *)) {
- qWarning("%s: Wrong key size", __FUNCTION__);
- return E_FAIL;
- }
-
- const void *key = *reinterpret_cast<void * const *>(fontFileReferenceKey);
- *fontFileStream = NULL;
- if (!m_fontDatas.contains(key))
- return E_FAIL;
-
- QByteArray fontData = m_fontDatas.value(key);
- DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData);
- stream->AddRef();
- *fontFileStream = stream;
-
- return S_OK;
- }
-
- class CustomFontFileLoader
- {
- public:
- CustomFontFileLoader() : m_directWriteFontFileLoader(Q_NULLPTR)
- {
- createDirectWriteFactory(&m_directWriteFactory);
-
- if (m_directWriteFactory) {
- m_directWriteFontFileLoader = new DirectWriteFontFileLoader();
- m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader);
- }
- }
-
- ~CustomFontFileLoader()
- {
- if (m_directWriteFactory != 0 && m_directWriteFontFileLoader != 0)
- m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader);
-
- if (m_directWriteFactory != 0)
- m_directWriteFactory->Release();
- }
-
- void addKey(const void *key, const QByteArray &fontData)
- {
- if (m_directWriteFontFileLoader != 0)
- m_directWriteFontFileLoader->addKey(key, fontData);
- }
-
- void removeKey(const void *key)
- {
- if (m_directWriteFontFileLoader != 0)
- m_directWriteFontFileLoader->removeKey(key);
- }
-
- IDWriteFontFileLoader *loader() const
- {
- return m_directWriteFontFileLoader;
- }
-
- private:
- IDWriteFactory *m_directWriteFactory;
- DirectWriteFontFileLoader *m_directWriteFontFileLoader;
- };
-
-#endif
-
-} // Anonymous namespace
-
-/*!
- \struct QWindowsFontEngineData
- \brief Static constant data shared by the font engines.
- \ingroup qt-lighthouse-win
-*/
-
-QWindowsFontEngineData::QWindowsFontEngineData()
- : clearTypeEnabled(false)
- , fontSmoothingGamma(QWindowsFontDatabase::fontSmoothingGamma())
-#if !defined(QT_NO_DIRECTWRITE)
- , directWriteFactory(0)
- , directWriteGdiInterop(0)
-#endif
-{
- // from qapplication_win.cpp
- UINT result = 0;
- if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0))
- clearTypeEnabled = (result == FE_FONTSMOOTHINGCLEARTYPE);
-
- const qreal gray_gamma = 2.31;
- for (int i=0; i<256; ++i)
- pow_gamma[i] = uint(qRound(qPow(i / qreal(255.), gray_gamma) * 2047));
-
- HDC displayDC = GetDC(0);
- hdc = CreateCompatibleDC(displayDC);
- ReleaseDC(0, displayDC);
-}
-
-QWindowsFontEngineData::~QWindowsFontEngineData()
-{
- if (hdc)
- DeleteDC(hdc);
-#if !defined(QT_NO_DIRECTWRITE)
- if (directWriteGdiInterop)
- directWriteGdiInterop->Release();
- if (directWriteFactory)
- directWriteFactory->Release();
-#endif
-}
-
-qreal QWindowsFontDatabase::fontSmoothingGamma()
-{
- int winSmooth;
- qreal result = 1;
- if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0))
- result = qreal(winSmooth) / qreal(1000.0);
-
- // Safeguard ourselves against corrupt registry values...
- if (result > 5 || result < 1)
- result = qreal(1.4);
- return result;
-}
-
-#if !defined(QT_NO_DIRECTWRITE)
-static inline bool initDirectWrite(QWindowsFontEngineData *d)
-{
- if (!d->directWriteFactory) {
- createDirectWriteFactory(&d->directWriteFactory);
- if (!d->directWriteFactory)
- return false;
- }
- if (!d->directWriteGdiInterop) {
- const HRESULT hr = d->directWriteFactory->GetGdiInterop(&d->directWriteGdiInterop);
- if (FAILED(hr)) {
- qErrnoWarning("%s: GetGdiInterop failed", __FUNCTION__);
- return false;
- }
- }
- return true;
-}
-
-#endif // !defined(QT_NO_DIRECTWRITE)
-
-/*!
- \class QWindowsFontDatabase
- \brief Font database for Windows
-
- \note The Qt 4.8 WIndows font database employed a mechanism of
- delayed population of the database again passing a font name
- to EnumFontFamiliesEx(), working around the fact that
- EnumFontFamiliesEx() does not list all fonts by default.
- This should be introduced to Lighthouse as well?
-
- \internal
- \ingroup qt-lighthouse-win
-*/
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const QFontDef &def)
-{
- QDebugStateSaver saver(d);
- d.nospace();
- d.noquote();
- d << "QFontDef(Family=\"" << def.family << '"';
- if (!def.styleName.isEmpty())
- d << ", stylename=" << def.styleName;
- d << ", pointsize=" << def.pointSize << ", pixelsize=" << def.pixelSize
- << ", styleHint=" << def.styleHint << ", weight=" << def.weight
- << ", stretch=" << def.stretch << ", hintingPreference="
- << def.hintingPreference << ')';
- return d;
-}
-
-QDebug operator<<(QDebug d, const LOGFONT &lf)
-{
- QDebugStateSaver saver(d);
- d.nospace();
- d.noquote();
- d << "LOGFONT(\"" << QString::fromWCharArray(lf.lfFaceName)
- << "\", lfWidth=" << lf.lfWidth << ", lfHeight=" << lf.lfHeight << ')';
- return d;
-}
-#endif // !QT_NO_DEBUG_STREAM
-
-static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSet)
-{
- switch (charSet) {
- case ANSI_CHARSET:
- case EASTEUROPE_CHARSET:
- case BALTIC_CHARSET:
- case TURKISH_CHARSET:
- return QFontDatabase::Latin;
- case GREEK_CHARSET:
- return QFontDatabase::Greek;
- case RUSSIAN_CHARSET:
- return QFontDatabase::Cyrillic;
- case HEBREW_CHARSET:
- return QFontDatabase::Hebrew;
- case ARABIC_CHARSET:
- return QFontDatabase::Arabic;
- case THAI_CHARSET:
- return QFontDatabase::Thai;
- case GB2312_CHARSET:
- return QFontDatabase::SimplifiedChinese;
- case CHINESEBIG5_CHARSET:
- return QFontDatabase::TraditionalChinese;
- case SHIFTJIS_CHARSET:
- return QFontDatabase::Japanese;
- case HANGUL_CHARSET:
- case JOHAB_CHARSET:
- return QFontDatabase::Korean;
- case VIETNAMESE_CHARSET:
- return QFontDatabase::Vietnamese;
- case SYMBOL_CHARSET:
- return QFontDatabase::Symbol;
- default:
- break;
- }
- return QFontDatabase::Any;
-}
-
-#ifdef MAKE_TAG
-#undef MAKE_TAG
-#endif
-// GetFontData expects the tags in little endian ;(
-#define MAKE_TAG(ch1, ch2, ch3, ch4) (\
- (((quint32)(ch4)) << 24) | \
- (((quint32)(ch3)) << 16) | \
- (((quint32)(ch2)) << 8) | \
- ((quint32)(ch1)) \
- )
-
-bool localizedName(const QString &name)
-{
- const QChar *c = name.unicode();
- for (int i = 0; i < name.length(); ++i) {
- if (c[i].unicode() >= 0x100)
- return true;
- }
- return false;
-}
-
-static inline quint16 getUShort(const unsigned char *p)
-{
- quint16 val;
- val = *p++ << 8;
- val |= *p;
-
- return val;
-}
-
-namespace {
-
-struct FontNames {
- QString name; // e.g. "DejaVu Sans Condensed"
- QString style; // e.g. "Italic"
- QString preferredName; // e.g. "DejaVu Sans"
- QString preferredStyle; // e.g. "Condensed Italic"
-};
-
-static QString readName(bool unicode, const uchar *string, int length)
-{
- QString out;
- if (unicode) {
- // utf16
-
- length /= 2;
- out.resize(length);
- QChar *uc = out.data();
- for (int i = 0; i < length; ++i)
- uc[i] = getUShort(string + 2*i);
- } else {
- // Apple Roman
-
- out.resize(length);
- QChar *uc = out.data();
- for (int i = 0; i < length; ++i)
- uc[i] = QLatin1Char(char(string[i]));
- }
- return out;
-}
-
-enum FieldTypeValue {
- FamilyId = 1,
- StyleId = 2,
- PreferredFamilyId = 16,
- PreferredStyleId = 17,
-};
-
-enum PlatformFieldValue {
- PlatformId_Unicode = 0,
- PlatformId_Apple = 1,
- PlatformId_Microsoft = 3
-};
-
-static FontNames getCanonicalFontNames(const uchar *table, quint32 bytes)
-{
- FontNames out;
- const int NameRecordSize = 12;
- const int MS_LangIdEnglish = 0x009;
-
- // get the name table
- quint16 count;
- quint16 string_offset;
- const unsigned char *names;
-
- if (bytes < 8)
- return out;
-
- if (getUShort(table) != 0)
- return out;
-
- count = getUShort(table+2);
- string_offset = getUShort(table+4);
- names = table + 6;
-
- if (string_offset >= bytes || 6 + count*NameRecordSize > string_offset)
- return out;
-
- enum PlatformIdType {
- NotFound = 0,
- Unicode = 1,
- Apple = 2,
- Microsoft = 3
- };
-
- PlatformIdType idStatus[4] = { NotFound, NotFound, NotFound, NotFound };
- int ids[4] = { -1, -1, -1, -1 };
-
- for (int i = 0; i < count; ++i) {
- // search for the correct name entries
-
- quint16 platform_id = getUShort(names + i*NameRecordSize);
- quint16 encoding_id = getUShort(names + 2 + i*NameRecordSize);
- quint16 language_id = getUShort(names + 4 + i*NameRecordSize);
- quint16 name_id = getUShort(names + 6 + i*NameRecordSize);
-
- PlatformIdType *idType = nullptr;
- int *id = nullptr;
-
- switch (name_id) {
- case FamilyId:
- idType = &idStatus[0];
- id = &ids[0];
- break;
- case StyleId:
- idType = &idStatus[1];
- id = &ids[1];
- break;
- case PreferredFamilyId:
- idType = &idStatus[2];
- id = &ids[2];
- break;
- case PreferredStyleId:
- idType = &idStatus[3];
- id = &ids[3];
- break;
- default:
- continue;
- }
-
- quint16 length = getUShort(names + 8 + i*NameRecordSize);
- quint16 offset = getUShort(names + 10 + i*NameRecordSize);
- if (DWORD(string_offset + offset + length) > bytes)
- continue;
-
- if ((platform_id == PlatformId_Microsoft
- && (encoding_id == 0 || encoding_id == 1))
- && (language_id & 0x3ff) == MS_LangIdEnglish
- && *idType < Microsoft) {
- *id = i;
- *idType = Microsoft;
- }
- // not sure if encoding id 4 for Unicode is utf16 or ucs4...
- else if (platform_id == PlatformId_Unicode && encoding_id < 4 && *idType < Unicode) {
- *id = i;
- *idType = Unicode;
- }
- else if (platform_id == PlatformId_Apple && encoding_id == 0 && language_id == 0 && *idType < Apple) {
- *id = i;
- *idType = Apple;
- }
- }
-
- QString strings[4];
- for (int i = 0; i < 4; ++i) {
- if (idStatus[i] == NotFound)
- continue;
- int id = ids[i];
- quint16 length = getUShort(names + 8 + id * NameRecordSize);
- quint16 offset = getUShort(names + 10 + id * NameRecordSize);
- const unsigned char *string = table + string_offset + offset;
- strings[i] = readName(idStatus[i] != Apple, string, length);
- }
-
- out.name = strings[0];
- out.style = strings[1];
- out.preferredName = strings[2];
- out.preferredStyle = strings[3];
- return out;
-}
-
-} // namespace
-
-QString getEnglishName(const QString &familyName, bool includeStyle = false)
-{
- QString i18n_name;
- QString faceName = familyName;
- faceName.truncate(LF_FACESIZE - 1);
-
- HDC hdc = GetDC( 0 );
- LOGFONT lf;
- memset(&lf, 0, sizeof(LOGFONT));
- faceName.toWCharArray(lf.lfFaceName);
- lf.lfFaceName[faceName.size()] = 0;
- lf.lfCharSet = DEFAULT_CHARSET;
- HFONT hfont = CreateFontIndirect(&lf);
-
- if (!hfont) {
- ReleaseDC(0, hdc);
- return QString();
- }
-
- HGDIOBJ oldobj = SelectObject( hdc, hfont );
-
- const DWORD name_tag = MAKE_TAG( 'n', 'a', 'm', 'e' );
-
- // get the name table
- unsigned char *table = 0;
-
- DWORD bytes = GetFontData( hdc, name_tag, 0, 0, 0 );
- if ( bytes == GDI_ERROR ) {
- // ### Unused variable
- // int err = GetLastError();
- goto error;
- }
-
- table = new unsigned char[bytes];
- GetFontData(hdc, name_tag, 0, table, bytes);
- if ( bytes == GDI_ERROR )
- goto error;
-
- {
- const FontNames names = getCanonicalFontNames(table, bytes);
- i18n_name = names.name;
- if (includeStyle)
- i18n_name += QLatin1Char(' ') + names.style;
- }
-error:
- delete [] table;
- SelectObject( hdc, oldobj );
- DeleteObject( hfont );
- ReleaseDC( 0, hdc );
-
- //qDebug("got i18n name of '%s' for font '%s'", i18n_name.latin1(), familyName.toLocal8Bit().data());
- return i18n_name;
-}
-
-static bool addFontToDatabase(const QString &familyName, const QString &styleName, uchar charSet,
- const TEXTMETRIC *textmetric,
- const FONTSIGNATURE *signature,
- int type,
- bool registerAlias)
-{
- // the "@family" fonts are just the same as "family". Ignore them.
- if (familyName.isEmpty() || familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QLatin1String("WST_")))
- return false;
-
- static const int SMOOTH_SCALABLE = 0xffff;
- const QString foundryName; // No such concept.
- const bool fixed = !(textmetric->tmPitchAndFamily & TMPF_FIXED_PITCH);
- const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE);
- const bool scalable = textmetric->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
- const int size = scalable ? SMOOTH_SCALABLE : textmetric->tmHeight;
- const QFont::Style style = textmetric->tmItalic ? QFont::StyleItalic : QFont::StyleNormal;
- const bool antialias = false;
- const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(textmetric->tmWeight);
- const QFont::Stretch stretch = QFont::Unstretched;
-
-#ifndef QT_NO_DEBUG_OUTPUT
- if (QWindowsContext::verbose > 2) {
- QString message;
- QTextStream str(&message);
- str << __FUNCTION__ << ' ' << familyName << ' ' << charSet << " TTF=" << ttf;
- if (type & DEVICE_FONTTYPE)
- str << " DEVICE";
- if (type & RASTER_FONTTYPE)
- str << " RASTER";
- if (type & TRUETYPE_FONTTYPE)
- str << " TRUETYPE";
- str << " scalable=" << scalable << " Size=" << size
- << " Style=" << style << " Weight=" << weight
- << " stretch=" << stretch;
- qCDebug(lcQpaFonts) << message;
- }
-#endif
-
- QString englishName;
- if (registerAlias && ttf && localizedName(familyName))
- englishName = getEnglishName(familyName);
-
- QSupportedWritingSystems writingSystems;
- if (type & TRUETYPE_FONTTYPE) {
- Q_ASSERT(signature);
- quint32 unicodeRange[4] = {
- signature->fsUsb[0], signature->fsUsb[1],
- signature->fsUsb[2], signature->fsUsb[3]
- };
- quint32 codePageRange[2] = {
- signature->fsCsb[0], signature->fsCsb[1]
- };
- writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
- // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains
- // the symbol for Baht, and Windows thus reports that it supports the Thai script.
- // Since it's the default UI font on this platform, most widgets will be unable to
- // display Thai text by default. As a temporary work around, we special case Segoe UI
- // and remove the Thai script from its list of supported writing systems.
- if (writingSystems.supported(QFontDatabase::Thai) &&
- familyName == QLatin1String("Segoe UI"))
- writingSystems.setSupported(QFontDatabase::Thai, false);
- } else {
- const QFontDatabase::WritingSystem ws = writingSystemFromCharSet(charSet);
- if (ws != QFontDatabase::Any)
- writingSystems.setSupported(ws);
- }
-
- QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight,
- style, stretch, antialias, scalable, size, fixed, writingSystems, 0);
- // add fonts windows can generate for us:
- if (weight <= QFont::DemiBold && styleName.isEmpty())
- QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold,
- style, stretch, antialias, scalable, size, fixed, writingSystems, 0);
- if (style != QFont::StyleItalic && styleName.isEmpty())
- QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, weight,
- QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, 0);
- if (weight <= QFont::DemiBold && style != QFont::StyleItalic && styleName.isEmpty())
- QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold,
- QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, 0);
-
- if (!englishName.isEmpty())
- QPlatformFontDatabase::registerAliasToFontFamily(familyName, englishName);
-
- return true;
-}
-
-static int QT_WIN_CALLBACK storeFont(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
- DWORD type, LPARAM lParam)
-{
- const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont);
- const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
- const QString styleName = QString::fromWCharArray(f->elfStyle);
- const uchar charSet = f->elfLogFont.lfCharSet;
- const bool registerAlias = bool(lParam);
-
- // NEWTEXTMETRICEX (passed for TT fonts) 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
- const FONTSIGNATURE *signature = Q_NULLPTR;
- if (type & TRUETYPE_FONTTYPE)
- signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig;
- addFontToDatabase(familyName, styleName, charSet, textmetric, signature, type, registerAlias);
-
- // keep on enumerating
- return 1;
-}
-
-void QWindowsFontDatabase::populateFamily(const QString &familyName, bool registerAlias)
-{
- qCDebug(lcQpaFonts) << familyName;
- if (familyName.size() >= LF_FACESIZE) {
- qCWarning(lcQpaFonts) << "Unable to enumerate family '" << familyName << '\'';
- return;
- }
- HDC dummy = GetDC(0);
- LOGFONT lf;
- lf.lfCharSet = DEFAULT_CHARSET;
- familyName.toWCharArray(lf.lfFaceName);
- lf.lfFaceName[familyName.size()] = 0;
- lf.lfPitchAndFamily = 0;
- EnumFontFamiliesEx(dummy, &lf, storeFont, LPARAM(registerAlias), 0);
- ReleaseDC(0, dummy);
-}
-
-void QWindowsFontDatabase::populateFamily(const QString &familyName)
-{
- populateFamily(familyName, false);
-}
-
-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(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
- DWORD, LPARAM lparam)
-{
- // the "@family" fonts are just the same as "family". Ignore them.
- const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont);
- 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;
-
- // Register current font's english name as alias
- const bool ttf = textmetric->tmPitchAndFamily & TMPF_TRUETYPE;
- if (ttf && localizedName(faceName)) {
- const QString englishName = getEnglishName(faceName);
- if (!englishName.isEmpty()) {
- QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName);
- // Check whether the system default font name is an alias of the current font family name,
- // as on Chinese Windows, where the system font "SimSun" is an alias to a font registered under a local name
- if (!context->seenSystemDefaultFont && englishName == 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, 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;
-
-#ifndef QT_NO_THREAD
-typedef QThreadStorage<QWindowsFontEngineDataPtr> FontEngineThreadLocalData;
-
-Q_GLOBAL_STATIC(FontEngineThreadLocalData, fontEngineThreadLocalData)
-
-QSharedPointer<QWindowsFontEngineData> sharedFontData()
-{
- FontEngineThreadLocalData *data = fontEngineThreadLocalData();
- if (!data->hasLocalData())
- data->setLocalData(QSharedPointer<QWindowsFontEngineData>::create());
- return data->localData();
-}
-#else // !QT_NO_THREAD
-Q_GLOBAL_STATIC(QWindowsFontEngineDataPtr, fontEngineData)
-
-QWindowsFontEngineDataPtr sharedFontData()
-{
- QWindowsFontEngineDataPtr *data = fontEngineData();
- if (data->isNull())
- *data = QWindowsFontEngineDataPtr::create();
- return *data;
-}
-#endif // QT_NO_THREAD
-
-extern Q_GUI_EXPORT bool qt_needs_a8_gamma_correction;
-
-QWindowsFontDatabase::QWindowsFontDatabase()
-{
- // Properties accessed by QWin32PrintEngine (Qt Print Support)
- static const int hfontMetaTypeId = qRegisterMetaType<HFONT>();
- static const int logFontMetaTypeId = qRegisterMetaType<LOGFONT>();
- Q_UNUSED(hfontMetaTypeId)
- Q_UNUSED(logFontMetaTypeId)
-
- if (lcQpaFonts().isDebugEnabled()) {
- const QWindowsFontEngineDataPtr data = sharedFontData();
- qCDebug(lcQpaFonts) << __FUNCTION__ << "Clear type: "
- << data->clearTypeEnabled << "gamma: " << data->fontSmoothingGamma;
- }
- qt_needs_a8_gamma_correction = true;
-}
-
-QWindowsFontDatabase::~QWindowsFontDatabase()
-{
- removeApplicationFonts();
-}
-
-QFontEngineMulti *QWindowsFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
-{
- return new QWindowsMultiFontEngine(fontEngine, script);
-}
-
-QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
-{
- QFontEngine *fe = QWindowsFontDatabase::createEngine(fontDef,
- QWindowsContext::instance()->defaultDPI(),
- sharedFontData());
- qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << fe << handle;
- return fe;
-}
-
-QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
-{
- EmbeddedFont font(fontData);
- QFontEngine *fontEngine = 0;
-
-#if !defined(QT_NO_DIRECTWRITE)
- if (!useDirectWrite(hintingPreference))
-#endif
- {
- GUID guid;
- CoCreateGuid(&guid);
-
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_GCC("-Wstrict-aliasing")
- QString uniqueFamilyName = QLatin1Char('f')
- + QString::number(guid.Data1, 36) + QLatin1Char('-')
- + QString::number(guid.Data2, 36) + QLatin1Char('-')
- + QString::number(guid.Data3, 36) + QLatin1Char('-')
- + QString::number(*reinterpret_cast<quint64 *>(guid.Data4), 36);
-QT_WARNING_POP
-
- QString actualFontName = font.changeFamilyName(uniqueFamilyName);
- if (actualFontName.isEmpty()) {
- qWarning("%s: Can't change family name of font", __FUNCTION__);
- return 0;
- }
-
- DWORD count = 0;
- QByteArray newFontData = font.data();
- HANDLE fontHandle =
- AddFontMemResourceEx(const_cast<char *>(newFontData.constData()),
- DWORD(newFontData.size()), 0, &count);
- if (count == 0 && fontHandle != 0) {
- RemoveFontMemResourceEx(fontHandle);
- fontHandle = 0;
- }
-
- if (fontHandle == 0) {
- qWarning("%s: AddFontMemResourceEx failed", __FUNCTION__);
- } else {
- QFontDef request;
- request.family = uniqueFamilyName;
- request.pixelSize = pixelSize;
- request.styleStrategy = QFont::PreferMatch;
- request.hintingPreference = hintingPreference;
- request.stretch = QFont::Unstretched;
-
- fontEngine = QWindowsFontDatabase::createEngine(request,
- QWindowsContext::instance()->defaultDPI(),
- sharedFontData());
-
- if (fontEngine) {
- if (request.family != fontEngine->fontDef.family) {
- qWarning("%s: Failed to load font. Got fallback instead: %s",
- __FUNCTION__, qPrintable(fontEngine->fontDef.family));
- if (fontEngine->ref.load() == 0)
- delete fontEngine;
- fontEngine = 0;
- } else {
- Q_ASSERT(fontEngine->ref.load() == 0);
-
- // Override the generated font name
- switch (fontEngine->type()) {
- case QFontEngine::Win:
- static_cast<QWindowsFontEngine *>(fontEngine)->setUniqueFamilyName(uniqueFamilyName);
- fontEngine->fontDef.family = actualFontName;
- break;
-
-#if !defined(QT_NO_DIRECTWRITE)
- case QFontEngine::DirectWrite:
- static_cast<QWindowsFontEngineDirectWrite *>(fontEngine)->setUniqueFamilyName(uniqueFamilyName);
- fontEngine->fontDef.family = actualFontName;
- break;
-#endif // !QT_NO_DIRECTWRITE
-
- default:
- Q_ASSERT_X(false, Q_FUNC_INFO, "Unhandled font engine.");
- }
-
- UniqueFontData uniqueData;
- uniqueData.handle = fontHandle;
- uniqueData.refCount.ref();
- m_uniqueFontData[uniqueFamilyName] = uniqueData;
- }
- } else {
- RemoveFontMemResourceEx(fontHandle);
- }
- }
- }
-#if !defined(QT_NO_DIRECTWRITE)
- else {
- CustomFontFileLoader fontFileLoader;
- fontFileLoader.addKey(this, fontData);
-
- QSharedPointer<QWindowsFontEngineData> fontEngineData = sharedFontData();
- if (!initDirectWrite(fontEngineData.data()))
- return 0;
-
- IDWriteFontFile *fontFile = 0;
- void *key = this;
-
- HRESULT hres = fontEngineData->directWriteFactory->CreateCustomFontFileReference(&key,
- sizeof(void *),
- fontFileLoader.loader(),
- &fontFile);
- if (FAILED(hres)) {
- qErrnoWarning(hres, "%s: CreateCustomFontFileReference failed", __FUNCTION__);
- return 0;
- }
-
- BOOL isSupportedFontType;
- DWRITE_FONT_FILE_TYPE fontFileType;
- DWRITE_FONT_FACE_TYPE fontFaceType;
- UINT32 numberOfFaces;
- fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces);
- if (!isSupportedFontType) {
- fontFile->Release();
- return 0;
- }
-
- IDWriteFontFace *directWriteFontFace = 0;
- hres = fontEngineData->directWriteFactory->CreateFontFace(fontFaceType,
- 1,
- &fontFile,
- 0,
- DWRITE_FONT_SIMULATIONS_NONE,
- &directWriteFontFace);
- if (FAILED(hres)) {
- qErrnoWarning(hres, "%s: CreateFontFace failed", __FUNCTION__);
- fontFile->Release();
- return 0;
- }
-
- fontFile->Release();
-
- fontEngine = new QWindowsFontEngineDirectWrite(directWriteFontFace,
- pixelSize,
- fontEngineData);
-
- // Get font family from font data
- fontEngine->fontDef.family = font.familyName();
- fontEngine->fontDef.hintingPreference = hintingPreference;
-
- directWriteFontFace->Release();
- }
-#endif
-
- // Get style and weight info
- if (fontEngine != 0) {
- TableDirectory *os2TableEntry = font.tableDirectoryEntry("OS/2");
- if (os2TableEntry != 0) {
- const OS2Table *os2Table =
- reinterpret_cast<const OS2Table *>(fontData.constData()
- + qFromBigEndian<quint32>(os2TableEntry->offset));
-
- bool italic = qFromBigEndian<quint16>(os2Table->selection) & 1;
- bool oblique = qFromBigEndian<quint16>(os2Table->selection) & 128;
-
- if (italic)
- fontEngine->fontDef.style = QFont::StyleItalic;
- else if (oblique)
- fontEngine->fontDef.style = QFont::StyleOblique;
- else
- fontEngine->fontDef.style = QFont::StyleNormal;
-
- fontEngine->fontDef.weight = QPlatformFontDatabase::weightFromInteger(qFromBigEndian<quint16>(os2Table->weightClass));
- }
- }
-
- qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fontEngine;
- return fontEngine;
-}
-
-static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData)
-{
- QList<quint32> offsets;
- const quint32 headerTag = *reinterpret_cast<const quint32 *>(fontData);
- if (headerTag != MAKE_TAG('t', 't', 'c', 'f')) {
- if (headerTag != MAKE_TAG(0, 1, 0, 0)
- && headerTag != MAKE_TAG('O', 'T', 'T', 'O')
- && headerTag != MAKE_TAG('t', 'r', 'u', 'e')
- && headerTag != MAKE_TAG('t', 'y', 'p', '1'))
- return offsets;
- offsets << 0;
- return offsets;
- }
- const quint32 numFonts = qFromBigEndian<quint32>(fontData + 8);
- for (uint i = 0; i < numFonts; ++i) {
- offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4);
- }
- return offsets;
-}
-
-static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, const uchar **table, quint32 *length)
-{
- const quint16 numTables = qFromBigEndian<quint16>(data + 4);
- for (uint i = 0; i < numTables; ++i) {
- const quint32 offset = 12 + 16 * i;
- if (*reinterpret_cast<const quint32 *>(data + offset) == tag) {
- *table = fileBegin + qFromBigEndian<quint32>(data + offset + 8);
- *length = qFromBigEndian<quint32>(data + offset + 12);
- return;
- }
- }
- *table = 0;
- *length = 0;
- return;
-}
-
-static void getFamiliesAndSignatures(const QByteArray &fontData,
- QList<FontNames> *families,
- QVector<FONTSIGNATURE> *signatures)
-{
- const uchar *data = reinterpret_cast<const uchar *>(fontData.constData());
-
- QList<quint32> offsets = getTrueTypeFontOffsets(data);
- if (offsets.isEmpty())
- return;
-
- for (int i = 0; i < offsets.count(); ++i) {
- const uchar *font = data + offsets.at(i);
- const uchar *table;
- quint32 length;
- getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
- if (!table)
- continue;
- FontNames names = getCanonicalFontNames(table, length);
- if (names.name.isEmpty())
- continue;
-
- families->append(qMove(names));
-
- if (signatures) {
- FONTSIGNATURE signature;
- getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length);
- if (table && length >= 86) {
- // Offsets taken from OS/2 table in the TrueType spec
- signature.fsUsb[0] = qFromBigEndian<quint32>(table + 42);
- signature.fsUsb[1] = qFromBigEndian<quint32>(table + 46);
- signature.fsUsb[2] = qFromBigEndian<quint32>(table + 50);
- signature.fsUsb[3] = qFromBigEndian<quint32>(table + 54);
-
- signature.fsCsb[0] = qFromBigEndian<quint32>(table + 78);
- signature.fsCsb[1] = qFromBigEndian<quint32>(table + 82);
- } else {
- memset(&signature, 0, sizeof(signature));
- }
- signatures->append(signature);
- }
- }
-}
-
-QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
-{
- WinApplicationFont font;
- font.fileName = fileName;
- QVector<FONTSIGNATURE> signatures;
- QList<FontNames> families;
- QStringList familyNames;
-
- if (!fontData.isEmpty()) {
- getFamiliesAndSignatures(fontData, &families, &signatures);
- if (families.isEmpty())
- return familyNames;
-
- DWORD dummy = 0;
- font.handle =
- AddFontMemResourceEx(const_cast<char *>(fontData.constData()),
- DWORD(fontData.size()), 0, &dummy);
- if (font.handle == 0)
- return QStringList();
-
- // Memory fonts won't show up in enumeration, so do add them the hard way.
- for (int j = 0; j < families.count(); ++j) {
- const QString familyName = families.at(j).name;
- const QString styleName = families.at(j).style;
- familyNames << familyName;
- HDC hdc = GetDC(0);
- LOGFONT lf;
- memset(&lf, 0, sizeof(LOGFONT));
- memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE - 1, familyName.size()));
- lf.lfCharSet = DEFAULT_CHARSET;
- HFONT hfont = CreateFontIndirect(&lf);
- HGDIOBJ oldobj = SelectObject(hdc, hfont);
-
- TEXTMETRIC textMetrics;
- GetTextMetrics(hdc, &textMetrics);
-
- addFontToDatabase(familyName, styleName, lf.lfCharSet, &textMetrics, &signatures.at(j),
- TRUETYPE_FONTTYPE, true);
-
- SelectObject(hdc, oldobj);
- DeleteObject(hfont);
- ReleaseDC(0, hdc);
- }
- } else {
- QFile f(fileName);
- if (!f.open(QIODevice::ReadOnly))
- return QStringList();
- QByteArray data = f.readAll();
- f.close();
-
- getFamiliesAndSignatures(data, &families, 0);
- if (families.isEmpty())
- return QStringList();
-
- if (AddFontResourceExW((wchar_t*)fileName.utf16(), FR_PRIVATE, 0) == 0)
- return QStringList();
-
- font.handle = 0;
-
- // Fonts based on files are added via populate, as they will show up in font enumeration.
- for (int j = 0; j < families.count(); ++j) {
- const QString familyName = families.at(j).name;
- familyNames << familyName;
- populateFamily(familyName, true);
- }
- }
-
- m_applicationFonts << font;
-
- return familyNames;
-}
-
-void QWindowsFontDatabase::removeApplicationFonts()
-{
- foreach (const WinApplicationFont &font, m_applicationFonts) {
- if (font.handle) {
- RemoveFontMemResourceEx(font.handle);
- } else {
- RemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0);
- }
- }
- m_applicationFonts.clear();
-}
-
-void QWindowsFontDatabase::releaseHandle(void * /* handle */)
-{
-}
-
-QString QWindowsFontDatabase::fontDir() const
-{
- const QString result = QPlatformFontDatabase::fontDir();
- qCDebug(lcQpaFonts) << __FUNCTION__ << result;
- return result;
-}
-
-bool QWindowsFontDatabase::fontsAlwaysScalable() const
-{
- return true;
-}
-
-void QWindowsFontDatabase::derefUniqueFont(const QString &uniqueFont)
-{
- if (m_uniqueFontData.contains(uniqueFont)) {
- if (!m_uniqueFontData[uniqueFont].refCount.deref()) {
- RemoveFontMemResourceEx(m_uniqueFontData[uniqueFont].handle);
- m_uniqueFontData.remove(uniqueFont);
- }
- }
-}
-
-void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont)
-{
- if (m_uniqueFontData.contains(uniqueFont))
- m_uniqueFontData[uniqueFont].refCount.ref();
-}
-
-HFONT QWindowsFontDatabase::systemFont()
-{
- static const HFONT stock_sysfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
- return stock_sysfont;
-}
-
-// Creation functions
-
-static const char *other_tryFonts[] = {
- "Arial",
- "MS UI Gothic",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *jp_tryFonts [] = {
- "MS UI Gothic",
- "Arial",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_CN_tryFonts [] = {
- "SimSun",
- "Arial",
- "PMingLiU",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_TW_tryFonts [] = {
- "PMingLiU",
- "Arial",
- "SimSun",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *kr_tryFonts[] = {
- "Gulim",
- "Arial",
- "PMingLiU",
- "SimSun",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char **tryFonts = 0;
-
-LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request)
-{
- LOGFONT lf;
- memset(&lf, 0, sizeof(LOGFONT));
-
- lf.lfHeight = -qRound(request.pixelSize);
- lf.lfWidth = 0;
- lf.lfEscapement = 0;
- lf.lfOrientation = 0;
- if (request.weight == 50)
- lf.lfWeight = FW_DONTCARE;
- else
- lf.lfWeight = (request.weight*900)/99;
- lf.lfItalic = request.style != QFont::StyleNormal;
- lf.lfCharSet = DEFAULT_CHARSET;
-
- int strat = OUT_DEFAULT_PRECIS;
- if (request.styleStrategy & QFont::PreferBitmap) {
- strat = OUT_RASTER_PRECIS;
- } else if (request.styleStrategy & QFont::PreferDevice) {
- strat = OUT_DEVICE_PRECIS;
- } else if (request.styleStrategy & QFont::PreferOutline) {
- strat = OUT_OUTLINE_PRECIS;
- } else if (request.styleStrategy & QFont::ForceOutline) {
- strat = OUT_TT_ONLY_PRECIS;
- }
-
- lf.lfOutPrecision = strat;
-
- int qual = DEFAULT_QUALITY;
-
- if (request.styleStrategy & QFont::PreferMatch)
- qual = DRAFT_QUALITY;
- else if (request.styleStrategy & QFont::PreferQuality)
- qual = PROOF_QUALITY;
-
- if (request.styleStrategy & QFont::PreferAntialias) {
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && !(request.styleStrategy & QFont::NoSubpixelAntialias)) {
- qual = CLEARTYPE_QUALITY;
- } else {
- qual = ANTIALIASED_QUALITY;
- }
- } else if (request.styleStrategy & QFont::NoAntialias) {
- qual = NONANTIALIASED_QUALITY;
- } else if ((request.styleStrategy & QFont::NoSubpixelAntialias) && sharedFontData()->clearTypeEnabled) {
- qual = ANTIALIASED_QUALITY;
- }
-
- lf.lfQuality = qual;
-
- lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-
- int hint = FF_DONTCARE;
- switch (request.styleHint) {
- case QFont::Helvetica:
- hint = FF_SWISS;
- break;
- case QFont::Times:
- hint = FF_ROMAN;
- break;
- case QFont::Courier:
- hint = FF_MODERN;
- break;
- case QFont::OldEnglish:
- hint = FF_DECORATIVE;
- break;
- case QFont::System:
- hint = FF_MODERN;
- break;
- default:
- break;
- }
-
- lf.lfPitchAndFamily = DEFAULT_PITCH | hint;
-
- QString fam = request.family;
- if (Q_UNLIKELY(fam.size() >= LF_FACESIZE)) {
- qCritical("%s: Family name '%s' is too long.", __FUNCTION__, qPrintable(fam));
- fam.truncate(LF_FACESIZE - 1);
- }
-
- if (fam.isEmpty())
- fam = QStringLiteral("MS Sans Serif");
-
- if (fam == QLatin1String("MS Sans Serif")
- && (request.style == QFont::StyleItalic || (-lf.lfHeight > 18 && -lf.lfHeight != 24))) {
- fam = QStringLiteral("Arial"); // MS Sans Serif has bearing problems in italic, and does not scale
- }
- if (fam == QLatin1String("Courier") && !(request.styleStrategy & QFont::PreferBitmap))
- fam = QStringLiteral("Courier New");
-
- memcpy(lf.lfFaceName, fam.utf16(), fam.size() * sizeof(wchar_t));
-
- return lf;
-}
-
-QStringList QWindowsFontDatabase::extraTryFontsForFamily(const QString &family)
-{
- QStringList result;
- QFontDatabase db;
- if (!db.writingSystems(family).contains(QFontDatabase::Symbol)) {
- if (!tryFonts) {
- LANGID lid = GetUserDefaultLangID();
- switch (lid&0xff) {
- case LANG_CHINESE: // Chinese
- if ( lid == 0x0804 || lid == 0x1004) // China mainland and Singapore
- tryFonts = ch_CN_tryFonts;
- else
- tryFonts = ch_TW_tryFonts; // Taiwan, Hong Kong and Macau
- break;
- case LANG_JAPANESE:
- tryFonts = jp_tryFonts;
- break;
- case LANG_KOREAN:
- tryFonts = kr_tryFonts;
- break;
- default:
- tryFonts = other_tryFonts;
- break;
- }
- }
- QFontDatabase db;
- const QStringList families = db.families();
- const char **tf = tryFonts;
- while (tf && *tf) {
- // QTBUG-31689, family might be an English alias for a localized font name.
- const QString family = QString::fromLatin1(*tf);
- if (families.contains(family) || db.hasFamily(family))
- result << family;
- ++tf;
- }
- }
- result.append(QStringLiteral("Segoe UI Emoji"));
- result.append(QStringLiteral("Segoe UI Symbol"));
- return result;
-}
-
-QString QWindowsFontDatabase::familyForStyleHint(QFont::StyleHint styleHint)
-{
- switch (styleHint) {
- case QFont::Times:
- return QStringLiteral("Times New Roman");
- case QFont::Courier:
- return QStringLiteral("Courier New");
- case QFont::Monospace:
- return QStringLiteral("Courier New");
- case QFont::Cursive:
- return QStringLiteral("Comic Sans MS");
- case QFont::Fantasy:
- return QStringLiteral("Impact");
- case QFont::Decorative:
- return QStringLiteral("Old English");
- case QFont::Helvetica:
- return QStringLiteral("Arial");
- case QFont::System:
- default:
- break;
- }
- return QStringLiteral("MS Shell Dlg 2");
-}
-
-QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
-{
- QStringList result;
- result.append(QWindowsFontDatabase::familyForStyleHint(styleHint));
- result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
- result.append(QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script));
-
- qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
- << script << result;
- return result;
-}
-
-
-QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request,
- int dpi,
- const QSharedPointer<QWindowsFontEngineData> &data)
-{
- QFontEngine *fe = 0;
-
- LOGFONT lf = fontDefToLOGFONT(request);
- const bool preferClearTypeAA = lf.lfQuality == CLEARTYPE_QUALITY;
-
- if (request.stretch != 100) {
- HFONT hfont = CreateFontIndirect(&lf);
- if (!hfont) {
- qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__);
- hfont = QWindowsFontDatabase::systemFont();
- }
-
- HGDIOBJ oldObj = SelectObject(data->hdc, hfont);
- TEXTMETRIC tm;
- if (!GetTextMetrics(data->hdc, &tm))
- qErrnoWarning("%s: GetTextMetrics failed", __FUNCTION__);
- else
- lf.lfWidth = tm.tmAveCharWidth * request.stretch / 100;
- SelectObject(data->hdc, oldObj);
-
- DeleteObject(hfont);
- }
-
-#if !defined(QT_NO_DIRECTWRITE)
- if (initDirectWrite(data.data())) {
- const QString fam = QString::fromWCharArray(lf.lfFaceName);
- const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(fam);
- if (nameSubstitute != fam) {
- const int nameSubstituteLength = qMin(nameSubstitute.length(), LF_FACESIZE - 1);
- memcpy(lf.lfFaceName, nameSubstitute.utf16(), nameSubstituteLength * sizeof(wchar_t));
- lf.lfFaceName[nameSubstituteLength] = 0;
- }
-
- HFONT hfont = CreateFontIndirect(&lf);
- if (!hfont) {
- qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__);
- } else {
- HGDIOBJ oldFont = SelectObject(data->hdc, hfont);
-
- IDWriteFontFace *directWriteFontFace = NULL;
- HRESULT hr = data->directWriteGdiInterop->CreateFontFaceFromHdc(data->hdc, &directWriteFontFace);
- if (FAILED(hr)) {
- const QString errorString = qt_error_string(int(hr));
- qWarning().noquote().nospace() << "DirectWrite: CreateFontFaceFromHDC() failed ("
- << errorString << ") for " << request << ' ' << lf << " dpi=" << dpi;
- } else {
- bool isColorFont = false;
-#if defined(QT_USE_DIRECTWRITE2)
- IDWriteFontFace2 *directWriteFontFace2 = Q_NULLPTR;
- if (SUCCEEDED(directWriteFontFace->QueryInterface(__uuidof(IDWriteFontFace2),
- reinterpret_cast<void **>(&directWriteFontFace2)))) {
- if (directWriteFontFace2->IsColorFont())
- isColorFont = directWriteFontFace2->GetPaletteEntryCount() > 0;
- }
-#endif
- const QFont::HintingPreference hintingPreference =
- static_cast<QFont::HintingPreference>(request.hintingPreference);
- const bool useDw = useDirectWrite(hintingPreference, isColorFont);
- qCDebug(lcQpaFonts) << __FUNCTION__ << request.family << request.pointSize
- << "pt" << "hintingPreference=" << hintingPreference << "color=" << isColorFont
- << dpi << "dpi" << "useDirectWrite=" << useDw;
- if (useDw) {
- QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace,
- request.pixelSize,
- data);
-
- wchar_t n[64];
- GetTextFace(data->hdc, 64, n);
-
- QFontDef fontDef = request;
- fontDef.family = QString::fromWCharArray(n);
-
- if (isColorFont)
- fedw->glyphFormat = QFontEngine::Format_ARGB;
- fedw->initFontInfo(fontDef, dpi);
- fe = fedw;
- } else {
- directWriteFontFace->Release();
- }
- }
-
- SelectObject(data->hdc, oldFont);
- DeleteObject(hfont);
- }
- }
-#endif // QT_NO_DIRECTWRITE
-
- if (!fe) {
- QWindowsFontEngine *few = new QWindowsFontEngine(request.family, lf, data);
- if (preferClearTypeAA)
- few->glyphFormat = QFontEngine::Format_A32;
- few->initFontInfo(request, dpi);
- fe = few;
- }
-
- return fe;
-}
-
-static inline int verticalDPI()
-{
- return GetDeviceCaps(QWindowsContext::instance()->displayContext(), LOGPIXELSY);
-}
-
-QFont QWindowsFontDatabase::systemDefaultFont()
-{
- LOGFONT lf;
- GetObject(QWindowsFontDatabase::systemFont(), sizeof(lf), &lf);
- QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(lf);
- // "MS Shell Dlg 2" is the correct system font >= Win2k
- if (systemFont.family() == QLatin1String("MS Shell Dlg"))
- systemFont.setFamily(QStringLiteral("MS Shell Dlg 2"));
- qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont;
- return systemFont;
-}
-
-QFont QWindowsFontDatabase::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
-{
- if (verticalDPI_In <= 0)
- verticalDPI_In = verticalDPI();
- QFont qFont(QString::fromWCharArray(logFont.lfFaceName));
- qFont.setItalic(logFont.lfItalic);
- if (logFont.lfWeight != FW_DONTCARE)
- qFont.setWeight(QPlatformFontDatabase::weightFromInteger(logFont.lfWeight));
- const qreal logFontHeight = qAbs(logFont.lfHeight);
- qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
- qFont.setUnderline(logFont.lfUnderline);
- qFont.setOverline(false);
- qFont.setStrikeOut(logFont.lfStrikeOut);
- return qFont;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h
deleted file mode 100644
index 8b8c9c15f4..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSFONTDATABASE_H
-#define QWINDOWSFONTDATABASE_H
-
-#include <qpa/qplatformfontdatabase.h>
-#include <QtCore/QSharedPointer>
-#include <QtCore/qt_windows.h>
-
-#if !defined(QT_NO_DIRECTWRITE)
- struct IDWriteFactory;
- struct IDWriteGdiInterop;
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsFontEngineData
-{
- Q_DISABLE_COPY(QWindowsFontEngineData)
-public:
- QWindowsFontEngineData();
- ~QWindowsFontEngineData();
-
- uint pow_gamma[256];
-
- bool clearTypeEnabled;
- qreal fontSmoothingGamma;
- HDC hdc;
-#if !defined(QT_NO_DIRECTWRITE)
- IDWriteFactory *directWriteFactory;
- IDWriteGdiInterop *directWriteGdiInterop;
-#endif
-};
-
-class QWindowsFontDatabase : public QPlatformFontDatabase
-{
-public:
- QWindowsFontDatabase();
- ~QWindowsFontDatabase();
-
- void populateFontDatabase() Q_DECL_OVERRIDE;
- void populateFamily(const QString &familyName) 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 QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) Q_DECL_OVERRIDE;
- QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const Q_DECL_OVERRIDE;
- QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) Q_DECL_OVERRIDE;
- void releaseHandle(void *handle) Q_DECL_OVERRIDE;
- QString fontDir() const Q_DECL_OVERRIDE;
-
- QFont defaultFont() const Q_DECL_OVERRIDE { return systemDefaultFont(); }
- bool fontsAlwaysScalable() const Q_DECL_OVERRIDE;
- void derefUniqueFont(const QString &uniqueFont);
- void refUniqueFont(const QString &uniqueFont);
-
- static QFont systemDefaultFont();
-
- static QFontEngine *createEngine(const QFontDef &request,
- int dpi,
- const QSharedPointer<QWindowsFontEngineData> &data);
-
- static HFONT systemFont();
- static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
-
- static qreal fontSmoothingGamma();
- static LOGFONT fontDefToLOGFONT(const QFontDef &fontDef);
-
- static QStringList extraTryFontsForFamily(const QString &family);
- static QString familyForStyleHint(QFont::StyleHint styleHint);
-
-private:
- void populateFamily(const QString &familyName, bool registerAlias);
- void removeApplicationFonts();
-
- struct WinApplicationFont {
- HANDLE handle;
- QString fileName;
- };
-
- QList<WinApplicationFont> m_applicationFonts;
-
- struct UniqueFontData {
- HANDLE handle;
- QAtomicInt refCount;
- };
-
- QMap<QString, UniqueFontData> m_uniqueFontData;
-};
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug, const QFontDef &def);
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSFONTDATABASE_H
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
deleted file mode 100644
index f7c8dbdf23..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ /dev/null
@@ -1,438 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsfontdatabase_ft.h"
-#include "qwindowsfontdatabase.h"
-#include "qwindowscontext.h"
-
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-
-#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>
-
-#include <wchar.h>
-
-QT_BEGIN_NAMESPACE
-
-static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSet)
-{
- switch (charSet) {
- case ANSI_CHARSET:
- case EASTEUROPE_CHARSET:
- case BALTIC_CHARSET:
- case TURKISH_CHARSET:
- return QFontDatabase::Latin;
- case GREEK_CHARSET:
- return QFontDatabase::Greek;
- case RUSSIAN_CHARSET:
- return QFontDatabase::Cyrillic;
- case HEBREW_CHARSET:
- return QFontDatabase::Hebrew;
- case ARABIC_CHARSET:
- return QFontDatabase::Arabic;
- case THAI_CHARSET:
- return QFontDatabase::Thai;
- case GB2312_CHARSET:
- return QFontDatabase::SimplifiedChinese;
- case CHINESEBIG5_CHARSET:
- return QFontDatabase::TraditionalChinese;
- case SHIFTJIS_CHARSET:
- return QFontDatabase::Japanese;
- case HANGUL_CHARSET:
- case JOHAB_CHARSET:
- return QFontDatabase::Korean;
- case VIETNAMESE_CHARSET:
- return QFontDatabase::Vietnamese;
- case SYMBOL_CHARSET:
- return QFontDatabase::Symbol;
- default:
- break;
- }
- return QFontDatabase::Any;
-}
-
-static FontFile * createFontFile(const QString &fileName, int index)
-{
- FontFile *fontFile = new FontFile;
- fontFile->fileName = fileName;
- fontFile->indexValue = index;
- return fontFile;
-}
-
-extern bool localizedName(const QString &name);
-extern QString getEnglishName(const QString &familyName, bool includeStyle = false);
-
-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)");
-#ifndef QT_NO_REGULAREXPRESSION
- const QRegularExpression sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+"));
-#else
- const QRegExp sizeListMatch(QLatin1String("\\s(\\d+,)+\\d+"));
-#endif
- 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)
-{
- const FontKeys &keys = fontKeys();
- for (auto 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;
-}
-
-static bool addFontToDatabase(const QString &faceName,
- const QString &styleName,
- const QString &fullName,
- uchar charSet,
- const TEXTMETRIC *textmetric,
- const FONTSIGNATURE *signature,
- int type,
- bool registerAlias)
-{
- // the "@family" fonts are just the same as "family". Ignore them.
- if (faceName.isEmpty() || faceName.at(0) == QLatin1Char('@') || faceName.startsWith(QLatin1String("WST_")))
- return false;
-
- static const int SMOOTH_SCALABLE = 0xffff;
- const QString foundryName; // No such concept.
- const bool fixed = !(textmetric->tmPitchAndFamily & TMPF_FIXED_PITCH);
- const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE);
- const bool scalable = textmetric->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
- const int size = scalable ? SMOOTH_SCALABLE : textmetric->tmHeight;
- const QFont::Style style = textmetric->tmItalic ? QFont::StyleItalic : QFont::StyleNormal;
- const bool antialias = false;
- const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(textmetric->tmWeight);
- const QFont::Stretch stretch = QFont::Unstretched;
-
-#ifndef QT_NO_DEBUG_STREAM
- if (QWindowsContext::verbose > 2) {
- QString message;
- QTextStream str(&message);
- str << __FUNCTION__ << ' ' << faceName << "::" << fullName << ' ' << charSet << " TTF=" << ttf;
- if (type & DEVICE_FONTTYPE)
- str << " DEVICE";
- if (type & RASTER_FONTTYPE)
- str << " RASTER";
- if (type & TRUETYPE_FONTTYPE)
- str << " TRUETYPE";
- str << " scalable=" << scalable << " Size=" << size
- << " Style=" << style << " Weight=" << weight
- << " stretch=" << stretch;
- qCDebug(lcQpaFonts) << message;
- }
-#endif
-
- QString englishName;
- if (registerAlias & ttf && localizedName(faceName))
- englishName = getEnglishName(faceName);
-
- QSupportedWritingSystems writingSystems;
- if (type & TRUETYPE_FONTTYPE) {
- Q_ASSERT(signature);
- quint32 unicodeRange[4] = {
- signature->fsUsb[0], signature->fsUsb[1],
- signature->fsUsb[2], signature->fsUsb[3]
- };
- quint32 codePageRange[2] = {
- signature->fsCsb[0], signature->fsCsb[1]
- };
- writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
- // ### Hack to work around problem with Thai text on Windows 7. Segoe UI contains
- // the symbol for Baht, and Windows thus reports that it supports the Thai script.
- // Since it's the default UI font on this platform, most widgets will be unable to
- // display Thai text by default. As a temporary work around, we special case Segoe UI
- // and remove the Thai script from its list of supported writing systems.
- if (writingSystems.supported(QFontDatabase::Thai) &&
- faceName == QLatin1String("Segoe UI"))
- writingSystems.setSupported(QFontDatabase::Thai, false);
- } else {
- const QFontDatabase::WritingSystem ws = writingSystemFromCharSet(charSet);
- if (ws != QFontDatabase::Any)
- writingSystems.setSupported(ws);
- }
-
- int index = 0;
- const FontKey *key = findFontKey(fullName, &index);
- if (!key) {
- // On non-English locales, the styles of the font may be localized in enumeration, but
- // not in the registry.
- QLocale systemLocale = QLocale::system();
- if (systemLocale.language() != QLocale::C
- && systemLocale.language() != QLocale::English
- && styleName != QLatin1String("Italic")
- && styleName != QLatin1String("Bold")) {
- key = findFontKey(getEnglishName(fullName, true), &index);
- }
- if (!key)
- key = findFontKey(faceName, &index);
- if (!key && !registerAlias && englishName.isEmpty() && localizedName(faceName))
- englishName = getEnglishName(faceName);
- if (!key && !englishName.isEmpty())
- key = findFontKey(englishName, &index);
- if (!key)
- return false;
- }
- QString value = key->fileName;
- if (value.isEmpty())
- return false;
-
- if (!QDir::isAbsolutePath(value))
- value.prepend(QFile::decodeName(qgetenv("windir") + "\\Fonts\\"));
-
- QPlatformFontDatabase::registerFont(faceName, styleName, foundryName, weight, style, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
-
- // add fonts windows can generate for us:
- if (weight <= QFont::DemiBold && styleName.isEmpty())
- QPlatformFontDatabase::registerFont(faceName, QString(), foundryName, QFont::Bold, style, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
-
- if (style != QFont::StyleItalic && styleName.isEmpty())
- QPlatformFontDatabase::registerFont(faceName, QString(), foundryName, weight, QFont::StyleItalic, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
-
- if (weight <= QFont::DemiBold && style != QFont::StyleItalic && styleName.isEmpty())
- QPlatformFontDatabase::registerFont(faceName, QString(), foundryName, QFont::Bold, QFont::StyleItalic, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
-
- if (!englishName.isEmpty())
- QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName);
-
- return true;
-}
-
-static int QT_WIN_CALLBACK storeFont(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
- DWORD type, LPARAM)
-{
- const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont);
- const QString faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
- const QString styleName = QString::fromWCharArray(f->elfStyle);
- const QString fullName = QString::fromWCharArray(f->elfFullName);
- const uchar charSet = f->elfLogFont.lfCharSet;
-
- // NEWTEXTMETRICEX (passed for TT fonts) 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
- const FONTSIGNATURE *signature = Q_NULLPTR;
- if (type & TRUETYPE_FONTTYPE)
- signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig;
- addFontToDatabase(faceName, styleName, fullName, charSet, textmetric, signature, type, false);
-
- // keep on enumerating
- return 1;
-}
-
-/*!
- \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 QWindowsFontDatabaseFT::populateFamily(const QString &familyName)
-{
- qCDebug(lcQpaFonts) << familyName;
- if (familyName.size() >= LF_FACESIZE) {
- qCWarning(lcQpaFonts) << "Unable to enumerate family '" << familyName << '\'';
- return;
- }
- HDC dummy = GetDC(0);
- LOGFONT lf;
- lf.lfCharSet = DEFAULT_CHARSET;
- familyName.toWCharArray(lf.lfFaceName);
- lf.lfFaceName[familyName.size()] = 0;
- lf.lfPitchAndFamily = 0;
- EnumFontFamiliesEx(dummy, &lf, storeFont, 0, 0);
- ReleaseDC(0, dummy);
-}
-
-namespace {
-// Context for enumerating system fonts, records whether the default font has been
-// encountered, which is normally not enumerated.
-struct PopulateFamiliesContext
-{
- PopulateFamiliesContext(const QString &f) : systemDefaultFont(f), seenSystemDefaultFont(false) {}
-
- QString systemDefaultFont;
- bool seenSystemDefaultFont;
-};
-} // namespace
-
-// Delayed population of font families
-
-static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
- DWORD, LPARAM lparam)
-{
- const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont);
- // 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)) {
- // Register only font families for which a font file exists for delayed population
- const bool ttf = textmetric->tmPitchAndFamily & TMPF_TRUETYPE;
- const QString faceName = QString::fromWCharArray(faceNameW);
- const FontKey *key = findFontKey(faceName);
- if (!key) {
- key = findFontKey(QString::fromWCharArray(f->elfFullName));
- if (!key && ttf && localizedName(faceName))
- key = findFontKey(getEnglishName(faceName));
- }
- if (key) {
- QPlatformFontDatabase::registerFontFamily(faceName);
- PopulateFamiliesContext *context = reinterpret_cast<PopulateFamiliesContext *>(lparam);
- if (!context->seenSystemDefaultFont && faceName == context->systemDefaultFont)
- context->seenSystemDefaultFont = true;
-
- // Register current font's english name as alias
- if (ttf && localizedName(faceName)) {
- const QString englishName = getEnglishName(faceName);
- if (!englishName.isEmpty()) {
- QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName);
- // Check whether the system default font name is an alias of the current font family name,
- // as on Chinese Windows, where the system font "SimSun" is an alias to a font registered under a local name
- if (!context->seenSystemDefaultFont && englishName == context->systemDefaultFont)
- context->seenSystemDefaultFont = true;
- }
- }
- }
- }
- return 1; // continue
-}
-
-void QWindowsFontDatabaseFT::populateFontDatabase()
-{
- 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, populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0);
- ReleaseDC(0, dummy);
- // Work around EnumFontFamiliesEx() not listing the system font
- if (!context.seenSystemDefaultFont)
- QPlatformFontDatabase::registerFontFamily(context.systemDefaultFont);
-}
-
-QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, void *handle)
-{
- QFontEngine *fe = QBasicFontDatabase::fontEngine(fontDef, handle);
- qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef.family << fe << handle;
- return fe;
-}
-
-QFontEngine *QWindowsFontDatabaseFT::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
-{
- QFontEngine *fe = QBasicFontDatabase::fontEngine(fontData, pixelSize, hintingPreference);
- qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe;
- return fe;
-}
-
-QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
-{
- QStringList result;
- result.append(QWindowsFontDatabase::familyForStyleHint(styleHint));
- result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
- result.append(QBasicFontDatabase::fallbacksForFamily(family, style, styleHint, script));
-
- qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
- << script << result;
-
- return result;
-}
-QString QWindowsFontDatabaseFT::fontDir() const
-{
- const QString result = QLatin1String(qgetenv("windir")) + QLatin1String("/Fonts");//QPlatformFontDatabase::fontDir();
- qCDebug(lcQpaFonts) << __FUNCTION__ << result;
- return result;
-}
-
-QFont QWindowsFontDatabaseFT::defaultFont() const
-{
- return QWindowsFontDatabase::systemDefaultFont();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
deleted file mode 100644
index fa8f777133..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSFONTDATABASEFT_H
-#define QWINDOWSFONTDATABASEFT_H
-
-#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
-#include <QtCore/QSharedPointer>
-#include <QtCore/qt_windows.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsFontDatabaseFT : public QBasicFontDatabase
-{
-public:
- void populateFontDatabase() Q_DECL_OVERRIDE;
- void populateFamily(const QString &familyName) 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;
-
- QStringList fallbacksForFamily(const QString &family, QFont::Style style,
- QFont::StyleHint styleHint,
- QChar::Script script) const Q_DECL_OVERRIDE;
-
- QString fontDir() const Q_DECL_OVERRIDE;
- QFont defaultFont() const Q_DECL_OVERRIDE;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSFONTDATABASEFT_H
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
deleted file mode 100644
index f5d1ed9fad..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ /dev/null
@@ -1,1328 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsintegration.h"
-#include "qwindowsfontengine.h"
-#include "qwindowsnativeimage.h"
-#include "qwindowscontext.h"
-#include "qwindowsfontdatabase.h"
-#include <QtCore/qt_windows.h>
-#include "qwindowsfontenginedirectwrite.h"
-
-#include <QtGui/private/qtextengine_p.h> // glyph_metrics_t
-#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/QPaintDevice>
-#include <QtGui/QBitmap>
-#include <QtGui/QPainter>
-#include <QtGui/private/qpainter_p.h>
-#include <QtGui/QPaintEngine>
-#include <QtGui/private/qpaintengine_raster_p.h>
-
-#include <QtCore/QtEndian>
-#include <QtCore/QFile>
-#include <QtCore/qmath.h>
-#include <QtCore/QThreadStorage>
-#include <QtCore/private/qsystemlibrary_p.h>
-#include <QtCore/private/qstringiterator_p.h>
-
-#include <QtCore/QDebug>
-
-#include <limits.h>
-
-#if !defined(QT_NO_DIRECTWRITE)
-# include <dwrite.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-//### mingw needed define
-#ifndef TT_PRIM_CSPLINE
-#define TT_PRIM_CSPLINE 3
-#endif
-
-// GetFontData expects the tags in little endian ;(
-#define MAKE_LITTLE_ENDIAN_TAG(ch1, ch2, ch3, ch4) (\
- (((quint32)(ch4)) << 24) | \
- (((quint32)(ch3)) << 16) | \
- (((quint32)(ch2)) << 8) | \
- ((quint32)(ch1)) \
- )
-
-// common DC for all fonts
-
-typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);
-static PtrGetCharWidthI ptrGetCharWidthI = 0;
-static bool resolvedGetCharWidthI = false;
-
-static void resolveGetCharWidthI()
-{
- if (resolvedGetCharWidthI)
- return;
- resolvedGetCharWidthI = true;
- ptrGetCharWidthI = (PtrGetCharWidthI)QSystemLibrary::resolve(QStringLiteral("gdi32"), "GetCharWidthI");
-}
-
-static inline quint16 getUShort(unsigned char *p)
-{
- quint16 val;
- val = *p++ << 8;
- val |= *p;
-
- return val;
-}
-
-// general font engine
-
-QFixed QWindowsFontEngine::lineThickness() const
-{
- if(lineWidth > 0)
- return lineWidth;
-
- return QFontEngine::lineThickness();
-}
-
-static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc)
-{
- int size;
- size = GetOutlineTextMetrics(hdc, 0, 0);
- OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size);
- GetOutlineTextMetrics(hdc, size, otm);
- return otm;
-}
-
-bool QWindowsFontEngine::hasCFFTable() const
-{
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
- return GetFontData(hdc, MAKE_LITTLE_ENDIAN_TAG('C', 'F', 'F', ' '), 0, 0, 0) != GDI_ERROR;
-}
-
-bool QWindowsFontEngine::hasCMapTable() const
-{
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
- return GetFontData(hdc, MAKE_LITTLE_ENDIAN_TAG('c', 'm', 'a', 'p'), 0, 0, 0) != GDI_ERROR;
-}
-
-bool QWindowsFontEngine::hasGlyfTable() const
-{
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
- return GetFontData(hdc, MAKE_LITTLE_ENDIAN_TAG('g', 'l', 'y', 'f'), 0, 0, 0) != GDI_ERROR;
-}
-
-bool QWindowsFontEngine::hasEbdtTable() const
-{
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
- return GetFontData(hdc, MAKE_LITTLE_ENDIAN_TAG('E', 'B', 'D', 'T'), 0, 0, 0) != GDI_ERROR;
-}
-
-static inline QString stringFromOutLineTextMetric(const OUTLINETEXTMETRIC *otm, PSTR offset)
-{
- const uchar *p = reinterpret_cast<const uchar *>(otm) + quintptr(offset);
- return QString::fromWCharArray(reinterpret_cast<const wchar_t *>(p));
-}
-
-void QWindowsFontEngine::getCMap()
-{
- ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE) || hasCMapTable();
-
- cffTable = hasCFFTable();
-
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
- bool symb = false;
- if (ttf) {
- cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
- cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
- cmapTable.size(), &symb, &cmapSize);
- }
- if (!cmap) {
- ttf = false;
- symb = false;
- }
- symbol = symb;
- designToDevice = 1;
- _faceId.index = 0;
- if(cmap) {
- OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
- unitsPerEm = int(otm->otmEMSquare);
- const QFixed unitsPerEmF(unitsPerEm);
- designToDevice = unitsPerEmF / QFixed::fromReal(fontDef.pixelSize);
- x_height = int(otm->otmsXHeight);
- loadKerningPairs(designToDevice);
- _faceId.filename = QFile::encodeName(stringFromOutLineTextMetric(otm, otm->otmpFullName));
- lineWidth = otm->otmsUnderscoreSize;
- fsType = otm->otmfsType;
- free(otm);
-
- } else {
- unitsPerEm = tm.tmHeight;
- }
-}
-
-int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs) const
-{
- int glyph_pos = 0;
- {
- if (symbol) {
- QStringIterator it(str, str + numChars);
- while (it.hasNext()) {
- const uint uc = it.next();
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
- if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
- ++glyph_pos;
- }
- } else if (ttf) {
- QStringIterator it(str, str + numChars);
- while (it.hasNext()) {
- const uint uc = it.next();
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
- ++glyph_pos;
- }
- } else {
- QStringIterator it(str, str + numChars);
- while (it.hasNext()) {
- const uint uc = it.next();
- if (uc >= tm.tmFirstChar && uc <= tm.tmLastChar)
- glyphs->glyphs[glyph_pos] = uc;
- else
- glyphs->glyphs[glyph_pos] = 0;
- ++glyph_pos;
- }
- }
- }
- glyphs->numGlyphs = glyph_pos;
- return glyph_pos;
-}
-
-/*!
- \class QWindowsFontEngine
- \brief Standard Windows font engine.
- \internal
- \ingroup qt-lighthouse-win
-
- Will probably be superseded by a common Free Type font engine in Qt 5.X.
-*/
-
-QWindowsFontEngine::QWindowsFontEngine(const QString &name,
- LOGFONT lf,
- const QSharedPointer<QWindowsFontEngineData> &fontEngineData)
- : QFontEngine(Win),
- m_fontEngineData(fontEngineData),
- _name(name),
- hfont(0),
- m_logfont(lf),
- ttf(0),
- hasOutline(0),
- cmap(0),
- cmapSize(0),
- lbearing(SHRT_MIN),
- rbearing(SHRT_MIN),
- x_height(-1),
- synthesized_flags(-1),
- lineWidth(-1),
- widthCache(0),
- widthCacheSize(0),
- designAdvances(0),
- designAdvancesSize(0)
-{
- qCDebug(lcQpaFonts) << __FUNCTION__ << name << lf.lfHeight;
- hfont = CreateFontIndirect(&m_logfont);
- if (!hfont) {
- qErrnoWarning("%s: CreateFontIndirect failed for family '%s'", __FUNCTION__, qPrintable(name));
- hfont = QWindowsFontDatabase::systemFont();
- }
-
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
- const BOOL res = GetTextMetrics(hdc, &tm);
- if (!res) {
- qErrnoWarning("%s: GetTextMetrics failed", __FUNCTION__);
- ZeroMemory(&tm, sizeof(TEXTMETRIC));
- }
-
- fontDef.pixelSize = -lf.lfHeight;
- fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
-
- cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000;
- getCMap();
-
- if (!resolvedGetCharWidthI)
- resolveGetCharWidthI();
-
- // ### Properties accessed by QWin32PrintEngine (QtPrintSupport)
- QVariantMap userData;
- userData.insert(QStringLiteral("logFont"), QVariant::fromValue(m_logfont));
- userData.insert(QStringLiteral("hFont"), QVariant::fromValue(hfont));
- userData.insert(QStringLiteral("trueType"), QVariant(bool(ttf)));
- setUserData(userData);
-
- hasUnreliableOutline = hasGlyfTable() && hasEbdtTable();
-}
-
-QWindowsFontEngine::~QWindowsFontEngine()
-{
- if (designAdvances)
- free(designAdvances);
-
- if (widthCache)
- free(widthCache);
-
- // make sure we aren't by accident still selected
- SelectObject(m_fontEngineData->hdc, QWindowsFontDatabase::systemFont());
-
- if (!DeleteObject(hfont))
- qErrnoWarning("%s: QFontEngineWin: failed to delete font...", __FUNCTION__);
- qCDebug(lcQpaFonts) << __FUNCTION__ << _name;
-
- if (!uniqueFamilyName.isEmpty()) {
- QPlatformFontDatabase *pfdb = QWindowsIntegration::instance()->fontDatabase();
- static_cast<QWindowsFontDatabase *>(pfdb)->derefUniqueFont(uniqueFamilyName);
- }
-}
-
-glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const
-{
- glyph_t glyph = 0;
-
- if (symbol) {
- glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
- if (glyph == 0 && ucs4 < 0x100)
- glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000);
- } else if (ttf) {
- glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
- } else if (ucs4 >= tm.tmFirstChar && ucs4 <= tm.tmLastChar) {
- glyph = ucs4;
- }
-
- return glyph;
-}
-
-HGDIOBJ QWindowsFontEngine::selectDesignFont() const
-{
- LOGFONT f = m_logfont;
- f.lfHeight = -unitsPerEm;
- f.lfWidth = 0;
- HFONT designFont = CreateFontIndirect(&f);
- return SelectObject(m_fontEngineData->hdc, designFont);
-}
-
-bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const
-{
- Q_ASSERT(glyphs->numGlyphs >= *nglyphs);
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- glyphs->numGlyphs = *nglyphs;
- *nglyphs = getGlyphIndexes(str, len, glyphs);
-
- if (!(flags & GlyphIndicesOnly))
- recalcAdvances(glyphs, flags);
-
- return true;
-}
-
-inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width)
-{
- if (ptrGetCharWidthI)
- ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
-}
-
-void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const
-{
- HGDIOBJ oldFont = 0;
- HDC hdc = m_fontEngineData->hdc;
- if (ttf && (flags & DesignMetrics)) {
- for(int i = 0; i < glyphs->numGlyphs; i++) {
- unsigned int glyph = glyphs->glyphs[i];
- if(int(glyph) >= designAdvancesSize) {
- const int newSize = int(glyph + 256) >> 8 << 8;
- designAdvances = reinterpret_cast<QFixed *>(realloc(designAdvances, size_t(newSize) * sizeof(QFixed)));
- Q_CHECK_PTR(designAdvances);
- for(int i = designAdvancesSize; i < newSize; ++i)
- designAdvances[i] = -1000000;
- designAdvancesSize = newSize;
- }
- if (designAdvances[glyph] < -999999) {
- if (!oldFont)
- oldFont = selectDesignFont();
-
- int width = 0;
- calculateTTFGlyphWidth(hdc, glyph, width);
- designAdvances[glyph] = QFixed(width) / designToDevice;
- }
- glyphs->advances[i] = designAdvances[glyph];
- }
- if(oldFont)
- DeleteObject(SelectObject(hdc, oldFont));
- } else {
- for(int i = 0; i < glyphs->numGlyphs; i++) {
- unsigned int glyph = glyphs->glyphs[i];
-
- if (glyph >= widthCacheSize) {
- const uint newSize = (glyph + 256) >> 8 << 8;
- widthCache = reinterpret_cast<unsigned char *>(realloc(widthCache, newSize * sizeof(QFixed)));
- Q_CHECK_PTR(widthCache);
- memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
- widthCacheSize = newSize;
- }
- glyphs->advances[i] = widthCache[glyph];
- // font-width cache failed
- if (glyphs->advances[i].value() == 0) {
- int width = 0;
- if (!oldFont)
- oldFont = SelectObject(hdc, hfont);
-
- if (!ttf) {
- QChar ch[2] = { ushort(glyph), 0 };
- int chrLen = 1;
- if (QChar::requiresSurrogates(glyph)) {
- ch[0] = QChar::highSurrogate(glyph);
- ch[1] = QChar::lowSurrogate(glyph);
- ++chrLen;
- }
- SIZE size = {0, 0};
- GetTextExtentPoint32(hdc, reinterpret_cast<const wchar_t *>(ch), chrLen, &size);
- width = size.cx;
- } else {
- calculateTTFGlyphWidth(hdc, glyph, width);
- }
- glyphs->advances[i] = width;
- // if glyph's within cache range, store it for later
- if (width > 0 && width < 0x100)
- widthCache[glyph] = uchar(width);
- }
- }
-
- if (oldFont)
- SelectObject(hdc, oldFont);
- }
-}
-
-glyph_metrics_t QWindowsFontEngine::boundingBox(const QGlyphLayout &glyphs)
-{
- if (glyphs.numGlyphs == 0)
- return glyph_metrics_t();
-
- QFixed w = 0;
- for (int i = 0; i < glyphs.numGlyphs; ++i)
- w += glyphs.effectiveAdvance(i);
-
- return glyph_metrics_t(0, -tm.tmAscent, w - lastRightBearing(glyphs), tm.tmHeight, w, 0);
-}
-
-bool QWindowsFontEngine::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const
-{
- Q_ASSERT(metrics != 0);
-
- HDC hdc = m_fontEngineData->hdc;
-
- GLYPHMETRICS gm;
- DWORD res = 0;
- MAT2 mat;
- mat.eM11.value = mat.eM22.value = 1;
- mat.eM11.fract = mat.eM22.fract = 0;
- mat.eM21.value = mat.eM12.value = 0;
- mat.eM21.fract = mat.eM12.fract = 0;
-
- if (t.type() > QTransform::TxTranslate) {
- // We need to set the transform using the HDC's world
- // matrix rather than using the MAT2 above, because the
- // results provided when transforming via MAT2 does not
- // match the glyphs that are drawn using a WorldTransform
- XFORM xform;
- xform.eM11 = FLOAT(t.m11());
- xform.eM12 = FLOAT(t.m12());
- xform.eM21 = FLOAT(t.m21());
- xform.eM22 = FLOAT(t.m22());
- xform.eDx = 0;
- xform.eDy = 0;
- SetGraphicsMode(hdc, GM_ADVANCED);
- SetWorldTransform(hdc, &xform);
- }
-
- uint format = GGO_METRICS;
- if (ttf)
- format |= GGO_GLYPH_INDEX;
- res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat);
-
- if (t.type() > QTransform::TxTranslate) {
- XFORM xform;
- xform.eM11 = xform.eM22 = 1;
- xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0;
- SetWorldTransform(hdc, &xform);
- SetGraphicsMode(hdc, GM_COMPATIBLE);
- }
-
- if (res != GDI_ERROR) {
- *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y,
- int(gm.gmBlackBoxX), int(gm.gmBlackBoxY),
- gm.gmCellIncX, gm.gmCellIncY);
- return true;
- } else {
- return false;
- }
-}
-
-glyph_metrics_t QWindowsFontEngine::boundingBox(glyph_t glyph, const QTransform &t)
-{
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
-
- glyph_metrics_t glyphMetrics;
- bool success = getOutlineMetrics(glyph, t, &glyphMetrics);
-
- if (!ttf && !success) {
- // Bitmap fonts
- wchar_t ch = wchar_t(glyph);
- ABCFLOAT abc;
- GetCharABCWidthsFloat(hdc, ch, ch, &abc);
- int width = qRound(abc.abcfB);
-
- return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t);
- }
-
- return glyphMetrics;
-}
-
-QFixed QWindowsFontEngine::ascent() const
-{
- return tm.tmAscent;
-}
-
-QFixed QWindowsFontEngine::descent() const
-{
- return tm.tmDescent;
-}
-
-QFixed QWindowsFontEngine::leading() const
-{
- return tm.tmExternalLeading;
-}
-
-namespace {
-# pragma pack(1)
-
- struct OS2Table
- {
- quint16 version;
- qint16 avgCharWidth;
- quint16 weightClass;
- quint16 widthClass;
- quint16 type;
- qint16 subscriptXSize;
- qint16 subscriptYSize;
- qint16 subscriptXOffset;
- qint16 subscriptYOffset;
- qint16 superscriptXSize;
- qint16 superscriptYSize;
- qint16 superscriptXOffset;
- qint16 superscriptYOffset;
- qint16 strikeOutSize;
- qint16 strikeOutPosition;
- qint16 familyClass;
- quint8 panose[10];
- quint32 unicodeRanges[4];
- quint8 vendorID[4];
- quint16 selection;
- quint16 firstCharIndex;
- quint16 lastCharIndex;
- qint16 typoAscender;
- qint16 typoDescender;
- qint16 typoLineGap;
- quint16 winAscent;
- quint16 winDescent;
- quint32 codepageRanges[2];
- qint16 height;
- qint16 capHeight;
- quint16 defaultChar;
- quint16 breakChar;
- quint16 maxContext;
- };
-
-# pragma pack()
-}
-
-QFixed QWindowsFontEngine::capHeight() const
-{
- const QByteArray tableData = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
- if (size_t(tableData.size()) >= sizeof(OS2Table)) {
- const OS2Table *table = reinterpret_cast<const OS2Table *>(tableData.constData());
- if (qFromBigEndian<quint16>(table->version) >= 2) {
- qint16 capHeight = qFromBigEndian<qint16>(table->capHeight);
- if (capHeight > 0)
- return QFixed(capHeight) / designToDevice;
- }
- }
- return calculatedCapHeight();
-}
-
-QFixed QWindowsFontEngine::xHeight() const
-{
- if(x_height >= 0)
- return x_height;
- return QFontEngine::xHeight();
-}
-
-QFixed QWindowsFontEngine::averageCharWidth() const
-{
- return tm.tmAveCharWidth;
-}
-
-qreal QWindowsFontEngine::maxCharWidth() const
-{
- return tm.tmMaxCharWidth;
-}
-
-enum { max_font_count = 256 };
-static const ushort char_table[] = {
- 40,
- 67,
- 70,
- 75,
- 86,
- 88,
- 89,
- 91,
- 102,
- 114,
- 124,
- 127,
- 205,
- 645,
- 884,
- 922,
- 1070,
- 12386,
- 0
-};
-
-static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
-
-#ifndef Q_CC_MINGW
-void QWindowsFontEngine::getGlyphBearings(glyph_t glyph, qreal *leftBearing, qreal *rightBearing)
-{
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
-
- if (ttf) {
- ABC abcWidths;
- GetCharABCWidthsI(hdc, glyph, 1, 0, &abcWidths);
- if (leftBearing)
- *leftBearing = abcWidths.abcA;
- if (rightBearing)
- *rightBearing = abcWidths.abcC;
- } else {
- QFontEngine::getGlyphBearings(glyph, leftBearing, rightBearing);
- }
-}
-#endif // Q_CC_MINGW
-
-bool QWindowsFontEngine::hasUnreliableGlyphOutline() const
-{
- return hasUnreliableOutline || QFontEngine::hasUnreliableGlyphOutline();
-}
-
-qreal QWindowsFontEngine::minLeftBearing() const
-{
- if (lbearing == SHRT_MIN)
- minRightBearing(); // calculates both
-
- return lbearing;
-}
-
-qreal QWindowsFontEngine::minRightBearing() const
-{
- if (rbearing == SHRT_MIN) {
- int ml = 0;
- int mr = 0;
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
- if (ttf) {
- ABC *abc = 0;
- int n = tm.tmLastChar - tm.tmFirstChar;
- if (n <= max_font_count) {
- abc = new ABC[n+1];
- GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
- } else {
- abc = new ABC[char_table_entries+1];
- for(int i = 0; i < char_table_entries; i++)
- GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i);
- n = char_table_entries;
- }
- ml = abc[0].abcA;
- mr = abc[0].abcC;
- for (int i = 1; i < n; i++) {
- if (abc[i].abcA + abc[i].abcB + abc[i].abcC != 0) {
- ml = qMin(ml,abc[i].abcA);
- mr = qMin(mr,abc[i].abcC);
- }
- }
- delete [] abc;
- } else {
- ABCFLOAT *abc = 0;
- int n = tm.tmLastChar - tm.tmFirstChar+1;
- if (n <= max_font_count) {
- abc = new ABCFLOAT[n];
- GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
- } else {
- abc = new ABCFLOAT[char_table_entries];
- for(int i = 0; i < char_table_entries; i++)
- GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i);
- n = char_table_entries;
- }
- float fml = abc[0].abcfA;
- float fmr = abc[0].abcfC;
- for (int i=1; i<n; i++) {
- if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) {
- fml = qMin(fml,abc[i].abcfA);
- fmr = qMin(fmr,abc[i].abcfC);
- }
- }
- ml = int(fml - 0.9999);
- mr = int(fmr - 0.9999);
- delete [] abc;
- }
- lbearing = ml;
- rbearing = mr;
- }
-
- return rbearing;
-}
-
-static inline double qt_fixed_to_double(const FIXED &p) {
- return ((p.value << 16) + p.fract) / 65536.0;
-}
-
-static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) {
- return QPointF(qt_fixed_to_double(pt.x) * scale, -qt_fixed_to_double(pt.y) * scale);
-}
-
-#ifndef GGO_UNHINTED
-#define GGO_UNHINTED 0x0100
-#endif
-
-static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
- QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1)
-{
- MAT2 mat;
- mat.eM11.value = mat.eM22.value = 1;
- mat.eM11.fract = mat.eM22.fract = 0;
- mat.eM21.value = mat.eM12.value = 0;
- mat.eM21.fract = mat.eM12.fract = 0;
-
- GLYPHMETRICS gMetric;
- memset(&gMetric, 0, sizeof(GLYPHMETRICS));
-
- if (metric) {
- // If metrics requested, retrieve first using GGO_METRICS, because the returned
- // values are incorrect for OpenType PS fonts if obtained at the same time as the
- // glyph paths themselves (ie. with GGO_NATIVE as the format).
- uint format = GGO_METRICS;
- if (ttf)
- format |= GGO_GLYPH_INDEX;
- if (GetGlyphOutline(hdc, glyph, format, &gMetric, 0, 0, &mat) == GDI_ERROR)
- return false;
- // #### obey scale
- *metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y,
- int(gMetric.gmBlackBoxX), int(gMetric.gmBlackBoxY),
- gMetric.gmCellIncX, gMetric.gmCellIncY);
- }
-
- uint glyphFormat = GGO_NATIVE;
-
- if (ttf)
- glyphFormat |= GGO_GLYPH_INDEX;
-
- const DWORD bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
- if (bufferSize == GDI_ERROR)
- return false;
-
- char *dataBuffer = new char[bufferSize];
- DWORD ret = GDI_ERROR;
- ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat);
- if (ret == GDI_ERROR) {
- delete [] dataBuffer;
- return false;
- }
-
- DWORD offset = 0;
- DWORD headerOffset = 0;
-
- QPointF oset = position.toPointF();
- while (headerOffset < bufferSize) {
- const TTPOLYGONHEADER *ttph = reinterpret_cast<const TTPOLYGONHEADER *>(dataBuffer + headerOffset);
-
- QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale));
- path->moveTo(lastPoint + oset);
- offset += sizeof(TTPOLYGONHEADER);
- while (offset < headerOffset + ttph->cb) {
- const TTPOLYCURVE *curve = reinterpret_cast<const TTPOLYCURVE *>(dataBuffer + offset);
- switch (curve->wType) {
- case TT_PRIM_LINE: {
- for (int i=0; i<curve->cpfx; ++i) {
- QPointF p = qt_to_qpointf(curve->apfx[i], scale) + oset;
- path->lineTo(p);
- }
- break;
- }
- case TT_PRIM_QSPLINE: {
- const QPainterPath::Element &elm = path->elementAt(path->elementCount()-1);
- QPointF prev(elm.x, elm.y);
- QPointF endPoint;
- for (int i=0; i<curve->cpfx - 1; ++i) {
- QPointF p1 = qt_to_qpointf(curve->apfx[i], scale) + oset;
- QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale) + oset;
- if (i < curve->cpfx - 2) {
- endPoint = QPointF((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2);
- } else {
- endPoint = p2;
- }
-
- path->quadTo(p1, endPoint);
- prev = endPoint;
- }
-
- break;
- }
- case TT_PRIM_CSPLINE: {
- for (int i=0; i<curve->cpfx; ) {
- QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
- QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
- QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale) + oset;
- path->cubicTo(p2, p3, p4);
- }
- break;
- }
- default:
- qWarning("QFontEngineWin::addOutlineToPath, unhandled switch case");
- }
- offset += sizeof(TTPOLYCURVE) + (curve->cpfx-1) * sizeof(POINTFX);
- }
- path->closeSubpath();
- headerOffset += ttph->cb;
- }
- delete [] dataBuffer;
-
- return true;
-}
-
-void QWindowsFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags)
-{
- LOGFONT lf = m_logfont;
- // The sign must be negative here to make sure we match against character height instead of
- // hinted cell height. This ensures that we get linear matching, and we need this for
- // paths since we later on apply a scaling transform to the glyph outline to get the
- // font at the correct pixel size.
- lf.lfHeight = -unitsPerEm;
- lf.lfWidth = 0;
- HFONT hf = CreateFontIndirect(&lf);
- HDC hdc = m_fontEngineData->hdc;
- HGDIOBJ oldfont = SelectObject(hdc, hf);
-
- for(int i = 0; i < nglyphs; ++i) {
- if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0,
- qreal(fontDef.pixelSize) / unitsPerEm)) {
- // Some windows fonts, like "Modern", are vector stroke
- // fonts, which are reported as TMPF_VECTOR but do not
- // support GetGlyphOutline, and thus we set this bit so
- // that addOutLineToPath can check it and return safely...
- hasOutline = false;
- break;
- }
- }
- DeleteObject(SelectObject(hdc, oldfont));
-}
-
-void QWindowsFontEngine::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
- QPainterPath *path, QTextItem::RenderFlags flags)
-{
- if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) {
- hasOutline = true;
- QFontEngine::addOutlineToPath(x, y, glyphs, path, flags);
- if (hasOutline) {
- // has_outline is set to false if addGlyphToPath gets
- // false from GetGlyphOutline, meaning its not an outline
- // font.
- return;
- }
- }
- QFontEngine::addBitmapFontToPath(x, y, glyphs, path, flags);
-}
-
-QFontEngine::FaceId QWindowsFontEngine::faceId() const
-{
- return _faceId;
-}
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <qdebug.h>
-QT_END_INCLUDE_NAMESPACE
-
-int QWindowsFontEngine::synthesized() const
-{
- if(synthesized_flags == -1) {
- synthesized_flags = 0;
- if(ttf) {
- const DWORD HEAD = MAKE_LITTLE_ENDIAN_TAG('h', 'e', 'a', 'd');
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
- uchar data[4];
- GetFontData(hdc, HEAD, 44, &data, 4);
- USHORT macStyle = getUShort(data);
- if (tm.tmItalic && !(macStyle & 2))
- synthesized_flags = SynthesizedItalic;
- if (fontDef.stretch != 100 && ttf)
- synthesized_flags |= SynthesizedStretch;
- if (tm.tmWeight >= 500 && !(macStyle & 1))
- synthesized_flags |= SynthesizedBold;
- //qDebug() << "font is" << _name <<
- // "it=" << (macStyle & 2) << fontDef.style << "flags=" << synthesized_flags;
- }
- }
- return synthesized_flags;
-}
-
-QFixed QWindowsFontEngine::emSquareSize() const
-{
- return unitsPerEm;
-}
-
-QFontEngine::Properties QWindowsFontEngine::properties() const
-{
- LOGFONT lf = m_logfont;
- lf.lfHeight = unitsPerEm;
- HFONT hf = CreateFontIndirect(&lf);
- HDC hdc = m_fontEngineData->hdc;
- HGDIOBJ oldfont = SelectObject(hdc, hf);
- OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
- Properties p;
- p.emSquare = unitsPerEm;
- p.italicAngle = otm->otmItalicAngle;
- const QByteArray name = stringFromOutLineTextMetric(otm, otm->otmpFamilyName).toLatin1()
- + stringFromOutLineTextMetric(otm, otm->otmpStyleName).toLatin1();
- p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(name);
- p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top,
- otm->otmrcFontBox.right - otm->otmrcFontBox.left,
- otm->otmrcFontBox.top - otm->otmrcFontBox.bottom);
- p.ascent = otm->otmAscent;
- p.descent = -otm->otmDescent;
- p.leading = int(otm->otmLineGap);
- p.capHeight = 0;
- p.lineWidth = otm->otmsUnderscoreSize;
- free(otm);
- DeleteObject(SelectObject(hdc, oldfont));
- return p;
-}
-
-void QWindowsFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
-{
- LOGFONT lf = m_logfont;
- lf.lfHeight = -unitsPerEm;
- int flags = synthesized();
- if(flags & SynthesizedItalic)
- lf.lfItalic = false;
- lf.lfWidth = 0;
- HFONT hf = CreateFontIndirect(&lf);
- HDC hdc = m_fontEngineData->hdc;
- HGDIOBJ oldfont = SelectObject(hdc, hf);
- QFixedPoint p;
- p.x = 0;
- p.y = 0;
- addGlyphToPath(glyph, p, hdc, path, ttf, metrics);
- DeleteObject(SelectObject(hdc, oldfont));
-}
-
-bool QWindowsFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
- if (!ttf && !cffTable)
- return false;
- HDC hdc = m_fontEngineData->hdc;
- SelectObject(hdc, hfont);
- DWORD t = qbswap<quint32>(tag);
- *length = GetFontData(hdc, t, 0, buffer, *length);
- Q_ASSERT(*length == GDI_ERROR || int(*length) > 0);
- return *length != GDI_ERROR;
-}
-
-#if !defined(CLEARTYPE_QUALITY)
-# define CLEARTYPE_QUALITY 5
-#endif
-
-QWindowsNativeImage *QWindowsFontEngine::drawGDIGlyph(HFONT font, glyph_t glyph, int margin,
- const QTransform &t,
- QImage::Format mask_format)
-{
- Q_UNUSED(mask_format)
- glyph_metrics_t gm = boundingBox(glyph);
-
-// printf(" -> for glyph %4x\n", glyph);
-
- int gx = gm.x.toInt();
- int gy = gm.y.toInt();
- int iw = gm.width.toInt();
- int ih = gm.height.toInt();
-
- if (iw <= 0 || ih <= 0)
- return 0;
-
- bool has_transformation = t.type() > QTransform::TxTranslate;
-
- unsigned int options = ttf ? ETO_GLYPH_INDEX : 0;
- XFORM xform;
-
- if (has_transformation) {
- xform.eM11 = FLOAT(t.m11());
- xform.eM12 = FLOAT(t.m12());
- xform.eM21 = FLOAT(t.m21());
- xform.eM22 = FLOAT(t.m22());
- xform.eDx = margin;
- xform.eDy = margin;
-
- const HDC hdc = m_fontEngineData->hdc;
-
- SetGraphicsMode(hdc, GM_ADVANCED);
- SetWorldTransform(hdc, &xform);
- HGDIOBJ old_font = SelectObject(hdc, font);
-
- const UINT ggo_options = GGO_METRICS | (ttf ? GGO_GLYPH_INDEX : 0);
- GLYPHMETRICS tgm;
- MAT2 mat;
- memset(&mat, 0, sizeof(mat));
- mat.eM11.value = mat.eM22.value = 1;
-
- const DWORD result = GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat);
-
- XFORM identity = {1, 0, 0, 1, 0, 0};
- SetWorldTransform(hdc, &identity);
- SetGraphicsMode(hdc, GM_COMPATIBLE);
- SelectObject(hdc, old_font);
-
- if (result == GDI_ERROR) {
- const int errorCode = int(GetLastError());
- qErrnoWarning(errorCode, "QWinFontEngine: unable to query transformed glyph metrics (GetGlyphOutline() failed, error %d)...", errorCode);
- return 0;
- }
-
- iw = int(tgm.gmBlackBoxX);
- ih = int(tgm.gmBlackBoxY);
-
- xform.eDx -= tgm.gmptGlyphOrigin.x;
- xform.eDy += tgm.gmptGlyphOrigin.y;
- }
-
- // The padding here needs to be kept in sync with the values in alphaMapBoundingBox.
- QWindowsNativeImage *ni = new QWindowsNativeImage(iw + 2 * margin,
- ih + 2 * margin,
- QWindowsNativeImage::systemFormat());
-
- /*If cleartype is enabled we use the standard system format even on Windows CE
- and not the special textbuffer format we have to use if cleartype is disabled*/
-
- ni->image().fill(0xffffffff);
-
- HDC hdc = ni->hdc();
-
- SelectObject(hdc, GetStockObject(NULL_BRUSH));
- SelectObject(hdc, GetStockObject(BLACK_PEN));
- SetTextColor(hdc, RGB(0,0,0));
- SetBkMode(hdc, TRANSPARENT);
- SetTextAlign(hdc, TA_BASELINE);
-
- HGDIOBJ old_font = SelectObject(hdc, font);
-
- if (has_transformation) {
- SetGraphicsMode(hdc, GM_ADVANCED);
- SetWorldTransform(hdc, &xform);
- ExtTextOut(hdc, 0, 0, options, 0, reinterpret_cast<LPCWSTR>(&glyph), 1, 0);
- } else {
- ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, reinterpret_cast<LPCWSTR>(&glyph), 1, 0);
- }
-
- SelectObject(hdc, old_font);
- return ni;
-}
-
-glyph_metrics_t QWindowsFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat format)
-{
- int margin = 0;
- if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB)
- margin = glyphMargin(QFontEngine::Format_A32);
- glyph_metrics_t gm = boundingBox(glyph, matrix);
- gm.width += margin * 2;
- gm.height += margin * 2;
- return gm;
-}
-
-QImage QWindowsFontEngine::alphaMapForGlyph(glyph_t glyph, const QTransform &xform)
-{
- HFONT font = hfont;
-
- bool clearTypeTemporarilyDisabled = (m_fontEngineData->clearTypeEnabled && m_logfont.lfQuality != NONANTIALIASED_QUALITY);
- if (clearTypeTemporarilyDisabled) {
- LOGFONT lf = m_logfont;
- lf.lfQuality = ANTIALIASED_QUALITY;
- font = CreateFontIndirect(&lf);
- }
- QImage::Format mask_format = QWindowsNativeImage::systemFormat();
- mask_format = QImage::Format_RGB32;
-
- const QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format);
- if (mask == 0) {
- if (m_fontEngineData->clearTypeEnabled)
- DeleteObject(font);
- return QImage();
- }
-
- QImage alphaMap(mask->width(), mask->height(), QImage::Format_Alpha8);
-
-
- // Copy data... Cannot use QPainter here as GDI has messed up the
- // Alpha channel of the ni.image pixels...
- for (int y=0; y<mask->height(); ++y) {
- uchar *dest = alphaMap.scanLine(y);
- if (mask->image().format() == QImage::Format_RGB16) {
- const qint16 *src = reinterpret_cast<const qint16 *>(mask->image().constScanLine(y));
- for (int x=0; x<mask->width(); ++x)
- dest[x] = 255 - qGray(src[x]);
- } else {
- const uint *src = reinterpret_cast<const uint *>(mask->image().constScanLine(y));
- for (int x=0; x<mask->width(); ++x) {
- if (QWindowsNativeImage::systemFormat() == QImage::Format_RGB16)
- dest[x] = 255 - qGray(src[x]);
- else
- dest[x] = 255 - (m_fontEngineData->pow_gamma[qGray(src[x])] * 255. / 2047.);
- }
- }
- }
-
- // Cleanup...
- delete mask;
- if (clearTypeTemporarilyDisabled) {
- DeleteObject(font);
- }
-
- return alphaMap;
-}
-
-#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
-#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
-
-QImage QWindowsFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed, const QTransform &t)
-{
- HFONT font = hfont;
-
- UINT contrast;
- SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &contrast, 0);
- SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, reinterpret_cast<void *>(quintptr(1000)), 0);
-
- int margin = glyphMargin(QFontEngine::Format_A32);
- QWindowsNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32);
- SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, reinterpret_cast<void *>(quintptr(contrast)), 0);
-
- if (mask == 0)
- return QImage();
-
- // Gracefully handle the odd case when the display is 16-bit
- const QImage source = mask->image().depth() == 32
- ? mask->image()
- : mask->image().convertToFormat(QImage::Format_RGB32);
-
- QImage rgbMask(mask->width(), mask->height(), QImage::Format_RGB32);
- for (int y=0; y<mask->height(); ++y) {
- uint *dest = (uint *) rgbMask.scanLine(y);
- const uint *src = reinterpret_cast<const uint *>(source.constScanLine(y));
- for (int x=0; x<mask->width(); ++x) {
- dest[x] = 0xffffffff - (0x00ffffff & src[x]);
- }
- }
-
- delete mask;
-
- return rgbMask;
-}
-
-QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const
-{
- QFontDef request = fontDef;
- QString actualFontName = request.family;
- if (!uniqueFamilyName.isEmpty())
- request.family = uniqueFamilyName;
- request.pixelSize = pixelSize;
-
- QFontEngine *fontEngine =
- QWindowsFontDatabase::createEngine(request,
- QWindowsContext::instance()->defaultDPI(),
- m_fontEngineData);
- if (fontEngine) {
- fontEngine->fontDef.family = actualFontName;
- if (!uniqueFamilyName.isEmpty()) {
- static_cast<QWindowsFontEngine *>(fontEngine)->setUniqueFamilyName(uniqueFamilyName);
- QPlatformFontDatabase *pfdb = QWindowsIntegration::instance()->fontDatabase();
- static_cast<QWindowsFontDatabase *>(pfdb)->refUniqueFont(uniqueFamilyName);
- }
- }
- return fontEngine;
-}
-
-Qt::HANDLE QWindowsFontEngine::handle() const
-{
- return hfont;
-}
-
-void QWindowsFontEngine::initFontInfo(const QFontDef &request,
- int dpi)
-{
- fontDef = request; // most settings are equal
- HDC dc = m_fontEngineData->hdc;
- SelectObject(dc, hfont);
- wchar_t n[64];
- GetTextFace(dc, 64, n);
- fontDef.family = QString::fromWCharArray(n);
- fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
- if (fontDef.pointSize < 0) {
- fontDef.pointSize = fontDef.pixelSize * 72. / dpi;
- } else if (fontDef.pixelSize == -1) {
- fontDef.pixelSize = qRound(fontDef.pointSize * dpi / 72.);
- }
-}
-
-/*!
- \class QWindowsMultiFontEngine
- \brief Standard Windows Multi font engine.
- \internal
- \ingroup qt-lighthouse-win
-
- "Merges" several font engines that have gaps in the
- supported writing systems.
-
- Will probably be superseded by a common Free Type font engine in Qt 5.X.
-*/
-QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *fe, int script)
- : QFontEngineMulti(fe, script)
-{
-}
-
-QFontEngine *QWindowsMultiFontEngine::loadEngine(int at)
-{
- QFontEngine *fontEngine = engine(0);
- QSharedPointer<QWindowsFontEngineData> data;
- LOGFONT lf;
-
-#ifndef QT_NO_DIRECTWRITE
- if (fontEngine->type() == QFontEngine::DirectWrite) {
- QWindowsFontEngineDirectWrite *fe = static_cast<QWindowsFontEngineDirectWrite *>(fontEngine);
- lf = QWindowsFontDatabase::fontDefToLOGFONT(fe->fontDef);
-
- data = fe->fontEngineData();
- } else
-#endif
- {
- QWindowsFontEngine *fe = static_cast<QWindowsFontEngine*>(fontEngine);
- lf = fe->m_logfont;
-
- data = fe->fontEngineData();
- }
-
- const QString fam = fallbackFamilyAt(at - 1);
- const int faceNameLength = qMin(fam.length(), LF_FACESIZE - 1);
- memcpy(lf.lfFaceName, fam.utf16(), faceNameLength * sizeof(wchar_t));
- lf.lfFaceName[faceNameLength] = 0;
-
-#ifndef QT_NO_DIRECTWRITE
- if (fontEngine->type() == QFontEngine::DirectWrite) {
- const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(fam);
- if (nameSubstitute != fam) {
- const int nameSubstituteLength = qMin(nameSubstitute.length(), LF_FACESIZE - 1);
- memcpy(lf.lfFaceName, nameSubstitute.utf16(), nameSubstituteLength * sizeof(wchar_t));
- lf.lfFaceName[nameSubstituteLength] = 0;
- }
-
- IDWriteFont *directWriteFont = 0;
- HRESULT hr = data->directWriteGdiInterop->CreateFontFromLOGFONT(&lf, &directWriteFont);
- if (FAILED(hr)) {
- qErrnoWarning("%s: CreateFontFromLOGFONT failed", __FUNCTION__);
- } else {
- Q_ASSERT(directWriteFont);
- IDWriteFontFace *directWriteFontFace = NULL;
- HRESULT hr = directWriteFont->CreateFontFace(&directWriteFontFace);
- if (SUCCEEDED(hr)) {
- Q_ASSERT(directWriteFontFace);
- QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace,
- fontEngine->fontDef.pixelSize,
- data);
- fedw->fontDef.weight = fontEngine->fontDef.weight;
- if (fontEngine->fontDef.style > QFont::StyleNormal)
- fedw->fontDef.style = fontEngine->fontDef.style;
- fedw->fontDef.family = fam;
- fedw->fontDef.hintingPreference = fontEngine->fontDef.hintingPreference;
- return fedw;
- } else {
- qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__);
- }
- }
- }
-#endif
-
- // Get here if original font is not DirectWrite or DirectWrite creation failed for some
- // reason
-
- QFontEngine *fe = new QWindowsFontEngine(fam, lf, data);
- fe->fontDef.weight = fontEngine->fontDef.weight;
- if (fontEngine->fontDef.style > QFont::StyleNormal)
- fe->fontDef.style = fontEngine->fontDef.style;
- fe->fontDef.family = fam;
- fe->fontDef.hintingPreference = fontEngine->fontDef.hintingPreference;
- return fe;
-}
-
-bool QWindowsFontEngine::supportsTransformation(const QTransform &transform) const
-{
- // Support all transformations for ttf files, and translations for raster fonts
- return ttf || transform.type() <= QTransform::TxTranslate;
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
deleted file mode 100644
index b63d8fd282..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSFONTENGINE_H
-#define QWINDOWSFONTENGINE_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qfontengine_p.h>
-
-#include <QtGui/QImage>
-#include <QtCore/QSharedPointer>
-#include <QtCore/QMetaType>
-
-#include <QtCore/qt_windows.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsNativeImage;
-class QWindowsFontEngineData;
-
-class QWindowsFontEngine : public QFontEngine
-{
- friend class QWindowsMultiFontEngine;
-
-public:
- QWindowsFontEngine(const QString &name, LOGFONT lf,
- const QSharedPointer<QWindowsFontEngineData> &fontEngineData);
-
- ~QWindowsFontEngine();
- void initFontInfo(const QFontDef &request,
- int dpi);
-
- QFixed lineThickness() const Q_DECL_OVERRIDE;
- Properties properties() const Q_DECL_OVERRIDE;
- void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) Q_DECL_OVERRIDE;
- FaceId faceId() const Q_DECL_OVERRIDE;
- bool getSfntTableData(uint tag, uchar *buffer, uint *length) const Q_DECL_OVERRIDE;
- int synthesized() const Q_DECL_OVERRIDE;
- QFixed emSquareSize() const Q_DECL_OVERRIDE;
-
- glyph_t glyphIndex(uint ucs4) const Q_DECL_OVERRIDE;
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const Q_DECL_OVERRIDE;
- void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags) const Q_DECL_OVERRIDE;
-
- void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
- virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
-
- HGDIOBJ selectDesignFont() const;
-
- glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) Q_DECL_OVERRIDE;
- glyph_metrics_t boundingBox(glyph_t g) Q_DECL_OVERRIDE { return boundingBox(g, QTransform()); }
- glyph_metrics_t boundingBox(glyph_t g, const QTransform &t) Q_DECL_OVERRIDE;
-
-
- QFixed ascent() const Q_DECL_OVERRIDE;
- QFixed descent() const Q_DECL_OVERRIDE;
- QFixed leading() const Q_DECL_OVERRIDE;
- QFixed xHeight() const Q_DECL_OVERRIDE;
- QFixed capHeight() const Q_DECL_OVERRIDE;
- QFixed averageCharWidth() const Q_DECL_OVERRIDE;
- qreal maxCharWidth() const Q_DECL_OVERRIDE;
- qreal minLeftBearing() const Q_DECL_OVERRIDE;
- qreal minRightBearing() const Q_DECL_OVERRIDE;
-
- QImage alphaMapForGlyph(glyph_t t) Q_DECL_OVERRIDE { return alphaMapForGlyph(t, QTransform()); }
- QImage alphaMapForGlyph(glyph_t, const QTransform &xform) Q_DECL_OVERRIDE;
- QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform) Q_DECL_OVERRIDE;
- glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) Q_DECL_OVERRIDE;
-
- QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE;
- Qt::HANDLE handle() const Q_DECL_OVERRIDE;
- bool supportsTransformation(const QTransform &transform) const Q_DECL_OVERRIDE;
-
-#ifndef Q_CC_MINGW
- void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0) Q_DECL_OVERRIDE;
-#endif
-
- bool hasUnreliableGlyphOutline() const Q_DECL_OVERRIDE;
-
- int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs) const;
- void getCMap();
-
- bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const;
-
- const QSharedPointer<QWindowsFontEngineData> &fontEngineData() const { return m_fontEngineData; }
-
- void setUniqueFamilyName(const QString &newName) { uniqueFamilyName = newName; }
-
-private:
- QWindowsNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform,
- QImage::Format mask_format);
- bool hasCFFTable() const;
- bool hasCMapTable() const;
- bool hasGlyfTable() const;
- bool hasEbdtTable() const;
-
- const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
-
- const QString _name;
- QString uniqueFamilyName;
- HFONT hfont;
- const LOGFONT m_logfont;
- uint ttf : 1;
- uint hasOutline : 1;
- uint hasUnreliableOutline : 1;
- uint cffTable : 1;
- TEXTMETRIC tm;
- const unsigned char *cmap;
- int cmapSize;
- QByteArray cmapTable;
- mutable qreal lbearing;
- mutable qreal rbearing;
- QFixed designToDevice;
- int unitsPerEm;
- QFixed x_height;
- FaceId _faceId;
-
- mutable int synthesized_flags;
- mutable QFixed lineWidth;
- mutable unsigned char *widthCache;
- mutable uint widthCacheSize;
- mutable QFixed *designAdvances;
- mutable int designAdvancesSize;
-};
-
-class QWindowsMultiFontEngine : public QFontEngineMulti
-{
-public:
- explicit QWindowsMultiFontEngine(QFontEngine *fe, int script);
-
- QFontEngine *loadEngine(int at) Q_DECL_OVERRIDE;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(HFONT)
-Q_DECLARE_METATYPE(LOGFONT)
-
-#endif // QWINDOWSFONTENGINE_H
-
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
deleted file mode 100644
index 66cc08f9fa..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ /dev/null
@@ -1,992 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT_NO_DIRECTWRITE
-
-#include "qwindowsfontenginedirectwrite.h"
-#include "qwindowsfontdatabase.h"
-#include "qwindowscontext.h"
-
-#include <QtCore/QSettings>
-#include <QtCore/QtEndian>
-#include <QtCore/QVarLengthArray>
-#include <QtCore/QFile>
-#include <private/qstringiterator_p.h>
-#include <QtCore/private/qsystemlibrary_p.h>
-#include <QtGui/private/qguiapplication_p.h>
-#include <qpa/qplatformintegration.h>
-
-#if defined(QT_USE_DIRECTWRITE2)
-# include <dwrite_2.h>
-#else
-# include <dwrite.h>
-#endif
-
-#include <d2d1.h>
-
-QT_BEGIN_NAMESPACE
-
-// Convert from design units to logical pixels
-#define DESIGN_TO_LOGICAL(DESIGN_UNIT_VALUE) \
- QFixed::fromReal((qreal(DESIGN_UNIT_VALUE) / qreal(m_unitsPerEm)) * fontDef.pixelSize)
-
-namespace {
-
- class GeometrySink: public IDWriteGeometrySink
- {
- public:
- GeometrySink(QPainterPath *path)
- : m_refCount(0), m_path(path)
- {
- Q_ASSERT(m_path != 0);
- }
- virtual ~GeometrySink()
- {
- }
-
- IFACEMETHOD_(void, AddBeziers)(const D2D1_BEZIER_SEGMENT *beziers, UINT bezierCount);
- IFACEMETHOD_(void, AddLines)(const D2D1_POINT_2F *points, UINT pointCount);
- IFACEMETHOD_(void, BeginFigure)(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN figureBegin);
- IFACEMETHOD(Close)();
- IFACEMETHOD_(void, EndFigure)(D2D1_FIGURE_END figureEnd);
- IFACEMETHOD_(void, SetFillMode)(D2D1_FILL_MODE fillMode);
- IFACEMETHOD_(void, SetSegmentFlags)(D2D1_PATH_SEGMENT vertexFlags);
-
- IFACEMETHOD_(unsigned long, AddRef)();
- IFACEMETHOD_(unsigned long, Release)();
- IFACEMETHOD(QueryInterface)(IID const &riid, void **ppvObject);
-
- private:
- inline static QPointF fromD2D1_POINT_2F(const D2D1_POINT_2F &inp)
- {
- return QPointF(inp.x, inp.y);
- }
-
- unsigned long m_refCount;
- QPointF m_startPoint;
- QPainterPath *m_path;
- };
-
- void GeometrySink::AddBeziers(const D2D1_BEZIER_SEGMENT *beziers,
- UINT bezierCount)
- {
- for (uint i=0; i<bezierCount; ++i) {
- QPointF c1 = fromD2D1_POINT_2F(beziers[i].point1);
- QPointF c2 = fromD2D1_POINT_2F(beziers[i].point2);
- QPointF p2 = fromD2D1_POINT_2F(beziers[i].point3);
-
- m_path->cubicTo(c1, c2, p2);
- }
- }
-
- void GeometrySink::AddLines(const D2D1_POINT_2F *points, UINT pointsCount)
- {
- for (uint i=0; i<pointsCount; ++i)
- m_path->lineTo(fromD2D1_POINT_2F(points[i]));
- }
-
- void GeometrySink::BeginFigure(D2D1_POINT_2F startPoint,
- D2D1_FIGURE_BEGIN /*figureBegin*/)
- {
- m_startPoint = fromD2D1_POINT_2F(startPoint);
- m_path->moveTo(m_startPoint);
- }
-
- IFACEMETHODIMP GeometrySink::Close()
- {
- return E_NOTIMPL;
- }
-
- void GeometrySink::EndFigure(D2D1_FIGURE_END figureEnd)
- {
- if (figureEnd == D2D1_FIGURE_END_CLOSED)
- m_path->closeSubpath();
- }
-
- void GeometrySink::SetFillMode(D2D1_FILL_MODE fillMode)
- {
- m_path->setFillRule(fillMode == D2D1_FILL_MODE_ALTERNATE
- ? Qt::OddEvenFill
- : Qt::WindingFill);
- }
-
- void GeometrySink::SetSegmentFlags(D2D1_PATH_SEGMENT /*vertexFlags*/)
- {
- /* Not implemented */
- }
-
- IFACEMETHODIMP_(unsigned long) GeometrySink::AddRef()
- {
- return InterlockedIncrement(&m_refCount);
- }
-
- IFACEMETHODIMP_(unsigned long) GeometrySink::Release()
- {
- unsigned long newCount = InterlockedDecrement(&m_refCount);
- if (newCount == 0)
- {
- delete this;
- return 0;
- }
-
- return newCount;
- }
-
- IFACEMETHODIMP GeometrySink::QueryInterface(IID const &riid, void **ppvObject)
- {
- if (__uuidof(IDWriteGeometrySink) == riid) {
- *ppvObject = this;
- } else if (__uuidof(IUnknown) == riid) {
- *ppvObject = this;
- } else {
- *ppvObject = NULL;
- return E_FAIL;
- }
-
- AddRef();
- return S_OK;
- }
-
-}
-
-/*!
- \class QWindowsFontEngineDirectWrite
- \brief Windows font engine using Direct Write.
- \internal
- \ingroup qt-lighthouse-win
-
- Font engine for subpixel positioned text on Windows Vista
- (with platform update) and Windows 7. If selected during
- configuration, the engine will be selected only when the hinting
- preference of a font is set to None or Vertical hinting. The font
- database uses most of the same logic but creates a direct write
- font based on the LOGFONT rather than a GDI handle.
-
- Will probably be superseded by a common Free Type font engine in Qt 5.X.
-*/
-
-QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
- qreal pixelSize,
- const QSharedPointer<QWindowsFontEngineData> &d)
- : QFontEngine(DirectWrite)
- , m_fontEngineData(d)
- , m_directWriteFontFace(directWriteFontFace)
- , m_directWriteBitmapRenderTarget(0)
- , m_lineThickness(-1)
- , m_unitsPerEm(-1)
- , m_ascent(-1)
- , m_capHeight(-1)
- , m_descent(-1)
- , m_xHeight(-1)
- , m_lineGap(-1)
-{
- qCDebug(lcQpaFonts) << __FUNCTION__ << pixelSize;
-
- Q_ASSERT(m_directWriteFontFace);
-
- m_fontEngineData->directWriteFactory->AddRef();
- m_directWriteFontFace->AddRef();
-
- fontDef.pixelSize = pixelSize;
- collectMetrics();
- cache_cost = (m_ascent.toInt() + m_descent.toInt()) * m_xHeight.toInt() * 2000;
-}
-
-QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
-{
- qCDebug(lcQpaFonts) << __FUNCTION__;
-
- m_fontEngineData->directWriteFactory->Release();
- m_directWriteFontFace->Release();
-
- if (m_directWriteBitmapRenderTarget != 0)
- m_directWriteBitmapRenderTarget->Release();
-
- if (!m_uniqueFamilyName.isEmpty()) {
- QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
- static_cast<QWindowsFontDatabase *>(pfdb)->derefUniqueFont(m_uniqueFamilyName);
- }
-}
-
-#ifndef Q_CC_MINGW
-typedef IDWriteLocalFontFileLoader QIdWriteLocalFontFileLoader;
-
-static UUID uuidIdWriteLocalFontFileLoader()
-{
- return __uuidof(IDWriteLocalFontFileLoader);
-}
-#else // !Q_CC_MINGW
-DECLARE_INTERFACE_(QIdWriteLocalFontFileLoader, IDWriteFontFileLoader)
-{
- STDMETHOD(GetFilePathLengthFromKey)(THIS_ void const *, UINT32, UINT32*) PURE;
- STDMETHOD(GetFilePathFromKey)(THIS_ void const *, UINT32, WCHAR *, UINT32) PURE;
- STDMETHOD(GetLastWriteTimeFromKey)(THIS_ void const *, UINT32, FILETIME *) PURE;
-};
-
-static UUID uuidIdWriteLocalFontFileLoader()
-{
- static const UUID result = { 0xb2d9f3ec, 0xc9fe, 0x4a11, {0xa2, 0xec, 0xd8, 0x62, 0x8, 0xf7, 0xc0, 0xa2}};
- return result;
-}
-#endif // Q_CC_MINGW
-
-QString QWindowsFontEngineDirectWrite::filenameFromFontFile(IDWriteFontFile *fontFile)
-{
- IDWriteFontFileLoader *loader = Q_NULLPTR;
-
- HRESULT hr = fontFile->GetLoader(&loader);
- if (FAILED(hr)) {
- qErrnoWarning("%s: GetLoader failed", __FUNCTION__);
- return QString();
- }
-
- QIdWriteLocalFontFileLoader *localLoader = Q_NULLPTR;
- hr = loader->QueryInterface(uuidIdWriteLocalFontFileLoader(),
- reinterpret_cast<void **>(&localLoader));
-
- const void *fontFileReferenceKey = Q_NULLPTR;
- UINT32 fontFileReferenceKeySize = 0;
- if (SUCCEEDED(hr)) {
- hr = fontFile->GetReferenceKey(&fontFileReferenceKey,
- &fontFileReferenceKeySize);
- if (FAILED(hr))
- qErrnoWarning(hr, "%s: GetReferenceKey failed", __FUNCTION__);
- }
-
- UINT32 filePathLength = 0;
- if (SUCCEEDED(hr)) {
- hr = localLoader->GetFilePathLengthFromKey(fontFileReferenceKey,
- fontFileReferenceKeySize,
- &filePathLength);
- if (FAILED(hr))
- qErrnoWarning(hr, "GetFilePathLength failed", __FUNCTION__);
- }
-
- QString ret;
- if (SUCCEEDED(hr) && filePathLength > 0) {
- QVarLengthArray<wchar_t> filePath(filePathLength + 1);
-
- hr = localLoader->GetFilePathFromKey(fontFileReferenceKey,
- fontFileReferenceKeySize,
- filePath.data(),
- filePathLength + 1);
- if (FAILED(hr))
- qErrnoWarning(hr, "%s: GetFilePathFromKey failed", __FUNCTION__);
- else
- ret = QString::fromWCharArray(filePath.data());
- }
-
- if (localLoader != Q_NULLPTR)
- localLoader->Release();
-
- if (loader != Q_NULLPTR)
- loader->Release();
- return ret;
-}
-
-void QWindowsFontEngineDirectWrite::collectMetrics()
-{
- DWRITE_FONT_METRICS metrics;
-
- m_directWriteFontFace->GetMetrics(&metrics);
- m_unitsPerEm = metrics.designUnitsPerEm;
-
- m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
- m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
- m_capHeight = DESIGN_TO_LOGICAL(metrics.capHeight);
- m_descent = DESIGN_TO_LOGICAL(metrics.descent);
- m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
- m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
- m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
-
- IDWriteFontFile *fontFile = Q_NULLPTR;
- UINT32 numberOfFiles = 1;
- if (SUCCEEDED(m_directWriteFontFace->GetFiles(&numberOfFiles, &fontFile))) {
- m_faceId.filename = QFile::encodeName(filenameFromFontFile(fontFile));
- fontFile->Release();
- }
-}
-
-QFixed QWindowsFontEngineDirectWrite::underlinePosition() const
-{
- if (m_underlinePosition > 0)
- return m_underlinePosition;
- else
- return QFontEngine::underlinePosition();
-}
-
-QFixed QWindowsFontEngineDirectWrite::lineThickness() const
-{
- if (m_lineThickness > 0)
- return m_lineThickness;
- else
- return QFontEngine::lineThickness();
-}
-
-bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
- bool ret = false;
-
- const void *tableData = 0;
- UINT32 tableSize;
- void *tableContext = 0;
- BOOL exists;
- HRESULT hr = m_directWriteFontFace->TryGetFontTable(qbswap<quint32>(tag),
- &tableData, &tableSize,
- &tableContext, &exists);
- if (SUCCEEDED(hr)) {
- if (exists) {
- ret = true;
- if (buffer && *length >= tableSize)
- memcpy(buffer, tableData, tableSize);
- *length = tableSize;
- Q_ASSERT(int(*length) > 0);
- }
- m_directWriteFontFace->ReleaseFontTable(tableContext);
- } else {
- qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
- }
-
- return ret;
-}
-
-QFixed QWindowsFontEngineDirectWrite::emSquareSize() const
-{
- if (m_unitsPerEm > 0)
- return m_unitsPerEm;
- else
- return QFontEngine::emSquareSize();
-}
-
-glyph_t QWindowsFontEngineDirectWrite::glyphIndex(uint ucs4) const
-{
- UINT16 glyphIndex;
-
- HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(&ucs4, 1, &glyphIndex);
- if (FAILED(hr)) {
- qErrnoWarning("%s: glyphIndex failed", __FUNCTION__);
- glyphIndex = 0;
- }
-
- return glyphIndex;
-}
-
-bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
- int *nglyphs, QFontEngine::ShaperFlags flags) const
-{
- Q_ASSERT(glyphs->numGlyphs >= *nglyphs);
- if (*nglyphs < len) {
- *nglyphs = len;
- return false;
- }
-
- QVarLengthArray<UINT32> codePoints(len);
- int actualLength = 0;
- QStringIterator it(str, str + len);
- while (it.hasNext())
- codePoints[actualLength++] = it.next();
-
- QVarLengthArray<UINT16> glyphIndices(actualLength);
- HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength,
- glyphIndices.data());
- if (FAILED(hr)) {
- qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
- return false;
- }
-
- for (int i = 0; i < actualLength; ++i)
- glyphs->glyphs[i] = glyphIndices.at(i);
-
- *nglyphs = actualLength;
- glyphs->numGlyphs = actualLength;
-
- if (!(flags & GlyphIndicesOnly))
- recalcAdvances(glyphs, 0);
-
- return true;
-}
-
-QFontEngine::FaceId QWindowsFontEngineDirectWrite::faceId() const
-{
- return m_faceId;
-}
-
-void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
-{
- QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);
-
- // ### Caching?
- for(int i=0; i<glyphs->numGlyphs; i++)
- glyphIndices[i] = UINT16(glyphs->glyphs[i]);
-
- QVarLengthArray<DWRITE_GLYPH_METRICS> glyphMetrics(glyphIndices.size());
- HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(glyphIndices.data(),
- glyphIndices.size(),
- glyphMetrics.data());
- if (SUCCEEDED(hr)) {
- qreal stretch = fontDef.stretch != QFont::AnyStretch ? fontDef.stretch / 100.0 : 1.0;
- for (int i = 0; i < glyphs->numGlyphs; ++i)
- glyphs->advances[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth * stretch);
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- for (int i = 0; i < glyphs->numGlyphs; ++i)
- glyphs->advances[i] = glyphs->advances[i].round();
- }
- } else {
- qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
- }
-}
-
-void QWindowsFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags)
-{
- QVarLengthArray<UINT16> glyphIndices(nglyphs);
- QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(nglyphs);
- QVarLengthArray<FLOAT> glyphAdvances(nglyphs);
-
- for (int i=0; i<nglyphs; ++i) {
- glyphIndices[i] = glyphs[i];
- glyphOffsets[i].advanceOffset = positions[i].x.toReal();
- glyphOffsets[i].ascenderOffset = -positions[i].y.toReal();
- glyphAdvances[i] = 0.0;
- }
-
- GeometrySink geometrySink(path);
- HRESULT hr = m_directWriteFontFace->GetGlyphRunOutline(
- fontDef.pixelSize,
- glyphIndices.data(),
- glyphAdvances.data(),
- glyphOffsets.data(),
- nglyphs,
- false,
- flags & QTextItem::RightToLeft,
- &geometrySink
- );
-
- if (FAILED(hr))
- qErrnoWarning("%s: GetGlyphRunOutline failed", __FUNCTION__);
-}
-
-glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(const QGlyphLayout &glyphs)
-{
- if (glyphs.numGlyphs == 0)
- return glyph_metrics_t();
-
- bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
-
- QFixed w = 0;
- for (int i = 0; i < glyphs.numGlyphs; ++i) {
- w += round ? glyphs.effectiveAdvance(i).round() : glyphs.effectiveAdvance(i);
-
- }
-
- return glyph_metrics_t(0, -m_ascent, w - lastRightBearing(glyphs), m_ascent + m_descent, w, 0);
-}
-
-glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g)
-{
- UINT16 glyphIndex = g;
-
- DWRITE_GLYPH_METRICS glyphMetrics;
- HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(&glyphIndex, 1, &glyphMetrics);
- if (SUCCEEDED(hr)) {
- QFixed advanceWidth = DESIGN_TO_LOGICAL(glyphMetrics.advanceWidth);
- QFixed leftSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.leftSideBearing);
- QFixed rightSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.rightSideBearing);
- QFixed advanceHeight = DESIGN_TO_LOGICAL(glyphMetrics.advanceHeight);
- QFixed verticalOriginY = DESIGN_TO_LOGICAL(glyphMetrics.verticalOriginY);
- QFixed topSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.topSideBearing);
- QFixed bottomSideBearing = DESIGN_TO_LOGICAL(glyphMetrics.bottomSideBearing);
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- advanceWidth = advanceWidth.round();
- advanceHeight = advanceHeight.round();
- }
-
- QFixed width = advanceWidth - leftSideBearing - rightSideBearing;
- QFixed height = advanceHeight - topSideBearing - bottomSideBearing;
- return glyph_metrics_t(leftSideBearing,
- -verticalOriginY + topSideBearing,
- width,
- height,
- advanceWidth,
- 0);
- } else {
- qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
- }
-
- return glyph_metrics_t();
-}
-
-QFixed QWindowsFontEngineDirectWrite::ascent() const
-{
- return fontDef.styleStrategy & QFont::ForceIntegerMetrics
- ? m_ascent.round()
- : m_ascent;
-}
-
-QFixed QWindowsFontEngineDirectWrite::capHeight() const
-{
- if (m_capHeight <= 0)
- return calculatedCapHeight();
-
- return fontDef.styleStrategy & QFont::ForceIntegerMetrics
- ? m_capHeight.round()
- : m_capHeight;
-}
-
-QFixed QWindowsFontEngineDirectWrite::descent() const
-{
- return fontDef.styleStrategy & QFont::ForceIntegerMetrics
- ? m_descent.round()
- : m_descent;
-}
-
-QFixed QWindowsFontEngineDirectWrite::leading() const
-{
- return fontDef.styleStrategy & QFont::ForceIntegerMetrics
- ? m_lineGap.round()
- : m_lineGap;
-}
-
-QFixed QWindowsFontEngineDirectWrite::xHeight() const
-{
- return fontDef.styleStrategy & QFont::ForceIntegerMetrics
- ? m_xHeight.round()
- : m_xHeight;
-}
-
-qreal QWindowsFontEngineDirectWrite::maxCharWidth() const
-{
- // ###
- return 0;
-}
-
-QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
-{
- QImage im = alphaRGBMapForGlyph(glyph, subPixelPosition, t);
-
- QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8);
-
- for (int y=0; y<im.height(); ++y) {
- const uint *src = reinterpret_cast<const uint *>(im.constScanLine(y));
- uchar *dst = alphaMap.scanLine(y);
- for (int x=0; x<im.width(); ++x) {
- *dst = 255 - (m_fontEngineData->pow_gamma[qGray(0xffffffff - *src)] * 255. / 2047.);
- ++dst;
- ++src;
- }
- }
-
- return alphaMap;
-}
-
-QImage QWindowsFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
-{
- return alphaMapForGlyph(glyph, subPixelPosition, QTransform());
-}
-
-bool QWindowsFontEngineDirectWrite::supportsSubPixelPositions() const
-{
- return true;
-}
-
-QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
- QFixed subPixelPosition,
- int margin,
- const QTransform &originalTransform)
-{
- UINT16 glyphIndex = t;
- FLOAT glyphAdvance = 0;
-
- DWRITE_GLYPH_OFFSET glyphOffset;
- glyphOffset.advanceOffset = 0;
- glyphOffset.ascenderOffset = 0;
-
- DWRITE_GLYPH_RUN glyphRun;
- glyphRun.fontFace = m_directWriteFontFace;
- glyphRun.fontEmSize = fontDef.pixelSize;
- glyphRun.glyphCount = 1;
- glyphRun.glyphIndices = &glyphIndex;
- glyphRun.glyphAdvances = &glyphAdvance;
- glyphRun.isSideways = false;
- glyphRun.bidiLevel = 0;
- glyphRun.glyphOffsets = &glyphOffset;
-
- QTransform xform = originalTransform;
- if (fontDef.stretch != 100)
- xform.scale(fontDef.stretch / 100.0, 1.0);
-
- DWRITE_MATRIX transform;
- transform.dx = subPixelPosition.toReal();
- transform.dy = 0;
- transform.m11 = xform.m11();
- transform.m12 = xform.m12();
- transform.m21 = xform.m21();
- transform.m22 = xform.m22();
-
- DWRITE_RENDERING_MODE renderMode =
- fontDef.hintingPreference == QFont::PreferNoHinting
- ? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC
- : DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
-
- IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
- HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
- &glyphRun,
- 1.0f,
- &transform,
- renderMode,
- DWRITE_MEASURING_MODE_NATURAL,
- 0.0, 0.0,
- &glyphAnalysis
- );
-
- if (SUCCEEDED(hr)) {
- RECT rect;
- glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
-
- QRect boundingRect = QRect(QPoint(rect.left - margin,
- rect.top - margin),
- QPoint(rect.right + margin,
- rect.bottom + margin));
-
-
- const int width = boundingRect.width() - 1; // -1 due to Qt's off-by-one definition of a QRect
- const int height = boundingRect.height() - 1;
-
- QImage image;
-#if defined(QT_USE_DIRECTWRITE2)
- HRESULT hr = DWRITE_E_NOCOLOR;
- IDWriteColorGlyphRunEnumerator *enumerator = 0;
- IDWriteFactory2 *factory2 = Q_NULLPTR;
- if (glyphFormat == QFontEngine::Format_ARGB
- && SUCCEEDED(m_fontEngineData->directWriteFactory->QueryInterface(__uuidof(IDWriteFactory2),
- reinterpret_cast<void **>(&factory2)))) {
- hr = factory2->TranslateColorGlyphRun(0.0f,
- 0.0f,
- &glyphRun,
- NULL,
- DWRITE_MEASURING_MODE_NATURAL,
- NULL,
- 0,
- &enumerator);
- image = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
- image.fill(0);
- } else
-#endif
- {
- image = QImage(width, height, QImage::Format_RGB32);
- image.fill(0xffffffff);
- }
-
-#if defined(QT_USE_DIRECTWRITE2)
- BOOL ok = true;
- if (SUCCEEDED(hr)) {
- while (SUCCEEDED(hr) && ok) {
- const DWRITE_COLOR_GLYPH_RUN *colorGlyphRun = 0;
- hr = enumerator->GetCurrentRun(&colorGlyphRun);
- if (FAILED(hr)) { // No colored runs, only outline
- qErrnoWarning(hr, "%s: IDWriteColorGlyphRunEnumerator::GetCurrentRun failed", __FUNCTION__);
- break;
- }
-
- IDWriteGlyphRunAnalysis *colorGlyphsAnalysis = NULL;
- hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
- &colorGlyphRun->glyphRun,
- 1.0f,
- &transform,
- renderMode,
- DWRITE_MEASURING_MODE_NATURAL,
- 0.0, 0.0,
- &colorGlyphsAnalysis
- );
- if (FAILED(hr)) {
- qErrnoWarning(hr, "%s: CreateGlyphRunAnalysis failed for color run", __FUNCTION__);
- break;
- }
-
- float r = qBound(0.0f, colorGlyphRun->runColor.r, 1.0f);
- float g = qBound(0.0f, colorGlyphRun->runColor.g, 1.0f);
- float b = qBound(0.0f, colorGlyphRun->runColor.b, 1.0f);
- float a = qBound(0.0f, colorGlyphRun->runColor.a, 1.0f);
-
- if (!qFuzzyIsNull(a)) {
- renderGlyphRun(&image,
- r,
- g,
- b,
- a,
- colorGlyphsAnalysis,
- boundingRect);
- }
- colorGlyphsAnalysis->Release();
-
- hr = enumerator->MoveNext(&ok);
- if (FAILED(hr)) {
- qErrnoWarning(hr, "%s: IDWriteColorGlyphRunEnumerator::MoveNext failed", __FUNCTION__);
- break;
- }
- }
- } else
-#endif
- {
- renderGlyphRun(&image,
- 0.0,
- 0.0,
- 0.0,
- 1.0,
- glyphAnalysis,
- boundingRect);
- }
-
- glyphAnalysis->Release();
- return image;
- } else {
- qErrnoWarning(hr, "%s: CreateGlyphRunAnalysis failed", __FUNCTION__);
- return QImage();
- }
-}
-
-
-void QWindowsFontEngineDirectWrite::renderGlyphRun(QImage *destination,
- float r,
- float g,
- float b,
- float a,
- IDWriteGlyphRunAnalysis *glyphAnalysis,
- const QRect &boundingRect)
-{
- const int width = destination->width();
- const int height = destination->height();
-
- r *= 255.0;
- g *= 255.0;
- b *= 255.0;
-
- const int size = width * height * 3;
- if (size > 0) {
- RECT rect;
- rect.left = boundingRect.left();
- rect.top = boundingRect.top();
- rect.right = boundingRect.right();
- rect.bottom = boundingRect.bottom();
-
- QVarLengthArray<BYTE, 1024> alphaValueArray(size);
- BYTE *alphaValues = alphaValueArray.data();
- memset(alphaValues, 0, size);
-
- HRESULT hr = glyphAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1,
- &rect,
- alphaValues,
- size);
- if (SUCCEEDED(hr)) {
- if (destination->hasAlphaChannel()) {
- for (int y = 0; y < height; ++y) {
- uint *dest = reinterpret_cast<uint *>(destination->scanLine(y));
- BYTE *src = alphaValues + width * 3 * y;
-
- for (int x = 0; x < width; ++x) {
- float redAlpha = a * *src++ / 255.0;
- float greenAlpha = a * *src++ / 255.0;
- float blueAlpha = a * *src++ / 255.0;
- float averageAlpha = (redAlpha + greenAlpha + blueAlpha) / 3.0;
-
- QRgb currentRgb = dest[x];
- dest[x] = qRgba(qRound(qRed(currentRgb) * (1.0 - averageAlpha) + averageAlpha * r),
- qRound(qGreen(currentRgb) * (1.0 - averageAlpha) + averageAlpha * g),
- qRound(qBlue(currentRgb) * (1.0 - averageAlpha) + averageAlpha * b),
- qRound(qAlpha(currentRgb) * (1.0 - averageAlpha) + averageAlpha * 255));
- }
- }
-
- } else {
- for (int y = 0; y < height; ++y) {
- uint *dest = reinterpret_cast<uint *>(destination->scanLine(y));
- BYTE *src = alphaValues + width * 3 * y;
-
- for (int x = 0; x < width; ++x) {
- dest[x] = *(src + 0) << 16
- | *(src + 1) << 8
- | *(src + 2);
-
- src += 3;
- }
- }
- }
- } else {
- qErrnoWarning("%s: CreateAlphaTexture failed", __FUNCTION__);
- }
- } else {
- glyphAnalysis->Release();
- qWarning("%s: Glyph has no bounds", __FUNCTION__);
- }
-}
-
-QImage QWindowsFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t,
- QFixed subPixelPosition,
- const QTransform &xform)
-{
- QImage mask = imageForGlyph(t,
- subPixelPosition,
- glyphMargin(QFontEngine::Format_A32),
- xform);
-
- return mask.depth() == 32
- ? mask
- : mask.convertToFormat(QImage::Format_RGB32);
-}
-
-QFontEngine *QWindowsFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const
-{
- QWindowsFontEngineDirectWrite *fontEngine = new QWindowsFontEngineDirectWrite(m_directWriteFontFace,
- pixelSize,
- m_fontEngineData);
-
- fontEngine->fontDef = fontDef;
- fontEngine->fontDef.pixelSize = pixelSize;
- if (!m_uniqueFamilyName.isEmpty()) {
- fontEngine->setUniqueFamilyName(m_uniqueFamilyName);
- QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
- static_cast<QWindowsFontDatabase *>(pfdb)->refUniqueFont(m_uniqueFamilyName);
- }
-
- return fontEngine;
-}
-
-Qt::HANDLE QWindowsFontEngineDirectWrite::handle() const
-{
- return m_directWriteFontFace;
-}
-
-void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request,
- int dpi)
-{
- fontDef = request;
-
- if (fontDef.pointSize < 0)
- fontDef.pointSize = fontDef.pixelSize * 72. / dpi;
- else if (fontDef.pixelSize == -1)
- fontDef.pixelSize = qRound(fontDef.pointSize * dpi / 72.);
-}
-
-QString QWindowsFontEngineDirectWrite::fontNameSubstitute(const QString &familyName)
-{
- static const char keyC[] = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\"
- "FontSubstitutes";
- return QSettings(QLatin1String(keyC), QSettings::NativeFormat).value(familyName, familyName).toString();
-}
-
-glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph,
- QFixed subPixelPosition,
- const QTransform &originalTransform,
- GlyphFormat format)
-{
- Q_UNUSED(format);
-
- QTransform matrix = originalTransform;
- if (fontDef.stretch != 100)
- matrix.scale(fontDef.stretch / 100.0, 1.0);
-
- glyph_metrics_t bbox = QFontEngine::boundingBox(glyph, matrix); // To get transformed advance
-
- UINT16 glyphIndex = glyph;
- FLOAT glyphAdvance = 0;
-
- DWRITE_GLYPH_OFFSET glyphOffset;
- glyphOffset.advanceOffset = 0;
- glyphOffset.ascenderOffset = 0;
-
- DWRITE_GLYPH_RUN glyphRun;
- glyphRun.fontFace = m_directWriteFontFace;
- glyphRun.fontEmSize = fontDef.pixelSize;
- glyphRun.glyphCount = 1;
- glyphRun.glyphIndices = &glyphIndex;
- glyphRun.glyphAdvances = &glyphAdvance;
- glyphRun.isSideways = false;
- glyphRun.bidiLevel = 0;
- glyphRun.glyphOffsets = &glyphOffset;
-
- DWRITE_MATRIX transform;
- transform.dx = subPixelPosition.toReal();
- transform.dy = 0;
- transform.m11 = matrix.m11();
- transform.m12 = matrix.m12();
- transform.m21 = matrix.m21();
- transform.m22 = matrix.m22();
-
- DWRITE_RENDERING_MODE renderMode =
- fontDef.hintingPreference == QFont::PreferNoHinting
- ? DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC
- : DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
-
- IDWriteGlyphRunAnalysis *glyphAnalysis = NULL;
- HRESULT hr = m_fontEngineData->directWriteFactory->CreateGlyphRunAnalysis(
- &glyphRun,
- 1.0f,
- &transform,
- renderMode,
- DWRITE_MEASURING_MODE_NATURAL,
- 0.0, 0.0,
- &glyphAnalysis
- );
-
- if (SUCCEEDED(hr)) {
- RECT rect;
- glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
- glyphAnalysis->Release();
-
- int margin = glyphMargin(QFontEngine::Format_A32);
-
- return glyph_metrics_t(rect.left,
- rect.top,
- rect.right - rect.left + margin * 2,
- rect.bottom - rect.top + margin * 2,
- bbox.xoff, bbox.yoff);
- } else {
- return glyph_metrics_t();
- }
-}
-
-QImage QWindowsFontEngineDirectWrite::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t)
-{
- return imageForGlyph(glyph, subPixelPosition, glyphMargin(QFontEngine::Format_A32), t);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DIRECTWRITE
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
deleted file mode 100644
index e4a82c6a6e..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSFONTENGINEDIRECTWRITE_H
-#define QWINDOWSFONTENGINEDIRECTWRITE_H
-
-#include <QtCore/qglobal.h>
-
-#ifndef QT_NO_DIRECTWRITE
-
-#include <QtGui/private/qfontengine_p.h>
-#include <QtCore/QSharedPointer>
-
-struct IDWriteFont;
-struct IDWriteFontFace;
-struct IDWriteFontFile;
-struct IDWriteFactory;
-struct IDWriteBitmapRenderTarget;
-struct IDWriteGdiInterop;
-struct IDWriteGlyphRunAnalysis;
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsFontEngineData;
-
-class QWindowsFontEngineDirectWrite : public QFontEngine
-{
-public:
- explicit QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
- qreal pixelSize,
- const QSharedPointer<QWindowsFontEngineData> &d);
- ~QWindowsFontEngineDirectWrite();
-
- void initFontInfo(const QFontDef &request, int dpi);
-
- QFixed lineThickness() const Q_DECL_OVERRIDE;
- QFixed underlinePosition() const Q_DECL_OVERRIDE;
- bool getSfntTableData(uint tag, uchar *buffer, uint *length) const Q_DECL_OVERRIDE;
- QFixed emSquareSize() const Q_DECL_OVERRIDE;
-
- glyph_t glyphIndex(uint ucs4) const Q_DECL_OVERRIDE;
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
- ShaperFlags flags) const Q_DECL_OVERRIDE;
- void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags) const Q_DECL_OVERRIDE;
-
- void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags) Q_DECL_OVERRIDE;
-
- glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) Q_DECL_OVERRIDE;
- glyph_metrics_t boundingBox(glyph_t g) Q_DECL_OVERRIDE;
- glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed,
- const QTransform &matrix, GlyphFormat) Q_DECL_OVERRIDE;
-
- QFixed ascent() const Q_DECL_OVERRIDE;
- QFixed capHeight() const Q_DECL_OVERRIDE;
- QFixed descent() const Q_DECL_OVERRIDE;
- QFixed leading() const Q_DECL_OVERRIDE;
- QFixed xHeight() const Q_DECL_OVERRIDE;
- qreal maxCharWidth() const Q_DECL_OVERRIDE;
- FaceId faceId() const Q_DECL_OVERRIDE;
-
- bool supportsSubPixelPositions() const Q_DECL_OVERRIDE;
-
- QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) Q_DECL_OVERRIDE;
- QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE;
- QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform) Q_DECL_OVERRIDE;
- QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE;
-
- QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE;
- Qt::HANDLE handle() const Q_DECL_OVERRIDE;
-
- const QSharedPointer<QWindowsFontEngineData> &fontEngineData() const { return m_fontEngineData; }
-
- static QString fontNameSubstitute(const QString &familyName);
-
- IDWriteFontFace *directWriteFontFace() const { return m_directWriteFontFace; }
-
- void setUniqueFamilyName(const QString &newName) { m_uniqueFamilyName = newName; }
-
-private:
- QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
- void collectMetrics();
- void renderGlyphRun(QImage *destination, float r, float g, float b, float a, IDWriteGlyphRunAnalysis *glyphAnalysis, const QRect &boundingRect);
- static QString filenameFromFontFile(IDWriteFontFile *fontFile);
-
- const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
-
- IDWriteFontFace *m_directWriteFontFace;
- IDWriteBitmapRenderTarget *m_directWriteBitmapRenderTarget;
-
- QFixed m_lineThickness;
- QFixed m_underlinePosition;
- int m_unitsPerEm;
- QFixed m_ascent;
- QFixed m_capHeight;
- QFixed m_descent;
- QFixed m_xHeight;
- QFixed m_lineGap;
- FaceId m_faceId;
- QString m_uniqueFamilyName;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DIRECTWRITE
-
-#endif // QWINDOWSFONTENGINEDIRECTWRITE_H
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index b9a63c7a89..004b03d9a9 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -47,9 +47,8 @@
#include "qwindowstheme.h"
#include "qwindowsservices.h"
#ifndef QT_NO_FREETYPE
-# include "qwindowsfontdatabase_ft.h"
+# include <QtFontDatabaseSupport/private/qwindowsfontdatabase_ft_p.h>
#endif
-#include "qwindowsfontdatabase.h"
#ifndef QT_NO_CLIPBOARD
# include "qwindowsclipboard.h"
# ifndef QT_NO_DRAGANDDROP
@@ -72,7 +71,7 @@
#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/qpa/qplatforminputcontextfactory_p.h>
-#include <QtPlatformSupport/private/qwindowsguieventdispatcher_p.h>
+#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
#include <QtCore/QDebug>
#include <QtCore/QVariant>
@@ -220,6 +219,7 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
// are connected to Windows 8.1
QtWindows::ProcessDpiAwareness dpiAwareness = QtWindows::ProcessPerMonitorDpiAware;
m_options = parseOptions(paramList, &tabletAbsoluteRange, &dpiAwareness);
+ QWindowsFontDatabase::setFontOptions(m_options);
if (tabletAbsoluteRange >= 0)
m_context.setTabletAbsoluteRange(tabletAbsoluteRange);
if (!dpiAwarenessSet) { // Set only once in case of repeated instantiations of QGuiApplication.
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 4258f908e7..a668470993 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -43,6 +43,7 @@
#include <qpa/qplatformintegration.h>
#include <QtCore/QScopedPointer>
+#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
QT_BEGIN_NAMESPACE
@@ -61,8 +62,9 @@ public:
NoNativeDialogs = 0x8,
XpNativeDialogs = 0x10,
DontPassOsMouseEventsSynthesizedFromTouch = 0x20, // Do not pass OS-generated mouse events from touch.
- DontUseDirectWriteFonts = 0x40,
- DontUseColorFonts = 0x80
+ // Keep in sync with QWindowsFontDatabase::FontOptions
+ DontUseDirectWriteFonts = QWindowsFontDatabase::DontUseDirectWriteFonts,
+ DontUseColorFonts = QWindowsFontDatabase::DontUseColorFonts
};
explicit QWindowsIntegration(const QStringList &paramList);
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index fd7eca9e32..b8c4f0b736 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -49,7 +49,7 @@
#include <private/qguiapplication_p.h>
#include <private/qhighdpiscaling_p.h>
#include <QtGui/QKeyEvent>
-#include <QtPlatformSupport/private/qwindowsguieventdispatcher_p.h>
+#include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h>
#if defined(WM_APPCOMMAND)
# ifndef FAPPCOMMAND_MOUSE
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.cpp b/src/plugins/platforms/windows/qwindowsnativeimage.cpp
deleted file mode 100644
index ec9683ea8d..0000000000
--- a/src/plugins/platforms/windows/qwindowsnativeimage.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsnativeimage.h"
-#include "qwindowscontext.h"
-
-#include <QtGui/private/qpaintengine_p.h>
-#include <QtGui/private/qpaintengine_raster_p.h>
-
-QT_BEGIN_NAMESPACE
-
-typedef struct {
- BITMAPINFOHEADER bmiHeader;
- DWORD redMask;
- DWORD greenMask;
- DWORD blueMask;
-} BITMAPINFO_MASK;
-
-/*!
- \class QWindowsNativeImage
- \brief Windows Native image
-
- Note that size can be 0 (widget autotests with zero size), which
- causes CreateDIBSection() to fail.
-
- \sa QWindowsBackingStore
- \internal
- \ingroup qt-lighthouse-win
-*/
-
-static inline HDC createDC()
-{
- HDC display_dc = GetDC(0);
- HDC hdc = CreateCompatibleDC(display_dc);
- ReleaseDC(0, display_dc);
- Q_ASSERT(hdc);
- return hdc;
-}
-
-static inline HBITMAP createDIB(HDC hdc, int width, int height,
- QImage::Format format,
- uchar **bitsIn)
-{
- BITMAPINFO_MASK bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = width;
- bmi.bmiHeader.biHeight = -height; // top-down.
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biSizeImage = 0;
-
- if (format == QImage::Format_RGB16) {
- bmi.bmiHeader.biBitCount = 16;
- bmi.bmiHeader.biCompression = BI_BITFIELDS;
- bmi.redMask = 0xF800;
- bmi.greenMask = 0x07E0;
- bmi.blueMask = 0x001F;
- } else {
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.redMask = 0;
- bmi.greenMask = 0;
- bmi.blueMask = 0;
- }
-
- uchar *bits = Q_NULLPTR;
- HBITMAP bitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bmi),
- DIB_RGB_COLORS, reinterpret_cast<void **>(&bits), 0, 0);
- if (Q_UNLIKELY(!bitmap || !bits))
- qFatal("%s: CreateDIBSection failed.", __FUNCTION__);
-
- *bitsIn = bits;
- return bitmap;
-}
-
-QWindowsNativeImage::QWindowsNativeImage(int width, int height,
- QImage::Format format) :
- m_hdc(createDC()),
- m_bitmap(0),
- m_null_bitmap(0)
-{
- if (width != 0 && height != 0) {
- uchar *bits;
- m_bitmap = createDIB(m_hdc, width, height, format, &bits);
- m_null_bitmap = static_cast<HBITMAP>(SelectObject(m_hdc, m_bitmap));
- m_image = QImage(bits, width, height, format);
- Q_ASSERT(m_image.paintEngine()->type() == QPaintEngine::Raster);
- static_cast<QRasterPaintEngine *>(m_image.paintEngine())->setDC(m_hdc);
- } else {
- m_image = QImage(width, height, format);
- }
-
- GdiFlush();
-}
-
-QWindowsNativeImage::~QWindowsNativeImage()
-{
- if (m_hdc) {
- if (m_bitmap) {
- if (m_null_bitmap)
- SelectObject(m_hdc, m_null_bitmap);
- DeleteObject(m_bitmap);
- }
- DeleteDC(m_hdc);
- }
-}
-
-QImage::Format QWindowsNativeImage::systemFormat()
-{
- static const int depth = QWindowsContext::instance()->screenDepth();
- return depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.h b/src/plugins/platforms/windows/qwindowsnativeimage.h
deleted file mode 100644
index bfe0f07dfd..0000000000
--- a/src/plugins/platforms/windows/qwindowsnativeimage.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSNATIVEIMAGE_H
-#define QWINDOWSNATIVEIMAGE_H
-
-#include <QtCore/qt_windows.h>
-
-#include <QtGui/QImage>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsNativeImage
-{
- Q_DISABLE_COPY(QWindowsNativeImage)
-public:
- QWindowsNativeImage(int width, int height,
- QImage::Format format);
-
- ~QWindowsNativeImage();
-
- inline int width() const { return m_image.width(); }
- inline int height() const { return m_image.height(); }
-
- QImage &image() { return m_image; }
- const QImage &image() const { return m_image; }
-
- HDC hdc() const { return m_hdc; }
-
- static QImage::Format systemFormat();
-
-private:
- const HDC m_hdc;
- QImage m_image;
-
- HBITMAP m_bitmap;
- HBITMAP m_null_bitmap;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSNATIVEIMAGE_H
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index e0ae111b9a..eaa6e45b9f 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -41,7 +41,6 @@
#include "qwindowswindow.h"
#include "qwindowscontext.h"
#include "qwindowscursor.h"
-#include "qwindowsfontdatabase.h"
#include "qwindowsopenglcontext.h"
#include "qwindowsopengltester.h"
#include "qwindowsintegration.h"
@@ -51,6 +50,7 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
#include <qpa/qplatformscreen.h>
+#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 841464391d..ed12c8124e 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -48,7 +48,6 @@
#include "qwindowscontext.h"
#include "qwindowsintegration.h"
#include "qt_windows.h"
-#include "qwindowsfontdatabase.h"
#include <commctrl.h>
#include <objbase.h>
#ifndef Q_CC_MINGW
@@ -68,7 +67,8 @@
#include <QtGui/QPainter>
#include <QtGui/QPixmapCache>
#include <qpa/qwindowsysteminterface.h>
-#include <QtPlatformSupport/private/qabstractfileiconengine_p.h>
+#include <QtThemeSupport/private/qabstractfileiconengine_p.h>
+#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
#include <private/qhighdpiscaling_p.h>
#include <private/qsystemlibrary_p.h>
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 7289f8de6d..a9b061ad73 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qwindowswindow.h"
-#include "qwindowsnativeimage.h"
#include "qwindowscontext.h"
#include "qwindowsdrag.h"
#include "qwindowsscreen.h"
@@ -424,11 +423,9 @@ static inline void fixTopLevelWindowFlags(Qt::WindowFlags &flags)
|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint;
break;
case Qt::Dialog:
- flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint | Qt::WindowCloseButtonHint;
- break;
case Qt::Tool:
- flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
- break;
+ flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
+ break;
default:
break;
}
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index 35d4c85a73..5071cd8e21 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -9,24 +9,12 @@ LIBS += -lshlwapi -lshell32 -ladvapi32
DEFINES *= QT_NO_CAST_FROM_ASCII
-qtConfig(directwrite) {
- qtConfig(directwrite2): \
- DEFINES *= QT_USE_DIRECTWRITE2
-
- SOURCES += $$PWD/qwindowsfontenginedirectwrite.cpp
- HEADERS += $$PWD/qwindowsfontenginedirectwrite.h
-} else {
- DEFINES *= QT_NO_DIRECTWRITE
-}
-
SOURCES += \
$$PWD/qwindowswindow.cpp \
$$PWD/qwindowsintegration.cpp \
$$PWD/qwindowscontext.cpp \
$$PWD/qwindowsscreen.cpp \
$$PWD/qwindowskeymapper.cpp \
- $$PWD/qwindowsfontengine.cpp \
- $$PWD/qwindowsfontdatabase.cpp \
$$PWD/qwindowsmousehandler.cpp \
$$PWD/qwindowsole.cpp \
$$PWD/qwindowsmime.cpp \
@@ -36,7 +24,6 @@ SOURCES += \
$$PWD/qwindowstheme.cpp \
$$PWD/qwindowsdialoghelpers.cpp \
$$PWD/qwindowsservices.cpp \
- $$PWD/qwindowsnativeimage.cpp \
$$PWD/qwindowsnativeinterface.cpp \
$$PWD/qwindowsopengltester.cpp
@@ -46,8 +33,6 @@ HEADERS += \
$$PWD/qwindowscontext.h \
$$PWD/qwindowsscreen.h \
$$PWD/qwindowskeymapper.h \
- $$PWD/qwindowsfontengine.h \
- $$PWD/qwindowsfontdatabase.h \
$$PWD/qwindowsmousehandler.h \
$$PWD/qtwindowsglobal.h \
$$PWD/qwindowsole.h \
@@ -58,7 +43,6 @@ HEADERS += \
$$PWD/qwindowstheme.h \
$$PWD/qwindowsdialoghelpers.h \
$$PWD/qwindowsservices.h \
- $$PWD/qwindowsnativeimage.h \
$$PWD/qwindowsnativeinterface.h \
$$PWD/qwindowsopengltester.h \
$$PWD/qwindowsthreadpoolrunner.h
@@ -111,16 +95,6 @@ qtConfig(dynamicgl) {
RESOURCES += $$PWD/openglblacklists.qrc
-qtConfig(freetype) {
- HEADERS += $$PWD/qwindowsfontdatabase_ft.h
- SOURCES += $$PWD/qwindowsfontdatabase_ft.cpp
- qtConfig(system-freetype) {
- include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri)
- } else {
- include($$QT_SOURCE_TREE/src/3rdparty/freetype_dependency.pri)
- }
-}
-
qtConfig(accessibility): include($$PWD/accessible/accessible.pri)
DEFINES *= LIBEGL_NAME=$${LIBQTANGLE_NAME}
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
index adafa830d5..23168c10dc 100644
--- a/src/plugins/platforms/windows/windows.pro
+++ b/src/plugins/platforms/windows/windows.pro
@@ -1,8 +1,9 @@
TARGET = qwindows
-QT *= core-private
-QT *= gui-private
-QT *= platformsupport-private
+QT += \
+ core-private gui-private \
+ eventdispatcher_support-private accessibility_support-private \
+ fontdatabase_support-private theme_support-private
LIBS += -lgdi32 -ldwmapi