summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@qt.io>2016-06-03 16:22:21 -0700
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2016-10-28 08:02:46 +0000
commitf9a80e06ac928bf796d013dd7fba10ba30827202 (patch)
treed2ebe633b63305076e60d263ce148191f42f1442 /src/plugins/platforms
parent5700644a4268fdf8717b83a63e4843dcb86814b6 (diff)
Move Windows font DB and engines to QtFontDatabaseSupport
This allows creating or extending QPA plugins to provide access to QFont and related types. It concerns both GDI and DirectWrite engines, as well as the regular and the freetype based font databases. The qt.qpa.fonts logging category has been moved together into the QWindowsFontDatabase related files to avoid depending on the qwindowscontext.h header file. Finally, QwindowsNativeImage is following pending a future refactor with similar code in qpixmap_win.cpp and the Windows XP style. Change-Id: Iddff2f3d715e3ab7695e6c2052b7596a01fd6fa8 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/direct2d/direct2d.pro3
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h1
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp1960
-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.cpp1000
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h143
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h6
-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.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp1
-rw-r--r--src/plugins/platforms/windows/windows.pri21
21 files changed, 13 insertions, 5519 deletions
diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro
index 83c4a730f4..c30703720c 100644
--- a/src/plugins/platforms/direct2d/direct2d.pro
+++ b/src/plugins/platforms/direct2d/direct2d.pro
@@ -2,7 +2,8 @@ TARGET = qdirect2d
QT += \
core-private gui-private \
- eventdispatcher_support-private
+ eventdispatcher_support-private \
+ fontdatabase_support-private theme_support-private
LIBS += -ldwmapi -ld2d1 -ld3d11 -ldwrite -lVersion -lgdi32
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index 0ea2fcfa74..69d2e12778 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -45,8 +45,8 @@
#include "qwindowsdirect2dbitmap.h"
#include "qwindowsdirect2ddevicecontext.h"
-#include "qwindowsfontengine.h"
-#include "qwindowsfontdatabase.h"
+#include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
+#include <QtFontDatabaseSupport/private/qwindowsfontengine_p.h>
#include "qwindowsintegration.h"
#include <QtCore/QtMath>
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/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index bc317c7f5d..1a03df6ac2 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -84,7 +84,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 1630b80306..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ /dev/null
@@ -1,1960 +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,
- const QString &familyName = QString(),
- bool isColorFont = false)
-{
- const unsigned options = QWindowsIntegration::instance()->options();
- if (Q_UNLIKELY(options & QWindowsIntegration::DontUseDirectWriteFonts))
- return false;
- if (isColorFont)
- return (options & QWindowsIntegration::DontUseColorFonts) == 0;
-
- // At some scales, GDI will misrender the MingLiU font, so we force use of
- // DirectWrite to work around the issue.
- if (Q_UNLIKELY(familyName.startsWith(QLatin1String("MingLiU"))))
- return true;
-
- 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, fam, 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 bc0e5cc523..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 auto fontNames = QStringRef(&realKey).trimmed().split(QLatin1Char('&'));
- fontKey.fontNames.reserve(fontNames.size());
- for (const QStringRef &fontName : fontNames)
- fontKey.fontNames.append(fontName.trimmed().toString());
- 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 90008e20a4..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 <QtFontDatabaseSupport/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 334e9cb8b9..0000000000
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ /dev/null
@@ -1,1000 +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;
- }
-
-}
-
-static DWRITE_RENDERING_MODE hintingPreferenceToRenderingMode(QFont::HintingPreference hintingPreference)
-{
- switch (hintingPreference) {
- case QFont::PreferNoHinting:
- return DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
- case QFont::PreferVerticalHinting:
- return DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
- default:
- return DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC;
- }
-}
-
-/*!
- \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 =
- hintingPreferenceToRenderingMode(QFont::HintingPreference(fontDef.hintingPreference));
-
- 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 =
- hintingPreferenceToRenderingMode(QFont::HintingPreference(fontDef.hintingPreference));
-
- 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 16a2b56774..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
@@ -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/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 fe67c0ce37..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
@@ -69,6 +68,7 @@
#include <QtGui/QPixmapCache>
#include <qpa/qwindowsysteminterface.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 0ebed59a1d..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"
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index 411c9e032b..d97e49309f 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,11 +95,6 @@ qtConfig(dynamicgl) {
RESOURCES += $$PWD/openglblacklists.qrc
-qtConfig(freetype) {
- HEADERS += $$PWD/qwindowsfontdatabase_ft.h
- SOURCES += $$PWD/qwindowsfontdatabase_ft.cpp
-}
-
qtConfig(accessibility): include($$PWD/accessible/accessible.pri)
DEFINES *= LIBEGL_NAME=$${LIBEGL_NAME}