summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/fontdatabases
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport/fontdatabases')
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/fontconfig.pri6
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp1013
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h80
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp94
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h75
-rw-r--r--src/platformsupport/fontdatabases/fontdatabases.pro34
-rw-r--r--src/platformsupport/fontdatabases/freetype/freetype.pri9
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp2122
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h364
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp213
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase_p.h80
-rw-r--r--src/platformsupport/fontdatabases/genericunix/genericunix.pri1
-rw-r--r--src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h64
-rw-r--r--src/platformsupport/fontdatabases/mac/coretext.pri15
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm797
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h116
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm1055
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h161
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp2087
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp446
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft_p.h79
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h193
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp1211
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h175
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp1035
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h156
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsnativeimage.cpp159
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h89
-rw-r--r--src/platformsupport/fontdatabases/windows/windows.pri34
-rw-r--r--src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp507
-rw-r--r--src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h92
-rw-r--r--src/platformsupport/fontdatabases/winrt/winrt.pri11
32 files changed, 0 insertions, 12573 deletions
diff --git a/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri
deleted file mode 100644
index 671d6be237..0000000000
--- a/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri
+++ /dev/null
@@ -1,6 +0,0 @@
-HEADERS += $$PWD/qfontconfigdatabase_p.h \
- $$PWD/qfontenginemultifontconfig_p.h
-SOURCES += $$PWD/qfontconfigdatabase.cpp \
- $$PWD/qfontenginemultifontconfig.cpp
-
-QMAKE_USE_PRIVATE += fontconfig
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
deleted file mode 100644
index 7af5490963..0000000000
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ /dev/null
@@ -1,1013 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 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 "qfontconfigdatabase_p.h"
-#include "qfontenginemultifontconfig_p.h"
-
-#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h>
-
-#include <QtCore/QList>
-#include <QtCore/QElapsedTimer>
-#include <QtCore/QFile>
-
-#include <qpa/qplatformnativeinterface.h>
-#include <qpa/qplatformscreen.h>
-#include <qpa/qplatformintegration.h>
-#include <qpa/qplatformservices.h>
-
-#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/private/qhighdpiscaling_p.h>
-
-#include <QtGui/qguiapplication.h>
-
-#include <fontconfig/fontconfig.h>
-#if FC_VERSION >= 20402
-#include <fontconfig/fcfreetype.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-static const int maxWeight = 99;
-
-static inline int mapToQtWeightForRange(int fcweight, int fcLower, int fcUpper, int qtLower, int qtUpper)
-{
- return qtLower + ((fcweight - fcLower) * (qtUpper - qtLower)) / (fcUpper - fcLower);
-}
-
-static inline int weightFromFcWeight(int fcweight)
-{
- // Font Config uses weights from 0 to 215 (the highest enum value) while QFont ranges from
- // 0 to 99. The spacing between the values for the enums are uneven so a linear mapping from
- // Font Config values to Qt would give surprising results. So, we do a piecewise linear
- // mapping. This ensures that where there is a corresponding enum on both sides (for example
- // FC_WEIGHT_DEMIBOLD and QFont::DemiBold) we map one to the other but other values map
- // to intermediate Qt weights.
-
- if (fcweight <= FC_WEIGHT_THIN)
- return QFont::Thin;
- if (fcweight <= FC_WEIGHT_ULTRALIGHT)
- return mapToQtWeightForRange(fcweight, FC_WEIGHT_THIN, FC_WEIGHT_ULTRALIGHT, QFont::Thin, QFont::ExtraLight);
- if (fcweight <= FC_WEIGHT_LIGHT)
- return mapToQtWeightForRange(fcweight, FC_WEIGHT_ULTRALIGHT, FC_WEIGHT_LIGHT, QFont::ExtraLight, QFont::Light);
- if (fcweight <= FC_WEIGHT_NORMAL)
- return mapToQtWeightForRange(fcweight, FC_WEIGHT_LIGHT, FC_WEIGHT_NORMAL, QFont::Light, QFont::Normal);
- if (fcweight <= FC_WEIGHT_MEDIUM)
- return mapToQtWeightForRange(fcweight, FC_WEIGHT_NORMAL, FC_WEIGHT_MEDIUM, QFont::Normal, QFont::Medium);
- if (fcweight <= FC_WEIGHT_DEMIBOLD)
- return mapToQtWeightForRange(fcweight, FC_WEIGHT_MEDIUM, FC_WEIGHT_DEMIBOLD, QFont::Medium, QFont::DemiBold);
- if (fcweight <= FC_WEIGHT_BOLD)
- return mapToQtWeightForRange(fcweight, FC_WEIGHT_DEMIBOLD, FC_WEIGHT_BOLD, QFont::DemiBold, QFont::Bold);
- if (fcweight <= FC_WEIGHT_ULTRABOLD)
- return mapToQtWeightForRange(fcweight, FC_WEIGHT_BOLD, FC_WEIGHT_ULTRABOLD, QFont::Bold, QFont::ExtraBold);
- if (fcweight <= FC_WEIGHT_BLACK)
- return mapToQtWeightForRange(fcweight, FC_WEIGHT_ULTRABOLD, FC_WEIGHT_BLACK, QFont::ExtraBold, QFont::Black);
- if (fcweight <= FC_WEIGHT_ULTRABLACK)
- return mapToQtWeightForRange(fcweight, FC_WEIGHT_BLACK, FC_WEIGHT_ULTRABLACK, QFont::Black, maxWeight);
- return maxWeight;
-}
-
-static inline int stretchFromFcWidth(int fcwidth)
-{
- // Font Config enums for width match pretty closely with those used by Qt so just use
- // Font Config values directly while enforcing the same limits imposed by QFont.
- const int maxStretch = 4000;
- int qtstretch;
- if (fcwidth < 1)
- qtstretch = 1;
- else if (fcwidth > maxStretch)
- qtstretch = maxStretch;
- else
- qtstretch = fcwidth;
-
- return qtstretch;
-}
-
-static const char specialLanguages[][6] = {
- "", // Unknown
- "", // Inherited
- "", // Common
- "en", // Latin
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "dv", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "ko", // Hangul
- "am", // Ethiopic
- "chr", // Cherokee
- "cr", // CanadianAboriginal
- "sga", // Ogham
- "non", // Runic
- "km", // Khmer
- "mn", // Mongolian
- "ja", // Hiragana
- "ja", // Katakana
- "zh-TW", // Bopomofo
- "", // Han
- "ii", // Yi
- "ett", // OldItalic
- "got", // Gothic
- "en", // Deseret
- "fil", // Tagalog
- "hnn", // Hanunoo
- "bku", // Buhid
- "tbw", // Tagbanwa
- "cop", // Coptic
- "lif", // Limbu
- "tdd", // TaiLe
- "grc", // LinearB
- "uga", // Ugaritic
- "en", // Shavian
- "so", // Osmanya
- "grc", // Cypriot
- "", // Braille
- "bug", // Buginese
- "khb", // NewTaiLue
- "cu", // Glagolitic
- "shi", // Tifinagh
- "syl", // SylotiNagri
- "peo", // OldPersian
- "pra", // Kharoshthi
- "ban", // Balinese
- "akk", // Cuneiform
- "phn", // Phoenician
- "lzh", // PhagsPa
- "man", // Nko
- "su", // Sundanese
- "lep", // Lepcha
- "sat", // OlChiki
- "vai", // Vai
- "saz", // Saurashtra
- "eky", // KayahLi
- "rej", // Rejang
- "xlc", // Lycian
- "xcr", // Carian
- "xld", // Lydian
- "cjm", // Cham
- "nod", // TaiTham
- "blt", // TaiViet
- "ae", // Avestan
- "egy", // EgyptianHieroglyphs
- "smp", // Samaritan
- "lis", // Lisu
- "bax", // Bamum
- "jv", // Javanese
- "mni", // MeeteiMayek
- "arc", // ImperialAramaic
- "xsa", // OldSouthArabian
- "xpr", // InscriptionalParthian
- "pal", // InscriptionalPahlavi
- "otk", // OldTurkic
- "bh", // Kaithi
- "bbc", // Batak
- "pra", // Brahmi
- "myz", // Mandaic
- "ccp", // Chakma
- "xmr", // MeroiticCursive
- "xmr", // MeroiticHieroglyphs
- "hmd", // Miao
- "sa", // Sharada
- "srb", // SoraSompeng
- "doi", // Takri
- "lez", // CaucasianAlbanian
- "bsq", // BassaVah
- "fr", // Duployan
- "sq", // Elbasan
- "sa", // Grantha
- "hnj", // PahawhHmong
- "sd", // Khojki
- "lab", // LinearA
- "hi", // Mahajani
- "xmn", // Manichaean
- "men", // MendeKikakui
- "mr", // Modi
- "mru", // Mro
- "xna", // OldNorthArabian
- "arc", // Nabataean
- "arc", // Palmyrene
- "ctd", // PauCinHau
- "kv", // OldPermic
- "pal", // PsalterPahlavi
- "sa", // Siddham
- "sd", // Khudawadi
- "mai", // Tirhuta
- "hoc", // WarangCiti
- "", // Ahom
- "", // AnatolianHieroglyphs
- "", // Hatran
- "", // Multani
- "", // OldHungarian
- "", // SignWriting
- "", // Adlam
- "", // Bhaiksuki
- "", // Marchen
- "", // Newa
- "", // Osage
- "", // Tangut
- "", // MasaramGondi
- "", // Nushu
- "", // Soyombo
- "", // ZanabazarSquare
- "", // Dogra
- "", // GunjalaGondi
- "", // HanifiRohingya
- "", // Makasar
- "", // Medefaidrin
- "", // OldSogdian
- "", // Sogdian
- "", // Elymaic
- "", // Nandinagari
- "", // NyiakengPuachueHmong
- "" // Wancho
-};
-Q_STATIC_ASSERT(sizeof specialLanguages / sizeof *specialLanguages == QChar::ScriptCount);
-
-// this could become a list of all languages used for each writing
-// system, instead of using the single most common language.
-static const char languageForWritingSystem[][6] = {
- "", // Any
- "en", // Latin
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "km", // Khmer
- "zh-cn", // SimplifiedChinese
- "zh-tw", // TraditionalChinese
- "ja", // Japanese
- "ko", // Korean
- "vi", // Vietnamese
- "", // Symbol
- "sga", // Ogham
- "non", // Runic
- "man" // N'Ko
-};
-Q_STATIC_ASSERT(sizeof languageForWritingSystem / sizeof *languageForWritingSystem == QFontDatabase::WritingSystemsCount);
-
-#if FC_VERSION >= 20297
-// Newer FontConfig let's us sort out fonts that report certain scripts support,
-// but no open type tables for handling them correctly.
-// Check the reported script presence in the FC_CAPABILITY's "otlayout:" section.
-static const char capabilityForWritingSystem[][5] = {
- "", // Any
- "", // Latin
- "", // Greek
- "", // Cyrillic
- "", // Armenian
- "", // Hebrew
- "", // Arabic
- "syrc", // Syriac
- "thaa", // Thaana
- "deva", // Devanagari
- "beng", // Bengali
- "guru", // Gurmukhi
- "gujr", // Gujarati
- "orya", // Oriya
- "taml", // Tamil
- "telu", // Telugu
- "knda", // Kannada
- "mlym", // Malayalam
- "sinh", // Sinhala
- "", // Thai
- "", // Lao
- "tibt", // Tibetan
- "mymr", // Myanmar
- "", // Georgian
- "khmr", // Khmer
- "", // SimplifiedChinese
- "", // TraditionalChinese
- "", // Japanese
- "", // Korean
- "", // Vietnamese
- "", // Symbol
- "", // Ogham
- "", // Runic
- "nko " // N'Ko
-};
-Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount);
-#endif
-
-static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
-{
- const char *stylehint = nullptr;
- switch (style) {
- case QFont::SansSerif:
- stylehint = "sans-serif";
- break;
- case QFont::Serif:
- stylehint = "serif";
- break;
- case QFont::TypeWriter:
- case QFont::Monospace:
- stylehint = "monospace";
- break;
- case QFont::Cursive:
- stylehint = "cursive";
- break;
- case QFont::Fantasy:
- stylehint = "fantasy";
- break;
- default:
- break;
- }
- return stylehint;
-}
-
-static inline bool requiresOpenType(int writingSystem)
-{
- return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
- || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
-}
-
-static void populateFromPattern(FcPattern *pattern)
-{
- QString familyName;
- QString familyNameLang;
- FcChar8 *value = nullptr;
- int weight_value;
- int slant_value;
- int spacing_value;
- int width_value;
- FcChar8 *file_value;
- int indexValue;
- FcChar8 *foundry_value;
- FcChar8 *style_value;
- FcBool scalable;
- FcBool antialias;
-
- if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) != FcResultMatch)
- return;
-
- familyName = QString::fromUtf8((const char *)value);
-
- if (FcPatternGetString(pattern, FC_FAMILYLANG, 0, &value) == FcResultMatch)
- familyNameLang = QString::fromUtf8((const char *)value);
-
- slant_value = FC_SLANT_ROMAN;
- weight_value = FC_WEIGHT_REGULAR;
- spacing_value = FC_PROPORTIONAL;
- file_value = nullptr;
- indexValue = 0;
- scalable = FcTrue;
-
-
- if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant_value) != FcResultMatch)
- slant_value = FC_SLANT_ROMAN;
- if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight_value) != FcResultMatch)
- weight_value = FC_WEIGHT_REGULAR;
- if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width_value) != FcResultMatch)
- width_value = FC_WIDTH_NORMAL;
- if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
- spacing_value = FC_PROPORTIONAL;
- if (FcPatternGetString(pattern, FC_FILE, 0, &file_value) != FcResultMatch)
- file_value = nullptr;
- if (FcPatternGetInteger(pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
- indexValue = 0;
- if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = FcTrue;
- if (FcPatternGetString(pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
- foundry_value = nullptr;
- if (FcPatternGetString(pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
- style_value = nullptr;
- if (FcPatternGetBool(pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
- antialias = true;
-
- QSupportedWritingSystems writingSystems;
- FcLangSet *langset = nullptr;
- FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
- if (res == FcResultMatch) {
- bool hasLang = false;
-#if FC_VERSION >= 20297
- FcChar8 *cap = nullptr;
- FcResult capRes = FcResultNoMatch;
-#endif
- for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
- const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
- if (lang) {
- FcLangResult langRes = FcLangSetHasLang(langset, lang);
- if (langRes != FcLangDifferentLang) {
-#if FC_VERSION >= 20297
- if (*capabilityForWritingSystem[j] && requiresOpenType(j)) {
- if (cap == nullptr)
- capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap);
- if (capRes == FcResultMatch && strstr(reinterpret_cast<const char *>(cap), capabilityForWritingSystem[j]) == nullptr)
- continue;
- }
-#endif
- writingSystems.setSupported(QFontDatabase::WritingSystem(j));
- hasLang = true;
- }
- }
- }
- if (!hasLang)
- // none of our known languages, add it to the other set
- writingSystems.setSupported(QFontDatabase::Other);
- } else {
- // we set Other to supported for symbol fonts. It makes no
- // sense to merge these with other ones, as they are
- // special in a way.
- writingSystems.setSupported(QFontDatabase::Other);
- }
-
- FontFile *fontFile = new FontFile;
- fontFile->fileName = QString::fromLocal8Bit((const char *)file_value);
- fontFile->indexValue = indexValue;
-
- QFont::Style style = (slant_value == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant_value == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
- // Note: weight should really be an int but registerFont incorrectly uses an enum
- QFont::Weight weight = QFont::Weight(weightFromFcWeight(weight_value));
-
- double pixel_size = 0;
- if (!scalable)
- FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixel_size);
-
- bool fixedPitch = spacing_value >= FC_MONO;
- // Note: stretch should really be an int but registerFont incorrectly uses an enum
- QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
- QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
- QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
-// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
-
- for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k) {
- const QString altFamilyName = QString::fromUtf8((const char *)value);
- // Extra family names can be aliases or subfamilies.
- // If it is a subfamily, register it as a separate font, so only members of the subfamily are
- // matched when the subfamily is requested.
- QString altStyleName;
- if (FcPatternGetString(pattern, FC_STYLE, k, &value) == FcResultMatch)
- altStyleName = QString::fromUtf8((const char *)value);
- else
- altStyleName = styleName;
-
- QString altFamilyNameLang;
- if (FcPatternGetString(pattern, FC_FAMILYLANG, k, &value) == FcResultMatch)
- altFamilyNameLang = QString::fromUtf8((const char *)value);
- else
- altFamilyNameLang = familyNameLang;
-
- if (familyNameLang == altFamilyNameLang && altStyleName != styleName) {
- FontFile *altFontFile = new FontFile(*fontFile);
- QPlatformFontDatabase::registerFont(altFamilyName, altStyleName, QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,altFontFile);
- } else {
- QPlatformFontDatabase::registerAliasToFontFamily(familyName, altFamilyName);
- }
- }
-
-}
-
-void QFontconfigDatabase::populateFontDatabase()
-{
- FcInit();
- FcFontSet *fonts;
-
- {
- FcObjectSet *os = FcObjectSetCreate();
- FcPattern *pattern = FcPatternCreate();
- const char *properties [] = {
- FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
- FC_SPACING, FC_FILE, FC_INDEX,
- FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
- FC_WIDTH, FC_FAMILYLANG,
-#if FC_VERSION >= 20297
- FC_CAPABILITY,
-#endif
- (const char *)nullptr
- };
- const char **p = properties;
- while (*p) {
- FcObjectSetAdd(os, *p);
- ++p;
- }
- fonts = FcFontList(nullptr, pattern, os);
- FcObjectSetDestroy(os);
- FcPatternDestroy(pattern);
- }
-
- for (int i = 0; i < fonts->nfont; i++)
- populateFromPattern(fonts->fonts[i]);
-
- FcFontSetDestroy (fonts);
-
- struct FcDefaultFont {
- const char *qtname;
- const char *rawname;
- bool fixed;
- };
- const FcDefaultFont defaults[] = {
- { "Serif", "serif", false },
- { "Sans Serif", "sans-serif", false },
- { "Monospace", "monospace", true },
- { nullptr, nullptr, false }
- };
- const FcDefaultFont *f = defaults;
- // aliases only make sense for 'common', not for any of the specials
- QSupportedWritingSystems ws;
- ws.setSupported(QFontDatabase::Latin);
-
- while (f->qtname) {
- QString familyQtName = QString::fromLatin1(f->qtname);
- registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleNormal,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
- registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleItalic,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
- registerFont(familyQtName,QString(),QString(),QFont::Normal,QFont::StyleOblique,QFont::Unstretched,true,true,0,f->fixed,ws,nullptr);
- ++f;
- }
-
- //Lighthouse has very lazy population of the font db. We want it to be initialized when
- //QApplication is constructed, so that the population procedure can do something like this to
- //set the default font
-// const FcDefaultFont *s = defaults;
-// QFont font("Sans Serif");
-// font.setPointSize(9);
-// QApplication::setFont(font);
-}
-
-void QFontconfigDatabase::invalidate()
-{
- // Clear app fonts.
- FcConfigAppFontClear(nullptr);
-}
-
-QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
-{
- return new QFontEngineMultiFontConfig(fontEngine, script);
-}
-
-namespace {
-QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintingPreference, FcPattern *match, bool useXftConf)
-{
- switch (hintingPreference) {
- case QFont::PreferNoHinting:
- return QFontEngine::HintNone;
- case QFont::PreferVerticalHinting:
- return QFontEngine::HintLight;
- case QFont::PreferFullHinting:
- return QFontEngine::HintFull;
- case QFont::PreferDefaultHinting:
- break;
- }
-
- if (QHighDpiScaling::isActive())
- return QFontEngine::HintNone;
-
- int hint_style = 0;
- if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultMatch) {
- switch (hint_style) {
- case FC_HINT_NONE:
- return QFontEngine::HintNone;
- case FC_HINT_SLIGHT:
- return QFontEngine::HintLight;
- case FC_HINT_MEDIUM:
- return QFontEngine::HintMedium;
- case FC_HINT_FULL:
- return QFontEngine::HintFull;
- default:
- Q_UNREACHABLE();
- break;
- }
- }
-
- if (useXftConf) {
- void *hintStyleResource =
- QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
- QGuiApplication::primaryScreen());
- int hintStyle = int(reinterpret_cast<qintptr>(hintStyleResource));
- if (hintStyle > 0)
- return QFontEngine::HintStyle(hintStyle - 1);
- }
-
- return QFontEngine::HintFull;
-}
-
-QFontEngine::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match, bool useXftConf)
-{
- int subpixel = FC_RGBA_UNKNOWN;
- if (FcPatternGetInteger(match, FC_RGBA, 0, &subpixel) == FcResultMatch) {
- switch (subpixel) {
- case FC_RGBA_UNKNOWN:
- case FC_RGBA_NONE:
- return QFontEngine::Subpixel_None;
- case FC_RGBA_RGB:
- return QFontEngine::Subpixel_RGB;
- case FC_RGBA_BGR:
- return QFontEngine::Subpixel_BGR;
- case FC_RGBA_VRGB:
- return QFontEngine::Subpixel_VRGB;
- case FC_RGBA_VBGR:
- return QFontEngine::Subpixel_VBGR;
- default:
- Q_UNREACHABLE();
- break;
- }
- }
-
- if (useXftConf) {
- void *subpixelTypeResource =
- QGuiApplication::platformNativeInterface()->nativeResourceForScreen("subpixeltype",
- QGuiApplication::primaryScreen());
- int subpixelType = int(reinterpret_cast<qintptr>(subpixelTypeResource));
- if (subpixelType > 0)
- return QFontEngine::SubpixelAntialiasingType(subpixelType - 1);
- }
-
- return QFontEngine::Subpixel_None;
-}
-} // namespace
-
-QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
-{
- if (!usrPtr)
- return nullptr;
-
- FontFile *fontfile = static_cast<FontFile *> (usrPtr);
- QFontEngine::FaceId fid;
- fid.filename = QFile::encodeName(fontfile->fileName);
- fid.index = fontfile->indexValue;
-
- // FIXME: Unify with logic in QFontEngineFT::create()
- QFontEngineFT *engine = new QFontEngineFT(f);
- engine->face_id = fid;
-
- setupFontEngine(engine, f);
-
- if (!engine->init(fid, engine->antialias, engine->defaultFormat) || engine->invalid()) {
- delete engine;
- engine = nullptr;
- }
-
- return engine;
-}
-
-QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
-{
- QFontEngineFT *engine = static_cast<QFontEngineFT*>(QFreeTypeFontDatabase::fontEngine(fontData, pixelSize, hintingPreference));
- if (engine == nullptr)
- return nullptr;
-
- setupFontEngine(engine, engine->fontDef);
-
- return engine;
-}
-
-QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
-{
- QStringList fallbackFamilies;
- FcPattern *pattern = FcPatternCreate();
- if (!pattern)
- return fallbackFamilies;
-
- FcValue value;
- value.type = FcTypeString;
- const QByteArray cs = family.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAdd(pattern,FC_FAMILY,value,true);
-
- int slant_value = FC_SLANT_ROMAN;
- if (style == QFont::StyleItalic)
- slant_value = FC_SLANT_ITALIC;
- else if (style == QFont::StyleOblique)
- slant_value = FC_SLANT_OBLIQUE;
- FcPatternAddInteger(pattern, FC_SLANT, slant_value);
-
- Q_ASSERT(uint(script) < QChar::ScriptCount);
- if (*specialLanguages[script] != '\0') {
- FcLangSet *ls = FcLangSetCreate();
- FcLangSetAdd(ls, (const FcChar8*)specialLanguages[script]);
- FcPatternAddLangSet(pattern, FC_LANG, ls);
- FcLangSetDestroy(ls);
- } else if (!family.isEmpty()) {
- // If script is Common or Han, then it may include languages like CJK,
- // we should attach system default language set to the pattern
- // to obtain correct font fallback list (i.e. if LANG=zh_CN
- // then we normally want to use a Chinese font for CJK text;
- // while a Japanese font should be used for that if LANG=ja)
- FcPattern *dummy = FcPatternCreate();
- FcDefaultSubstitute(dummy);
- FcChar8 *lang = nullptr;
- FcResult res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
- if (res == FcResultMatch)
- FcPatternAddString(pattern, FC_LANG, lang);
- FcPatternDestroy(dummy);
- }
-
- const char *stylehint = getFcFamilyForStyleHint(styleHint);
- if (stylehint) {
- value.u.s = (const FcChar8 *)stylehint;
- FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
- }
-
- FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- FcResult result = FcResultMatch;
- FcFontSet *fontSet = FcFontSort(nullptr,pattern,FcFalse,nullptr,&result);
- FcPatternDestroy(pattern);
-
- if (fontSet) {
- QSet<QString> duplicates;
- duplicates.reserve(fontSet->nfont + 1);
- duplicates.insert(family.toCaseFolded());
- for (int i = 0; i < fontSet->nfont; i++) {
- FcChar8 *value = nullptr;
- if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- const QString familyName = QString::fromUtf8((const char *)value);
- const QString familyNameCF = familyName.toCaseFolded();
- if (!duplicates.contains(familyNameCF)) {
- fallbackFamilies << familyName;
- duplicates.insert(familyNameCF);
- }
- }
- FcFontSetDestroy(fontSet);
- }
-// qDebug() << "fallbackFamilies for:" << family << style << styleHint << script << fallbackFamilies;
-
- return fallbackFamilies;
-}
-
-static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id, FcBlanks *blanks, int *count)
-{
-#if FC_VERSION < 20402
- Q_UNUSED(data)
- return FcFreeTypeQuery(file, id, blanks, count);
-#else
- if (data.isEmpty())
- return FcFreeTypeQuery(file, id, blanks, count);
-
- FT_Library lib = qt_getFreetype();
-
- FcPattern *pattern = nullptr;
-
- FT_Face face;
- if (!FT_New_Memory_Face(lib, (const FT_Byte *)data.constData(), data.size(), id, &face)) {
- *count = face->num_faces;
-
- pattern = FcFreeTypeQueryFace(face, file, id, blanks);
-
- FT_Done_Face(face);
- }
-
- return pattern;
-#endif
-}
-
-QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
-{
- QStringList families;
-
- FcFontSet *set = FcConfigGetFonts(nullptr, FcSetApplication);
- if (!set) {
- FcConfigAppFontAddFile(nullptr, (const FcChar8 *)":/non-existent");
- set = FcConfigGetFonts(nullptr, FcSetApplication); // try again
- if (!set)
- return families;
- }
-
- int id = 0;
- FcBlanks *blanks = FcConfigGetBlanks(nullptr);
- int count = 0;
-
- FcPattern *pattern;
- do {
- pattern = queryFont((const FcChar8 *)QFile::encodeName(fileName).constData(),
- fontData, id, blanks, &count);
- if (!pattern)
- return families;
-
- FcChar8 *fam = nullptr;
- if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
- QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
- families << family;
- }
- populateFromPattern(pattern);
-
- FcFontSetAdd(set, pattern);
-
- ++id;
- } while (id < count);
-
- return families;
-}
-
-QString QFontconfigDatabase::resolveFontFamilyAlias(const QString &family) const
-{
- QString resolved = QFreeTypeFontDatabase::resolveFontFamilyAlias(family);
- if (!resolved.isEmpty() && resolved != family)
- return resolved;
- FcPattern *pattern = FcPatternCreate();
- if (!pattern)
- return family;
-
- if (!family.isEmpty()) {
- const QByteArray cs = family.toUtf8();
- FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) cs.constData());
- }
- FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- FcChar8 *familyAfterSubstitution = nullptr;
- FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution);
- resolved = QString::fromUtf8((const char *) familyAfterSubstitution);
- FcPatternDestroy(pattern);
-
- return resolved;
-}
-
-QFont QFontconfigDatabase::defaultFont() const
-{
- // Hack to get system default language until FcGetDefaultLangs()
- // is exported (https://bugs.freedesktop.org/show_bug.cgi?id=32853)
- // or https://bugs.freedesktop.org/show_bug.cgi?id=35482 is fixed
- FcPattern *dummy = FcPatternCreate();
- FcDefaultSubstitute(dummy);
- FcChar8 *lang = nullptr;
- FcResult res = FcPatternGetString(dummy, FC_LANG, 0, &lang);
-
- FcPattern *pattern = FcPatternCreate();
- if (res == FcResultMatch) {
- // Make defaultFont pattern matching locale language aware, because
- // certain FC_LANG based custom rules may happen in FcConfigSubstitute()
- FcPatternAddString(pattern, FC_LANG, lang);
- }
- FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- FcChar8 *familyAfterSubstitution = nullptr;
- FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution);
- QString resolved = QString::fromUtf8((const char *) familyAfterSubstitution);
- FcPatternDestroy(pattern);
- FcPatternDestroy(dummy);
-
- return QFont(resolved);
-}
-
-void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef &fontDef) const
-{
- bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
- bool forcedAntialiasSetting = !antialias || QHighDpiScaling::isActive();
-
- const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
- bool useXftConf = false;
-
- if (services) {
- const QList<QByteArray> desktopEnv = services->desktopEnvironment().split(':');
- useXftConf = desktopEnv.contains("GNOME") || desktopEnv.contains("UNITY") || desktopEnv.contains("XFCE");
- }
-
- if (useXftConf && !forcedAntialiasSetting) {
- void *antialiasResource =
- QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled",
- QGuiApplication::primaryScreen());
- int antialiasingEnabled = int(reinterpret_cast<qintptr>(antialiasResource));
- if (antialiasingEnabled > 0)
- antialias = antialiasingEnabled - 1;
- }
-
- QFontEngine::GlyphFormat format;
- // try and get the pattern
- FcPattern *pattern = FcPatternCreate();
-
- FcValue value;
- value.type = FcTypeString;
- QByteArray cs = fontDef.family.toUtf8();
- value.u.s = (const FcChar8 *)cs.data();
- FcPatternAdd(pattern,FC_FAMILY,value,true);
-
- QFontEngine::FaceId fid = engine->faceId();
-
- if (!fid.filename.isEmpty()) {
- value.u.s = (const FcChar8 *)fid.filename.data();
- FcPatternAdd(pattern,FC_FILE,value,true);
-
- value.type = FcTypeInteger;
- value.u.i = fid.index;
- FcPatternAdd(pattern,FC_INDEX,value,true);
- }
-
- if (fontDef.pixelSize > 0.1)
- FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontDef.pixelSize);
-
- FcResult result;
-
- FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- FcPattern *match = FcFontMatch(nullptr, pattern, &result);
- if (match) {
- engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)fontDef.hintingPreference, match, useXftConf));
-
- FcBool fc_autohint;
- if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch)
- engine->forceAutoHint = fc_autohint;
-
-#if defined(FT_LCD_FILTER_H)
- int lcdFilter;
- if (FcPatternGetInteger(match, FC_LCD_FILTER, 0, &lcdFilter) == FcResultMatch)
- engine->lcdFilterType = lcdFilter;
-#endif
-
- if (!forcedAntialiasSetting) {
- FcBool fc_antialias;
- if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch)
- antialias = fc_antialias;
- }
-
- if (antialias) {
- QFontEngine::SubpixelAntialiasingType subpixelType = QFontEngine::Subpixel_None;
- if (!(fontDef.styleStrategy & QFont::NoSubpixelAntialias))
- subpixelType = subpixelTypeFromMatch(match, useXftConf);
- engine->subpixelType = subpixelType;
-
- format = (subpixelType == QFontEngine::Subpixel_None)
- ? QFontEngine::Format_A8
- : QFontEngine::Format_A32;
- } else
- format = QFontEngine::Format_Mono;
-
- FcPatternDestroy(match);
- } else
- format = antialias ? QFontEngine::Format_A8 : QFontEngine::Format_Mono;
-
- FcPatternDestroy(pattern);
-
- engine->antialias = antialias;
- engine->defaultFormat = format;
- engine->glyphFormat = format;
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
deleted file mode 100644
index a7257c2f98..0000000000
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
+++ /dev/null
@@ -1,80 +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 QFONTCONFIGDATABASE_H
-#define QFONTCONFIGDATABASE_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 <qpa/qplatformfontdatabase.h>
-#include <QtFontDatabaseSupport/private/qfreetypefontdatabase_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFontEngineFT;
-
-class QFontconfigDatabase : public QFreeTypeFontDatabase
-{
-public:
- void populateFontDatabase() override;
- void invalidate() override;
- QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) override;
- QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
- QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
- QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
- QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override;
- QString resolveFontFamilyAlias(const QString &family) const override;
- QFont defaultFont() const override;
-
-private:
- void setupFontEngine(QFontEngineFT *engine, const QFontDef &fontDef) const;
-};
-
-QT_END_NAMESPACE
-
-#endif // QFONTCONFIGDATABASE_H
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
deleted file mode 100644
index cbf0793d75..0000000000
--- a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
+++ /dev/null
@@ -1,94 +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 "qfontenginemultifontconfig_p.h"
-
-#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QFontEngineMultiFontConfig::QFontEngineMultiFontConfig(QFontEngine *fe, int script)
- : QFontEngineMulti(fe, script)
-{
-}
-
-QFontEngineMultiFontConfig::~QFontEngineMultiFontConfig()
-{
- for (FcPattern *pattern : qAsConst(cachedMatchPatterns)) {
- if (pattern)
- FcPatternDestroy(pattern);
- }
-}
-
-bool QFontEngineMultiFontConfig::shouldLoadFontEngineForCharacter(int at, uint ucs4) const
-{
- bool charSetHasChar = true;
- FcPattern *matchPattern = getMatchPatternForFallback(at - 1);
- if (matchPattern != nullptr) {
- FcCharSet *charSet;
- FcPatternGetCharSet(matchPattern, FC_CHARSET, 0, &charSet);
- charSetHasChar = FcCharSetHasChar(charSet, ucs4);
- }
-
- return charSetHasChar;
-}
-
-
-FcPattern * QFontEngineMultiFontConfig::getMatchPatternForFallback(int fallBackIndex) const
-{
- Q_ASSERT(fallBackIndex < fallbackFamilyCount());
- if (fallbackFamilyCount() > cachedMatchPatterns.size())
- cachedMatchPatterns.resize(fallbackFamilyCount());
- FcPattern *ret = cachedMatchPatterns.at(fallBackIndex);
- if (ret)
- return ret;
- FcPattern *requestPattern = FcPatternCreate();
- FcValue value;
- value.type = FcTypeString;
- QByteArray cs = fallbackFamilyAt(fallBackIndex).toUtf8();
- value.u.s = reinterpret_cast<const FcChar8 *>(cs.data());
- FcPatternAdd(requestPattern, FC_FAMILY, value, true);
- FcResult result;
- ret = FcFontMatch(nullptr, requestPattern, &result);
- cachedMatchPatterns.insert(fallBackIndex, ret);
- FcPatternDestroy(requestPattern);
- return ret;
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h
deleted file mode 100644
index 7f560c2d05..0000000000
--- a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig_p.h
+++ /dev/null
@@ -1,75 +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 QFONTENGINEMULTIFONTCONFIG_H
-#define QFONTENGINEMULTIFONTCONFIG_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 <fontconfig/fontconfig.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFontEngineMultiFontConfig : public QFontEngineMulti
-{
-public:
- explicit QFontEngineMultiFontConfig(QFontEngine *fe, int script);
-
- ~QFontEngineMultiFontConfig();
-
- bool shouldLoadFontEngineForCharacter(int at, uint ucs4) const override;
-private:
- FcPattern* getMatchPatternForFallback(int at) const;
-
- mutable QVector<FcPattern*> cachedMatchPatterns;
-};
-
-QT_END_NAMESPACE
-
-#endif // QFONTENGINEMULTIFONTCONFIG_H
diff --git a/src/platformsupport/fontdatabases/fontdatabases.pro b/src/platformsupport/fontdatabases/fontdatabases.pro
deleted file mode 100644
index c3985ed398..0000000000
--- a/src/platformsupport/fontdatabases/fontdatabases.pro
+++ /dev/null
@@ -1,34 +0,0 @@
-TARGET = QtFontDatabaseSupport
-MODULE = fontdatabase_support
-
-QT = core-private gui-private
-CONFIG += static internal_module
-
-DEFINES += QT_NO_CAST_FROM_ASCII
-PRECOMPILED_HEADER = ../../corelib/global/qt_pch.h
-
-darwin {
- include($$PWD/mac/coretext.pri)
-}
-
-qtConfig(freetype) {
- include($$PWD/freetype/freetype.pri)
-}
-
-unix {
- include($$PWD/genericunix/genericunix.pri)
-}
-
-qtConfig(fontconfig) {
- include($$PWD/fontconfig/fontconfig.pri)
-}
-
-win32:!winrt {
- include($$PWD/windows/windows.pri)
-}
-
-winrt {
- include($$PWD/winrt/winrt.pri)
-}
-
-load(qt_module)
diff --git a/src/platformsupport/fontdatabases/freetype/freetype.pri b/src/platformsupport/fontdatabases/freetype/freetype.pri
deleted file mode 100644
index 7bda687ef4..0000000000
--- a/src/platformsupport/fontdatabases/freetype/freetype.pri
+++ /dev/null
@@ -1,9 +0,0 @@
-HEADERS += \
- $$PWD/qfreetypefontdatabase_p.h \
- $$PWD/qfontengine_ft_p.h
-
-SOURCES += \
- $$PWD/qfreetypefontdatabase.cpp \
- $$PWD/qfontengine_ft.cpp
-
-QMAKE_USE_PRIVATE += freetype
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
deleted file mode 100644
index ca78063f08..0000000000
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ /dev/null
@@ -1,2122 +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 "qdir.h"
-#include "qmetatype.h"
-#include "qtextstream.h"
-#include "qvariant.h"
-#include "qfontengine_ft_p.h"
-#include "private/qimage_p.h"
-#include <private/qstringiterator_p.h>
-#include <qguiapplication.h>
-#include <qscreen.h>
-#include <qpa/qplatformscreen.h>
-#include <QtCore/QUuid>
-
-#ifndef QT_NO_FREETYPE
-
-#include "qfile.h"
-#include "qfileinfo.h"
-#include <qscopedvaluerollback.h>
-#include "qthreadstorage.h"
-#include <qmath.h>
-#include <qendian.h>
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_OUTLINE_H
-#include FT_SYNTHESIS_H
-#include FT_TRUETYPE_TABLES_H
-#include FT_TYPE1_TABLES_H
-#include FT_GLYPH_H
-#include FT_MODULE_H
-#include FT_LCD_FILTER_H
-
-#if defined(FT_CONFIG_OPTIONS_H)
-#include FT_CONFIG_OPTIONS_H
-#endif
-
-#if defined(FT_FONT_FORMATS_H)
-#include FT_FONT_FORMATS_H
-#endif
-
-#ifdef QT_LINUXBASE
-#include FT_ERRORS_H
-#endif
-
-#if !defined(QT_MAX_CACHED_GLYPH_SIZE)
-# define QT_MAX_CACHED_GLYPH_SIZE 64
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#define FLOOR(x) ((x) & -64)
-#define CEIL(x) (((x)+63) & -64)
-#define TRUNC(x) ((x) >> 6)
-#define ROUND(x) (((x)+32) & -64)
-
-static bool ft_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length)
-{
- FT_Face face = (FT_Face)user_data;
-
- bool result = false;
- if (FT_IS_SFNT(face)) {
- FT_ULong len = *length;
- result = FT_Load_Sfnt_Table(face, tag, 0, buffer, &len) == FT_Err_Ok;
- *length = len;
- Q_ASSERT(!result || int(*length) > 0);
- }
-
- return result;
-}
-
-static QFontEngineFT::Glyph emptyGlyph;
-
-static const QFontEngine::HintStyle ftInitialDefaultHintStyle =
-#ifdef Q_OS_WIN
- QFontEngineFT::HintFull;
-#else
- QFontEngineFT::HintNone;
-#endif
-
-// -------------------------- Freetype support ------------------------------
-
-class QtFreetypeData
-{
-public:
- QtFreetypeData()
- : library(nullptr)
- { }
- ~QtFreetypeData();
-
- FT_Library library;
- QHash<QFontEngine::FaceId, QFreetypeFace *> faces;
-};
-
-QtFreetypeData::~QtFreetypeData()
-{
- for (QHash<QFontEngine::FaceId, QFreetypeFace *>::ConstIterator iter = faces.cbegin(); iter != faces.cend(); ++iter)
- iter.value()->cleanup();
- faces.clear();
- FT_Done_FreeType(library);
- library = nullptr;
-}
-
-Q_GLOBAL_STATIC(QThreadStorage<QtFreetypeData *>, theFreetypeData)
-
-QtFreetypeData *qt_getFreetypeData()
-{
- QtFreetypeData *&freetypeData = theFreetypeData()->localData();
- if (!freetypeData)
- freetypeData = new QtFreetypeData;
- if (!freetypeData->library) {
- FT_Init_FreeType(&freetypeData->library);
-#if defined(FT_FONT_FORMATS_H)
- // Freetype defaults to disabling stem-darkening on CFF, we re-enable it.
- FT_Bool no_darkening = false;
- FT_Property_Set(freetypeData->library, "cff", "no-stem-darkening", &no_darkening);
-#endif
- }
- return freetypeData;
-}
-
-FT_Library qt_getFreetype()
-{
- QtFreetypeData *freetypeData = qt_getFreetypeData();
- Q_ASSERT(freetypeData->library);
- return freetypeData->library;
-}
-
-int QFreetypeFace::fsType() const
-{
- int fsType = 0;
- TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
- if (os2)
- fsType = os2->fsType;
- return fsType;
-}
-
-int QFreetypeFace::getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints)
-{
- if (int error = FT_Load_Glyph(face, glyph, flags))
- return error;
-
- if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
- return Err_Invalid_SubTable;
-
- *nPoints = face->glyph->outline.n_points;
- if (!(*nPoints))
- return Err_Ok;
-
- if (point > *nPoints)
- return Err_Invalid_SubTable;
-
- *xpos = QFixed::fromFixed(face->glyph->outline.points[point].x);
- *ypos = QFixed::fromFixed(face->glyph->outline.points[point].y);
-
- return Err_Ok;
-}
-
-bool QFreetypeFace::isScalableBitmap() const
-{
-#ifdef FT_HAS_COLOR
- return !FT_IS_SCALABLE(face) && FT_HAS_COLOR(face);
-#else
- return false;
-#endif
-}
-
-extern QByteArray qt_fontdata_from_index(int);
-
-/*
- * One font file can contain more than one font (bold/italic for example)
- * find the right one and return it.
- *
- * Returns the freetype face or 0 in case of an empty file or any other problems
- * (like not being able to open the file)
- */
-QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id,
- const QByteArray &fontData)
-{
- if (face_id.filename.isEmpty() && fontData.isEmpty())
- return nullptr;
-
- QtFreetypeData *freetypeData = qt_getFreetypeData();
-
- QFreetypeFace *freetype = freetypeData->faces.value(face_id, 0);
- if (freetype) {
- freetype->ref.ref();
- } else {
- QScopedPointer<QFreetypeFace> newFreetype(new QFreetypeFace);
- FT_Face face;
- if (!face_id.filename.isEmpty()) {
- QString fileName = QFile::decodeName(face_id.filename);
- if (face_id.filename.startsWith(":qmemoryfonts/")) {
- // from qfontdatabase.cpp
- QByteArray idx = face_id.filename;
- idx.remove(0, 14); // remove ':qmemoryfonts/'
- bool ok = false;
- newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
- if (!ok)
- newFreetype->fontData = QByteArray();
- } else if (!QFileInfo(fileName).isNativePath()) {
- QFile file(fileName);
- if (!file.open(QIODevice::ReadOnly)) {
- return nullptr;
- }
- newFreetype->fontData = file.readAll();
- }
- } else {
- newFreetype->fontData = fontData;
- }
- if (!newFreetype->fontData.isEmpty()) {
- if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) {
- return nullptr;
- }
- } else if (FT_New_Face(freetypeData->library, face_id.filename, face_id.index, &face)) {
- return nullptr;
- }
- newFreetype->face = face;
-
- newFreetype->ref.storeRelaxed(1);
- newFreetype->xsize = 0;
- newFreetype->ysize = 0;
- newFreetype->matrix.xx = 0x10000;
- newFreetype->matrix.yy = 0x10000;
- newFreetype->matrix.xy = 0;
- newFreetype->matrix.yx = 0;
- newFreetype->unicode_map = nullptr;
- newFreetype->symbol_map = nullptr;
-
- memset(newFreetype->cmapCache, 0, sizeof(newFreetype->cmapCache));
-
- for (int i = 0; i < newFreetype->face->num_charmaps; ++i) {
- FT_CharMap cm = newFreetype->face->charmaps[i];
- switch(cm->encoding) {
- case FT_ENCODING_UNICODE:
- newFreetype->unicode_map = cm;
- break;
- case FT_ENCODING_APPLE_ROMAN:
- case FT_ENCODING_ADOBE_LATIN_1:
- if (!newFreetype->unicode_map || newFreetype->unicode_map->encoding != FT_ENCODING_UNICODE)
- newFreetype->unicode_map = cm;
- break;
- case FT_ENCODING_ADOBE_CUSTOM:
- case FT_ENCODING_MS_SYMBOL:
- if (!newFreetype->symbol_map)
- newFreetype->symbol_map = cm;
- break;
- default:
- break;
- }
- }
-
- if (!FT_IS_SCALABLE(newFreetype->face) && newFreetype->face->num_fixed_sizes == 1)
- FT_Set_Char_Size(face, newFreetype->face->available_sizes[0].x_ppem, newFreetype->face->available_sizes[0].y_ppem, 0, 0);
-
- FT_Set_Charmap(newFreetype->face, newFreetype->unicode_map);
- QT_TRY {
- freetypeData->faces.insert(face_id, newFreetype.data());
- } QT_CATCH(...) {
- newFreetype.take()->release(face_id);
- // we could return null in principle instead of throwing
- QT_RETHROW;
- }
- freetype = newFreetype.take();
- }
- return freetype;
-}
-
-void QFreetypeFace::cleanup()
-{
- hbFace.reset();
- FT_Done_Face(face);
- face = nullptr;
-}
-
-void QFreetypeFace::release(const QFontEngine::FaceId &face_id)
-{
- if (!ref.deref()) {
- if (face) {
- QtFreetypeData *freetypeData = qt_getFreetypeData();
-
- cleanup();
-
- auto it = freetypeData->faces.constFind(face_id);
- if (it != freetypeData->faces.constEnd())
- freetypeData->faces.erase(it);
-
- if (freetypeData->faces.isEmpty()) {
- FT_Done_FreeType(freetypeData->library);
- freetypeData->library = nullptr;
- }
- }
-
- delete this;
- }
-}
-
-
-void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing, QFixed *scalableBitmapScaleFactor)
-{
- *ysize = qRound(fontDef.pixelSize * 64);
- *xsize = *ysize * fontDef.stretch / 100;
- *scalableBitmapScaleFactor = 1;
- *outline_drawing = false;
-
- if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) {
- int best = 0;
- if (!isScalableBitmap()) {
- /*
- * Bitmap only faces must match exactly, so find the closest
- * one (height dominant search)
- */
- for (int i = 1; i < face->num_fixed_sizes; i++) {
- if (qAbs(*ysize - face->available_sizes[i].y_ppem) <
- qAbs(*ysize - face->available_sizes[best].y_ppem) ||
- (qAbs(*ysize - face->available_sizes[i].y_ppem) ==
- qAbs(*ysize - face->available_sizes[best].y_ppem) &&
- qAbs(*xsize - face->available_sizes[i].x_ppem) <
- qAbs(*xsize - face->available_sizes[best].x_ppem))) {
- best = i;
- }
- }
- } else {
- // Select the shortest bitmap strike whose height is larger than the desired height
- for (int i = 1; i < face->num_fixed_sizes; i++) {
- if (face->available_sizes[i].y_ppem < *ysize) {
- if (face->available_sizes[i].y_ppem > face->available_sizes[best].y_ppem)
- best = i;
- } else if (face->available_sizes[best].y_ppem < *ysize) {
- best = i;
- } else if (face->available_sizes[i].y_ppem < face->available_sizes[best].y_ppem) {
- best = i;
- }
- }
- }
-
- // According to freetype documentation we must use FT_Select_Size
- // to make sure we can select the desired bitmap strike index
- if (FT_Select_Size(face, best) == 0) {
- if (isScalableBitmap())
- *scalableBitmapScaleFactor = QFixed::fromReal((qreal)fontDef.pixelSize / face->available_sizes[best].height);
- *xsize = face->available_sizes[best].x_ppem;
- *ysize = face->available_sizes[best].y_ppem;
- } else {
- *xsize = *ysize = 0;
- }
- } else {
- *outline_drawing = (*xsize > (QT_MAX_CACHED_GLYPH_SIZE<<6) || *ysize > (QT_MAX_CACHED_GLYPH_SIZE<<6));
- }
-}
-
-QFontEngine::Properties QFreetypeFace::properties() const
-{
- QFontEngine::Properties p;
- p.postscriptName = FT_Get_Postscript_Name(face);
- PS_FontInfoRec font_info;
- if (FT_Get_PS_Font_Info(face, &font_info) == 0)
- p.copyright = font_info.notice;
- if (FT_IS_SCALABLE(face)) {
- p.ascent = face->ascender;
- p.descent = -face->descender;
- p.leading = face->height - face->ascender + face->descender;
- p.emSquare = face->units_per_EM;
- p.boundingBox = QRectF(face->bbox.xMin, -face->bbox.yMax,
- face->bbox.xMax - face->bbox.xMin,
- face->bbox.yMax - face->bbox.yMin);
- } else {
- p.ascent = QFixed::fromFixed(face->size->metrics.ascender);
- p.descent = QFixed::fromFixed(-face->size->metrics.descender);
- p.leading = QFixed::fromFixed(face->size->metrics.height - face->size->metrics.ascender + face->size->metrics.descender);
- p.emSquare = face->size->metrics.y_ppem;
-// p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.);
- p.boundingBox = QRectF(0, -p.ascent.toReal(),
- face->size->metrics.max_advance/64, (p.ascent + p.descent).toReal() );
- }
- p.italicAngle = 0;
- p.capHeight = p.ascent;
- p.lineWidth = face->underline_thickness;
-
- return p;
-}
-
-bool QFreetypeFace::getSfntTable(uint tag, uchar *buffer, uint *length) const
-{
- return ft_getSfntTable(face, tag, buffer, length);
-}
-
-/* Some fonts (such as MingLiu rely on hinting to scale different
- components to their correct sizes. While this is really broken (it
- should be done in the component glyph itself, not the hinter) we
- will have to live with it.
-
- This means we can not use FT_LOAD_NO_HINTING to get the glyph
- outline. All we can do is to load the unscaled glyph and scale it
- down manually when required.
-*/
-static void scaleOutline(FT_Face face, FT_GlyphSlot g, FT_Fixed x_scale, FT_Fixed y_scale)
-{
- x_scale = FT_MulDiv(x_scale, 1 << 10, face->units_per_EM);
- y_scale = FT_MulDiv(y_scale, 1 << 10, face->units_per_EM);
- FT_Vector *p = g->outline.points;
- const FT_Vector *e = p + g->outline.n_points;
- while (p < e) {
- p->x = FT_MulFix(p->x, x_scale);
- p->y = FT_MulFix(p->y, y_scale);
- ++p;
- }
-}
-
-#define GLYPH2PATH_DEBUG QT_NO_QDEBUG_MACRO // qDebug
-void QFreetypeFace::addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoint &point, QPainterPath *path, FT_Fixed x_scale, FT_Fixed y_scale)
-{
- const qreal factor = 1/64.;
- scaleOutline(face, g, x_scale, y_scale);
-
- QPointF cp = point.toPointF();
-
- // convert the outline to a painter path
- int i = 0;
- for (int j = 0; j < g->outline.n_contours; ++j) {
- int last_point = g->outline.contours[j];
- GLYPH2PATH_DEBUG() << "contour:" << i << "to" << last_point;
- QPointF start = QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
- if (!(g->outline.tags[i] & 1)) { // start point is not on curve:
- if (!(g->outline.tags[last_point] & 1)) { // end point is not on curve:
- GLYPH2PATH_DEBUG() << " start and end point are not on curve";
- start = (QPointF(g->outline.points[last_point].x*factor,
- -g->outline.points[last_point].y*factor) + start) / 2.0;
- } else {
- GLYPH2PATH_DEBUG() << " end point is on curve, start is not";
- start = QPointF(g->outline.points[last_point].x*factor,
- -g->outline.points[last_point].y*factor);
- }
- --i; // to use original start point as control point below
- }
- start += cp;
- GLYPH2PATH_DEBUG() << " start at" << start;
-
- path->moveTo(start);
- QPointF c[4];
- c[0] = start;
- int n = 1;
- while (i < last_point) {
- ++i;
- c[n] = cp + QPointF(g->outline.points[i].x*factor, -g->outline.points[i].y*factor);
- GLYPH2PATH_DEBUG() << " " << i << c[n] << "tag =" << (int)g->outline.tags[i]
- << ": on curve =" << (bool)(g->outline.tags[i] & 1);
- ++n;
- switch (g->outline.tags[i] & 3) {
- case 2:
- // cubic bezier element
- if (n < 4)
- continue;
- c[3] = (c[3] + c[2])/2;
- --i;
- break;
- case 0:
- // quadratic bezier element
- if (n < 3)
- continue;
- c[3] = (c[1] + c[2])/2;
- c[2] = (2*c[1] + c[3])/3;
- c[1] = (2*c[1] + c[0])/3;
- --i;
- break;
- case 1:
- case 3:
- if (n == 2) {
- GLYPH2PATH_DEBUG() << " lineTo" << c[1];
- path->lineTo(c[1]);
- c[0] = c[1];
- n = 1;
- continue;
- } else if (n == 3) {
- c[3] = c[2];
- c[2] = (2*c[1] + c[3])/3;
- c[1] = (2*c[1] + c[0])/3;
- }
- break;
- }
- GLYPH2PATH_DEBUG() << " cubicTo" << c[1] << c[2] << c[3];
- path->cubicTo(c[1], c[2], c[3]);
- c[0] = c[3];
- n = 1;
- }
-
- if (n == 1) {
- GLYPH2PATH_DEBUG() << " closeSubpath";
- path->closeSubpath();
- } else {
- c[3] = start;
- if (n == 2) {
- c[2] = (2*c[1] + c[3])/3;
- c[1] = (2*c[1] + c[0])/3;
- }
- GLYPH2PATH_DEBUG() << " close cubicTo" << c[1] << c[2] << c[3];
- path->cubicTo(c[1], c[2], c[3]);
- }
- ++i;
- }
-}
-
-extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data, int bpl, int w, int h, QPainterPath *path);
-
-void QFreetypeFace::addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path)
-{
- if (slot->format != FT_GLYPH_FORMAT_BITMAP
- || slot->bitmap.pixel_mode != FT_PIXEL_MODE_MONO)
- return;
-
- QPointF cp = point.toPointF();
- qt_addBitmapToPath(cp.x() + TRUNC(slot->metrics.horiBearingX), cp.y() - TRUNC(slot->metrics.horiBearingY),
- slot->bitmap.buffer, slot->bitmap.pitch, slot->bitmap.width, slot->bitmap.rows, path);
-}
-
-static inline void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
-{
- const int offs = bgr ? -1 : 1;
- const int w = width * 3;
- while (height--) {
- uint *dd = dst;
- for (int x = 0; x < w; x += 3) {
- uchar red = src[x + 1 - offs];
- uchar green = src[x + 1];
- uchar blue = src[x + 1 + offs];
- *dd++ = (0xFFU << 24) | (red << 16) | (green << 8) | blue;
- }
- dst += width;
- src += src_pitch;
- }
-}
-
-static inline void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
-{
- const int offs = bgr ? -src_pitch : src_pitch;
- while (height--) {
- for (int x = 0; x < width; x++) {
- uchar red = src[x + src_pitch - offs];
- uchar green = src[x + src_pitch];
- uchar blue = src[x + src_pitch + offs];
- *dst++ = (0XFFU << 24) | (red << 16) | (green << 8) | blue;
- }
- src += 3*src_pitch;
- }
-}
-
-static QFontEngine::SubpixelAntialiasingType subpixelAntialiasingTypeHint()
-{
- static int type = -1;
- if (type == -1) {
- if (QScreen *screen = QGuiApplication::primaryScreen())
- type = screen->handle()->subpixelAntialiasingTypeHint();
- }
- return static_cast<QFontEngine::SubpixelAntialiasingType>(type);
-}
-
-QFontEngineFT *QFontEngineFT::create(const QFontDef &fontDef, FaceId faceId, const QByteArray &fontData)
-{
- QScopedPointer<QFontEngineFT> engine(new QFontEngineFT(fontDef));
-
- QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_Mono;
- const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
-
- if (antialias) {
- QFontEngine::SubpixelAntialiasingType subpixelType = subpixelAntialiasingTypeHint();
- if (subpixelType == QFontEngine::Subpixel_None || (fontDef.styleStrategy & QFont::NoSubpixelAntialias)) {
- format = QFontEngineFT::Format_A8;
- engine->subpixelType = QFontEngine::Subpixel_None;
- } else {
- format = QFontEngineFT::Format_A32;
- engine->subpixelType = subpixelType;
- }
- }
-
- if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) {
- qWarning("QFontEngineFT: Failed to create FreeType font engine");
- return nullptr;
- }
-
- engine->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
- return engine.take();
-}
-
-namespace {
- class QFontEngineFTRawData: public QFontEngineFT
- {
- public:
- QFontEngineFTRawData(const QFontDef &fontDef) : QFontEngineFT(fontDef)
- {
- }
-
- void updateFamilyNameAndStyle()
- {
- fontDef.family = QString::fromLatin1(freetype->face->family_name);
-
- if (freetype->face->style_flags & FT_STYLE_FLAG_ITALIC)
- fontDef.style = QFont::StyleItalic;
-
- if (freetype->face->style_flags & FT_STYLE_FLAG_BOLD)
- fontDef.weight = QFont::Bold;
- }
-
- bool initFromData(const QByteArray &fontData)
- {
- FaceId faceId;
- faceId.filename = "";
- faceId.index = 0;
- faceId.uuid = QUuid::createUuid().toByteArray();
-
- return init(faceId, true, Format_None, fontData);
- }
- };
-}
-
-QFontEngineFT *QFontEngineFT::create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
-{
- QFontDef fontDef;
- fontDef.pixelSize = pixelSize;
- fontDef.stretch = QFont::Unstretched;
- fontDef.hintingPreference = hintingPreference;
-
- QFontEngineFTRawData *fe = new QFontEngineFTRawData(fontDef);
- if (!fe->initFromData(fontData)) {
- delete fe;
- return nullptr;
- }
-
- fe->updateFamilyNameAndStyle();
- fe->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
-
- return fe;
-}
-
-QFontEngineFT::QFontEngineFT(const QFontDef &fd)
- : QFontEngine(Freetype)
-{
- fontDef = fd;
- matrix.xx = 0x10000;
- matrix.yy = 0x10000;
- matrix.xy = 0;
- matrix.yx = 0;
- cache_cost = 100 * 1024;
- kerning_pairs_loaded = false;
- transform = false;
- embolden = false;
- obliquen = false;
- antialias = true;
- freetype = nullptr;
- default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
- default_hint_style = ftInitialDefaultHintStyle;
- subpixelType = Subpixel_None;
- lcdFilterType = (int)((quintptr) FT_LCD_FILTER_DEFAULT);
- defaultFormat = Format_None;
- embeddedbitmap = false;
- const QByteArray env = qgetenv("QT_NO_FT_CACHE");
- cacheEnabled = env.isEmpty() || env.toInt() == 0;
- m_subPixelPositionCount = 4;
- forceAutoHint = false;
- stemDarkeningDriver = false;
-}
-
-QFontEngineFT::~QFontEngineFT()
-{
- if (freetype)
- freetype->release(face_id);
-}
-
-bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
- const QByteArray &fontData)
-{
- return init(faceId, antialias, format, QFreetypeFace::getFace(faceId, fontData));
-}
-
-static void dont_delete(void*) {}
-
-bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
- QFreetypeFace *freetypeFace)
-{
- freetype = freetypeFace;
- if (!freetype) {
- xsize = 0;
- ysize = 0;
- return false;
- }
- defaultFormat = format;
- this->antialias = antialias;
-
- if (!antialias)
- glyphFormat = QFontEngine::Format_Mono;
- else
- glyphFormat = defaultFormat;
-
- face_id = faceId;
-
- symbol = freetype->symbol_map != nullptr;
- PS_FontInfoRec psrec;
- // don't assume that type1 fonts are symbol fonts by default
- if (FT_Get_PS_Font_Info(freetype->face, &psrec) == FT_Err_Ok) {
- symbol = bool(fontDef.family.contains(QLatin1String("symbol"), Qt::CaseInsensitive));
- }
-
- freetype->computeSize(fontDef, &xsize, &ysize, &defaultGlyphSet.outline_drawing, &scalableBitmapScaleFactor);
-
- FT_Face face = lockFace();
-
- if (FT_IS_SCALABLE(face)) {
- bool fake_oblique = (fontDef.style != QFont::StyleNormal) && !(face->style_flags & FT_STYLE_FLAG_ITALIC);
- if (fake_oblique)
- obliquen = true;
- FT_Set_Transform(face, &matrix, nullptr);
- freetype->matrix = matrix;
- // fake bold
- if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face)) {
- if (const TT_OS2 *os2 = reinterpret_cast<const TT_OS2 *>(FT_Get_Sfnt_Table(face, ft_sfnt_os2))) {
- if (os2->usWeightClass < 700)
- embolden = true;
- }
- }
- // underline metrics
- line_thickness = QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale));
- underline_position = QFixed::fromFixed(-FT_MulFix(face->underline_position, face->size->metrics.y_scale));
- } else {
- // ad hoc algorithm
- int score = fontDef.weight * fontDef.pixelSize;
- line_thickness = score / 700;
- // looks better with thicker line for small pointsizes
- if (line_thickness < 2 && score >= 1050)
- line_thickness = 2;
- underline_position = ((line_thickness * 2) + 3) / 6;
-
- if (isScalableBitmap()) {
- glyphFormat = defaultFormat = GlyphFormat::Format_ARGB;
- cacheEnabled = false;
- }
- }
- if (line_thickness < 1)
- line_thickness = 1;
-
- metrics = face->size->metrics;
-
- /*
- TrueType fonts with embedded bitmaps may have a bitmap font specific
- ascent/descent in the EBLC table. There is no direct public API
- to extract those values. The only way we've found is to trick freetype
- into thinking that it's not a scalable font in FT_SelectSize so that
- the metrics are retrieved from the bitmap strikes.
- */
- if (FT_IS_SCALABLE(face)) {
- for (int i = 0; i < face->num_fixed_sizes; ++i) {
- if (xsize == face->available_sizes[i].x_ppem && ysize == face->available_sizes[i].y_ppem) {
- face->face_flags &= ~FT_FACE_FLAG_SCALABLE;
-
- FT_Select_Size(face, i);
- if (face->size->metrics.ascender + face->size->metrics.descender > 0) {
- FT_Pos leading = metrics.height - metrics.ascender + metrics.descender;
- metrics.ascender = face->size->metrics.ascender;
- metrics.descender = face->size->metrics.descender;
- if (metrics.descender > 0
- && QString::fromUtf8(face->family_name) == QLatin1String("Courier New")) {
- metrics.descender *= -1;
- }
- metrics.height = metrics.ascender - metrics.descender + leading;
- }
- FT_Set_Char_Size(face, xsize, ysize, 0, 0);
-
- face->face_flags |= FT_FACE_FLAG_SCALABLE;
- break;
- }
- }
- }
-#if defined(FT_FONT_FORMATS_H)
- const char *fmt = FT_Get_Font_Format(face);
- if (fmt && qstrncmp(fmt, "CFF", 4) == 0) {
- FT_Bool no_stem_darkening = true;
- FT_Error err = FT_Property_Get(qt_getFreetype(), "cff", "no-stem-darkening", &no_stem_darkening);
- if (err == FT_Err_Ok)
- stemDarkeningDriver = !no_stem_darkening;
- else
- stemDarkeningDriver = false;
- }
-#endif
-
- fontDef.styleName = QString::fromUtf8(face->style_name);
-
- if (!freetype->hbFace) {
- faceData.user_data = face;
- faceData.get_font_table = ft_getSfntTable;
- (void)harfbuzzFace(); // populates face_
- freetype->hbFace = std::move(face_);
- } else {
- Q_ASSERT(!face_);
- }
- // we share the HB face in QFreeTypeFace, so do not let ~QFontEngine() destroy it
- face_ = Holder(freetype->hbFace.get(), dont_delete);
-
- unlockFace();
-
- fsType = freetype->fsType();
- return true;
-}
-
-void QFontEngineFT::setQtDefaultHintStyle(QFont::HintingPreference hintingPreference)
-{
- switch (hintingPreference) {
- case QFont::PreferNoHinting:
- setDefaultHintStyle(HintNone);
- break;
- case QFont::PreferFullHinting:
- setDefaultHintStyle(HintFull);
- break;
- case QFont::PreferVerticalHinting:
- setDefaultHintStyle(HintLight);
- break;
- case QFont::PreferDefaultHinting:
- setDefaultHintStyle(ftInitialDefaultHintStyle);
- break;
- }
-}
-
-void QFontEngineFT::setDefaultHintStyle(HintStyle style)
-{
- default_hint_style = style;
-}
-
-bool QFontEngineFT::expectsGammaCorrectedBlending() const
-{
- return stemDarkeningDriver;
-}
-
-int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags,
- bool &hsubpixel, int &vfactor) const
-{
- int load_flags = FT_LOAD_DEFAULT | default_load_flags;
- int load_target = default_hint_style == HintLight
- ? FT_LOAD_TARGET_LIGHT
- : FT_LOAD_TARGET_NORMAL;
-
- if (format == Format_Mono) {
- load_target = FT_LOAD_TARGET_MONO;
- } else if (format == Format_A32) {
- if (subpixelType == Subpixel_RGB || subpixelType == Subpixel_BGR)
- hsubpixel = true;
- else if (subpixelType == Subpixel_VRGB || subpixelType == Subpixel_VBGR)
- vfactor = 3;
- } else if (format == Format_ARGB) {
-#ifdef FT_LOAD_COLOR
- load_flags |= FT_LOAD_COLOR;
-#endif
- }
-
- if (set && set->outline_drawing)
- load_flags |= FT_LOAD_NO_BITMAP;
-
- if (default_hint_style == HintNone || (flags & DesignMetrics) || (set && set->outline_drawing))
- load_flags |= FT_LOAD_NO_HINTING;
- else
- load_flags |= load_target;
-
- if (forceAutoHint)
- load_flags |= FT_LOAD_FORCE_AUTOHINT;
-
- return load_flags;
-}
-
-static inline bool areMetricsTooLarge(const QFontEngineFT::GlyphInfo &info)
-{
- // false if exceeds QFontEngineFT::Glyph metrics
- return info.width > 0xFF || info.height > 0xFF;
-}
-
-static inline void transformBoundingBox(int *left, int *top, int *right, int *bottom, FT_Matrix *matrix)
-{
- int l, r, t, b;
- FT_Vector vector;
- vector.x = *left;
- vector.y = *top;
- FT_Vector_Transform(&vector, matrix);
- l = r = vector.x;
- t = b = vector.y;
- vector.x = *right;
- vector.y = *top;
- FT_Vector_Transform(&vector, matrix);
- if (l > vector.x) l = vector.x;
- if (r < vector.x) r = vector.x;
- if (t < vector.y) t = vector.y;
- if (b > vector.y) b = vector.y;
- vector.x = *right;
- vector.y = *bottom;
- FT_Vector_Transform(&vector, matrix);
- if (l > vector.x) l = vector.x;
- if (r < vector.x) r = vector.x;
- if (t < vector.y) t = vector.y;
- if (b > vector.y) b = vector.y;
- vector.x = *left;
- vector.y = *bottom;
- FT_Vector_Transform(&vector, matrix);
- if (l > vector.x) l = vector.x;
- if (r < vector.x) r = vector.x;
- if (t < vector.y) t = vector.y;
- if (b > vector.y) b = vector.y;
- *left = l;
- *right = r;
- *top = t;
- *bottom = b;
-}
-
-QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
- QFixed subPixelPosition,
- GlyphFormat format,
- bool fetchMetricsOnly,
- bool disableOutlineDrawing) const
-{
-// Q_ASSERT(freetype->lock == 1);
-
- if (format == Format_None)
- format = defaultFormat != Format_None ? defaultFormat : Format_Mono;
- Q_ASSERT(format != Format_None);
-
- Glyph *g = set ? set->getGlyph(glyph, subPixelPosition) : nullptr;
- if (g && g->format == format && (fetchMetricsOnly || g->data))
- return g;
-
- if (!g && set && set->isGlyphMissing(glyph))
- return &emptyGlyph;
-
-
- FT_Face face = freetype->face;
-
- FT_Matrix matrix = freetype->matrix;
-
- FT_Vector v;
- v.x = format == Format_Mono ? 0 : FT_Pos(subPixelPosition.value());
- v.y = 0;
- FT_Set_Transform(face, &matrix, &v);
-
- bool hsubpixel = false;
- int vfactor = 1;
- int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor);
-
- bool transform = matrix.xx != 0x10000
- || matrix.yy != 0x10000
- || matrix.xy != 0
- || matrix.yx != 0;
-
- if (transform || obliquen || (format != Format_Mono && !isScalableBitmap()))
- load_flags |= FT_LOAD_NO_BITMAP;
-
- FT_Error err = FT_Load_Glyph(face, glyph, load_flags);
- if (err && (load_flags & FT_LOAD_NO_BITMAP)) {
- load_flags &= ~FT_LOAD_NO_BITMAP;
- err = FT_Load_Glyph(face, glyph, load_flags);
- }
- if (err == FT_Err_Too_Few_Arguments) {
- // this is an error in the bytecode interpreter, just try to run without it
- load_flags |= FT_LOAD_FORCE_AUTOHINT;
- err = FT_Load_Glyph(face, glyph, load_flags);
- } else if (err == FT_Err_Execution_Too_Long) {
- // This is an error in the bytecode, probably a web font made by someone who
- // didn't test bytecode hinting at all so disable for it for all glyphs.
- qWarning("load glyph failed due to broken hinting bytecode in font, switching to auto hinting");
- default_load_flags |= FT_LOAD_FORCE_AUTOHINT;
- load_flags |= FT_LOAD_FORCE_AUTOHINT;
- err = FT_Load_Glyph(face, glyph, load_flags);
- }
- if (err != FT_Err_Ok) {
- qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
- if (set)
- set->setGlyphMissing(glyph);
- return &emptyGlyph;
- }
-
- FT_GlyphSlot slot = face->glyph;
-
- if (embolden)
- FT_GlyphSlot_Embolden(slot);
- if (obliquen) {
- FT_GlyphSlot_Oblique(slot);
-
- // While Embolden alters the metrics of the slot, oblique does not, so we need
- // to fix this ourselves.
- transform = true;
- FT_Matrix m;
- m.xx = 0x10000;
- m.yx = 0x0;
- m.xy = 0x6000;
- m.yy = 0x10000;
-
- FT_Matrix_Multiply(&m, &matrix);
- }
-
- GlyphInfo info;
- info.linearAdvance = slot->linearHoriAdvance >> 10;
- info.xOff = TRUNC(ROUND(slot->advance.x));
- info.yOff = 0;
-
- if ((set && set->outline_drawing && !disableOutlineDrawing) || fetchMetricsOnly) {
- int left = slot->metrics.horiBearingX;
- int right = slot->metrics.horiBearingX + slot->metrics.width;
- int top = slot->metrics.horiBearingY;
- int bottom = slot->metrics.horiBearingY - slot->metrics.height;
-
- if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP)
- transformBoundingBox(&left, &top, &right, &bottom, &matrix);
-
- left = FLOOR(left);
- right = CEIL(right);
- bottom = FLOOR(bottom);
- top = CEIL(top);
-
- info.x = TRUNC(left);
- info.y = TRUNC(top);
- info.width = TRUNC(right - left);
- info.height = TRUNC(top - bottom);
-
- // If any of the metrics are too large to fit, don't cache them
- if (areMetricsTooLarge(info))
- return nullptr;
-
- g = new Glyph;
- g->data = nullptr;
- g->linearAdvance = info.linearAdvance;
- g->width = info.width;
- g->height = info.height;
- g->x = info.x;
- g->y = info.y;
- g->advance = info.xOff;
- g->format = format;
-
- if (set)
- set->setGlyph(glyph, subPixelPosition, g);
-
- return g;
- }
-
- int glyph_buffer_size = 0;
- QScopedArrayPointer<uchar> glyph_buffer;
- FT_Render_Mode renderMode = (default_hint_style == HintLight) ? FT_RENDER_MODE_LIGHT : FT_RENDER_MODE_NORMAL;
- switch (format) {
- case Format_Mono:
- renderMode = FT_RENDER_MODE_MONO;
- break;
- case Format_A32:
- Q_ASSERT(hsubpixel || vfactor != 1);
- renderMode = hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V;
- break;
- case Format_A8:
- case Format_ARGB:
- break;
- default:
- Q_UNREACHABLE();
- }
- FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType);
-
- err = FT_Render_Glyph(slot, renderMode);
- if (err != FT_Err_Ok)
- qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
-
- FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE);
-
- info.height = slot->bitmap.rows;
- info.width = slot->bitmap.width;
- info.x = slot->bitmap_left;
- info.y = slot->bitmap_top;
- if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD)
- info.width = info.width / 3;
- if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V)
- info.height = info.height / vfactor;
-
- int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 :
- (format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4));
-
- glyph_buffer_size = info.height * pitch;
- glyph_buffer.reset(new uchar[glyph_buffer_size]);
-
- if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
- uchar *src = slot->bitmap.buffer;
- uchar *dst = glyph_buffer.data();
- int h = slot->bitmap.rows;
- // Some fonts return bitmaps even when we requested something else:
- if (format == Format_Mono) {
- int bytes = ((info.width + 7) & ~7) >> 3;
- while (h--) {
- memcpy (dst, src, bytes);
- dst += pitch;
- src += slot->bitmap.pitch;
- }
- } else if (format == Format_A8) {
- while (h--) {
- for (int x = 0; x < int{info.width}; x++)
- dst[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00);
- dst += pitch;
- src += slot->bitmap.pitch;
- }
- } else {
- while (h--) {
- uint *dd = reinterpret_cast<uint *>(dst);
- for (int x = 0; x < int{info.width}; x++)
- dd[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffffff : 0x00000000);
- dst += pitch;
- src += slot->bitmap.pitch;
- }
- }
- } else if (slot->bitmap.pixel_mode == 7 /*FT_PIXEL_MODE_BGRA*/) {
- Q_ASSERT(format == Format_ARGB);
- uchar *src = slot->bitmap.buffer;
- uchar *dst = glyph_buffer.data();
- int h = slot->bitmap.rows;
- while (h--) {
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- const quint32 *srcPixel = (const quint32 *)src;
- quint32 *dstPixel = (quint32 *)dst;
- for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++, srcPixel++, dstPixel++) {
- const quint32 pixel = *srcPixel;
- *dstPixel = qbswap(pixel);
- }
-#else
- memcpy(dst, src, slot->bitmap.width * 4);
-#endif
- dst += slot->bitmap.pitch;
- src += slot->bitmap.pitch;
- }
- info.linearAdvance = info.xOff = slot->bitmap.width;
- } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) {
- Q_ASSERT(format == Format_A8);
- uchar *src = slot->bitmap.buffer;
- uchar *dst = glyph_buffer.data();
- int h = slot->bitmap.rows;
- int bytes = info.width;
- while (h--) {
- memcpy (dst, src, bytes);
- dst += pitch;
- src += slot->bitmap.pitch;
- }
- } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD) {
- Q_ASSERT(format == Format_A32);
- convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB);
- } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) {
- Q_ASSERT(format == Format_A32);
- convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB);
- } else {
- qWarning("QFontEngine: Glyph rendered in unknown pixel_mode=%d", slot->bitmap.pixel_mode);
- return nullptr;
- }
-
- if (!g) {
- g = new Glyph;
- g->data = nullptr;
- }
-
- g->linearAdvance = info.linearAdvance;
- g->width = info.width;
- g->height = info.height;
- g->x = info.x;
- g->y = info.y;
- g->advance = info.xOff;
- g->format = format;
- delete [] g->data;
- g->data = glyph_buffer.take();
-
- if (set)
- set->setGlyph(glyph, subPixelPosition, g);
-
- return g;
-}
-
-QFontEngine::FaceId QFontEngineFT::faceId() const
-{
- return face_id;
-}
-
-QFontEngine::Properties QFontEngineFT::properties() const
-{
- Properties p = freetype->properties();
- if (p.postscriptName.isEmpty()) {
- p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(fontDef.family.toUtf8());
- }
-
- return freetype->properties();
-}
-
-QFixed QFontEngineFT::emSquareSize() const
-{
- if (FT_IS_SCALABLE(freetype->face))
- return freetype->face->units_per_EM;
- else
- return freetype->face->size->metrics.y_ppem;
-}
-
-bool QFontEngineFT::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
- return ft_getSfntTable(freetype->face, tag, buffer, length);
-}
-
-int QFontEngineFT::synthesized() const
-{
- int s = 0;
- if ((fontDef.style != QFont::StyleNormal) && !(freetype->face->style_flags & FT_STYLE_FLAG_ITALIC))
- s = SynthesizedItalic;
- if ((fontDef.weight >= QFont::Bold) && !(freetype->face->style_flags & FT_STYLE_FLAG_BOLD))
- s |= SynthesizedBold;
- if (fontDef.stretch != 100 && FT_IS_SCALABLE(freetype->face))
- s |= SynthesizedStretch;
- return s;
-}
-
-QFixed QFontEngineFT::ascent() const
-{
- QFixed v = QFixed::fromFixed(metrics.ascender);
- if (scalableBitmapScaleFactor != 1)
- v *= scalableBitmapScaleFactor;
- return v;
-}
-
-QFixed QFontEngineFT::capHeight() const
-{
- TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
- if (os2 && os2->version >= 2) {
- lockFace();
- QFixed answer = QFixed::fromFixed(FT_MulFix(os2->sCapHeight, freetype->face->size->metrics.y_scale));
- unlockFace();
- return answer;
- }
- return calculatedCapHeight();
-}
-
-QFixed QFontEngineFT::descent() const
-{
- QFixed v = QFixed::fromFixed(-metrics.descender);
- if (scalableBitmapScaleFactor != 1)
- v *= scalableBitmapScaleFactor;
- return v;
-}
-
-QFixed QFontEngineFT::leading() const
-{
- QFixed v = QFixed::fromFixed(metrics.height - metrics.ascender + metrics.descender);
- if (scalableBitmapScaleFactor != 1)
- v *= scalableBitmapScaleFactor;
- return v;
-}
-
-QFixed QFontEngineFT::xHeight() const
-{
- TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
- if (os2 && os2->sxHeight) {
- lockFace();
- QFixed answer = QFixed(os2->sxHeight * freetype->face->size->metrics.y_ppem) / emSquareSize();
- unlockFace();
- return answer;
- }
-
- return QFontEngine::xHeight();
-}
-
-QFixed QFontEngineFT::averageCharWidth() const
-{
- TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2);
- if (os2 && os2->xAvgCharWidth) {
- lockFace();
- QFixed answer = QFixed(os2->xAvgCharWidth * freetype->face->size->metrics.x_ppem) / emSquareSize();
- unlockFace();
- return answer;
- }
-
- return QFontEngine::averageCharWidth();
-}
-
-qreal QFontEngineFT::maxCharWidth() const
-{
- QFixed max_advance = QFixed::fromFixed(metrics.max_advance);
- if (scalableBitmapScaleFactor != 1)
- max_advance *= scalableBitmapScaleFactor;
- return max_advance.toReal();
-}
-
-QFixed QFontEngineFT::lineThickness() const
-{
- return line_thickness;
-}
-
-QFixed QFontEngineFT::underlinePosition() const
-{
- return underline_position;
-}
-
-void QFontEngineFT::doKerning(QGlyphLayout *g, QFontEngine::ShaperFlags flags) const
-{
- if (!kerning_pairs_loaded) {
- kerning_pairs_loaded = true;
- lockFace();
- if (freetype->face->size->metrics.x_ppem != 0) {
- QFixed scalingFactor = emSquareSize() / QFixed(freetype->face->size->metrics.x_ppem);
- unlockFace();
- const_cast<QFontEngineFT *>(this)->loadKerningPairs(scalingFactor);
- } else {
- unlockFace();
- }
- }
-
- if (shouldUseDesignMetrics(flags) && !(fontDef.styleStrategy & QFont::ForceIntegerMetrics))
- flags |= DesignMetrics;
- else
- flags &= ~DesignMetrics;
-
- QFontEngine::doKerning(g, flags);
-}
-
-static inline FT_Matrix QTransformToFTMatrix(const QTransform &matrix)
-{
- FT_Matrix m;
-
- m.xx = FT_Fixed(matrix.m11() * 65536);
- m.xy = FT_Fixed(-matrix.m21() * 65536);
- m.yx = FT_Fixed(-matrix.m12() * 65536);
- m.yy = FT_Fixed(matrix.m22() * 65536);
-
- return m;
-}
-
-QFontEngineFT::QGlyphSet *QFontEngineFT::TransformedGlyphSets::findSet(const QTransform &matrix, const QFontDef &fontDef)
-{
- FT_Matrix m = QTransformToFTMatrix(matrix);
-
- int i = 0;
- for (; i < nSets; ++i) {
- QGlyphSet *g = sets[i];
- if (!g)
- break;
- if (g->transformationMatrix.xx == m.xx
- && g->transformationMatrix.xy == m.xy
- && g->transformationMatrix.yx == m.yx
- && g->transformationMatrix.yy == m.yy) {
-
- // found a match, move it to the front
- moveToFront(i);
- return g;
- }
- }
-
- // don't cache more than nSets transformations
- if (i == nSets)
- // reuse the last set
- --i;
- moveToFront(nSets - 1);
- if (!sets[0])
- sets[0] = new QGlyphSet;
- QGlyphSet *gs = sets[0];
- gs->clear();
- gs->transformationMatrix = m;
- gs->outline_drawing = fontDef.pixelSize * fontDef.pixelSize * qAbs(matrix.determinant()) > QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE;
- Q_ASSERT(gs != nullptr);
-
- return gs;
-}
-
-void QFontEngineFT::TransformedGlyphSets::moveToFront(int i)
-{
- QGlyphSet *g = sets[i];
- while (i > 0) {
- sets[i] = sets[i - 1];
- --i;
- }
- sets[0] = g;
-}
-
-
-QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix)
-{
- if (matrix.type() > QTransform::TxShear || !cacheEnabled)
- return 0;
-
- // FT_Set_Transform only supports scalable fonts
- if (!FT_IS_SCALABLE(freetype->face))
- return matrix.type() <= QTransform::TxTranslate ? &defaultGlyphSet : nullptr;
-
- return transformedGlyphSets.findSet(matrix, fontDef);
-}
-
-void QFontEngineFT::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics)
-{
- FT_Face face = lockFace(Unscaled);
- FT_Set_Transform(face, nullptr, nullptr);
- FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);
-
- int left = face->glyph->metrics.horiBearingX;
- int right = face->glyph->metrics.horiBearingX + face->glyph->metrics.width;
- int top = face->glyph->metrics.horiBearingY;
- int bottom = face->glyph->metrics.horiBearingY - face->glyph->metrics.height;
-
- QFixedPoint p;
- p.x = 0;
- p.y = 0;
-
- metrics->width = QFixed::fromFixed(right-left);
- metrics->height = QFixed::fromFixed(top-bottom);
- metrics->x = QFixed::fromFixed(left);
- metrics->y = QFixed::fromFixed(-top);
- metrics->xoff = QFixed::fromFixed(face->glyph->advance.x);
-
- if (!FT_IS_SCALABLE(freetype->face))
- QFreetypeFace::addBitmapToPath(face->glyph, p, path);
- else
- QFreetypeFace::addGlyphToPath(face, face->glyph, p, path, face->units_per_EM << 6, face->units_per_EM << 6);
-
- FT_Set_Transform(face, &freetype->matrix, nullptr);
- unlockFace();
-}
-
-bool QFontEngineFT::supportsTransformation(const QTransform &transform) const
-{
- return transform.type() <= QTransform::TxRotate;
-}
-
-void QFontEngineFT::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
-{
- if (!glyphs.numGlyphs)
- return;
-
- if (FT_IS_SCALABLE(freetype->face)) {
- QFontEngine::addOutlineToPath(x, y, glyphs, path, flags);
- } else {
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> positioned_glyphs;
- QTransform matrix;
- matrix.translate(x, y);
- getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions);
-
- FT_Face face = lockFace(Unscaled);
- for (int gl = 0; gl < glyphs.numGlyphs; gl++) {
- FT_UInt glyph = positioned_glyphs[gl];
- FT_Load_Glyph(face, glyph, FT_LOAD_TARGET_MONO);
- QFreetypeFace::addBitmapToPath(face->glyph, positions[gl], path);
- }
- unlockFace();
- }
-}
-
-void QFontEngineFT::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs,
- QPainterPath *path, QTextItem::RenderFlags)
-{
- FT_Face face = lockFace(Unscaled);
-
- for (int gl = 0; gl < numGlyphs; gl++) {
- FT_UInt glyph = glyphs[gl];
-
- FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP);
-
- FT_GlyphSlot g = face->glyph;
- if (g->format != FT_GLYPH_FORMAT_OUTLINE)
- continue;
- if (embolden)
- FT_GlyphSlot_Embolden(g);
- if (obliquen)
- FT_GlyphSlot_Oblique(g);
- QFreetypeFace::addGlyphToPath(face, g, positions[gl], path, xsize, ysize);
- }
- unlockFace();
-}
-
-glyph_t QFontEngineFT::glyphIndex(uint ucs4) const
-{
- glyph_t glyph = ucs4 < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[ucs4] : 0;
- if (glyph == 0) {
- FT_Face face = freetype->face;
- glyph = FT_Get_Char_Index(face, ucs4);
- if (glyph == 0) {
- // Certain fonts don't have no-break space and tab,
- // while we usually want to render them as space
- if (ucs4 == QChar::Nbsp || ucs4 == QChar::Tabulation) {
- glyph = FT_Get_Char_Index(face, QChar::Space);
- } else if (freetype->symbol_map) {
- // Symbol fonts can have more than one CMAPs, FreeType should take the
- // correct one for us by default, so we always try FT_Get_Char_Index
- // first. If it didn't work (returns 0), we will explicitly set the
- // CMAP to symbol font one and try again. symbol_map is not always the
- // correct one because in certain fonts like Wingdings symbol_map only
- // contains PUA codepoints instead of the common ones.
- FT_Set_Charmap(face, freetype->symbol_map);
- glyph = FT_Get_Char_Index(face, ucs4);
- FT_Set_Charmap(face, freetype->unicode_map);
- }
- }
- if (ucs4 < QFreetypeFace::cmapCacheSize)
- freetype->cmapCache[ucs4] = glyph;
- }
-
- return glyph;
-}
-
-bool QFontEngineFT::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;
- }
-
- int glyph_pos = 0;
- if (freetype->symbol_map) {
- FT_Face face = freetype->face;
- QStringIterator it(str, str + len);
- while (it.hasNext()) {
- uint uc = it.next();
- glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
- if ( !glyphs->glyphs[glyph_pos] ) {
- // Symbol fonts can have more than one CMAPs, FreeType should take the
- // correct one for us by default, so we always try FT_Get_Char_Index
- // first. If it didn't work (returns 0), we will explicitly set the
- // CMAP to symbol font one and try again. symbol_map is not always the
- // correct one because in certain fonts like Wingdings symbol_map only
- // contains PUA codepoints instead of the common ones.
- glyph_t glyph = FT_Get_Char_Index(face, uc);
- // Certain symbol fonts don't have no-break space (0xa0) and tab (0x9),
- // while we usually want to render them as space
- if (!glyph && (uc == 0xa0 || uc == 0x9)) {
- uc = 0x20;
- glyph = FT_Get_Char_Index(face, uc);
- }
- if (!glyph) {
- FT_Set_Charmap(face, freetype->symbol_map);
- glyph = FT_Get_Char_Index(face, uc);
- FT_Set_Charmap(face, freetype->unicode_map);
- }
- glyphs->glyphs[glyph_pos] = glyph;
- if (uc < QFreetypeFace::cmapCacheSize)
- freetype->cmapCache[uc] = glyph;
- }
- ++glyph_pos;
- }
- } else {
- FT_Face face = freetype->face;
- QStringIterator it(str, str + len);
- while (it.hasNext()) {
- uint uc = it.next();
- glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
- if (!glyphs->glyphs[glyph_pos]) {
- {
- redo:
- glyph_t glyph = FT_Get_Char_Index(face, uc);
- if (!glyph && (uc == 0xa0 || uc == 0x9)) {
- uc = 0x20;
- goto redo;
- }
- glyphs->glyphs[glyph_pos] = glyph;
- if (uc < QFreetypeFace::cmapCacheSize)
- freetype->cmapCache[uc] = glyph;
- }
- }
- ++glyph_pos;
- }
- }
-
- *nglyphs = glyph_pos;
- glyphs->numGlyphs = glyph_pos;
-
- if (!(flags & GlyphIndicesOnly))
- recalcAdvances(glyphs, flags);
-
- return true;
-}
-
-bool QFontEngineFT::shouldUseDesignMetrics(QFontEngine::ShaperFlags flags) const
-{
- if (!FT_IS_SCALABLE(freetype->face))
- return false;
-
- return default_hint_style == HintNone || default_hint_style == HintLight || (flags & DesignMetrics);
-}
-
-QFixed QFontEngineFT::scaledBitmapMetrics(QFixed m) const
-{
- return m * scalableBitmapScaleFactor;
-}
-
-glyph_metrics_t QFontEngineFT::scaledBitmapMetrics(const glyph_metrics_t &m, const QTransform &t) const
-{
- QTransform trans;
- trans.setMatrix(t.m11(), t.m12(), t.m13(),
- t.m21(), t.m22(), t.m23(),
- 0, 0, t.m33());
- const qreal scaleFactor = scalableBitmapScaleFactor.toReal();
- trans.scale(scaleFactor, scaleFactor);
-
- QRectF rect(m.x.toReal(), m.y.toReal(), m.width.toReal(), m.height.toReal());
- QPointF offset(m.xoff.toReal(), m.yoff.toReal());
-
- rect = trans.mapRect(rect);
- offset = trans.map(offset);
-
- glyph_metrics_t metrics;
- metrics.x = QFixed::fromReal(rect.x());
- metrics.y = QFixed::fromReal(rect.y());
- metrics.width = QFixed::fromReal(rect.width());
- metrics.height = QFixed::fromReal(rect.height());
- metrics.xoff = QFixed::fromReal(offset.x());
- metrics.yoff = QFixed::fromReal(offset.y());
- return metrics;
-}
-
-void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const
-{
- FT_Face face = nullptr;
- bool design = shouldUseDesignMetrics(flags);
- for (int i = 0; i < glyphs->numGlyphs; i++) {
- Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs->glyphs[i]) : nullptr;
- // Since we are passing Format_None to loadGlyph, use same default format logic as loadGlyph
- GlyphFormat acceptableFormat = (defaultFormat != Format_None) ? defaultFormat : Format_Mono;
- if (g && g->format == acceptableFormat) {
- glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
- } else {
- if (!face)
- face = lockFace();
- g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyphs->glyphs[i], 0, Format_None, true);
- if (g)
- glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
- else
- glyphs->advances[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
- : QFixed::fromFixed(face->glyph->metrics.horiAdvance).round();
- if (!cacheEnabled && g != &emptyGlyph)
- delete g;
- }
-
- if (scalableBitmapScaleFactor != 1)
- glyphs->advances[i] *= scalableBitmapScaleFactor;
- }
- if (face)
- unlockFace();
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- for (int i = 0; i < glyphs->numGlyphs; ++i)
- glyphs->advances[i] = glyphs->advances[i].round();
- }
-}
-
-glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
-{
- FT_Face face = nullptr;
-
- glyph_metrics_t overall;
- // initialize with line height, we get the same behaviour on all platforms
- if (!isScalableBitmap()) {
- overall.y = -ascent();
- overall.height = ascent() + descent();
- } else {
- overall.y = QFixed::fromFixed(-metrics.ascender);
- overall.height = QFixed::fromFixed(metrics.ascender - metrics.descender);
- }
-
- QFixed ymax = 0;
- QFixed xmax = 0;
- for (int i = 0; i < glyphs.numGlyphs; i++) {
- Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs.glyphs[i]) : nullptr;
- if (!g) {
- if (!face)
- face = lockFace();
- g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyphs.glyphs[i], 0, Format_None, true);
- }
- if (g) {
- QFixed x = overall.xoff + glyphs.offsets[i].x + g->x;
- QFixed y = overall.yoff + glyphs.offsets[i].y - g->y;
- overall.x = qMin(overall.x, x);
- overall.y = qMin(overall.y, y);
- xmax = qMax(xmax, x + g->width);
- ymax = qMax(ymax, y + g->height);
- overall.xoff += g->advance;
- if (!cacheEnabled && g != &emptyGlyph)
- delete g;
- } else {
- int left = FLOOR(face->glyph->metrics.horiBearingX);
- int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);
- int top = CEIL(face->glyph->metrics.horiBearingY);
- int bottom = FLOOR(face->glyph->metrics.horiBearingY - face->glyph->metrics.height);
-
- QFixed x = overall.xoff + glyphs.offsets[i].x - (-TRUNC(left));
- QFixed y = overall.yoff + glyphs.offsets[i].y - TRUNC(top);
- overall.x = qMin(overall.x, x);
- overall.y = qMin(overall.y, y);
- xmax = qMax(xmax, x + TRUNC(right - left));
- ymax = qMax(ymax, y + TRUNC(top - bottom));
- overall.xoff += int(TRUNC(ROUND(face->glyph->advance.x)));
- }
- }
- overall.height = qMax(overall.height, ymax - overall.y);
- overall.width = xmax - overall.x;
-
- if (face)
- unlockFace();
-
- if (isScalableBitmap())
- overall = scaledBitmapMetrics(overall, QTransform());
- return overall;
-}
-
-glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
-{
- FT_Face face = nullptr;
- glyph_metrics_t overall;
- Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyph) : nullptr;
- if (!g) {
- face = lockFace();
- g = loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyph, 0, Format_None, true);
- }
- if (g) {
- overall.x = g->x;
- overall.y = -g->y;
- overall.width = g->width;
- overall.height = g->height;
- overall.xoff = g->advance;
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- overall.xoff = overall.xoff.round();
- if (!cacheEnabled && g != &emptyGlyph)
- delete g;
- } else {
- int left = FLOOR(face->glyph->metrics.horiBearingX);
- int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);
- int top = CEIL(face->glyph->metrics.horiBearingY);
- int bottom = FLOOR(face->glyph->metrics.horiBearingY - face->glyph->metrics.height);
-
- overall.width = TRUNC(right-left);
- overall.height = TRUNC(top-bottom);
- overall.x = TRUNC(left);
- overall.y = -TRUNC(top);
- overall.xoff = TRUNC(ROUND(face->glyph->advance.x));
- }
- if (face)
- unlockFace();
-
- if (isScalableBitmap())
- overall = scaledBitmapMetrics(overall, QTransform());
- return overall;
-}
-
-glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph, const QTransform &matrix)
-{
- return alphaMapBoundingBox(glyph, 0, matrix, QFontEngine::Format_None);
-}
-
-glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, QFontEngine::GlyphFormat format)
-{
- Glyph *g = loadGlyphFor(glyph, subPixelPosition, format, matrix, true);
-
- glyph_metrics_t overall;
- if (g) {
- overall.x = g->x;
- overall.y = -g->y;
- overall.width = g->width;
- overall.height = g->height;
- overall.xoff = g->advance;
- if (!cacheEnabled && g != &emptyGlyph)
- delete g;
- } else {
- FT_Face face = lockFace();
- int left = FLOOR(face->glyph->metrics.horiBearingX);
- int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width);
- int top = CEIL(face->glyph->metrics.horiBearingY);
- int bottom = FLOOR(face->glyph->metrics.horiBearingY - face->glyph->metrics.height);
-
- overall.width = TRUNC(right-left);
- overall.height = TRUNC(top-bottom);
- overall.x = TRUNC(left);
- overall.y = -TRUNC(top);
- overall.xoff = TRUNC(ROUND(face->glyph->advance.x));
- unlockFace();
- }
-
- if (isScalableBitmap())
- overall = scaledBitmapMetrics(overall, matrix);
- return overall;
-}
-
-static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEngine::GlyphFormat glyphFormat)
-{
- if (glyph == nullptr || glyph->height == 0 || glyph->width == 0)
- return QImage();
-
- QImage::Format format = QImage::Format_Invalid;
- int bytesPerLine = -1;
- switch (glyphFormat) {
- case QFontEngine::Format_Mono:
- format = QImage::Format_Mono;
- bytesPerLine = ((glyph->width + 31) & ~31) >> 3;
- break;
- case QFontEngine::Format_A8:
- format = QImage::Format_Alpha8;
- bytesPerLine = (glyph->width + 3) & ~3;
- break;
- case QFontEngine::Format_A32:
- format = QImage::Format_RGB32;
- bytesPerLine = glyph->width * 4;
- break;
- default:
- Q_UNREACHABLE();
- };
-
- QImage img(static_cast<const uchar *>(glyph->data), glyph->width, glyph->height, bytesPerLine, format);
- if (format == QImage::Format_Mono)
- img.setColor(1, QColor(Qt::white).rgba()); // Expands color table to 2 items; item 0 set to transparent.
- return img;
-}
-
-QFontEngine::Glyph *QFontEngineFT::glyphData(glyph_t glyphIndex, QFixed subPixelPosition,
- QFontEngine::GlyphFormat neededFormat, const QTransform &t)
-{
- Q_ASSERT(cacheEnabled);
-
- if (isBitmapFont())
- neededFormat = Format_Mono;
- else if (neededFormat == Format_None && defaultFormat != Format_None)
- neededFormat = defaultFormat;
- else if (neededFormat == Format_None)
- neededFormat = Format_A8;
-
- Glyph *glyph = loadGlyphFor(glyphIndex, subPixelPosition, neededFormat, t);
- if (!glyph || !glyph->width || !glyph->height)
- return nullptr;
-
- return glyph;
-}
-
-static inline bool is2dRotation(const QTransform &t)
-{
- return qFuzzyCompare(t.m11(), t.m22()) && qFuzzyCompare(t.m12(), -t.m21())
- && qFuzzyCompare(t.m11()*t.m22() - t.m12()*t.m21(), qreal(1.0));
-}
-
-QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g,
- QFixed subPixelPosition,
- GlyphFormat format,
- const QTransform &t,
- bool fetchBoundingBox,
- bool disableOutlineDrawing)
-{
- QGlyphSet *glyphSet = loadGlyphSet(t);
- if (glyphSet != nullptr && glyphSet->outline_drawing && !disableOutlineDrawing && !fetchBoundingBox)
- return nullptr;
-
- Glyph *glyph = glyphSet != nullptr ? glyphSet->getGlyph(g, subPixelPosition) : nullptr;
- if (!glyph || glyph->format != format || (!fetchBoundingBox && !glyph->data)) {
- QScopedValueRollback<HintStyle> saved_default_hint_style(default_hint_style);
- if (t.type() >= QTransform::TxScale && !is2dRotation(t))
- default_hint_style = HintNone; // disable hinting if the glyphs are transformed
-
- lockFace();
- FT_Matrix m = this->matrix;
- FT_Matrix ftMatrix = glyphSet != nullptr ? glyphSet->transformationMatrix : QTransformToFTMatrix(t);
- FT_Matrix_Multiply(&ftMatrix, &m);
- freetype->matrix = m;
- glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false, disableOutlineDrawing);
- unlockFace();
- }
-
- return glyph;
-}
-
-QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
-{
- return alphaMapForGlyph(g, subPixelPosition, QTransform());
-}
-
-QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
-{
- const GlyphFormat neededFormat = antialias ? Format_A8 : Format_Mono;
-
- Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true);
-
- QImage img = alphaMapFromGlyphData(glyph, neededFormat);
- img = img.copy();
-
- if (!cacheEnabled && glyph != &emptyGlyph)
- delete glyph;
-
- return img;
-}
-
-QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t)
-{
- if (t.type() > QTransform::TxRotate)
- return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
-
- const GlyphFormat neededFormat = Format_A32;
-
- Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true);
-
- QImage img = alphaMapFromGlyphData(glyph, neededFormat);
- img = img.copy();
-
- if (!cacheEnabled && glyph != &emptyGlyph)
- delete glyph;
-
- if (!img.isNull())
- return img;
-
- return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
-}
-
-QImage QFontEngineFT::bitmapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t, const QColor &color)
-{
- Q_UNUSED(color);
-
- Glyph *glyph = loadGlyphFor(g, subPixelPosition, defaultFormat, t);
- if (glyph == nullptr)
- return QImage();
-
- QImage img;
- if (defaultFormat == GlyphFormat::Format_ARGB)
- img = QImage(glyph->data, glyph->width, glyph->height, QImage::Format_ARGB32_Premultiplied).copy();
- else if (defaultFormat == GlyphFormat::Format_Mono)
- img = QImage(glyph->data, glyph->width, glyph->height, QImage::Format_Mono).copy();
-
- if (!img.isNull() && (!t.isIdentity() || scalableBitmapScaleFactor != 1)) {
- QTransform trans(t);
- const qreal scaleFactor = scalableBitmapScaleFactor.toReal();
- trans.scale(scaleFactor, scaleFactor);
- img = img.transformed(trans, Qt::SmoothTransformation);
- }
-
- if (!cacheEnabled && glyph != &emptyGlyph)
- delete glyph;
-
- return img;
-}
-
-void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
-{
- defaultGlyphSet.removeGlyphFromCache(glyph, 0);
-}
-
-int QFontEngineFT::glyphCount() const
-{
- int count = 0;
- FT_Face face = lockFace();
- if (face) {
- count = face->num_glyphs;
- unlockFace();
- }
- return count;
-}
-
-FT_Face QFontEngineFT::lockFace(Scaling scale) const
-{
- freetype->lock();
- FT_Face face = freetype->face;
- if (scale == Unscaled) {
- if (FT_Set_Char_Size(face, face->units_per_EM << 6, face->units_per_EM << 6, 0, 0) == 0) {
- freetype->xsize = face->units_per_EM << 6;
- freetype->ysize = face->units_per_EM << 6;
- }
- } else if (freetype->xsize != xsize || freetype->ysize != ysize) {
- FT_Set_Char_Size(face, xsize, ysize, 0, 0);
- freetype->xsize = xsize;
- freetype->ysize = ysize;
- }
- if (freetype->matrix.xx != matrix.xx ||
- freetype->matrix.yy != matrix.yy ||
- freetype->matrix.xy != matrix.xy ||
- freetype->matrix.yx != matrix.yx) {
- freetype->matrix = matrix;
- FT_Set_Transform(face, &freetype->matrix, nullptr);
- }
-
- return face;
-}
-
-void QFontEngineFT::unlockFace() const
-{
- freetype->unlock();
-}
-
-FT_Face QFontEngineFT::non_locked_face() const
-{
- return freetype->face;
-}
-
-
-QFontEngineFT::QGlyphSet::QGlyphSet()
- : outline_drawing(false)
-{
- transformationMatrix.xx = 0x10000;
- transformationMatrix.yy = 0x10000;
- transformationMatrix.xy = 0;
- transformationMatrix.yx = 0;
- memset(fast_glyph_data, 0, sizeof(fast_glyph_data));
- fast_glyph_count = 0;
-}
-
-QFontEngineFT::QGlyphSet::~QGlyphSet()
-{
- clear();
-}
-
-void QFontEngineFT::QGlyphSet::clear()
-{
- if (fast_glyph_count > 0) {
- for (int i = 0; i < 256; ++i) {
- if (fast_glyph_data[i]) {
- delete fast_glyph_data[i];
- fast_glyph_data[i] = nullptr;
- }
- }
- fast_glyph_count = 0;
- }
- qDeleteAll(glyph_data);
- glyph_data.clear();
-}
-
-void QFontEngineFT::QGlyphSet::removeGlyphFromCache(glyph_t index, QFixed subPixelPosition)
-{
- if (useFastGlyphData(index, subPixelPosition)) {
- if (fast_glyph_data[index]) {
- delete fast_glyph_data[index];
- fast_glyph_data[index] = nullptr;
- if (fast_glyph_count > 0)
- --fast_glyph_count;
- }
- } else {
- delete glyph_data.take(GlyphAndSubPixelPosition(index, subPixelPosition));
- }
-}
-
-void QFontEngineFT::QGlyphSet::setGlyph(glyph_t index, QFixed subPixelPosition, Glyph *glyph)
-{
- if (useFastGlyphData(index, subPixelPosition)) {
- if (!fast_glyph_data[index])
- ++fast_glyph_count;
- fast_glyph_data[index] = glyph;
- } else {
- glyph_data.insert(GlyphAndSubPixelPosition(index, subPixelPosition), glyph);
- }
-}
-
-int QFontEngineFT::getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints)
-{
- lockFace();
- bool hsubpixel = true;
- int vfactor = 1;
- int load_flags = loadFlags(nullptr, Format_A8, flags, hsubpixel, vfactor);
- int result = freetype->getPointInOutline(glyph, load_flags, point, xpos, ypos, nPoints);
- unlockFace();
- return result;
-}
-
-bool QFontEngineFT::initFromFontEngine(const QFontEngineFT *fe)
-{
- if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype))
- return false;
-
- // Increase the reference of this QFreetypeFace since one more QFontEngineFT
- // will be using it
- freetype->ref.ref();
-
- default_load_flags = fe->default_load_flags;
- default_hint_style = fe->default_hint_style;
- antialias = fe->antialias;
- transform = fe->transform;
- embolden = fe->embolden;
- obliquen = fe->obliquen;
- subpixelType = fe->subpixelType;
- lcdFilterType = fe->lcdFilterType;
- embeddedbitmap = fe->embeddedbitmap;
-
- return true;
-}
-
-QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const
-{
- QFontDef fontDef(this->fontDef);
- fontDef.pixelSize = pixelSize;
- QFontEngineFT *fe = new QFontEngineFT(fontDef);
- if (!fe->initFromFontEngine(this)) {
- delete fe;
- return nullptr;
- } else {
- return fe;
- }
-}
-
-Qt::HANDLE QFontEngineFT::handle() const
-{
- return non_locked_face();
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_FREETYPE
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
deleted file mode 100644
index 8019588bf5..0000000000
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
+++ /dev/null
@@ -1,364 +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 QFONTENGINE_FT_P_H
-#define QFONTENGINE_FT_P_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 "private/qfontengine_p.h"
-
-#ifndef QT_NO_FREETYPE
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-
-#ifndef Q_OS_WIN
-#include <unistd.h>
-#endif
-
-#include <qmutex.h>
-
-#include <string.h>
-
-QT_BEGIN_NAMESPACE
-
-class QFontEngineFTRawFont;
-class QFontconfigDatabase;
-
-/*
- * This class represents one font file on disk (like Arial.ttf) and is shared between all the font engines
- * that show this font file (at different pixel sizes).
- */
-class QFreetypeFace
-{
-public:
- void computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing, QFixed *scalableBitmapScaleFactor);
- QFontEngine::Properties properties() const;
- bool getSfntTable(uint tag, uchar *buffer, uint *length) const;
-
- static QFreetypeFace *getFace(const QFontEngine::FaceId &face_id,
- const QByteArray &fontData = QByteArray());
- void release(const QFontEngine::FaceId &face_id);
-
- // locks the struct for usage. Any read/write operations require locking.
- void lock()
- {
- _lock.lock();
- }
- void unlock()
- {
- _lock.unlock();
- }
-
- FT_Face face;
- int xsize; // 26.6
- int ysize; // 26.6
- FT_Matrix matrix;
- FT_CharMap unicode_map;
- FT_CharMap symbol_map;
-
- enum { cmapCacheSize = 0x200 };
- glyph_t cmapCache[cmapCacheSize];
-
- int fsType() const;
-
- int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints);
-
- bool isScalableBitmap() const;
-
- static void addGlyphToPath(FT_Face face, FT_GlyphSlot g, const QFixedPoint &point, QPainterPath *path, FT_Fixed x_scale, FT_Fixed y_scale);
- static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path);
-
-private:
- friend class QFontEngineFT;
- friend class QtFreetypeData;
- friend struct QScopedPointerDeleter<QFreetypeFace>;
- QFreetypeFace() = default;
- ~QFreetypeFace() {}
- void cleanup();
- QAtomicInt ref;
- QRecursiveMutex _lock;
- QByteArray fontData;
-
- QFontEngine::Holder hbFace;
-};
-
-class QFontEngineFT : public QFontEngine
-{
-public:
- struct GlyphInfo {
- int linearAdvance;
- unsigned short width;
- unsigned short height;
- short x;
- short y;
- short xOff;
- short yOff;
- };
-
- struct GlyphAndSubPixelPosition
- {
- GlyphAndSubPixelPosition(glyph_t g, QFixed spp) : glyph(g), subPixelPosition(spp) {}
-
- bool operator==(const GlyphAndSubPixelPosition &other) const
- {
- return glyph == other.glyph && subPixelPosition == other.subPixelPosition;
- }
-
- glyph_t glyph;
- QFixed subPixelPosition;
- };
-
- struct QGlyphSet
- {
- QGlyphSet();
- ~QGlyphSet();
- FT_Matrix transformationMatrix;
- bool outline_drawing;
-
- void removeGlyphFromCache(glyph_t index, QFixed subPixelPosition);
- void clear();
- inline bool useFastGlyphData(glyph_t index, QFixed subPixelPosition) const {
- return (index < 256 && subPixelPosition == 0);
- }
- inline Glyph *getGlyph(glyph_t index, QFixed subPixelPosition = 0) const;
- void setGlyph(glyph_t index, QFixed spp, Glyph *glyph);
-
- inline bool isGlyphMissing(glyph_t index) const { return missing_glyphs.contains(index); }
- inline void setGlyphMissing(glyph_t index) const { missing_glyphs.insert(index); }
-private:
- Q_DISABLE_COPY(QGlyphSet);
- mutable QHash<GlyphAndSubPixelPosition, Glyph *> glyph_data; // maps from glyph index to glyph data
- mutable QSet<glyph_t> missing_glyphs;
- mutable Glyph *fast_glyph_data[256]; // for fast lookup of glyphs < 256
- mutable int fast_glyph_count;
- };
-
- QFontEngine::FaceId faceId() const override;
- QFontEngine::Properties properties() const override;
- QFixed emSquareSize() const override;
- bool supportsSubPixelPositions() const override
- {
- return default_hint_style == HintLight ||
- default_hint_style == HintNone;
- }
-
- bool getSfntTableData(uint tag, uchar *buffer, uint *length) const override;
- int synthesized() const override;
-
- QFixed ascent() const override;
- QFixed capHeight() const override;
- QFixed descent() const override;
- QFixed leading() const override;
- QFixed xHeight() const override;
- QFixed averageCharWidth() const override;
-
- qreal maxCharWidth() const override;
- QFixed lineThickness() const override;
- QFixed underlinePosition() const override;
-
- glyph_t glyphIndex(uint ucs4) const override;
- void doKerning(QGlyphLayout *, ShaperFlags) const override;
-
- void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) override;
-
- bool supportsTransformation(const QTransform &transform) const override;
-
- void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags) override;
- void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs,
- QPainterPath *path, QTextItem::RenderFlags flags) override;
-
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override;
-
- glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
- glyph_metrics_t boundingBox(glyph_t glyph) override;
- glyph_metrics_t boundingBox(glyph_t glyph, const QTransform &matrix) override;
-
- void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags flags) const override;
- QImage alphaMapForGlyph(glyph_t g) override { return alphaMapForGlyph(g, 0); }
- QImage alphaMapForGlyph(glyph_t, QFixed) override;
- QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override;
- QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
- QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override;
- glyph_metrics_t alphaMapBoundingBox(glyph_t glyph,
- QFixed subPixelPosition,
- const QTransform &matrix,
- QFontEngine::GlyphFormat format) override;
- Glyph *glyphData(glyph_t glyph, QFixed subPixelPosition,
- GlyphFormat neededFormat, const QTransform &t) override;
- bool hasInternalCaching() const override { return cacheEnabled; }
- bool expectsGammaCorrectedBlending() const override;
-
- void removeGlyphFromCache(glyph_t glyph) override;
- int glyphMargin(QFontEngine::GlyphFormat /* format */) override { return 0; }
-
- int glyphCount() const override;
-
- enum Scaling {
- Scaled,
- Unscaled
- };
- FT_Face lockFace(Scaling scale = Scaled) const;
- void unlockFace() const;
-
- FT_Face non_locked_face() const;
-
- inline bool drawAntialiased() const { return antialias; }
- inline bool invalid() const { return xsize == 0 && ysize == 0; }
- inline bool isBitmapFont() const { return defaultFormat == Format_Mono; }
- inline bool isScalableBitmap() const { return freetype->isScalableBitmap(); }
-
- inline Glyph *loadGlyph(uint glyph, QFixed subPixelPosition, GlyphFormat format = Format_None, bool fetchMetricsOnly = false, bool disableOutlineDrawing = false) const
- { return loadGlyph(cacheEnabled ? &defaultGlyphSet : nullptr, glyph, subPixelPosition, format, fetchMetricsOnly, disableOutlineDrawing); }
- Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false, bool disableOutlineDrawing = false) const;
- Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, bool fetchBoundingBox = false, bool disableOutlineDrawing = false);
-
- QGlyphSet *loadGlyphSet(const QTransform &matrix);
-
- QFontEngineFT(const QFontDef &fd);
- virtual ~QFontEngineFT();
-
- bool init(FaceId faceId, bool antiaalias, GlyphFormat defaultFormat = Format_None,
- const QByteArray &fontData = QByteArray());
- bool init(FaceId faceId, bool antialias, GlyphFormat format,
- QFreetypeFace *freetypeFace);
-
- int getPointInOutline(glyph_t glyph, int flags, quint32 point, QFixed *xpos, QFixed *ypos, quint32 *nPoints) override;
-
- void setQtDefaultHintStyle(QFont::HintingPreference hintingPreference);
- void setDefaultHintStyle(HintStyle style) override;
-
- QFontEngine *cloneWithSize(qreal pixelSize) const override;
- Qt::HANDLE handle() const override;
- bool initFromFontEngine(const QFontEngineFT *fontEngine);
-
- HintStyle defaultHintStyle() const { return default_hint_style; }
-
- static QFontEngineFT *create(const QFontDef &fontDef, FaceId faceId, const QByteArray &fontData = QByteArray());
- static QFontEngineFT *create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
-
-protected:
-
- QFreetypeFace *freetype;
- mutable int default_load_flags;
- HintStyle default_hint_style;
- bool antialias;
- bool transform;
- bool embolden;
- bool obliquen;
- SubpixelAntialiasingType subpixelType;
- int lcdFilterType;
- bool embeddedbitmap;
- bool cacheEnabled;
- bool forceAutoHint;
- bool stemDarkeningDriver;
-
-private:
- friend class QFontEngineFTRawFont;
- friend class QFontconfigDatabase;
- friend class QFreeTypeFontDatabase;
- friend class QFontEngineMultiFontConfig;
-
- int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const;
- bool shouldUseDesignMetrics(ShaperFlags flags) const;
- QFixed scaledBitmapMetrics(QFixed m) const;
- glyph_metrics_t scaledBitmapMetrics(const glyph_metrics_t &m, const QTransform &matrix) const;
-
- GlyphFormat defaultFormat;
- FT_Matrix matrix;
-
- struct TransformedGlyphSets {
- enum { nSets = 10 };
- QGlyphSet *sets[nSets];
-
- QGlyphSet *findSet(const QTransform &matrix, const QFontDef &fontDef);
- TransformedGlyphSets() { std::fill(&sets[0], &sets[nSets], nullptr); }
- ~TransformedGlyphSets() { qDeleteAll(&sets[0], &sets[nSets]); }
- private:
- void moveToFront(int i);
- Q_DISABLE_COPY(TransformedGlyphSets);
- };
- TransformedGlyphSets transformedGlyphSets;
- mutable QGlyphSet defaultGlyphSet;
-
- QFontEngine::FaceId face_id;
-
- int xsize;
- int ysize;
-
- QFixed line_thickness;
- QFixed underline_position;
-
- FT_Size_Metrics metrics;
- mutable bool kerning_pairs_loaded;
- QFixed scalableBitmapScaleFactor;
-};
-
-Q_DECLARE_TYPEINFO(QFontEngineFT::QGlyphSet, Q_MOVABLE_TYPE);
-
-
-inline uint qHash(const QFontEngineFT::GlyphAndSubPixelPosition &g)
-{
- return (g.glyph << 8) | (g.subPixelPosition * 10).round().toInt();
-}
-
-inline QFontEngineFT::Glyph *QFontEngineFT::QGlyphSet::getGlyph(glyph_t index, QFixed subPixelPosition) const
-{
- if (useFastGlyphData(index, subPixelPosition))
- return fast_glyph_data[index];
- return glyph_data.value(GlyphAndSubPixelPosition(index, subPixelPosition));
-}
-
-extern FT_Library qt_getFreetype();
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_FREETYPE
-
-#endif // QFONTENGINE_FT_P_H
diff --git a/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp b/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp
deleted file mode 100644
index 25c10fbd3c..0000000000
--- a/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase.cpp
+++ /dev/null
@@ -1,213 +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 "qfreetypefontdatabase_p.h"
-
-#include <QtGui/private/qguiapplication_p.h>
-#include <qpa/qplatformscreen.h>
-
-#include <QtCore/QFile>
-#include <QtCore/QLibraryInfo>
-#include <QtCore/QDir>
-#include <QtCore/QtEndian>
-
-#undef QT_NO_FREETYPE
-#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h>
-
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-#include FT_ERRORS_H
-
-QT_BEGIN_NAMESPACE
-
-void QFreeTypeFontDatabase::populateFontDatabase()
-{
- QString fontpath = fontDir();
- QDir dir(fontpath);
-
- if (!dir.exists()) {
- qWarning("QFontDatabase: Cannot find font directory %s.\n"
- "Note that Qt no longer ships fonts. Deploy some (from https://dejavu-fonts.github.io/ for example) or switch to fontconfig.",
- qPrintable(fontpath));
- return;
- }
-
- QStringList nameFilters;
- nameFilters << QLatin1String("*.ttf")
- << QLatin1String("*.ttc")
- << QLatin1String("*.pfa")
- << QLatin1String("*.pfb")
- << QLatin1String("*.otf");
-
- const auto fis = dir.entryInfoList(nameFilters, QDir::Files);
- for (const QFileInfo &fi : fis) {
- const QByteArray file = QFile::encodeName(fi.absoluteFilePath());
- QFreeTypeFontDatabase::addTTFile(QByteArray(), file);
- }
-}
-
-QFontEngine *QFreeTypeFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPtr)
-{
- FontFile *fontfile = static_cast<FontFile *>(usrPtr);
- QFontEngine::FaceId faceId;
- faceId.filename = QFile::encodeName(fontfile->fileName);
- faceId.index = fontfile->indexValue;
-
- return QFontEngineFT::create(fontDef, faceId);
-}
-
-QFontEngine *QFreeTypeFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize,
- QFont::HintingPreference hintingPreference)
-{
- return QFontEngineFT::create(fontData, pixelSize, hintingPreference);
-}
-
-QStringList QFreeTypeFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
-{
- return QFreeTypeFontDatabase::addTTFile(fontData, fileName.toLocal8Bit());
-}
-
-void QFreeTypeFontDatabase::releaseHandle(void *handle)
-{
- FontFile *file = static_cast<FontFile *>(handle);
- delete file;
-}
-
-extern FT_Library qt_getFreetype();
-
-QStringList QFreeTypeFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
-{
- FT_Library library = qt_getFreetype();
-
- int index = 0;
- int numFaces = 0;
- QStringList families;
- do {
- FT_Face face;
- FT_Error error;
- if (!fontData.isEmpty()) {
- error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
- } else {
- error = FT_New_Face(library, file.constData(), index, &face);
- }
- if (error != FT_Err_Ok) {
- qDebug() << "FT_New_Face failed with index" << index << ':' << Qt::hex << error;
- break;
- }
- numFaces = face->num_faces;
-
- QFont::Weight weight = QFont::Normal;
-
- QFont::Style style = QFont::StyleNormal;
- if (face->style_flags & FT_STYLE_FLAG_ITALIC)
- style = QFont::StyleItalic;
-
- if (face->style_flags & FT_STYLE_FLAG_BOLD)
- weight = QFont::Bold;
-
- bool fixedPitch = (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH);
- QSupportedWritingSystems writingSystems;
- // detect symbol fonts
- for (int i = 0; i < face->num_charmaps; ++i) {
- FT_CharMap cm = face->charmaps[i];
- if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM
- || cm->encoding == FT_ENCODING_MS_SYMBOL) {
- writingSystems.setSupported(QFontDatabase::Symbol);
- break;
- }
- }
-
- TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
- if (os2) {
- quint32 unicodeRange[4] = {
- quint32(os2->ulUnicodeRange1),
- quint32(os2->ulUnicodeRange2),
- quint32(os2->ulUnicodeRange3),
- quint32(os2->ulUnicodeRange4)
- };
- quint32 codePageRange[2] = {
- quint32(os2->ulCodePageRange1),
- quint32(os2->ulCodePageRange2)
- };
-
- writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
-
- if (os2->usWeightClass) {
- weight = QPlatformFontDatabase::weightFromInteger(os2->usWeightClass);
- } else if (os2->panose[2]) {
- int w = os2->panose[2];
- if (w <= 1)
- weight = QFont::Thin;
- else if (w <= 2)
- weight = QFont::ExtraLight;
- else if (w <= 3)
- weight = QFont::Light;
- else if (w <= 5)
- weight = QFont::Normal;
- else if (w <= 6)
- weight = QFont::Medium;
- else if (w <= 7)
- weight = QFont::DemiBold;
- else if (w <= 8)
- weight = QFont::Bold;
- else if (w <= 9)
- weight = QFont::ExtraBold;
- else if (w <= 10)
- weight = QFont::Black;
- }
- }
-
- QString family = QString::fromLatin1(face->family_name);
- FontFile *fontFile = new FontFile;
- fontFile->fileName = QFile::decodeName(file);
- fontFile->indexValue = index;
-
- QFont::Stretch stretch = QFont::Unstretched;
-
- registerFont(family,QString::fromLatin1(face->style_name),QString(),weight,style,stretch,true,true,0,fixedPitch,writingSystems,fontFile);
-
- families.append(family);
-
- FT_Done_Face(face);
- ++index;
- } while (index < numFaces);
- return families;
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase_p.h b/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase_p.h
deleted file mode 100644
index 0b2956b16e..0000000000
--- a/src/platformsupport/fontdatabases/freetype/qfreetypefontdatabase_p.h
+++ /dev/null
@@ -1,80 +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 QFREETYPEFONTDATABASE_H
-#define QFREETYPEFONTDATABASE_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 <qpa/qplatformfontdatabase.h>
-#include <QtCore/QByteArray>
-#include <QtCore/QString>
-
-QT_BEGIN_NAMESPACE
-
-struct FontFile
-{
- QString fileName;
- int indexValue;
-};
-
-class QFreeTypeFontDatabase : public QPlatformFontDatabase
-{
-public:
- void populateFontDatabase() override;
- QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
- QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
- QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override;
- void releaseHandle(void *handle) override;
-
- static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file);
-};
-
-QT_END_NAMESPACE
-
-#endif // QFREETYPEFONTDATABASE_H
diff --git a/src/platformsupport/fontdatabases/genericunix/genericunix.pri b/src/platformsupport/fontdatabases/genericunix/genericunix.pri
deleted file mode 100644
index e9db6c07e2..0000000000
--- a/src/platformsupport/fontdatabases/genericunix/genericunix.pri
+++ /dev/null
@@ -1 +0,0 @@
-HEADERS += $$PWD/qgenericunixfontdatabase_p.h
diff --git a/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h b/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h
deleted file mode 100644
index ccf5ad6d13..0000000000
--- a/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h
+++ /dev/null
@@ -1,64 +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 QGENERICUNIXFONTDATABASE_H
-#define QGENERICUNIXFONTDATABASE_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/qtguiglobal_p.h>
-
-#if QT_CONFIG(fontconfig)
-#include <QtFontDatabaseSupport/private/qfontconfigdatabase_p.h>
-typedef QFontconfigDatabase QGenericUnixFontDatabase;
-#else
-#include <QtFontDatabaseSupport/private/qfreetypefontdatabase_p.h>
-typedef QFreeTypeFontDatabase QGenericUnixFontDatabase;
-#endif //Q_FONTCONFIGDATABASE
-
-#endif // QGENERICUNIXFONTDATABASE_H
diff --git a/src/platformsupport/fontdatabases/mac/coretext.pri b/src/platformsupport/fontdatabases/mac/coretext.pri
deleted file mode 100644
index 95b9926e65..0000000000
--- a/src/platformsupport/fontdatabases/mac/coretext.pri
+++ /dev/null
@@ -1,15 +0,0 @@
-HEADERS += $$PWD/qcoretextfontdatabase_p.h $$PWD/qfontengine_coretext_p.h
-OBJECTIVE_SOURCES += $$PWD/qfontengine_coretext.mm $$PWD/qcoretextfontdatabase.mm
-
-LIBS_PRIVATE += \
- -framework CoreFoundation \
- -framework CoreGraphics \
- -framework CoreText \
- -framework Foundation
-
-macos: \
- LIBS_PRIVATE += -framework AppKit
-else: \
- LIBS_PRIVATE += -framework UIKit
-
-CONFIG += watchos_coretext
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
deleted file mode 100644
index 894919a1c8..0000000000
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ /dev/null
@@ -1,797 +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 "qglobal.h"
-
-#include <sys/param.h>
-
-#if defined(Q_OS_OSX)
-#import <AppKit/AppKit.h>
-#import <IOKit/graphics/IOGraphicsLib.h>
-#elif defined(QT_PLATFORM_UIKIT)
-#import <UIKit/UIFont.h>
-#endif
-
-#include <QtCore/qelapsedtimer.h>
-
-#include "qcoretextfontdatabase_p.h"
-#include "qfontengine_coretext_p.h"
-#if QT_CONFIG(settings)
-#include <QtCore/QSettings>
-#endif
-#include <QtCore/QtEndian>
-#ifndef QT_NO_FREETYPE
-#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-// this could become a list of all languages used for each writing
-// system, instead of using the single most common language.
-static const char *languageForWritingSystem[] = {
- 0, // Any
- "en", // Latin
- "el", // Greek
- "ru", // Cyrillic
- "hy", // Armenian
- "he", // Hebrew
- "ar", // Arabic
- "syr", // Syriac
- "div", // Thaana
- "hi", // Devanagari
- "bn", // Bengali
- "pa", // Gurmukhi
- "gu", // Gujarati
- "or", // Oriya
- "ta", // Tamil
- "te", // Telugu
- "kn", // Kannada
- "ml", // Malayalam
- "si", // Sinhala
- "th", // Thai
- "lo", // Lao
- "bo", // Tibetan
- "my", // Myanmar
- "ka", // Georgian
- "km", // Khmer
- "zh-Hans", // SimplifiedChinese
- "zh-Hant", // TraditionalChinese
- "ja", // Japanese
- "ko", // Korean
- "vi", // Vietnamese
- 0, // Symbol
- "sga", // Ogham
- "non", // Runic
- "man" // N'Ko
-};
-enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
-
-QCoreTextFontDatabase::QCoreTextFontDatabase()
- : m_hasPopulatedAliases(false)
-{
-}
-
-QCoreTextFontDatabase::~QCoreTextFontDatabase()
-{
- for (CTFontDescriptorRef ref : qAsConst(m_systemFontDescriptors))
- CFRelease(ref);
-}
-
-void QCoreTextFontDatabase::populateFontDatabase()
-{
- qCDebug(lcQpaFonts) << "Populating font database...";
- QElapsedTimer elapsed;
- if (lcQpaFonts().isDebugEnabled())
- elapsed.start();
-
- QCFType<CFArrayRef> familyNames = CTFontManagerCopyAvailableFontFamilyNames();
- for (NSString *familyName in familyNames.as<const NSArray *>())
- QPlatformFontDatabase::registerFontFamily(QString::fromNSString(familyName));
-
- qCDebug(lcQpaFonts) << "Populating available families took" << elapsed.restart() << "ms";
-
- // Force creating the theme fonts to get the descriptors in m_systemFontDescriptors
- if (m_themeFonts.isEmpty())
- (void)themeFonts();
-
- qCDebug(lcQpaFonts) << "Resolving theme fonts took" << elapsed.restart() << "ms";
-
- Q_FOREACH (CTFontDescriptorRef fontDesc, m_systemFontDescriptors)
- populateFromDescriptor(fontDesc);
-
- qCDebug(lcQpaFonts) << "Populating system descriptors took" << elapsed.restart() << "ms";
-
- Q_ASSERT(!m_hasPopulatedAliases);
-}
-
-bool QCoreTextFontDatabase::populateFamilyAliases(const QString &missingFamily)
-{
-#if defined(Q_OS_MACOS)
- if (m_hasPopulatedAliases)
- return false;
-
- // There's no API to go from a localized family name to its non-localized
- // name, so we have to resort to enumerating all the available fonts and
- // doing a reverse lookup.
-
- qCDebug(lcQpaFonts) << "Populating family aliases...";
- QElapsedTimer elapsed;
- elapsed.start();
-
- QString nonLocalizedMatch;
- QCFType<CFArrayRef> familyNames = CTFontManagerCopyAvailableFontFamilyNames();
- NSFontManager *fontManager = NSFontManager.sharedFontManager;
- for (NSString *familyName in familyNames.as<const NSArray *>()) {
- NSString *localizedFamilyName = [fontManager localizedNameForFamily:familyName face:nil];
- if (![localizedFamilyName isEqual:familyName]) {
- QString nonLocalizedFamily = QString::fromNSString(familyName);
- QString localizedFamily = QString::fromNSString(localizedFamilyName);
- QPlatformFontDatabase::registerAliasToFontFamily(nonLocalizedFamily, localizedFamily);
- if (localizedFamily == missingFamily)
- nonLocalizedMatch = nonLocalizedFamily;
- }
- }
- m_hasPopulatedAliases = true;
-
- if (lcQpaFonts().isWarningEnabled()) {
- QString warningMessage;
- QDebug msg(&warningMessage);
-
- msg << "Populating font family aliases took" << elapsed.restart() << "ms.";
- if (!nonLocalizedMatch.isNull())
- msg << "Replace uses of" << missingFamily << "with its non-localized name" << nonLocalizedMatch;
- else
- msg << "Replace uses of missing font family" << missingFamily << "with one that exists";
- msg << "to avoid this cost.";
-
- qCWarning(lcQpaFonts) << qPrintable(warningMessage);
- }
-
- return true;
-#else
- Q_UNUSED(missingFamily);
- return false;
-#endif
-}
-
-void QCoreTextFontDatabase::populateFamily(const QString &familyName)
-{
- QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, QCFString(familyName));
- QCFType<CTFontDescriptorRef> nameOnlyDescriptor = CTFontDescriptorCreateWithAttributes(attributes);
-
- // A single family might match several different fonts with different styles eg.
- QCFType<CFArrayRef> matchingFonts = (CFArrayRef) CTFontDescriptorCreateMatchingFontDescriptors(nameOnlyDescriptor, 0);
- if (!matchingFonts) {
- qCWarning(lcQpaFonts) << "QCoreTextFontDatabase: Found no matching fonts for family" << familyName;
- return;
- }
-
- const int numFonts = CFArrayGetCount(matchingFonts);
- for (int i = 0; i < numFonts; ++i)
- populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i)), familyName);
-}
-
-void QCoreTextFontDatabase::invalidate()
-{
- m_hasPopulatedAliases = false;
-}
-
-struct FontDescription {
- QCFString familyName;
- QCFString styleName;
- QString foundryName;
- QFont::Weight weight;
- QFont::Style style;
- QFont::Stretch stretch;
- qreal pointSize;
- bool fixedPitch;
- QSupportedWritingSystems writingSystems;
-};
-
-#ifndef QT_NO_DEBUG_STREAM
-Q_DECL_UNUSED static inline QDebug operator<<(QDebug debug, const FontDescription &fd)
-{
- QDebugStateSaver saver(debug);
- return debug.nospace() << "FontDescription("
- << "familyName=" << QString(fd.familyName)
- << ", styleName=" << QString(fd.styleName)
- << ", foundry=" << fd.foundryName
- << ", weight=" << fd.weight
- << ", style=" << fd.style
- << ", stretch=" << fd.stretch
- << ", pointSize=" << fd.pointSize
- << ", fixedPitch=" << fd.fixedPitch
- << ", writingSystems=" << fd.writingSystems
- << ")";
-}
-#endif
-
-static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
-{
- QCFType<CFDictionaryRef> styles = (CFDictionaryRef) CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute);
-
- fd->foundryName = QStringLiteral("CoreText");
- fd->familyName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
- fd->styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
- fd->weight = QFont::Normal;
- fd->style = QFont::StyleNormal;
- fd->stretch = QFont::Unstretched;
- fd->fixedPitch = false;
-
- if (QCFType<CTFontRef> tempFont = CTFontCreateWithFontDescriptor(font, 0.0, 0)) {
- uint tag = MAKE_TAG('O', 'S', '/', '2');
- CTFontRef tempFontRef = tempFont;
- void *userData = reinterpret_cast<void *>(&tempFontRef);
- uint length = 128;
- QVarLengthArray<uchar, 128> os2Table(length);
- if (QCoreTextFontEngine::ct_getSfntTable(userData, tag, os2Table.data(), &length) && length >= 86) {
- if (length > uint(os2Table.length())) {
- os2Table.resize(length);
- if (!QCoreTextFontEngine::ct_getSfntTable(userData, tag, os2Table.data(), &length))
- Q_UNREACHABLE();
- Q_ASSERT(length >= 86);
- }
- quint32 unicodeRange[4] = {
- qFromBigEndian<quint32>(os2Table.data() + 42),
- qFromBigEndian<quint32>(os2Table.data() + 46),
- qFromBigEndian<quint32>(os2Table.data() + 50),
- qFromBigEndian<quint32>(os2Table.data() + 54)
- };
- quint32 codePageRange[2] = {
- qFromBigEndian<quint32>(os2Table.data() + 78),
- qFromBigEndian<quint32>(os2Table.data() + 82)
- };
- fd->writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
- }
- }
-
- if (styles) {
- if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
- double normalizedWeight;
- if (CFNumberGetValue(weightValue, kCFNumberFloat64Type, &normalizedWeight))
- fd->weight = QCoreTextFontEngine::qtWeightFromCFWeight(float(normalizedWeight));
- }
- if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
- double d;
- if (CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
- if (d > 0.0)
- fd->style = QFont::StyleItalic;
- }
- }
- if (CFNumberRef symbolic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSymbolicTrait)) {
- int d;
- if (CFNumberGetValue(symbolic, kCFNumberSInt32Type, &d)) {
- if (d & kCTFontMonoSpaceTrait)
- fd->fixedPitch = true;
- if (d & kCTFontExpandedTrait)
- fd->stretch = QFont::Expanded;
- else if (d & kCTFontCondensedTrait)
- fd->stretch = QFont::Condensed;
- }
- }
- }
-
- if (QCFType<CFNumberRef> size = (CFNumberRef) CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
- if (CFNumberIsFloatType(size)) {
- double d;
- CFNumberGetValue(size, kCFNumberDoubleType, &d);
- fd->pointSize = d;
- } else {
- int i;
- CFNumberGetValue(size, kCFNumberIntType, &i);
- fd->pointSize = i;
- }
- }
-
- if (QCFType<CFArrayRef> languages = (CFArrayRef) CTFontDescriptorCopyAttribute(font, kCTFontLanguagesAttribute)) {
- CFIndex length = CFArrayGetCount(languages);
- for (int i = 1; i < LanguageCount; ++i) {
- if (!languageForWritingSystem[i])
- continue;
- QCFString lang = CFStringCreateWithCString(NULL, languageForWritingSystem[i], kCFStringEncodingASCII);
- if (CFArrayContainsValue(languages, CFRangeMake(0, length), lang))
- fd->writingSystems.setSupported(QFontDatabase::WritingSystem(i));
- }
- }
-}
-
-void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName)
-{
- FontDescription fd;
- getFontDescription(font, &fd);
-
- // Note: The familyName we are registering, and the family name of the font descriptor, may not
- // match, as CTFontDescriptorCreateMatchingFontDescriptors will return descriptors for replacement
- // fonts if a font family does not have any fonts available on the system.
- QString family = !familyName.isNull() ? familyName : static_cast<QString>(fd.familyName);
-
- CFRetain(font);
- QPlatformFontDatabase::registerFont(family, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch,
- true /* antialiased */, true /* scalable */, 0 /* pixelSize, ignored as font is scalable */,
- fd.fixedPitch, fd.writingSystems, (void *)font);
-}
-
-static NSString * const kQtFontDataAttribute = @"QtFontDataAttribute";
-
-template <typename T>
-T *descriptorAttribute(CTFontDescriptorRef descriptor, CFStringRef name)
-{
- return [static_cast<T *>(CTFontDescriptorCopyAttribute(descriptor, name)) autorelease];
-}
-
-void QCoreTextFontDatabase::releaseHandle(void *handle)
-{
- CTFontDescriptorRef descriptor = static_cast<CTFontDescriptorRef>(handle);
- if (NSValue *fontDataValue = descriptorAttribute<NSValue>(descriptor, (CFStringRef)kQtFontDataAttribute)) {
- QByteArray *fontData = static_cast<QByteArray *>(fontDataValue.pointerValue);
- delete fontData;
- }
- CFRelease(descriptor);
-}
-
-extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
-
-template <>
-QFontEngine *QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>::fontEngine(const QFontDef &fontDef, void *usrPtr)
-{
- QCFType<CTFontDescriptorRef> descriptor = QCFType<CTFontDescriptorRef>::constructFromGet(
- static_cast<CTFontDescriptorRef>(usrPtr));
-
- // Since we do not pass in the destination DPI to CoreText when making
- // the font, we need to pass in a point size which is scaled to include
- // the DPI. The default DPI for the screen is 72, thus the scale factor
- // is destinationDpi / 72, but since pixelSize = pointSize / 72 * dpi,
- // the pixelSize is actually the scaled point size for the destination
- // DPI, and we can use that directly.
- qreal scaledPointSize = fontDef.pixelSize;
-
- CGAffineTransform matrix = qt_transform_from_fontdef(fontDef);
- if (QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix))
- return new QCoreTextFontEngine(font, fontDef);
-
- return nullptr;
-}
-
-#ifndef QT_NO_FREETYPE
-template <>
-QFontEngine *QCoreTextFontDatabaseEngineFactory<QFontEngineFT>::fontEngine(const QFontDef &fontDef, void *usrPtr)
-{
- CTFontDescriptorRef descriptor = static_cast<CTFontDescriptorRef>(usrPtr);
-
- if (NSValue *fontDataValue = descriptorAttribute<NSValue>(descriptor, (CFStringRef)kQtFontDataAttribute)) {
- QByteArray *fontData = static_cast<QByteArray *>(fontDataValue.pointerValue);
- return QFontEngineFT::create(*fontData, fontDef.pixelSize,
- static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
- } else if (NSURL *url = descriptorAttribute<NSURL>(descriptor, kCTFontURLAttribute)) {
- Q_ASSERT(url.fileURL);
- QFontEngine::FaceId faceId;
- faceId.filename = QString::fromNSString(url.path).toUtf8();
- return QFontEngineFT::create(fontDef, faceId);
- }
- Q_UNREACHABLE();
-}
-#endif
-
-template <class T>
-QFontEngine *QCoreTextFontDatabaseEngineFactory<T>::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
-{
- return T::create(fontData, pixelSize, hintingPreference);
-}
-
-// Explicitly instantiate so that we don't need the plugin to involve FreeType
-template class QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>;
-#ifndef QT_NO_FREETYPE
-template class QCoreTextFontDatabaseEngineFactory<QFontEngineFT>;
-#endif
-
-CTFontDescriptorRef descriptorForFamily(const QString &familyName)
-{
- return CTFontDescriptorCreateWithAttributes(CFDictionaryRef(@{
- (id)kCTFontFamilyNameAttribute: familyName.toNSString()
- }));
-}
-
-CTFontDescriptorRef descriptorForFamily(const char *familyName)
-{
- return descriptorForFamily(QString::fromLatin1(familyName));
-}
-
-CFArrayRef fallbacksForDescriptor(CTFontDescriptorRef descriptor)
-{
- QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(descriptor, 0.0, nullptr);
- if (!font) {
- qCWarning(lcQpaFonts) << "Failed to create fallback font for" << descriptor;
- return nullptr;
- }
-
- CFArrayRef cascadeList = CFArrayRef(CTFontCopyDefaultCascadeListForLanguages(font,
- (CFArrayRef)[NSUserDefaults.standardUserDefaults stringArrayForKey:@"AppleLanguages"]));
-
- if (!cascadeList) {
- qCWarning(lcQpaFonts) << "Failed to create fallback cascade list for" << descriptor;
- return nullptr;
- }
-
- return cascadeList;
-}
-
-CFArrayRef QCoreTextFontDatabase::fallbacksForFamily(const QString &family)
-{
- if (family.isEmpty())
- return nullptr;
-
- QCFType<CTFontDescriptorRef> fontDescriptor = descriptorForFamily(family);
- if (!fontDescriptor) {
- qCWarning(lcQpaFonts) << "Failed to create fallback font descriptor for" << family;
- return nullptr;
- }
-
- // If the font is not available we want to fall back to the style hint.
- // By creating a matching font descriptor we can verify whether the font
- // is available or not, and avoid CTFontCreateWithFontDescriptor picking
- // a default font for us based on incomplete information.
- fontDescriptor = CTFontDescriptorCreateMatchingFontDescriptor(fontDescriptor, 0);
- if (!fontDescriptor)
- return nullptr;
-
- return fallbacksForDescriptor(fontDescriptor);
-}
-
-CTFontDescriptorRef descriptorForFontType(CTFontUIFontType uiType)
-{
- static const CGFloat kDefaultSizeForRequestedUIType = 0.0;
- QCFType<CTFontRef> ctFont = CTFontCreateUIFontForLanguage(
- uiType, kDefaultSizeForRequestedUIType, nullptr);
- return CTFontCopyFontDescriptor(ctFont);
-}
-
-CTFontDescriptorRef descriptorForStyle(QFont::StyleHint styleHint)
-{
- switch (styleHint) {
- case QFont::SansSerif: return descriptorForFamily("Helvetica");
- case QFont::Serif: return descriptorForFamily("Times New Roman");
- case QFont::Monospace: return descriptorForFamily("Menlo");
-#ifdef Q_OS_MACOS
- case QFont::Cursive: return descriptorForFamily("Apple Chancery");
-#endif
- case QFont::Fantasy: return descriptorForFamily("Zapfino");
- case QFont::TypeWriter: return descriptorForFamily("American Typewriter");
- case QFont::AnyStyle: Q_FALLTHROUGH();
- case QFont::System: return descriptorForFontType(kCTFontUIFontSystem);
- default: return nullptr; // No matching font on this platform
- }
-}
-
-QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
-{
- Q_UNUSED(style);
-
- qCDebug(lcQpaFonts).nospace() << "Resolving fallbacks families for"
- << (!family.isEmpty() ? qPrintable(QLatin1String(" family '%1' with").arg(family)) : "")
- << " style hint " << styleHint;
-
- QMacAutoReleasePool pool;
-
- QStringList fallbackList;
-
- QCFType<CFArrayRef> fallbackFonts = fallbacksForFamily(family);
- if (!fallbackFonts || !CFArrayGetCount(fallbackFonts)) {
- // We were not able to find a fallback for the specific family,
- // or the family was empty, so we fall back to the style hint.
- if (!family.isEmpty())
- qCDebug(lcQpaFonts) << "No fallbacks found. Using style hint instead";
-
- if (QCFType<CTFontDescriptorRef> styleDescriptor = descriptorForStyle(styleHint)) {
- CFMutableArrayRef tmp = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- CFArrayAppendValue(tmp, styleDescriptor);
- QCFType<CFArrayRef> styleFallbacks = fallbacksForDescriptor(styleDescriptor);
- CFArrayAppendArray(tmp, styleFallbacks, CFRangeMake(0, CFArrayGetCount(styleFallbacks)));
- fallbackFonts = tmp;
- }
- }
-
- if (!fallbackFonts)
- return fallbackList;
-
- const int numberOfFallbacks = CFArrayGetCount(fallbackFonts);
- for (int i = 0; i < numberOfFallbacks; ++i) {
- auto fallbackDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fallbackFonts, i));
- auto fallbackFamilyName = QCFString(CTFontDescriptorCopyAttribute(fallbackDescriptor, kCTFontFamilyNameAttribute));
-
- if (!isFamilyPopulated(fallbackFamilyName)) {
- // We need to populate, or at least register the fallback fonts,
- // otherwise the Qt font database may not know they exist.
- if (isPrivateFontFamily(fallbackFamilyName))
- const_cast<QCoreTextFontDatabase *>(this)->populateFromDescriptor(fallbackDescriptor);
- else
- registerFontFamily(fallbackFamilyName);
- }
-
- fallbackList.append(fallbackFamilyName);
- }
-
- // Some fallback fonts will have have an order in the list returned
- // by Core Text that would indicate they should be preferred for e.g.
- // Arabic, or Emoji, while in reality only supporting a tiny subset
- // of the required glyphs, or representing them by question marks.
- // Move these to the end, so that the proper fonts are preferred.
- for (const char *family : { ".Apple Symbols Fallback", ".Noto Sans Universal" }) {
- int index = fallbackList.indexOf(QLatin1String(family));
- if (index >= 0)
- fallbackList.move(index, fallbackList.size() - 1);
- }
-
-#if defined(Q_OS_MACOS)
- // Since we are only returning a list of default fonts for the current language, we do not
- // cover all Unicode completely. This was especially an issue for some of the common script
- // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
- // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
- // of Unicode 2.1.
- if (!fallbackList.contains(QStringLiteral("Arial Unicode MS")))
- fallbackList.append(QStringLiteral("Arial Unicode MS"));
- // Since some symbols (specifically Braille) are not in Arial Unicode MS, we
- // add Apple Symbols to cover those too.
- if (!fallbackList.contains(QStringLiteral("Apple Symbols")))
- fallbackList.append(QStringLiteral("Apple Symbols"));
-#endif
-
- extern QStringList qt_sort_families_by_writing_system(QChar::Script, const QStringList &);
- fallbackList = qt_sort_families_by_writing_system(script, fallbackList);
-
- qCDebug(lcQpaFonts).nospace() << "Fallback families ordered by script " << script << ": " << fallbackList;
-
- return fallbackList;
-}
-
-QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
-{
- QCFType<CFArrayRef> fonts;
-
- if (!fontData.isEmpty()) {
- QCFType<CFDataRef> fontDataReference = fontData.toRawCFData();
- if (QCFType<CTFontDescriptorRef> descriptor = CTFontManagerCreateFontDescriptorFromData(fontDataReference)) {
- // There's no way to get the data back out of a font descriptor created with
- // CTFontManagerCreateFontDescriptorFromData, so we attach the data manually.
- NSDictionary *attributes = @{ kQtFontDataAttribute : [NSValue valueWithPointer:new QByteArray(fontData)] };
- descriptor = CTFontDescriptorCreateCopyWithAttributes(descriptor, (CFDictionaryRef)attributes);
- CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- CFArrayAppendValue(array, descriptor);
- fonts = array;
- }
- } else {
- QCFType<CFURLRef> fontURL = QUrl::fromLocalFile(fileName).toCFURL();
- fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL);
- }
-
- if (!fonts)
- return QStringList();
-
- QStringList families;
- const int numFonts = CFArrayGetCount(fonts);
- for (int i = 0; i < numFonts; ++i) {
- CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i));
- populateFromDescriptor(fontDescriptor);
- QCFType<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontFamilyNameAttribute));
- families.append(QString::fromCFString(familyName));
- }
-
- // Note: We don't do font matching via CoreText for application fonts, so we don't
- // need to enable font matching for them via CTFontManagerEnableFontDescriptors.
-
- return families;
-}
-
-bool QCoreTextFontDatabase::isPrivateFontFamily(const QString &family) const
-{
- if (family.startsWith(QLatin1Char('.')) || family == QLatin1String("LastResort"))
- return true;
-
- return QPlatformFontDatabase::isPrivateFontFamily(family);
-}
-
-static CTFontUIFontType fontTypeFromTheme(QPlatformTheme::Font f)
-{
- switch (f) {
- case QPlatformTheme::SystemFont:
- return kCTFontUIFontSystem;
-
- case QPlatformTheme::MenuFont:
- case QPlatformTheme::MenuBarFont:
- case QPlatformTheme::MenuItemFont:
- return kCTFontUIFontMenuItem;
-
- case QPlatformTheme::MessageBoxFont:
- return kCTFontUIFontEmphasizedSystem;
-
- case QPlatformTheme::LabelFont:
- return kCTFontUIFontSystem;
-
- case QPlatformTheme::TipLabelFont:
- return kCTFontUIFontToolTip;
-
- case QPlatformTheme::StatusBarFont:
- return kCTFontUIFontSystem;
-
- case QPlatformTheme::TitleBarFont:
- return kCTFontUIFontWindowTitle;
-
- case QPlatformTheme::MdiSubWindowTitleFont:
- return kCTFontUIFontSystem;
-
- case QPlatformTheme::DockWidgetTitleFont:
- return kCTFontUIFontSmallSystem;
-
- case QPlatformTheme::PushButtonFont:
- return kCTFontUIFontPushButton;
-
- case QPlatformTheme::CheckBoxFont:
- case QPlatformTheme::RadioButtonFont:
- return kCTFontUIFontSystem;
-
- case QPlatformTheme::ToolButtonFont:
- return kCTFontUIFontSmallToolbar;
-
- case QPlatformTheme::ItemViewFont:
- return kCTFontUIFontSystem;
-
- case QPlatformTheme::ListViewFont:
- return kCTFontUIFontViews;
-
- case QPlatformTheme::HeaderViewFont:
- return kCTFontUIFontSmallSystem;
-
- case QPlatformTheme::ListBoxFont:
- return kCTFontUIFontViews;
-
- case QPlatformTheme::ComboMenuItemFont:
- return kCTFontUIFontSystem;
-
- case QPlatformTheme::ComboLineEditFont:
- return kCTFontUIFontViews;
-
- case QPlatformTheme::SmallFont:
- return kCTFontUIFontSmallSystem;
-
- case QPlatformTheme::MiniFont:
- return kCTFontUIFontMiniSystem;
-
- case QPlatformTheme::FixedFont:
- return kCTFontUIFontUserFixedPitch;
-
- default:
- return kCTFontUIFontSystem;
- }
-}
-
-static CTFontDescriptorRef fontDescriptorFromTheme(QPlatformTheme::Font f)
-{
-#if defined(QT_PLATFORM_UIKIT)
- // Use Dynamic Type to resolve theme fonts if possible, to get
- // correct font sizes and style based on user configuration.
- NSString *textStyle = 0;
- switch (f) {
- case QPlatformTheme::TitleBarFont:
- case QPlatformTheme::HeaderViewFont:
- textStyle = UIFontTextStyleHeadline;
- break;
- case QPlatformTheme::MdiSubWindowTitleFont:
- textStyle = UIFontTextStyleSubheadline;
- break;
- case QPlatformTheme::TipLabelFont:
- case QPlatformTheme::SmallFont:
- textStyle = UIFontTextStyleFootnote;
- break;
- case QPlatformTheme::MiniFont:
- textStyle = UIFontTextStyleCaption2;
- break;
- case QPlatformTheme::FixedFont:
- // Fall back to regular code path, as iOS doesn't provide
- // an appropriate text style for this theme font.
- break;
- default:
- textStyle = UIFontTextStyleBody;
- break;
- }
-
- if (textStyle) {
- UIFontDescriptor *desc = [UIFontDescriptor preferredFontDescriptorWithTextStyle:textStyle];
- return static_cast<CTFontDescriptorRef>(CFBridgingRetain(desc));
- }
-#endif // Q_OS_IOS, Q_OS_TVOS, Q_OS_WATCHOS
-
- // macOS default case and iOS fallback case
- return descriptorForFontType(fontTypeFromTheme(f));
-}
-
-const QHash<QPlatformTheme::Font, QFont *> &QCoreTextFontDatabase::themeFonts() const
-{
- if (m_themeFonts.isEmpty()) {
- for (long f = QPlatformTheme::SystemFont; f < QPlatformTheme::NFonts; f++) {
- QPlatformTheme::Font ft = static_cast<QPlatformTheme::Font>(f);
- m_themeFonts.insert(ft, themeFont(ft));
- }
- }
-
- return m_themeFonts;
-}
-
-QFont *QCoreTextFontDatabase::themeFont(QPlatformTheme::Font f) const
-{
- CTFontDescriptorRef fontDesc = fontDescriptorFromTheme(f);
- FontDescription fd;
- getFontDescription(fontDesc, &fd);
-
- if (!m_systemFontDescriptors.contains(fontDesc))
- m_systemFontDescriptors.insert(fontDesc);
- else
- CFRelease(fontDesc);
-
- QFont *font = new QFont(fd.familyName, fd.pointSize, fd.weight, fd.style == QFont::StyleItalic);
- return font;
-}
-
-QFont QCoreTextFontDatabase::defaultFont() const
-{
- if (defaultFontName.isEmpty()) {
- QCFType<CTFontDescriptorRef> systemFont = descriptorForFontType(kCTFontUIFontSystem);
- defaultFontName = QCFString(CTFontDescriptorCopyAttribute(systemFont, kCTFontFamilyNameAttribute));
- }
-
- return QFont(defaultFontName);
-}
-
-bool QCoreTextFontDatabase::fontsAlwaysScalable() const
-{
- return true;
-}
-
-QList<int> QCoreTextFontDatabase::standardSizes() const
-{
- QList<int> ret;
- static const unsigned short standard[] =
- { 9, 10, 11, 12, 13, 14, 18, 24, 36, 48, 64, 72, 96, 144, 288, 0 };
- ret.reserve(int(sizeof(standard) / sizeof(standard[0])));
- const unsigned short *sizes = standard;
- while (*sizes) ret << *sizes++;
- return ret;
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
deleted file mode 100644
index eebb3eb964..0000000000
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ /dev/null
@@ -1,116 +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 QCORETEXTFONTDATABASE_H
-#define QCORETEXTFONTDATABASE_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 <qglobal.h>
-
-#include <qpa/qplatformfontdatabase.h>
-#include <qpa/qplatformtheme.h>
-#include <private/qcore_mac_p.h>
-
-Q_FORWARD_DECLARE_CF_TYPE(CTFontDescriptor);
-Q_FORWARD_DECLARE_CF_TYPE(CTFont);
-
-Q_DECLARE_METATYPE(QCFType<CGFontRef>);
-Q_DECLARE_METATYPE(QCFType<CFURLRef>);
-
-QT_BEGIN_NAMESPACE
-
-class QCoreTextFontDatabase : public QPlatformFontDatabase
-{
-public:
- QCoreTextFontDatabase();
- ~QCoreTextFontDatabase();
- void populateFontDatabase() override;
- bool populateFamilyAliases(const QString &missingFamily) override;
- void populateFamily(const QString &familyName) override;
- void invalidate() override;
-
- QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
- QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override;
- void releaseHandle(void *handle) override;
- bool isPrivateFontFamily(const QString &family) const override;
- QFont defaultFont() const override;
- bool fontsAlwaysScalable() const override;
- QList<int> standardSizes() const override;
-
- // For iOS and OS X platform themes
- QFont *themeFont(QPlatformTheme::Font) const;
- const QHash<QPlatformTheme::Font, QFont *> &themeFonts() const;
-
-protected:
- mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors;
-
-private:
- void populateFromDescriptor(CTFontDescriptorRef font, const QString &familyName = QString());
- static CFArrayRef fallbacksForFamily(const QString &family);
-
- mutable QString defaultFontName;
-
- mutable QHash<QPlatformTheme::Font, QFont *> m_themeFonts;
- bool m_hasPopulatedAliases;
-};
-
-// Split out into separate template class so that the compiler doesn't have
-// to generate code for each override in QCoreTextFontDatabase for each T.
-
-template <class T>
-class QCoreTextFontDatabaseEngineFactory : public QCoreTextFontDatabase
-{
-public:
- QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
- QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
-};
-
-QT_END_NAMESPACE
-
-#endif // QCORETEXTFONTDATABASE_H
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
deleted file mode 100644
index 30c80ebd86..0000000000
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ /dev/null
@@ -1,1055 +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 "qfontengine_coretext_p.h"
-
-#include <qpa/qplatformfontdatabase.h>
-#include <QtCore/qendian.h>
-#if QT_CONFIG(settings)
-#include <QtCore/qsettings.h>
-#endif
-#include <QtCore/qoperatingsystemversion.h>
-#include <private/qcoregraphics_p.h>
-#include <private/qimage_p.h>
-
-#include <cmath>
-
-#if defined(Q_OS_MACOS)
-#import <AppKit/AppKit.h>
-#endif
-
-#if defined(QT_PLATFORM_UIKIT)
-#import <UIKit/UIKit.h>
-#endif
-
-// These are available cross platform, exported as kCTFontWeightXXX from CoreText.framework,
-// but they are not documented and are not in public headers so are private API and exposed
-// only through the NSFontWeightXXX and UIFontWeightXXX aliases in AppKit and UIKit (rdar://26109857)
-#if defined(Q_OS_MACOS)
-#define kCTFontWeightUltraLight NSFontWeightUltraLight
-#define kCTFontWeightThin NSFontWeightThin
-#define kCTFontWeightLight NSFontWeightLight
-#define kCTFontWeightRegular NSFontWeightRegular
-#define kCTFontWeightMedium NSFontWeightMedium
-#define kCTFontWeightSemibold NSFontWeightSemibold
-#define kCTFontWeightBold NSFontWeightBold
-#define kCTFontWeightHeavy NSFontWeightHeavy
-#define kCTFontWeightBlack NSFontWeightBlack
-#elif defined(QT_PLATFORM_UIKIT)
-#define kCTFontWeightUltraLight UIFontWeightUltraLight
-#define kCTFontWeightThin UIFontWeightThin
-#define kCTFontWeightLight UIFontWeightLight
-#define kCTFontWeightRegular UIFontWeightRegular
-#define kCTFontWeightMedium UIFontWeightMedium
-#define kCTFontWeightSemibold UIFontWeightSemibold
-#define kCTFontWeightBold UIFontWeightBold
-#define kCTFontWeightHeavy UIFontWeightHeavy
-#define kCTFontWeightBlack UIFontWeightBlack
-#endif
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
-
-static float SYNTHETIC_ITALIC_SKEW = std::tan(14.f * std::acos(0.f) / 90.f);
-
-bool QCoreTextFontEngine::ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length)
-{
- CTFontRef ctfont = *(CTFontRef *)user_data;
-
- QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0);
- if (!table)
- return false;
-
- CFIndex tableLength = CFDataGetLength(table);
- if (buffer && int(*length) >= tableLength)
- CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer);
- *length = tableLength;
- Q_ASSERT(int(*length) > 0);
- return true;
-}
-
-QFont::Weight QCoreTextFontEngine::qtWeightFromCFWeight(float value)
-{
-#define COMPARE_WEIGHT_DISTANCE(ct_weight, qt_weight) \
- { \
- float d; \
- if ((d = qAbs(value - ct_weight)) < distance) { \
- distance = d; \
- ret = qt_weight; \
- } \
- }
-
- float distance = qAbs(value - kCTFontWeightBlack);
- QFont::Weight ret = QFont::Black;
-
- // Compare distance to system weight to find the closest match.
- // (Note: Must go from high to low, so that midpoints are rounded up)
- COMPARE_WEIGHT_DISTANCE(kCTFontWeightHeavy, QFont::ExtraBold);
- COMPARE_WEIGHT_DISTANCE(kCTFontWeightBold, QFont::Bold);
- COMPARE_WEIGHT_DISTANCE(kCTFontWeightSemibold, QFont::DemiBold);
- COMPARE_WEIGHT_DISTANCE(kCTFontWeightMedium, QFont::Medium);
- COMPARE_WEIGHT_DISTANCE(kCTFontWeightRegular, QFont::Normal);
- COMPARE_WEIGHT_DISTANCE(kCTFontWeightLight, QFont::Light);
- COMPARE_WEIGHT_DISTANCE(kCTFontWeightThin, QFont::ExtraLight);
- COMPARE_WEIGHT_DISTANCE(kCTFontWeightUltraLight, QFont::Thin);
-
-#undef COMPARE_WEIGHT_DISTANCE
-
- return ret;
-}
-
-CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef)
-{
- CGAffineTransform transform = CGAffineTransformIdentity;
- if (fontDef.stretch && fontDef.stretch != 100)
- transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
- return transform;
-}
-
-// Keeps font data alive until engine is disposed
-class QCoreTextRawFontEngine : public QCoreTextFontEngine
-{
-public:
- QCoreTextRawFontEngine(CGFontRef font, const QFontDef &def, const QByteArray &fontData)
- : QCoreTextFontEngine(font, def)
- , m_fontData(fontData)
- {}
- QFontEngine *cloneWithSize(qreal pixelSize) const
- {
- QFontDef newFontDef = fontDef;
- newFontDef.pixelSize = pixelSize;
- newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
-
- return new QCoreTextRawFontEngine(cgFont, newFontDef, m_fontData);
- }
- QByteArray m_fontData;
-};
-
-QCoreTextFontEngine *QCoreTextFontEngine::create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
-{
- Q_UNUSED(hintingPreference);
-
- QCFType<CFDataRef> fontDataReference = fontData.toRawCFData();
- QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithCFData(fontDataReference);
-
- // Note: CTFontCreateWithGraphicsFont (which we call from the QCoreTextFontEngine
- // constructor) has a bug causing it to retain the CGFontRef but never release it.
- // The result is that we are leaking the CGFont, CGDataProvider, and CGData, but
- // as the CGData is created from the raw QByteArray data, which we deref in the
- // subclass above during destruction, we're at least not leaking the font data,
- // (unless CoreText copies it internally). http://stackoverflow.com/questions/40805382/
- QCFType<CGFontRef> cgFont = CGFontCreateWithDataProvider(dataProvider);
-
- if (!cgFont) {
- qWarning("QCoreTextFontEngine::create: CGFontCreateWithDataProvider failed");
- return nullptr;
- }
-
- QFontDef def;
- def.pixelSize = pixelSize;
- def.pointSize = pixelSize * 72.0 / qt_defaultDpi();
- return new QCoreTextRawFontEngine(cgFont, def, fontData);
-}
-
-QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def)
- : QCoreTextFontEngine(def)
-{
- ctfont = QCFType<CTFontRef>::constructFromGet(font);
- cgFont = CTFontCopyGraphicsFont(font, nullptr);
- init();
-}
-
-QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def)
- : QCoreTextFontEngine(def)
-{
- cgFont = QCFType<CGFontRef>::constructFromGet(font);
- ctfont = CTFontCreateWithGraphicsFont(font, fontDef.pixelSize, &transform, nullptr);
- init();
-}
-
-QCoreTextFontEngine::QCoreTextFontEngine(const QFontDef &def)
- : QFontEngine(Mac)
-{
- fontDef = def;
- transform = qt_transform_from_fontdef(fontDef);
-}
-
-QCoreTextFontEngine::~QCoreTextFontEngine()
-{
-}
-
-void QCoreTextFontEngine::init()
-{
- Q_ASSERT(ctfont);
- Q_ASSERT(cgFont);
-
- face_id.index = 0;
- QCFString name = CTFontCopyName(ctfont, kCTFontUniqueNameKey);
- face_id.filename = QString::fromCFString(name).toUtf8();
-
- QCFString family = CTFontCopyFamilyName(ctfont);
- fontDef.family = family;
-
- QCFString styleName = (CFStringRef) CTFontCopyAttribute(ctfont, kCTFontStyleNameAttribute);
- fontDef.styleName = styleName;
-
- synthesisFlags = 0;
- CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(ctfont);
-
- if (traits & kCTFontColorGlyphsTrait)
- glyphFormat = QFontEngine::Format_ARGB;
- else if (shouldSmoothFont() && fontSmoothing() == FontSmoothing::Subpixel)
- glyphFormat = QFontEngine::Format_A32;
- else
- glyphFormat = QFontEngine::Format_A8;
-
- if (traits & kCTFontItalicTrait)
- fontDef.style = QFont::StyleItalic;
-
- static const auto getTraitValue = [](CFDictionaryRef allTraits, CFStringRef trait) -> float {
- if (CFDictionaryContainsKey(allTraits, trait)) {
- CFNumberRef traitNum = (CFNumberRef) CFDictionaryGetValue(allTraits, trait);
- float v = 0;
- CFNumberGetValue(traitNum, kCFNumberFloatType, &v);
- return v;
- }
- return 0;
- };
-
- QCFType<CFDictionaryRef> allTraits = CTFontCopyTraits(ctfont);
- fontDef.weight = QCoreTextFontEngine::qtWeightFromCFWeight(getTraitValue(allTraits, kCTFontWeightTrait));
- int slant = static_cast<int>(getTraitValue(allTraits, kCTFontSlantTrait) * 500 + 500);
- if (slant > 500 && !(traits & kCTFontItalicTrait))
- fontDef.style = QFont::StyleOblique;
-
- if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait))
- synthesisFlags |= SynthesizedBold;
- // XXX: we probably don't need to synthesis italic for oblique font
- if (fontDef.style != QFont::StyleNormal && !(traits & kCTFontItalicTrait))
- synthesisFlags |= SynthesizedItalic;
-
- avgCharWidth = 0;
- QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
- unsigned emSize = CTFontGetUnitsPerEm(ctfont);
- if (os2Table.size() >= 10) {
- fsType = qFromBigEndian<quint16>(os2Table.constData() + 8);
- // qAbs is a workaround for weird fonts like Lucida Grande
- qint16 width = qAbs(qFromBigEndian<qint16>(os2Table.constData() + 2));
- avgCharWidth = QFixed::fromReal(width * fontDef.pixelSize / emSize);
- } else
- avgCharWidth = QFontEngine::averageCharWidth();
-
- underlineThickness = QFixed::fromReal(CTFontGetUnderlineThickness(ctfont));
- underlinePos = -QFixed::fromReal(CTFontGetUnderlinePosition(ctfont));
-
- cache_cost = (CTFontGetAscent(ctfont) + CTFontGetDescent(ctfont)) * avgCharWidth.toInt() * 2000;
-
- // HACK hb_coretext requires both CTFont and CGFont but user_data is only void*
- Q_ASSERT((void *)(&ctfont + 1) == (void *)&cgFont);
- faceData.user_data = &ctfont;
- faceData.get_font_table = ct_getSfntTable;
-
- kerningPairsLoaded = false;
-}
-
-glyph_t QCoreTextFontEngine::glyphIndex(uint ucs4) const
-{
- int len = 0;
-
- QChar str[2];
- if (Q_UNLIKELY(QChar::requiresSurrogates(ucs4))) {
- str[len++] = QChar(QChar::highSurrogate(ucs4));
- str[len++] = QChar(QChar::lowSurrogate(ucs4));
- } else {
- str[len++] = QChar(ucs4);
- }
-
- CGGlyph glyphIndices[2];
-
- CTFontGetGlyphsForCharacters(ctfont, (const UniChar *)str, glyphIndices, len);
-
- return glyphIndices[0];
-}
-
-bool QCoreTextFontEngine::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<CGGlyph> cgGlyphs(len);
- CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len);
-
- int glyph_pos = 0;
- for (int i = 0; i < len; ++i) {
- glyphs->glyphs[glyph_pos] = cgGlyphs[i];
- if (glyph_pos < i)
- cgGlyphs[glyph_pos] = cgGlyphs[i];
- glyph_pos++;
-
- // If it's a non-BMP char, skip the lower part of surrogate pair and go
- // directly to the next char without increasing glyph_pos
- if (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate())
- ++i;
- }
-
- *nglyphs = glyph_pos;
- glyphs->numGlyphs = glyph_pos;
-
- if (!(flags & GlyphIndicesOnly))
- loadAdvancesForGlyphs(cgGlyphs, glyphs);
-
- return true;
-}
-
-glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs)
-{
- QFixed w;
- bool round = fontDef.styleStrategy & QFont::ForceIntegerMetrics;
-
- for (int i = 0; i < glyphs.numGlyphs; ++i) {
- w += round ? glyphs.effectiveAdvance(i).round()
- : glyphs.effectiveAdvance(i);
- }
- return glyph_metrics_t(0, -(ascent()), w - lastRightBearing(glyphs, round), ascent()+descent(), w, 0);
-}
-
-glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph)
-{
- glyph_metrics_t ret;
- CGGlyph g = glyph;
- CGRect rect = CTFontGetBoundingRectsForGlyphs(ctfont, kCTFontOrientationHorizontal, &g, 0, 1);
- if (synthesisFlags & QFontEngine::SynthesizedItalic) {
- rect.size.width += rect.size.height * SYNTHETIC_ITALIC_SKEW;
- }
- ret.width = QFixed::fromReal(rect.size.width);
- ret.height = QFixed::fromReal(rect.size.height);
- ret.x = QFixed::fromReal(rect.origin.x);
- ret.y = -QFixed::fromReal(rect.origin.y) - ret.height;
- CGSize advances[1];
- CTFontGetAdvancesForGlyphs(ctfont, kCTFontOrientationHorizontal, &g, advances, 1);
- ret.xoff = QFixed::fromReal(advances[0].width);
- ret.yoff = QFixed::fromReal(advances[0].height);
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- ret.xoff = ret.xoff.round();
- ret.yoff = ret.yoff.round();
- }
-
- return ret;
-}
-
-QFixed QCoreTextFontEngine::ascent() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? QFixed::fromReal(CTFontGetAscent(ctfont)).round()
- : QFixed::fromReal(CTFontGetAscent(ctfont));
-}
-
-QFixed QCoreTextFontEngine::capHeight() const
-{
- QFixed c = QFixed::fromReal(CTFontGetCapHeight(ctfont));
- if (c <= 0)
- return calculatedCapHeight();
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- c = c.round();
-
- return c;
-}
-
-QFixed QCoreTextFontEngine::descent() const
-{
- QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont));
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- d = d.round();
-
- return d;
-}
-QFixed QCoreTextFontEngine::leading() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? QFixed::fromReal(CTFontGetLeading(ctfont)).round()
- : QFixed::fromReal(CTFontGetLeading(ctfont));
-}
-QFixed QCoreTextFontEngine::xHeight() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? QFixed::fromReal(CTFontGetXHeight(ctfont)).round()
- : QFixed::fromReal(CTFontGetXHeight(ctfont));
-}
-
-QFixed QCoreTextFontEngine::averageCharWidth() const
-{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? avgCharWidth.round() : avgCharWidth;
-}
-
-qreal QCoreTextFontEngine::maxCharWidth() const
-{
- // ### FIXME: 'W' might not be the widest character, but this is better than nothing
- const glyph_t glyph = glyphIndex('W');
- glyph_metrics_t bb = const_cast<QCoreTextFontEngine *>(this)->boundingBox(glyph);
- return bb.xoff.toReal();
-}
-
-bool QCoreTextFontEngine::hasColorGlyphs() const
-{
- return glyphFormat == QFontEngine::Format_ARGB;
-}
-
-void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight)
-{
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix;
- matrix.translate(x, y);
- getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
- if (glyphs.size() == 0)
- return;
-
- CGContextSetFontSize(ctx, fontDef.pixelSize);
-
- CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
-
- CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight);
-
- CGAffineTransformConcat(cgMatrix, oldTextMatrix);
-
- if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
-
- cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
-
- CGContextSetTextMatrix(ctx, cgMatrix);
-
- CGContextSetTextDrawingMode(ctx, kCGTextFill);
-
- QVarLengthArray<CGPoint> cgPositions(glyphs.size());
- QVarLengthArray<CGGlyph> cgGlyphs(glyphs.size());
- const qreal firstX = positions[0].x.toReal();
- const qreal firstY = positions[0].y.toReal();
- for (int i = 0; i < glyphs.size(); ++i) {
- cgPositions[i].x = positions[i].x.toReal() - firstX;
- cgPositions[i].y = firstY - positions[i].y.toReal();
- cgGlyphs[i] = glyphs[i];
- }
-
- //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont));
-
- CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal());
- CTFontDrawGlyphs(ctfont, cgGlyphs.data(), cgPositions.data(), glyphs.size(), ctx);
-
- if (synthesisFlags & QFontEngine::SynthesizedBold) {
- CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(),
- positions[0].y.toReal());
- CTFontDrawGlyphs(ctfont, cgGlyphs.data(), cgPositions.data(), glyphs.size(), ctx);
- }
-
- CGContextSetTextMatrix(ctx, oldTextMatrix);
-}
-
-struct ConvertPathInfo
-{
- ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos, qreal newStretch = 1.0) :
- path(newPath), pos(newPos), stretch(newStretch) {}
- QPainterPath *path;
- QPointF pos;
- qreal stretch;
-};
-
-static void convertCGPathToQPainterPath(void *info, const CGPathElement *element)
-{
- ConvertPathInfo *myInfo = static_cast<ConvertPathInfo *>(info);
- switch(element->type) {
- case kCGPathElementMoveToPoint:
- myInfo->path->moveTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(),
- element->points[0].y + myInfo->pos.y());
- break;
- case kCGPathElementAddLineToPoint:
- myInfo->path->lineTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(),
- element->points[0].y + myInfo->pos.y());
- break;
- case kCGPathElementAddQuadCurveToPoint:
- myInfo->path->quadTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(),
- element->points[0].y + myInfo->pos.y(),
- (element->points[1].x * myInfo->stretch) + myInfo->pos.x(),
- element->points[1].y + myInfo->pos.y());
- break;
- case kCGPathElementAddCurveToPoint:
- myInfo->path->cubicTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(),
- element->points[0].y + myInfo->pos.y(),
- (element->points[1].x * myInfo->stretch) + myInfo->pos.x(),
- element->points[1].y + myInfo->pos.y(),
- (element->points[2].x * myInfo->stretch) + myInfo->pos.x(),
- element->points[2].y + myInfo->pos.y());
- break;
- case kCGPathElementCloseSubpath:
- myInfo->path->closeSubpath();
- break;
- default:
- qCWarning(lcQpaFonts) << "Unhandled path transform type: " << element->type;
- }
-
-}
-
-void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs,
- QPainterPath *path, QTextItem::RenderFlags)
-{
- if (hasColorGlyphs())
- return; // We can't convert color-glyphs to path
-
- CGAffineTransform cgMatrix = CGAffineTransformIdentity;
- cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1);
-
- if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
-
- qreal stretch = fontDef.stretch ? qreal(fontDef.stretch) / 100 : 1.0;
- for (int i = 0; i < nGlyphs; ++i) {
- QCFType<CGPathRef> cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix);
- ConvertPathInfo info(path, positions[i].toPointF(), stretch);
- CGPathApply(cgpath, &info, convertCGPathToQPainterPath);
- }
-}
-
-static void qcoretextfontengine_scaleMetrics(glyph_metrics_t &br, const QTransform &matrix)
-{
- if (matrix.isScaling()) {
- qreal hscale = matrix.m11();
- qreal vscale = matrix.m22();
- br.width = QFixed::fromReal(br.width.toReal() * hscale);
- br.height = QFixed::fromReal(br.height.toReal() * vscale);
- br.x = QFixed::fromReal(br.x.toReal() * hscale);
- br.y = QFixed::fromReal(br.y.toReal() * vscale);
- }
-}
-
-glyph_metrics_t QCoreTextFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, GlyphFormat format)
-{
- if (matrix.type() > QTransform::TxScale)
- return QFontEngine::alphaMapBoundingBox(glyph, subPixelPosition, matrix, format);
-
- glyph_metrics_t br = boundingBox(glyph);
- qcoretextfontengine_scaleMetrics(br, matrix);
-
- // Normalize width and height
- if (br.width < 0)
- br.width = -br.width;
- if (br.height < 0)
- br.height = -br.height;
-
- if (format == QFontEngine::Format_A8 || format == QFontEngine::Format_A32) {
- // Drawing a glyph at x-position 0 with anti-aliasing enabled
- // will potentially fill the pixel to the left of 0, as the
- // coordinates are not aligned to the center of pixels. To
- // prevent clipping of this pixel we need to shift the glyph
- // in the bitmap one pixel to the right. The shift needs to
- // be reflected in the glyph metrics as well, so that the final
- // position of the glyph is correct, which is why doing the
- // shift in imageForGlyph() is not enough.
- br.x -= 1;
-
- // As we've shifted the glyph one pixel to the right, we need
- // to expand the width of the alpha map bounding box as well.
- br.width += 1;
-
- // But we have the same anti-aliasing problem on the right
- // hand side of the glyph, eg. if the width of the glyph
- // results in the bounding rect landing between two pixels.
- // We pad the bounding rect again to account for the possible
- // anti-aliased drawing.
- br.width += 1;
-
- // We also shift the glyph to right right based on the subpixel
- // position, so we pad the bounding box to take account for the
- // subpixel positions that may result in the glyph being drawn
- // one pixel to the right of the 0-subpixel position.
- br.width += 1;
-
- // The same same logic as for the x-position needs to be applied
- // to the y-position, except we don't need to compensate for
- // the subpixel positioning.
- br.y -= 1;
- br.height += 2;
- }
-
- return br;
-}
-
-/*
- Apple has gone through many iterations of its font smoothing algorithms,
- and there are many ways to enable or disable certain aspects of it. As
- keeping up with all the different toggles and behavior differences between
- macOS versions is tricky, we resort to rendering a single glyph in a few
- configurations, picking up the font smoothing algorithm from the observed
- result.
-
- The possible values are:
-
- - Disabled: No font smoothing is applied.
-
- Possibly triggered by the user unchecking the "Use font smoothing when
- available" checkbox in the system preferences or setting AppleFontSmoothing
- to 0. Also controlled by the CGContextSetAllowsFontSmoothing() API,
- which gets its default from the settings above. This API overrides
- the more granular CGContextSetShouldSmoothFonts(), which we use to
- enable (request) or disable font smoothing.
-
- Note that this does not exclude normal antialiasing, controlled by
- the CGContextSetShouldAntialias() API.
-
- - Subpixel: Font smoothing is applied, and affects subpixels.
-
- This was the default mode on macOS versions prior to 10.14 (Mojave).
- The font dilation (stem darkening) parameters were controlled by the
- AppleFontSmoothing setting, ranging from 1 to 3 (light to strong).
-
- On Mojave it is no longer supported, but can be triggered by a legacy
- override (CGFontRenderingFontSmoothingDisabled=NO), so we need to
- still account for it, otherwise users will have a bad time.
-
- - Grayscale: Font smoothing is applied, but does not affect subpixels.
-
- This is the default mode on macOS 10.14 (Mojave). The font dilation
- (stem darkening) parameters are not affected by the AppleFontSmoothing
- setting, but are instead computed based on the fill color used when
- drawing the glyphs (white fill gives a lighter dilation than black
- fill). This affects how we build our glyph cache, since we produce
- alpha maps by drawing white on black.
-*/
-QCoreTextFontEngine::FontSmoothing QCoreTextFontEngine::fontSmoothing()
-{
- static const FontSmoothing cachedFontSmoothing = [] {
- static const int kSize = 10;
- QCFType<CTFontRef> font = CTFontCreateWithName(CFSTR("Helvetica"), kSize, nullptr);
-
- UniChar character('X'); CGGlyph glyph;
- CTFontGetGlyphsForCharacters(font, &character, &glyph, 1);
-
- auto drawGlyph = [&](bool smooth) -> QImage {
- QImage image(kSize, kSize, QImage::Format_RGB32);
- image.fill(0);
-
- QMacCGContext ctx(&image);
- CGContextSetTextDrawingMode(ctx, kCGTextFill);
- CGContextSetGrayFillColor(ctx, 1, 1);
-
- // Will be ignored if CGContextSetAllowsFontSmoothing() has been
- // set to false by CoreGraphics based on user defaults.
- CGContextSetShouldSmoothFonts(ctx, smooth);
-
- CTFontDrawGlyphs(font, &glyph, &CGPointZero, 1, ctx);
- return image;
- };
-
- QImage nonSmoothed = drawGlyph(false);
- QImage smoothed = drawGlyph(true);
-
- FontSmoothing fontSmoothing = FontSmoothing::Disabled;
- [&] {
- for (int x = 0; x < kSize; ++x) {
- for (int y = 0; y < kSize; ++y) {
- QRgb sp = smoothed.pixel(x, y);
- if (qRed(sp) != qGreen(sp) || qRed(sp) != qBlue(sp)) {
- fontSmoothing = FontSmoothing::Subpixel;
- return;
- }
-
- if (sp != nonSmoothed.pixel(x, y))
- fontSmoothing = FontSmoothing::Grayscale;
- }
- }
- }();
-
- auto defaults = [NSUserDefaults standardUserDefaults];
- qCDebug(lcQpaFonts) << "Resolved font smoothing algorithm. Defaults ="
- << [[defaults dictionaryRepresentation] dictionaryWithValuesForKeys:@[
- @"AppleFontSmoothing",
- @"CGFontRenderingFontSmoothingDisabled"
- ]] << "Result =" << fontSmoothing;
-
- return fontSmoothing;
- }();
-
- return cachedFontSmoothing;
-}
-
-bool QCoreTextFontEngine::shouldAntialias() const
-{
- return !(fontDef.styleStrategy & QFont::NoAntialias);
-}
-
-bool QCoreTextFontEngine::shouldSmoothFont() const
-{
- if (hasColorGlyphs())
- return false;
-
- if (!shouldAntialias())
- return false;
-
- switch (fontSmoothing()) {
- case Disabled: return false;
- case Subpixel: return !(fontDef.styleStrategy & QFont::NoSubpixelAntialias);
- case Grayscale: return true;
- }
-
- Q_UNREACHABLE();
-}
-
-bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const
-{
- return shouldSmoothFont() && fontSmoothing() == Subpixel;
-}
-
-qreal QCoreTextFontEngine::fontSmoothingGamma()
-{
- return 2.0;
-}
-
-QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, const QColor &color)
-{
- glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat);
-
- QImage::Format imageFormat = hasColorGlyphs() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
- QImage im(br.width.ceil().toInt(), br.height.ceil().toInt(), imageFormat);
- if (!im.width() || !im.height())
- return im;
-
- QCFType<CGColorSpaceRef> colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
- QCFType<CGContextRef> ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
- 8, im.bytesPerLine(), colorspace,
- qt_mac_bitmapInfoForImage(im));
- Q_ASSERT(ctx);
-
- CGContextSetShouldAntialias(ctx, shouldAntialias());
-
- const bool shouldSmooth = shouldSmoothFont();
- CGContextSetShouldSmoothFonts(ctx, shouldSmooth);
-
-#if defined(Q_OS_MACOS)
- auto glyphColor = [&] {
- if (shouldSmooth && fontSmoothing() == Grayscale) {
- // The grayscale font smoothing algorithm introduced in macOS Mojave (10.14) adjusts
- // its dilation (stem darkening) parameters based on the fill color. This means our
- // default approach of drawing white on black to produce the alpha map will result
- // in non-native looking text when then drawn as black on white during the final blit.
- // As a workaround we use the application's current appearance to decide whether to
- // draw with white or black fill, and then invert the glyph image in the latter case,
- // producing an alpha map. This covers the most common use-cases, but longer term we
- // should propagate the fill color all the way from the paint engine, and include it
- //in the key for the glyph cache.
-
- if (!qt_mac_applicationIsInDarkMode())
- return kCGColorBlack;
- }
- return kCGColorWhite;
- }();
-
- const bool blackOnWhiteGlyphs = glyphColor == kCGColorBlack;
- if (blackOnWhiteGlyphs)
- im.fill(Qt::white);
- else
-#endif
- im.fill(0);
-
- CGContextSetFontSize(ctx, fontDef.pixelSize);
-
- CGAffineTransform cgMatrix = CGAffineTransformIdentity;
-
- if (synthesisFlags & QFontEngine::SynthesizedItalic)
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
-
- if (!hasColorGlyphs()) // CTFontDrawGlyphs incorporates the font's matrix already
- cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
-
- if (matrix.isScaling())
- cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMakeScale(matrix.m11(), matrix.m22()));
-
- CGGlyph cgGlyph = glyph;
- qreal pos_x = -br.x.truncate() + subPixelPosition.toReal();
- qreal pos_y = im.height() + br.y.toReal();
-
- if (!hasColorGlyphs()) {
- CGContextSetTextMatrix(ctx, cgMatrix);
-#if defined(Q_OS_MACOS)
- CGContextSetFillColorWithColor(ctx, CGColorGetConstantColor(glyphColor));
-#else
- CGContextSetRGBFillColor(ctx, 1, 1, 1, 1);
-#endif
- CGContextSetTextDrawingMode(ctx, kCGTextFill);
- CGContextSetTextPosition(ctx, pos_x, pos_y);
-
- CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx);
-
- if (synthesisFlags & QFontEngine::SynthesizedBold) {
- CGContextSetTextPosition(ctx, pos_x + 0.5 * lineThickness().toReal(), pos_y);
- CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx);
- }
- } else {
- CGContextSetRGBFillColor(ctx, color.redF(), color.greenF(), color.blueF(), color.alphaF());
-
- // CGContextSetTextMatrix does not work with color glyphs, so we use
- // the CTM instead. This means we must translate the CTM as well, to
- // set the glyph position, instead of using CGContextSetTextPosition.
- CGContextTranslateCTM(ctx, pos_x, pos_y);
- CGContextConcatCTM(ctx, cgMatrix);
-
- // CGContextShowGlyphsWithAdvances does not support the 'sbix' color-bitmap
- // glyphs in the Apple Color Emoji font, so we use CTFontDrawGlyphs instead.
- CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx);
- }
-
- if (expectsGammaCorrectedBlending())
- qGamma_correct_back_to_linear_cs(&im);
-
-#if defined(Q_OS_MACOS)
- if (blackOnWhiteGlyphs)
- im.invertPixels();
-#endif
-
- return im;
-}
-
-QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition)
-{
- return alphaMapForGlyph(glyph, subPixelPosition, QTransform());
-}
-
-QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &x)
-{
- if (x.type() > QTransform::TxScale)
- return QFontEngine::alphaMapForGlyph(glyph, subPixelPosition, x);
-
- QImage im = imageForGlyph(glyph, subPixelPosition, x);
-
- QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8);
-
- for (int y=0; y<im.height(); ++y) {
- uint *src = (uint*) im.scanLine(y);
- uchar *dst = alphaMap.scanLine(y);
- for (int x=0; x<im.width(); ++x) {
- *dst = qGray(*src);
- ++dst;
- ++src;
- }
- }
-
- return alphaMap;
-}
-
-QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &x)
-{
- if (x.type() > QTransform::TxScale)
- return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, x);
-
- return imageForGlyph(glyph, subPixelPosition, x);
-}
-
-QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t, const QColor &color)
-{
- if (t.type() > QTransform::TxScale)
- return QFontEngine::bitmapForGlyph(glyph, subPixelPosition, t, color);
-
- return imageForGlyph(glyph, subPixelPosition, t, color);
-}
-
-void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const
-{
- Q_UNUSED(flags);
-
- const int numGlyphs = glyphs->numGlyphs;
- QVarLengthArray<CGGlyph> cgGlyphs(numGlyphs);
-
- for (int i = 0; i < numGlyphs; ++i) {
- Q_ASSERT(!QFontEngineMulti::highByte(glyphs->glyphs[i]));
- cgGlyphs[i] = glyphs->glyphs[i];
- }
-
- loadAdvancesForGlyphs(cgGlyphs, glyphs);
-}
-
-void QCoreTextFontEngine::loadAdvancesForGlyphs(QVarLengthArray<CGGlyph> &cgGlyphs, QGlyphLayout *glyphs) const
-{
- const int numGlyphs = glyphs->numGlyphs;
- QVarLengthArray<CGSize> advances(numGlyphs);
- CTFontGetAdvancesForGlyphs(ctfont, kCTFontOrientationHorizontal, cgGlyphs.data(), advances.data(), numGlyphs);
-
- for (int i = 0; i < numGlyphs; ++i) {
- QFixed advance = QFixed::fromReal(advances[i].width);
- glyphs->advances[i] = fontDef.styleStrategy & QFont::ForceIntegerMetrics
- ? advance.round() : advance;
- }
-}
-
-QFontEngine::FaceId QCoreTextFontEngine::faceId() const
-{
- return face_id;
-}
-
-bool QCoreTextFontEngine::canRender(const QChar *string, int len) const
-{
- QVarLengthArray<CGGlyph> cgGlyphs(len);
- return CTFontGetGlyphsForCharacters(ctfont, (const UniChar *) string, cgGlyphs.data(), len);
-}
-
-bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
-{
- return ct_getSfntTable((void *)&ctfont, tag, buffer, length);
-}
-
-void QCoreTextFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metric)
-{
- CGAffineTransform cgMatrix = CGAffineTransformIdentity;
-
- qreal emSquare = CTFontGetUnitsPerEm(ctfont);
- qreal scale = emSquare / CTFontGetSize(ctfont);
- cgMatrix = CGAffineTransformScale(cgMatrix, scale, -scale);
-
- QCFType<CGPathRef> cgpath = CTFontCreatePathForGlyph(ctfont, (CGGlyph) glyph, &cgMatrix);
- ConvertPathInfo info(path, QPointF(0,0));
- CGPathApply(cgpath, &info, convertCGPathToQPainterPath);
-
- *metric = boundingBox(glyph);
- // scale the metrics too
- metric->width = QFixed::fromReal(metric->width.toReal() * scale);
- metric->height = QFixed::fromReal(metric->height.toReal() * scale);
- metric->x = QFixed::fromReal(metric->x.toReal() * scale);
- metric->y = QFixed::fromReal(metric->y.toReal() * scale);
- metric->xoff = QFixed::fromReal(metric->xoff.toReal() * scale);
- metric->yoff = QFixed::fromReal(metric->yoff.toReal() * scale);
-}
-
-QFixed QCoreTextFontEngine::emSquareSize() const
-{
- return QFixed(int(CTFontGetUnitsPerEm(ctfont)));
-}
-
-QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const
-{
- QFontDef newFontDef = fontDef;
- newFontDef.pixelSize = pixelSize;
- newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
-
- return new QCoreTextFontEngine(cgFont, newFontDef);
-}
-
-Qt::HANDLE QCoreTextFontEngine::handle() const
-{
- return (Qt::HANDLE)(static_cast<CTFontRef>(ctfont));
-}
-
-bool QCoreTextFontEngine::supportsTransformation(const QTransform &transform) const
-{
- if (transform.type() < QTransform::TxScale)
- return true;
- else if (transform.type() == QTransform::TxScale &&
- transform.m11() >= 0 && transform.m22() >= 0)
- return true;
- else
- return false;
-}
-
-QFixed QCoreTextFontEngine::lineThickness() const
-{
- return underlineThickness;
-}
-
-QFixed QCoreTextFontEngine::underlinePosition() const
-{
- return underlinePos;
-}
-
-QFontEngine::Properties QCoreTextFontEngine::properties() const
-{
- Properties result;
-
- QCFString psName, copyright;
- psName = CTFontCopyPostScriptName(ctfont);
- copyright = CTFontCopyName(ctfont, kCTFontCopyrightNameKey);
- result.postscriptName = QString::fromCFString(psName).toUtf8();
- result.copyright = QString::fromCFString(copyright).toUtf8();
-
- qreal emSquare = CTFontGetUnitsPerEm(ctfont);
- qreal scale = emSquare / CTFontGetSize(ctfont);
-
- CGRect cgRect = CTFontGetBoundingBox(ctfont);
- result.boundingBox = QRectF(cgRect.origin.x * scale,
- -CTFontGetAscent(ctfont) * scale,
- cgRect.size.width * scale,
- cgRect.size.height * scale);
-
- result.emSquare = emSquareSize();
- result.ascent = QFixed::fromReal(CTFontGetAscent(ctfont) * scale);
- result.descent = QFixed::fromReal(CTFontGetDescent(ctfont) * scale);
- result.leading = QFixed::fromReal(CTFontGetLeading(ctfont) * scale);
- result.italicAngle = QFixed::fromReal(CTFontGetSlantAngle(ctfont));
- result.capHeight = QFixed::fromReal(CTFontGetCapHeight(ctfont) * scale);
- result.lineWidth = QFixed::fromReal(CTFontGetUnderlineThickness(ctfont) * scale);
-
- if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- result.ascent = result.ascent.round();
- result.descent = result.descent.round();
- result.leading = result.leading.round();
- result.italicAngle = result.italicAngle.round();
- result.capHeight = result.capHeight.round();
- result.lineWidth = result.lineWidth.round();
- }
-
- return result;
-}
-
-void QCoreTextFontEngine::doKerning(QGlyphLayout *g, ShaperFlags flags) const
-{
- if (!kerningPairsLoaded) {
- kerningPairsLoaded = true;
- qreal emSquare = CTFontGetUnitsPerEm(ctfont);
- qreal scale = emSquare / CTFontGetSize(ctfont);
-
- const_cast<QCoreTextFontEngine *>(this)->loadKerningPairs(QFixed::fromReal(scale));
- }
-
- QFontEngine::doKerning(g, flags);
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
deleted file mode 100644
index 51d839688d..0000000000
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
+++ /dev/null
@@ -1,161 +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 QFONTENGINE_CORETEXT_P_H
-#define QFONTENGINE_CORETEXT_P_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 <private/qfontengine_p.h>
-#include <private/qcore_mac_p.h>
-#include <QtCore/qloggingcategory.h>
-
-#ifdef Q_OS_OSX
-#include <ApplicationServices/ApplicationServices.h>
-#else
-#include <CoreText/CoreText.h>
-#include <CoreGraphics/CoreGraphics.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts)
-
-class QCoreTextFontEngine : public QFontEngine
-{
- Q_GADGET
-
-public:
- QCoreTextFontEngine(CTFontRef font, const QFontDef &def);
- QCoreTextFontEngine(CGFontRef font, const QFontDef &def);
- ~QCoreTextFontEngine();
-
- glyph_t glyphIndex(uint ucs4) const override;
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override;
- void recalcAdvances(QGlyphLayout *, ShaperFlags) const override;
-
- glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
- glyph_metrics_t boundingBox(glyph_t glyph) override;
-
- QFixed ascent() const override;
- QFixed capHeight() const override;
- QFixed descent() const override;
- QFixed leading() const override;
- QFixed xHeight() const override;
- qreal maxCharWidth() const override;
- QFixed averageCharWidth() const override;
-
- void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs,
- QPainterPath *path, QTextItem::RenderFlags) override;
-
- bool canRender(const QChar *string, int len) const override;
-
- int synthesized() const override { return synthesisFlags; }
- bool supportsSubPixelPositions() const override { return true; }
-
- QFixed lineThickness() const override;
- QFixed underlinePosition() const override;
-
- void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight);
-
- FaceId faceId() const override;
- bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const override;
- void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) override;
- QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition) override;
- QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override;
- QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override;
- glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) override;
- QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override;
- QFixed emSquareSize() const override;
- void doKerning(QGlyphLayout *g, ShaperFlags flags) const override;
-
- bool supportsTransformation(const QTransform &transform) const override;
- bool expectsGammaCorrectedBlending() const override;
-
- QFontEngine *cloneWithSize(qreal pixelSize) const override;
- Qt::HANDLE handle() const override;
- int glyphMargin(QFontEngine::GlyphFormat format) override { Q_UNUSED(format); return 0; }
-
- QFontEngine::Properties properties() const override;
-
- enum FontSmoothing { Disabled, Subpixel, Grayscale };
- Q_ENUM(FontSmoothing);
-
- static FontSmoothing fontSmoothing();
- static qreal fontSmoothingGamma();
-
- static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length);
- static QFont::Weight qtWeightFromCFWeight(float value);
-
- static QCoreTextFontEngine *create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
-
-protected:
- QCoreTextFontEngine(const QFontDef &def);
- void init();
- QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &m, const QColor &color = QColor());
- void loadAdvancesForGlyphs(QVarLengthArray<CGGlyph> &cgGlyphs, QGlyphLayout *glyphs) const;
- bool hasColorGlyphs() const;
- bool shouldAntialias() const;
- bool shouldSmoothFont() const;
-
- QCFType<CTFontRef> ctfont;
- QCFType<CGFontRef> cgFont;
- int synthesisFlags;
- CGAffineTransform transform;
- QFixed avgCharWidth;
- QFixed underlineThickness;
- QFixed underlinePos;
- QFontEngine::FaceId face_id;
- mutable bool kerningPairsLoaded;
-};
-
-CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
-
-QT_END_NAMESPACE
-
-#endif // QFONTENGINE_CORETEXT_P_H
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
deleted file mode 100644
index 36a94724c1..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
+++ /dev/null
@@ -1,2087 +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_p.h"
-#include "qwindowsfontdatabase_ft_p.h" // for default font
-#include "qwindowsfontengine_p.h"
-#include "qwindowsfontenginedirectwrite_p.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 <QtCore/private/qwinregistry_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
-
-Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
-
-#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()
-{
- QSystemLibrary library(QStringLiteral("dwrite"));
- QFunctionPointer result = library.resolve("DWriteCreateFactory");
- if (Q_UNLIKELY(!result)) {
- qWarning("Unable to load dwrite.dll");
- return nullptr;
- }
- return reinterpret_cast<DWriteCreateFactoryType>(result);
-}
-
-static void createDirectWriteFactory(IDWriteFactory **factory)
-{
- *factory = 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 = QWindowsFontDatabase::fontOptions();
- if (Q_UNLIKELY(options & QWindowsFontDatabase::DontUseDirectWriteFonts))
- return false;
-
- // 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;
-
- if (isColorFont)
- return (options & QWindowsFontDatabase::DontUseColorFonts) == 0;
-
- return hintingPreference == QFont::PreferNoHinting
- || hintingPreference == QFont::PreferVerticalHinting
- || (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting);
-}
-#endif // !QT_NO_DIRECTWRITE
-
-// Helper classes for creating font engines directly from font data
-namespace {
-
-# pragma pack(1)
-
- // Common structure for all formats of the "name" table
- struct NameTable
- {
- quint16 format;
- quint16 count;
- quint16 stringOffset;
- };
-
- struct NameRecord
- {
- quint16 platformID;
- quint16 encodingID;
- quint16 languageID;
- quint16 nameID;
- quint16 length;
- quint16 offset;
- };
-
- struct OffsetSubTable
- {
- quint32 scalerType;
- quint16 numTables;
- quint16 searchRange;
- quint16 entrySelector;
- quint16 rangeShift;
- };
-
- struct TableDirectory
- {
- quint32 identifier;
- quint32 checkSum;
- quint32 offset;
- quint32 length;
- };
-
- struct OS2Table
- {
- quint16 version;
- qint16 avgCharWidth;
- quint16 weightClass;
- quint16 widthClass;
- quint16 type;
- qint16 subscriptXSize;
- qint16 subscriptYSize;
- qint16 subscriptXOffset;
- qint16 subscriptYOffset;
- qint16 superscriptXSize;
- qint16 superscriptYSize;
- qint16 superscriptXOffset;
- qint16 superscriptYOffset;
- qint16 strikeOutSize;
- qint16 strikeOutPosition;
- qint16 familyClass;
- quint8 panose[10];
- quint32 unicodeRanges[4];
- quint8 vendorID[4];
- quint16 selection;
- quint16 firstCharIndex;
- quint16 lastCharIndex;
- qint16 typoAscender;
- qint16 typoDescender;
- qint16 typoLineGap;
- quint16 winAscent;
- quint16 winDescent;
- quint32 codepageRanges[2];
- qint16 height;
- qint16 capHeight;
- quint16 defaultChar;
- quint16 breakChar;
- quint16 maxContext;
- };
-
-# pragma pack()
-
- class EmbeddedFont
- {
- public:
- EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) {}
-
- QString changeFamilyName(const QString &newFamilyName);
- QByteArray data() const { return m_fontData; }
- TableDirectory *tableDirectoryEntry(const QByteArray &tagName);
- QString familyName(TableDirectory *nameTableDirectory = 0);
-
- private:
- QByteArray m_fontData;
- };
-
- TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName)
- {
- Q_ASSERT(tagName.size() == 4);
- quint32 tagId = *(reinterpret_cast<const quint32 *>(tagName.constData()));
- const size_t fontDataSize = m_fontData.size();
- if (Q_UNLIKELY(fontDataSize < sizeof(OffsetSubTable)))
- return 0;
-
- OffsetSubTable *offsetSubTable = reinterpret_cast<OffsetSubTable *>(m_fontData.data());
- TableDirectory *tableDirectory = reinterpret_cast<TableDirectory *>(offsetSubTable + 1);
-
- const size_t tableCount = qFromBigEndian<quint16>(offsetSubTable->numTables);
- if (Q_UNLIKELY(fontDataSize < sizeof(OffsetSubTable) + sizeof(TableDirectory) * tableCount))
- return 0;
-
- TableDirectory *tableDirectoryEnd = tableDirectory + tableCount;
- for (TableDirectory *entry = tableDirectory; entry < tableDirectoryEnd; ++entry) {
- if (entry->identifier == tagId)
- return entry;
- }
-
- return 0;
- }
-
- QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry)
- {
- QString name;
-
- if (nameTableDirectoryEntry == 0)
- nameTableDirectoryEntry = tableDirectoryEntry("name");
-
- if (nameTableDirectoryEntry != 0) {
- quint32 offset = qFromBigEndian<quint32>(nameTableDirectoryEntry->offset);
- if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameTable)))
- return QString();
-
- NameTable *nameTable = reinterpret_cast<NameTable *>(m_fontData.data() + offset);
- NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
-
- quint16 nameTableCount = qFromBigEndian<quint16>(nameTable->count);
- if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + sizeof(NameRecord) * nameTableCount))
- return QString();
-
- for (int i = 0; i < nameTableCount; ++i, ++nameRecord) {
- if (qFromBigEndian<quint16>(nameRecord->nameID) == 1
- && qFromBigEndian<quint16>(nameRecord->platformID) == 3 // Windows
- && qFromBigEndian<quint16>(nameRecord->languageID) == 0x0409) { // US English
- quint16 stringOffset = qFromBigEndian<quint16>(nameTable->stringOffset);
- quint16 nameOffset = qFromBigEndian<quint16>(nameRecord->offset);
- quint16 nameLength = qFromBigEndian<quint16>(nameRecord->length);
-
- if (Q_UNLIKELY(quint32(m_fontData.size()) < offset + stringOffset + nameOffset + nameLength))
- return QString();
-
- const void *ptr = reinterpret_cast<const quint8 *>(nameTable)
- + stringOffset
- + nameOffset;
-
- const quint16 *s = reinterpret_cast<const quint16 *>(ptr);
- const quint16 *e = s + nameLength / sizeof(quint16);
- while (s != e)
- name += QChar( qFromBigEndian<quint16>(*s++));
- break;
- }
- }
- }
-
- return name;
- }
-
- QString EmbeddedFont::changeFamilyName(const QString &newFamilyName)
- {
- TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name");
- if (nameTableDirectoryEntry == 0)
- return QString();
-
- QString oldFamilyName = familyName(nameTableDirectoryEntry);
-
- // Reserve size for name table header, five required name records and string
- const int requiredRecordCount = 5;
- quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 };
-
- int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount;
- int newFamilyNameSize = newFamilyName.size() * int(sizeof(quint16));
-
- const QString regularString = QString::fromLatin1("Regular");
- int regularStringSize = regularString.size() * int(sizeof(quint16));
-
- // Align table size of table to 32 bits (pad with 0)
- int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4;
-
- QByteArray newNameTable(fullSize, char(0));
-
- {
- NameTable *nameTable = reinterpret_cast<NameTable *>(newNameTable.data());
- nameTable->count = qbswap<quint16>(requiredRecordCount);
- nameTable->stringOffset = qbswap<quint16>(sizeOfHeader);
-
- NameRecord *nameRecord = reinterpret_cast<NameRecord *>(nameTable + 1);
- for (int i = 0; i < requiredRecordCount; ++i, nameRecord++) {
- nameRecord->nameID = qbswap<quint16>(nameIds[i]);
- nameRecord->encodingID = qbswap<quint16>(1);
- nameRecord->languageID = qbswap<quint16>(0x0409);
- nameRecord->platformID = qbswap<quint16>(3);
- nameRecord->length = qbswap<quint16>(newFamilyNameSize);
-
- // Special case for sub-family
- if (nameIds[i] == 4) {
- nameRecord->offset = qbswap<quint16>(newFamilyNameSize);
- nameRecord->length = qbswap<quint16>(regularStringSize);
- }
- }
-
- // nameRecord now points to string data
- quint16 *stringStorage = reinterpret_cast<quint16 *>(nameRecord);
- const quint16 *sourceString = newFamilyName.utf16();
- for (int i = 0; i < newFamilyName.size(); ++i)
- stringStorage[i] = qbswap<quint16>(sourceString[i]);
- stringStorage += newFamilyName.size();
-
- sourceString = regularString.utf16();
- for (int i = 0; i < regularString.size(); ++i)
- stringStorage[i] = qbswap<quint16>(sourceString[i]);
- }
-
- quint32 *p = reinterpret_cast<quint32 *>(newNameTable.data());
- quint32 *tableEnd = reinterpret_cast<quint32 *>(newNameTable.data() + fullSize);
-
- quint32 checkSum = 0;
- while (p < tableEnd)
- checkSum += qFromBigEndian<quint32>(*(p++));
-
- nameTableDirectoryEntry->checkSum = qbswap<quint32>(checkSum);
- nameTableDirectoryEntry->offset = qbswap<quint32>(m_fontData.size());
- nameTableDirectoryEntry->length = qbswap<quint32>(fullSize);
-
- m_fontData.append(newNameTable);
-
- return oldFamilyName;
- }
-
-#if !defined(QT_NO_DIRECTWRITE)
-
- class DirectWriteFontFileStream: public IDWriteFontFileStream
- {
- Q_DISABLE_COPY(DirectWriteFontFileStream)
- 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;
- auto it = m_fontDatas.constFind(key);
- if (it == m_fontDatas.constEnd())
- return E_FAIL;
-
- QByteArray fontData = it.value();
- DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData);
- stream->AddRef();
- *fontFileStream = stream;
-
- return S_OK;
- }
-
- class CustomFontFileLoader
- {
- public:
- CustomFontFileLoader() : m_directWriteFontFileLoader(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()
- : fontSmoothingGamma(QWindowsFontDatabase::fontSmoothingGamma())
-{
- // 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);
-}
-
-unsigned QWindowsFontDatabase::m_fontOptions = 0;
-
-void QWindowsFontDatabase::setFontOptions(unsigned options)
-{
- m_fontOptions = options & (QWindowsFontDatabase::DontUseDirectWriteFonts |
- QWindowsFontDatabase::DontUseColorFonts);
-}
-
-unsigned QWindowsFontDatabase::fontOptions()
-{
- return m_fontOptions;
-}
-
-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 qt_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;
-}
-
-namespace {
-
-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] = qt_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
-};
-
-QFontNames qt_getCanonicalFontNames(const uchar *table, quint32 bytes)
-{
- QFontNames 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 (qt_getUShort(table) != 0)
- return out;
-
- count = qt_getUShort(table + 2);
- string_offset = qt_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 = qt_getUShort(names + i*NameRecordSize);
- quint16 encoding_id = qt_getUShort(names + 2 + i*NameRecordSize);
- quint16 language_id = qt_getUShort(names + 4 + i*NameRecordSize);
- quint16 name_id = qt_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 = qt_getUShort(names + 8 + i*NameRecordSize);
- quint16 offset = qt_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 = qt_getUShort(names + 8 + id * NameRecordSize);
- quint16 offset = qt_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 qt_getEnglishName(const QString &familyName, bool includeStyle)
-{
- 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 QFontNames names = qt_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;
-}
-
-// Note this duplicates parts of qt_getEnglishName, we should try to unify the two functions.
-QFontNames qt_getCanonicalFontNames(const LOGFONT &lf)
-{
- QFontNames fontNames;
- HDC hdc = GetDC(0);
- HFONT hfont = CreateFontIndirect(&lf);
-
- if (!hfont) {
- ReleaseDC(0, hdc);
- return fontNames;
- }
-
- HGDIOBJ oldobj = SelectObject(hdc, hfont);
-
- // get the name table
- QByteArray table;
- const DWORD name_tag = MAKE_TAG('n', 'a', 'm', 'e');
- DWORD bytes = GetFontData(hdc, name_tag, 0, 0, 0);
- if (bytes != GDI_ERROR) {
- table.resize(bytes);
-
- if (GetFontData(hdc, name_tag, 0, table.data(), bytes) != GDI_ERROR)
- fontNames = qt_getCanonicalFontNames(reinterpret_cast<const uchar*>(table.constData()), bytes);
- }
-
- SelectObject(hdc, oldobj);
- DeleteObject(hfont);
- ReleaseDC(0, hdc);
-
- return fontNames;
-}
-
-static QChar *createFontFile(const QString &faceName)
-{
- QChar *faceNamePtr = nullptr;
- if (!faceName.isEmpty()) {
- const int nameLength = qMin(faceName.length(), LF_FACESIZE - 1);
- faceNamePtr = new QChar[nameLength + 1];
- memcpy(static_cast<void *>(faceNamePtr), faceName.utf16(), sizeof(wchar_t) * nameLength);
- faceNamePtr[nameLength] = 0;
- }
- return faceNamePtr;
-}
-
-namespace {
- struct StoreFontPayload {
- StoreFontPayload(const QString &family,
- QWindowsFontDatabase *fontDatabase)
- : populatedFontFamily(family)
- , windowsFontDatabase(fontDatabase)
- {}
-
- QString populatedFontFamily;
- QSet<QPair<QString,QString> > foundFontAndStyles;
- QWindowsFontDatabase *windowsFontDatabase;
- };
-}
-
-static bool addFontToDatabase(QString familyName,
- QString styleName,
- const LOGFONT &logFont,
- const TEXTMETRIC *textmetric,
- const FONTSIGNATURE *signature,
- int type,
- StoreFontPayload *sfp)
-{
- // the "@family" fonts are just the same as "family". Ignore them.
- if (familyName.isEmpty() || familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QLatin1String("WST_")))
- return false;
-
- uchar charSet = logFont.lfCharSet;
-
- 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 (lcQpaFonts().isDebugEnabled()) {
- 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;
- QString faceName;
-
- QString subFamilyName;
- QString subFamilyStyle;
- // Look-up names registered in the font
- QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
- if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
- englishName = canonicalNames.name;
- if (!canonicalNames.preferredName.isEmpty()) {
- subFamilyName = familyName;
- subFamilyStyle = styleName;
- faceName = familyName; // Remember the original name for later lookups
- familyName = canonicalNames.preferredName;
- styleName = canonicalNames.preferredStyle;
- }
-
- 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);
- }
-
- // We came here from populating a different font family, so we have
- // to ensure the entire typographic family is populated before we
- // mark it as such inside registerFont()
- if (!subFamilyName.isEmpty()
- && familyName != subFamilyName
- && sfp->populatedFontFamily != familyName
- && !QPlatformFontDatabase::isFamilyPopulated(familyName)) {
- sfp->windowsFontDatabase->populateFamily(familyName);
- }
-
- QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight,
- style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName));
-
- // 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, createFontFile(faceName));
- if (style != QFont::StyleItalic && styleName.isEmpty())
- QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, weight,
- QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName));
- if (weight <= QFont::DemiBold && style != QFont::StyleItalic && styleName.isEmpty())
- QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold,
- QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName));
-
- if (!subFamilyName.isEmpty() && familyName != subFamilyName) {
- QPlatformFontDatabase::registerFont(subFamilyName, subFamilyStyle, foundryName, weight,
- style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName));
- }
-
- if (!englishName.isEmpty() && englishName != familyName)
- 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);
-
- // 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 = nullptr;
- StoreFontPayload *sfp = reinterpret_cast<StoreFontPayload *>(lparam);
- Q_ASSERT(sfp != nullptr);
- if (type & TRUETYPE_FONTTYPE) {
- signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig;
- // We get a callback for each script-type supported, but we register them all
- // at once using the signature, so we only need one call to addFontToDatabase().
- QPair<QString,QString> fontAndStyle(familyName, styleName);
- if (sfp->foundFontAndStyles.contains(fontAndStyle))
- return 1;
- sfp->foundFontAndStyles.insert(fontAndStyle);
- }
- addFontToDatabase(familyName, styleName, *logFont, textmetric, signature, type, sfp);
-
- // keep on enumerating
- return 1;
-}
-
-void QWindowsFontDatabase::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;
- StoreFontPayload sfp(familyName, this);
- EnumFontFamiliesEx(dummy, &lf, storeFont, reinterpret_cast<intptr_t>(&sfp), 0);
- ReleaseDC(0, dummy);
-}
-
-static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
- DWORD, 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);
- // Register current font's english name as alias
- const bool ttf = (textmetric->tmPitchAndFamily & TMPF_TRUETYPE);
- if (ttf && qt_localizedName(faceName)) {
- const QString englishName = qt_getEnglishName(faceName);
- if (!englishName.isEmpty())
- QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName);
- }
- }
- return 1; // continue
-}
-
-void QWindowsFontDatabase::addDefaultEUDCFont()
-{
- const QString path = QWinRegistryKey(HKEY_CURRENT_USER, LR"(EUDC\1252)")
- .stringValue(L"SystemDefaultEUDCFont");
- if (!path.isEmpty()) {
- QFile file(path);
- if (!file.open(QIODevice::ReadOnly)) {
- qCWarning(lcQpaFonts) << "Unable to open default EUDC font:" << path;
- return;
- }
-
- m_eudcFonts = addApplicationFont(file.readAll(), path);
- }
-}
-
-void QWindowsFontDatabase::populateFontDatabase()
-{
- removeApplicationFonts();
- HDC dummy = GetDC(0);
- LOGFONT lf;
- lf.lfCharSet = DEFAULT_CHARSET;
- lf.lfFaceName[0] = 0;
- lf.lfPitchAndFamily = 0;
- EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, 0, 0);
- ReleaseDC(0, dummy);
- // Work around EnumFontFamiliesEx() not listing the system font.
- QString systemDefaultFamily = QWindowsFontDatabase::systemDefaultFont().family();
- if (QPlatformFontDatabase::resolveFontFamilyAlias(systemDefaultFamily) == systemDefaultFamily)
- QPlatformFontDatabase::registerFontFamily(systemDefaultFamily);
- addDefaultEUDCFont();
-}
-
-typedef QSharedPointer<QWindowsFontEngineData> QWindowsFontEngineDataPtr;
-
-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();
-}
-
-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;
- }
-}
-
-QWindowsFontDatabase::~QWindowsFontDatabase()
-{
- removeApplicationFonts();
-}
-
-QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
-{
- const QString faceName(static_cast<const QChar*>(handle));
- QFontEngine *fe = QWindowsFontDatabase::createEngine(fontDef, faceName,
- defaultVerticalDPI(),
- 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, QString(),
- defaultVerticalDPI(),
- 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.loadRelaxed() == 0)
- delete fontEngine;
- fontEngine = 0;
- } else {
- Q_ASSERT(fontEngine->ref.loadRelaxed() == 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 << 0);
- bool oblique = qFromBigEndian<quint16>(os2Table->selection) & (1 << 9);
-
- 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<QFontNames> *families,
- QVector<FONTSIGNATURE> *signatures,
- QVector<QFontValues> *values)
-{
- 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;
- QFontNames names = qt_getCanonicalFontNames(table, length);
- if (names.name.isEmpty())
- continue;
-
- families->append(std::move(names));
-
- if (values || signatures)
- getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length);
-
- if (values) {
- QFontValues fontValues;
- if (table && length >= 64) {
- // Read in some details about the font, offset calculated based on the specification
- fontValues.weight = qFromBigEndian<quint16>(table + 4);
-
- quint16 fsSelection = qFromBigEndian<quint16>(table + 62);
- fontValues.isItalic = (fsSelection & 1) != 0;
- fontValues.isUnderlined = (fsSelection & (1 << 1)) != 0;
- fontValues.isOverstruck = (fsSelection & (1 << 4)) != 0;
- }
- values->append(std::move(fontValues));
- }
-
- if (signatures) {
- FONTSIGNATURE signature;
- 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;
- QVector<QFontValues> fontValues;
- QList<QFontNames> families;
- QStringList familyNames;
-
- if (!fontData.isEmpty()) {
- getFamiliesAndSignatures(fontData, &families, &signatures, &fontValues);
- 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 auto &family = families.at(j);
- const QString &familyName = family.name;
- const QString &styleName = family.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;
- const QFontValues &values = fontValues.at(j);
- lf.lfWeight = values.weight;
- if (values.isItalic)
- lf.lfItalic = TRUE;
- if (values.isOverstruck)
- lf.lfStrikeOut = TRUE;
- if (values.isUnderlined)
- lf.lfUnderline = TRUE;
- HFONT hfont = CreateFontIndirect(&lf);
- HGDIOBJ oldobj = SelectObject(hdc, hfont);
-
- TEXTMETRIC textMetrics;
- GetTextMetrics(hdc, &textMetrics);
-
- StoreFontPayload sfp(familyName, this);
- addFontToDatabase(familyName, styleName, lf, &textMetrics, &signatures.at(j),
- TRUETYPE_FONTTYPE, &sfp);
-
- 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, nullptr, nullptr);
- 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);
- }
- }
-
- m_applicationFonts << font;
-
- return familyNames;
-}
-
-void QWindowsFontDatabase::removeApplicationFonts()
-{
- for (const WinApplicationFont &font : qAsConst(m_applicationFonts)) {
- if (font.handle) {
- RemoveFontMemResourceEx(font.handle);
- } else {
- RemoveFontResourceExW(reinterpret_cast<LPCWSTR>(font.fileName.utf16()),
- FR_PRIVATE, nullptr);
- }
- }
- m_applicationFonts.clear();
- m_eudcFonts.clear();
-}
-
-void QWindowsFontDatabase::releaseHandle(void *handle)
-{
- const QChar *faceName = reinterpret_cast<const QChar *>(handle);
- delete[] faceName;
-}
-
-QString QWindowsFontDatabase::fontDir() const
-{
- const QString result = QPlatformFontDatabase::fontDir();
- qCDebug(lcQpaFonts) << __FUNCTION__ << result;
- return result;
-}
-
-bool QWindowsFontDatabase::fontsAlwaysScalable() const
-{
- return false;
-}
-
-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();
-}
-
-// ### fixme Qt 6 (QTBUG-58610): See comment at QWindowsFontDatabase::systemDefaultFont()
-HFONT QWindowsFontDatabase::systemFont()
-{
- static const auto stock_sysfont =
- reinterpret_cast<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, const QString &faceName)
-{
- 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) {
- qual = (request.styleStrategy & QFont::NoSubpixelAntialias) == 0
- ? CLEARTYPE_QUALITY : 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 = faceName;
- if (fam.isEmpty())
- fam = request.families.size() > 0 ? request.families.at(0) : 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(m_eudcFonts);
- 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, const QString &faceName,
- int dpi,
- const QSharedPointer<QWindowsFontEngineData> &data)
-{
- QFontEngine *fe = 0;
-
- LOGFONT lf = fontDefToLOGFONT(request, faceName);
- 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);
-
- const QFont::HintingPreference hintingPreference =
- static_cast<QFont::HintingPreference>(request.hintingPreference);
- bool useDw = useDirectWrite(hintingPreference, fam);
-
- IDWriteFontFace *directWriteFontFace = NULL;
- HRESULT hr = data->directWriteGdiInterop->CreateFontFaceFromHdc(data->hdc, &directWriteFontFace);
- if (SUCCEEDED(hr)) {
- bool isColorFont = false;
-#if defined(QT_USE_DIRECTWRITE2)
- IDWriteFontFace2 *directWriteFontFace2 = nullptr;
- if (SUCCEEDED(directWriteFontFace->QueryInterface(__uuidof(IDWriteFontFace2),
- reinterpret_cast<void **>(&directWriteFontFace2)))) {
- if (directWriteFontFace2->IsColorFont())
- isColorFont = directWriteFontFace2->GetPaletteEntryCount() > 0;
- }
-#endif
- useDw = 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();
- }
- } else if (useDw) {
- const QString errorString = qt_error_string(int(hr));
- qWarning().noquote().nospace() << "DirectWrite: CreateFontFaceFromHDC() failed ("
- << errorString << ") for " << request << ' ' << lf << " dpi=" << dpi;
- }
-
- 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;
-}
-
-QFont QWindowsFontDatabase::systemDefaultFont()
-{
-#if QT_VERSION >= 0x060000
- // Qt 6: Obtain default GUI font (typically "Segoe UI, 9pt", see QTBUG-58610)
- NONCLIENTMETRICS ncm;
- ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
- const QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont);
-#else
- 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"));
- // Qt 5 by (Qt 4) legacy uses GetStockObject(DEFAULT_GUI_FONT) to
- // obtain the default GUI font (typically "MS Shell Dlg 2, 8pt"). This has been
- // long deprecated; the message font of the NONCLIENTMETRICS structure obtained by
- // SystemParametersInfo(SPI_GETNONCLIENTMETRICS) should be used instead (see
- // QWindowsTheme::refreshFonts(), typically "Segoe UI, 9pt"), which is larger.
-#endif // Qt 5
- qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont;
- return systemFont;
-}
-
-QFont QWindowsFontDatabase::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
-{
- if (verticalDPI_In <= 0)
- verticalDPI_In = defaultVerticalDPI();
- 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;
-}
-
-int QWindowsFontDatabase::defaultVerticalDPI()
-{
- static int vDPI = -1;
- if (vDPI == -1) {
- if (HDC defaultDC = GetDC(0)) {
- vDPI = GetDeviceCaps(defaultDC, LOGPIXELSY);
- ReleaseDC(0, defaultDC);
- } else {
- // FIXME: Resolve now or return 96 and keep unresolved?
- vDPI = 96;
- }
- }
- return vDPI;
-}
-
-bool QWindowsFontDatabase::isPrivateFontFamily(const QString &family) const
-{
- return m_eudcFonts.contains(family) || QPlatformFontDatabase::isPrivateFontFamily(family);
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
deleted file mode 100644
index 5c2742d295..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp
+++ /dev/null
@@ -1,446 +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_p.h"
-#include "qwindowsfontdatabase_p.h"
-
-#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h>
-
-#include <ft2build.h>
-#include FT_TRUETYPE_TABLES_H
-
-#include <QtCore/QDir>
-#include <QtCore/QDirIterator>
-#include <QtCore/QSettings>
-#if QT_CONFIG(regularexpression)
-#include <QtCore/QRegularExpression>
-#else
-#include <QtCore/QRegExp>
-#endif
-#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;
-}
-
-namespace {
-struct FontKey
-{
- QString fileName;
- QStringList fontNames;
-};
-} // namespace
-
-typedef QVector<FontKey> FontKeys;
-
-static FontKeys &fontKeys()
-{
- static FontKeys result;
- if (result.isEmpty()) {
- const QStringList keys = { QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"),
- QStringLiteral("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts") };
- for (const auto key : keys) {
- const QSettings fontRegistry(key, QSettings::NativeFormat);
- const QStringList allKeys = fontRegistry.allKeys();
- const QString trueType = QStringLiteral("(TrueType)");
-#if QT_CONFIG(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(result.size() + 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 = 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 nullptr;
-}
-
-static bool addFontToDatabase(QString familyName,
- QString styleName,
- const QString &fullName,
- const LOGFONT &logFont,
- const TEXTMETRIC *textmetric,
- const FONTSIGNATURE *signature,
- int type)
-{
- // the "@family" fonts are just the same as "family". Ignore them.
- if (familyName.isEmpty() || familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QLatin1String("WST_")))
- return false;
-
- uchar charSet = logFont.lfCharSet;
-
- 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 (lcQpaFonts().isDebugEnabled()) {
- QString message;
- QTextStream str(&message);
- str << __FUNCTION__ << ' ' << familyName << "::" << 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;
- QString faceName = familyName;
-
- QString subFamilyName;
- QString subFamilyStyle;
- // Look-up names registered in the font
- QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
- if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
- englishName = canonicalNames.name;
- if (!canonicalNames.preferredName.isEmpty()) {
- subFamilyName = familyName;
- subFamilyStyle = styleName;
- familyName = canonicalNames.preferredName;
- styleName = canonicalNames.preferredStyle;
- }
-
- 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(qt_getEnglishName(fullName, true), &index);
- }
- if (!key)
- key = findFontKey(faceName, &index);
- 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(familyName, 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(familyName, QString(), foundryName, QFont::Bold, style, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
-
- if (style != QFont::StyleItalic && styleName.isEmpty())
- QPlatformFontDatabase::registerFont(familyName, 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(familyName, QString(), foundryName, QFont::Bold, QFont::StyleItalic, stretch,
- antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
-
- if (!subFamilyName.isEmpty() && familyName != subFamilyName) {
- QPlatformFontDatabase::registerFont(subFamilyName, subFamilyStyle, foundryName, weight,
- style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(value, index));
- }
-
- if (!englishName.isEmpty() && englishName != familyName)
- 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 faceName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
- const QString styleName = QString::fromWCharArray(f->elfStyle);
- const QString fullName = QString::fromWCharArray(f->elfFullName);
-
- // 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 = nullptr;
- if (type & TRUETYPE_FONTTYPE) {
- signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig;
- // We get a callback for each script-type supported, but we register them all
- // at once using the signature, so we only need one call to addFontToDatabase().
- QSet<QPair<QString,QString>> *foundFontAndStyles = reinterpret_cast<QSet<QPair<QString,QString>> *>(lparam);
- QPair<QString,QString> fontAndStyle(faceName, styleName);
- if (foundFontAndStyles->contains(fontAndStyle))
- return 1;
- foundFontAndStyles->insert(fontAndStyle);
- }
- addFontToDatabase(faceName, styleName, fullName, *logFont, textmetric, signature, type);
-
- // 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;
- memset(&lf, 0, sizeof(LOGFONT));
- familyName.toWCharArray(lf.lfFaceName);
- lf.lfFaceName[familyName.size()] = 0;
- lf.lfCharSet = DEFAULT_CHARSET;
- lf.lfPitchAndFamily = 0;
- QSet<QPair<QString,QString>> foundFontAndStyles;
- EnumFontFamiliesEx(dummy, &lf, storeFont, reinterpret_cast<intptr_t>(&foundFontAndStyles), 0);
- ReleaseDC(0, dummy);
-}
-
-// Delayed population of font families
-
-static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric,
- DWORD, 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 && qt_localizedName(faceName))
- key = findFontKey(qt_getEnglishName(faceName));
- }
- if (key) {
- QPlatformFontDatabase::registerFontFamily(faceName);
- // Register current font's english name as alias
- if (ttf && qt_localizedName(faceName)) {
- const QString englishName = qt_getEnglishName(faceName);
- if (!englishName.isEmpty())
- QPlatformFontDatabase::registerAliasToFontFamily(faceName, englishName);
- }
- }
- }
- return 1; // continue
-}
-
-void QWindowsFontDatabaseFT::populateFontDatabase()
-{
- HDC dummy = GetDC(0);
- LOGFONT lf;
- lf.lfCharSet = DEFAULT_CHARSET;
- lf.lfFaceName[0] = 0;
- lf.lfPitchAndFamily = 0;
- EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, 0, 0);
- ReleaseDC(0, dummy);
- // Work around EnumFontFamiliesEx() not listing the system font
- QString systemDefaultFamily = QWindowsFontDatabase::systemDefaultFont().family();
- if (QPlatformFontDatabase::resolveFontFamilyAlias(systemDefaultFamily) == systemDefaultFamily)
- QPlatformFontDatabase::registerFontFamily(systemDefaultFamily);
-}
-
-QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, void *handle)
-{
- QFontEngine *fe = QFreeTypeFontDatabase::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 = QFreeTypeFontDatabase::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(QFreeTypeFontDatabase::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/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft_p.h
deleted file mode 100644
index c3d201b3a0..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft_p.h
+++ /dev/null
@@ -1,79 +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
-
-//
-// 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 <QtFontDatabaseSupport/private/qfreetypefontdatabase_p.h>
-#include <QtCore/QSharedPointer>
-#include <QtCore/qt_windows.h>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsFontDatabaseFT : public QFreeTypeFontDatabase
-{
-public:
- void populateFontDatabase() override;
- void populateFamily(const QString &familyName) override;
- QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
- QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize,
- QFont::HintingPreference hintingPreference) override;
-
- QStringList fallbacksForFamily(const QString &family, QFont::Style style,
- QFont::StyleHint styleHint,
- QChar::Script script) const override;
-
- QString fontDir() const override;
- QFont defaultFont() const override;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSFONTDATABASEFT_H
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
deleted file mode 100644
index f132e69d4d..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h
+++ /dev/null
@@ -1,193 +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
-
-//
-// 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 <qpa/qplatformfontdatabase.h>
-#include <QtCore/QSharedPointer>
-#include <QtCore/QLoggingCategory>
-#include <QtCore/qt_windows.h>
-
-#if !defined(QT_NO_DIRECTWRITE)
- struct IDWriteFactory;
- struct IDWriteGdiInterop;
-#endif
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts)
-
-class QWindowsFontEngineData
-{
- Q_DISABLE_COPY_MOVE(QWindowsFontEngineData)
-public:
- QWindowsFontEngineData();
- ~QWindowsFontEngineData();
-
- uint pow_gamma[256];
-
- bool clearTypeEnabled = false;
- qreal fontSmoothingGamma;
- HDC hdc = 0;
-#if !defined(QT_NO_DIRECTWRITE)
- IDWriteFactory *directWriteFactory = nullptr;
- IDWriteGdiInterop *directWriteGdiInterop = nullptr;
-#endif
-};
-
-class QWindowsFontDatabase : public QPlatformFontDatabase
-{
- Q_DISABLE_COPY_MOVE(QWindowsFontDatabase)
-public:
- enum FontOptions {
- // Relevant bits from QWindowsIntegration::Options
- DontUseDirectWriteFonts = 0x40,
- DontUseColorFonts = 0x80
- };
-
- QWindowsFontDatabase();
- ~QWindowsFontDatabase() override;
-
- void ensureFamilyPopulated(const QString &familyName);
-
- void populateFontDatabase() override;
- void populateFamily(const QString &familyName) override;
- QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
- QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override;
- QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override;
- QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName) override;
- void releaseHandle(void *handle) override;
- QString fontDir() const override;
-
- QFont defaultFont() const override { return systemDefaultFont(); }
- bool fontsAlwaysScalable() const override;
- void derefUniqueFont(const QString &uniqueFont);
- void refUniqueFont(const QString &uniqueFont);
- bool isPrivateFontFamily(const QString &family) const override;
-
- static QFont systemDefaultFont();
-
- static QFontEngine *createEngine(const QFontDef &request, const QString &faceName,
- 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, const QString &faceName);
-
- static QStringList extraTryFontsForFamily(const QString &family);
- static QString familyForStyleHint(QFont::StyleHint styleHint);
-
- static int defaultVerticalDPI();
-
- static void setFontOptions(unsigned options);
- static unsigned fontOptions();
-
-private:
- void removeApplicationFonts();
- void addDefaultEUDCFont();
-
- struct WinApplicationFont {
- HANDLE handle;
- QString fileName;
- };
-
- QList<WinApplicationFont> m_applicationFonts;
-
- struct UniqueFontData {
- HANDLE handle;
- QAtomicInt refCount;
- };
-
- QMap<QString, UniqueFontData> m_uniqueFontData;
-
- static unsigned m_fontOptions;
- QStringList m_eudcFonts;
-};
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug, const QFontDef &def);
-#endif
-
-inline quint16 qt_getUShort(const unsigned char *p)
-{
- quint16 val;
- val = *p++ << 8;
- val |= *p;
-
- return val;
-}
-
-struct QFontNames
-{
- QString name; // e.g. "DejaVu Sans Condensed"
- QString style; // e.g. "Italic"
- QString preferredName; // e.g. "DejaVu Sans"
- QString preferredStyle; // e.g. "Condensed Italic"
-};
-
-struct QFontValues
-{
- quint16 weight = 0;
- bool isItalic = false;
- bool isOverstruck = false;
- bool isUnderlined = false;
-};
-
-bool qt_localizedName(const QString &name);
-QString qt_getEnglishName(const QString &familyName, bool includeStyle = false);
-QFontNames qt_getCanonicalFontNames(const LOGFONT &lf);
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSFONTDATABASE_H
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp
deleted file mode 100644
index 2ae378c558..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp
+++ /dev/null
@@ -1,1211 +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 "qwindowsfontengine_p.h"
-#include "qwindowsnativeimage_p.h"
-#include "qwindowsfontdatabase_p.h"
-#include <QtCore/qt_windows.h>
-#include "qwindowsfontenginedirectwrite_p.h"
-
-#include <QtGui/qpa/qplatformintegration.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/QTextStream>
-#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>
-# include <comdef.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");
-}
-
-// general font engine
-
-QFixed QWindowsFontEngine::lineThickness() const
-{
- if(lineWidth > 0)
- return lineWidth;
-
- return QFontEngine::lineThickness();
-}
-
-static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc)
-{
- const auto size = GetOutlineTextMetrics(hdc, 0, nullptr);
- auto otm = reinterpret_cast<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;
-}
-
-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),
- m_logfont(lf),
- ttf(0),
- hasOutline(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 = (tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) == 0;
-}
-
-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()) {
- if (QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration()) {
- QPlatformFontDatabase *pfdb = pi->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, qreal stretch) {
- return QPointF(qt_fixed_to_double(pt.x) * scale * stretch, -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.0, qreal stretch = 1.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;
-
- 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, stretch));
- 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, stretch) + 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, stretch) + oset;
- QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale, stretch) + 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, stretch) + oset;
- QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset;
- QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + 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);
-
- qreal scale = qreal(fontDef.pixelSize) / unitsPerEm;
- qreal stretch = fontDef.stretch ? qreal(fontDef.stretch) / 100 : 1.0;
- for(int i = 0; i < nglyphs; ++i) {
- if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0,
- scale, stretch)) {
- // 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 = qt_getUShort(data);
- if (tm.tmItalic && !(macStyle & 2))
- synthesized_flags = SynthesizedItalic;
- if (fontDef.stretch != 100 && ttf)
- synthesized_flags |= SynthesizedStretch;
- if (tm.tmWeight >= 500 && tm.tmWeight < 750 && !(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) {
- auto dest = reinterpret_cast<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;
- const QString faceName = QString::fromWCharArray(m_logfont.lfFaceName);
-
- QFontEngine *fontEngine =
- QWindowsFontDatabase::createEngine(request, faceName,
- QWindowsFontDatabase::defaultVerticalDPI(),
- m_fontEngineData);
- if (fontEngine) {
- fontEngine->fontDef.family = actualFontName;
- if (!uniqueFamilyName.isEmpty()) {
- static_cast<QWindowsFontEngine *>(fontEngine)->setUniqueFamilyName(uniqueFamilyName);
- if (QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration()) {
- QPlatformFontDatabase *pfdb = pi->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.);
- }
-}
-
-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/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h
deleted file mode 100644
index b1b9d828ac..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h
+++ /dev/null
@@ -1,175 +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
-{
- Q_DISABLE_COPY_MOVE(QWindowsFontEngine)
-public:
- QWindowsFontEngine(const QString &name, LOGFONT lf,
- const QSharedPointer<QWindowsFontEngineData> &fontEngineData);
-
- ~QWindowsFontEngine() override;
- void initFontInfo(const QFontDef &request,
- int dpi);
-
- QFixed lineThickness() const override;
- Properties properties() const override;
- void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) override;
- FaceId faceId() const override;
- bool getSfntTableData(uint tag, uchar *buffer, uint *length) const override;
- int synthesized() const override;
- QFixed emSquareSize() const override;
-
- glyph_t glyphIndex(uint ucs4) const override;
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override;
- void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags) const override;
-
- void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) override;
- void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags) override;
-
- HGDIOBJ selectDesignFont() const;
-
- glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
- glyph_metrics_t boundingBox(glyph_t g) override { return boundingBox(g, QTransform()); }
- glyph_metrics_t boundingBox(glyph_t g, const QTransform &t) override;
-
-
- QFixed ascent() const override;
- QFixed descent() const override;
- QFixed leading() const override;
- QFixed xHeight() const override;
- QFixed capHeight() const override;
- QFixed averageCharWidth() const override;
- qreal maxCharWidth() const override;
- qreal minLeftBearing() const override;
- qreal minRightBearing() const override;
-
- QImage alphaMapForGlyph(glyph_t t) override { return alphaMapForGlyph(t, QTransform()); }
- QImage alphaMapForGlyph(glyph_t, const QTransform &xform) override;
- QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform) override;
- glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) override;
-
- QFontEngine *cloneWithSize(qreal pixelSize) const override;
- Qt::HANDLE handle() const override;
- bool supportsTransformation(const QTransform &transform) const override;
-
-#ifndef Q_CC_MINGW
- void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0) override;
-#endif
-
- bool hasUnreliableGlyphOutline() const 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;
-
- const QSharedPointer<QWindowsFontEngineData> m_fontEngineData;
-
- const QString _name;
- QString uniqueFamilyName;
- HFONT hfont = 0;
- const LOGFONT m_logfont;
- uint ttf : 1;
- uint hasOutline : 1;
- uint hasUnreliableOutline : 1;
- uint cffTable : 1;
- TEXTMETRIC tm;
- const unsigned char *cmap = nullptr;
- int cmapSize = 0;
- QByteArray cmapTable;
- mutable qreal lbearing = SHRT_MIN;
- mutable qreal rbearing = SHRT_MIN;
- QFixed designToDevice;
- int unitsPerEm = 0;
- QFixed x_height = -1;
- FaceId _faceId;
-
- mutable int synthesized_flags = -1;
- mutable QFixed lineWidth = -1;
- mutable unsigned char *widthCache = nullptr;
- mutable uint widthCacheSize = 0;
- mutable QFixed *designAdvances = nullptr;
- mutable int designAdvancesSize = 0;
-};
-
-QT_END_NAMESPACE
-
-Q_DECLARE_METATYPE(HFONT)
-Q_DECLARE_METATYPE(LOGFONT)
-
-#endif // QWINDOWSFONTENGINE_H
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
deleted file mode 100644
index 5c999f455e..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp
+++ /dev/null
@@ -1,1035 +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_p.h"
-#include "qwindowsfontdatabase_p.h"
-
-#include <QtCore/QtEndian>
-#include <QtCore/QVarLengthArray>
-#include <QtCore/QFile>
-#include <private/qstringiterator_p.h>
-#include <QtCore/private/qsystemlibrary_p.h>
-#include <QtCore/private/qwinregistry_p.h>
-#include <QtGui/private/qguiapplication_p.h>
-#include <qpa/qplatformintegration.h>
-#include <QtGui/private/qhighdpiscaling_p.h>
-
-#if defined(QT_USE_DIRECTWRITE2)
-# include <dwrite_2.h>
-#else
-# include <dwrite.h>
-#endif
-
-#include <d2d1.h>
-
-QT_BEGIN_NAMESPACE
-
-// Clang does not consider __declspec(nothrow) as nothrow
-QT_WARNING_DISABLE_CLANG("-Wmicrosoft-exception-spec")
-
-// 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
- {
- Q_DISABLE_COPY_MOVE(GeometrySink)
- public:
- GeometrySink(QPainterPath *path)
- : m_refCount(0), m_path(path)
- {
- Q_ASSERT(m_path != 0);
- }
- virtual ~GeometrySink() = default;
-
- 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)
-{
- if (QHighDpiScaling::isActive() && hintingPreference == QFont::PreferDefaultHinting)
- hintingPreference = QFont::PreferVerticalHinting;
-
- 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 = nullptr;
-
- HRESULT hr = fontFile->GetLoader(&loader);
- if (FAILED(hr)) {
- qErrnoWarning("%s: GetLoader failed", __FUNCTION__);
- return QString();
- }
-
- QIdWriteLocalFontFileLoader *localLoader = nullptr;
- hr = loader->QueryInterface(uuidIdWriteLocalFontFileLoader(),
- reinterpret_cast<void **>(&localLoader));
-
- const void *fontFileReferenceKey = 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 != nullptr)
- localLoader->Release();
-
- if (loader != 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 = nullptr;
- UINT32 numberOfFiles = 1;
- if (SUCCEEDED(m_directWriteFontFace->GetFiles(&numberOfFiles, &fontFile))) {
- m_faceId.filename = QFile::encodeName(filenameFromFontFile(fontFile));
- fontFile->Release();
- }
-
- QByteArray table = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a'));
- const int advanceWidthMaxLocation = 10;
- if (table.size() >= advanceWidthMaxLocation + int(sizeof(quint16))) {
- quint16 advanceWidthMax = qFromBigEndian<quint16>(table.constData() + advanceWidthMaxLocation);
- m_maxAdvanceWidth = DESIGN_TO_LOGICAL(advanceWidthMax);
- }
-}
-
-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, {});
-
- 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 fontDef.styleStrategy & QFont::ForceIntegerMetrics
- ? m_maxAdvanceWidth.round().toReal()
- : m_maxAdvanceWidth.toReal();
-}
-
-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,
- const QColor &color)
-{
- 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 && fontDef.stretch != QFont::AnyStretch)
- 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 = 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, g, b, a;
- if (colorGlyphRun->paletteIndex == 0xFFFF) {
- r = float(color.redF());
- g = float(color.greenF());
- b = float(color.blueF());
- a = float(color.alphaF());
- } else {
- r = qBound(0.0f, colorGlyphRun->runColor.r, 1.0f);
- g = qBound(0.0f, colorGlyphRun->runColor.g, 1.0f);
- b = qBound(0.0f, colorGlyphRun->runColor.b, 1.0f);
- 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
- {
- float r, g, b, a;
- if (glyphFormat == QFontEngine::Format_ARGB) {
- r = float(color.redF());
- g = float(color.greenF());
- b = float(color.blueF());
- a = float(color.alphaF());
- } else {
- r = g = b = a = 0.0;
- }
-
- renderGlyphRun(&image,
- r,
- g,
- b,
- a,
- 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)
-{
- const QString substitute =
- QWinRegistryKey(HKEY_LOCAL_MACHINE,
- LR"(Software\Microsoft\Windows NT\CurrentVersion\FontSubstitutes)")
- .stringValue(familyName);
- return substitute.isEmpty() ? familyName : substitute;
-}
-
-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 && fontDef.stretch != QFont::AnyStretch)
- 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 - margin,
- rect.top - margin,
- 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, const QColor &color)
-{
- return imageForGlyph(glyph, subPixelPosition, glyphMargin(QFontEngine::Format_A32), t, color);
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DIRECTWRITE
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
deleted file mode 100644
index c8c6b83bf9..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h
+++ /dev/null
@@ -1,156 +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
-
-//
-// 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 <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
-{
- Q_DISABLE_COPY_MOVE(QWindowsFontEngineDirectWrite)
-public:
- explicit QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace,
- qreal pixelSize,
- const QSharedPointer<QWindowsFontEngineData> &d);
- ~QWindowsFontEngineDirectWrite() override;
-
- void initFontInfo(const QFontDef &request, int dpi);
-
- QFixed lineThickness() const override;
- QFixed underlinePosition() const override;
- bool getSfntTableData(uint tag, uchar *buffer, uint *length) const override;
- QFixed emSquareSize() const override;
-
- glyph_t glyphIndex(uint ucs4) const override;
- bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
- ShaperFlags flags) const override;
- void recalcAdvances(QGlyphLayout *glyphs, ShaperFlags) const override;
-
- void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
- QPainterPath *path, QTextItem::RenderFlags flags) override;
-
- glyph_metrics_t boundingBox(const QGlyphLayout &glyphs) override;
- glyph_metrics_t boundingBox(glyph_t g) override;
- glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed,
- const QTransform &matrix, GlyphFormat) override;
-
- QFixed ascent() const override;
- QFixed capHeight() const override;
- QFixed descent() const override;
- QFixed leading() const override;
- QFixed xHeight() const override;
- qreal maxCharWidth() const override;
- FaceId faceId() const override;
-
- bool supportsSubPixelPositions() const override;
-
- QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) override;
- QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override;
- QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform) override;
- QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override;
-
- QFontEngine *cloneWithSize(qreal pixelSize) const override;
- Qt::HANDLE handle() const 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, const QColor &color = QColor());
- 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;
- QFixed m_maxAdvanceWidth;
- FaceId m_faceId;
- QString m_uniqueFamilyName;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DIRECTWRITE
-
-#endif // QWINDOWSFONTENGINEDIRECTWRITE_H
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage.cpp b/src/platformsupport/fontdatabases/windows/qwindowsnativeimage.cpp
deleted file mode 100644
index b1133dca22..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage.cpp
+++ /dev/null
@@ -1,159 +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_p.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 = 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 (%dx%d, format: %d)", __FUNCTION__,
- width, height, int(format));
- }
-
- *bitsIn = bits;
- return bitmap;
-}
-
-QWindowsNativeImage::QWindowsNativeImage(int width, int height,
- QImage::Format format) :
- m_hdc(createDC())
-{
- 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 int depth = -1;
- if (depth == -1) {
- if (HDC defaultDC = GetDC(0)) {
- depth = GetDeviceCaps(defaultDC, BITSPIXEL);
- ReleaseDC(0, defaultDC);
- } else {
- // FIXME Same remark as in QWindowsFontDatabase::defaultVerticalDPI()
- // BONUS FIXME: Is 32 too generous/optimistic?
- depth = 32;
- }
- }
- return depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h b/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h
deleted file mode 100644
index ed68ac2644..0000000000
--- a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h
+++ /dev/null
@@ -1,89 +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
-
-//
-// 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 <QtCore/QtGlobal>
-#include <QtCore/qt_windows.h>
-#include <QtGui/QImage>
-
-QT_BEGIN_NAMESPACE
-
-class QWindowsNativeImage
-{
- Q_DISABLE_COPY_MOVE(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 = 0;
- HBITMAP m_null_bitmap = 0;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSNATIVEIMAGE_H
diff --git a/src/platformsupport/fontdatabases/windows/windows.pri b/src/platformsupport/fontdatabases/windows/windows.pri
deleted file mode 100644
index 7ddfb2c281..0000000000
--- a/src/platformsupport/fontdatabases/windows/windows.pri
+++ /dev/null
@@ -1,34 +0,0 @@
-QT *= gui-private
-
-SOURCES += \
- $$PWD/qwindowsfontdatabase.cpp \
- $$PWD/qwindowsfontengine.cpp \
- $$PWD/qwindowsnativeimage.cpp
-
-HEADERS += \
- $$PWD/qwindowsfontdatabase_p.h \
- $$PWD/qwindowsfontengine_p.h \
- $$PWD/qwindowsnativeimage_p.h
-
-qtConfig(freetype) {
- SOURCES += $$PWD/qwindowsfontdatabase_ft.cpp
- HEADERS += $$PWD/qwindowsfontdatabase_ft_p.h
-}
-
-qtConfig(directwrite):qtConfig(direct2d) {
- qtConfig(directwrite2) {
- QMAKE_USE_PRIVATE += dwrite_2
- DEFINES *= QT_USE_DIRECTWRITE2
- } else {
- QMAKE_USE_PRIVATE += dwrite
- }
- QMAKE_USE_PRIVATE += d2d1
-
- SOURCES += $$PWD/qwindowsfontenginedirectwrite.cpp
- HEADERS += $$PWD/qwindowsfontenginedirectwrite_p.h
-} else {
- DEFINES *= QT_NO_DIRECTWRITE
-}
-
-QMAKE_USE_PRIVATE += advapi32 ole32 user32 gdi32
-mingw: QMAKE_USE_PRIVATE += uuid
diff --git a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp
deleted file mode 100644
index db58e49bb2..0000000000
--- a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp
+++ /dev/null
@@ -1,507 +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 "qwinrtfontdatabase_p.h"
-
-#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h>
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QFile>
-
-#include <QtCore/QUuid>
-#include <dwrite_1.h>
-#include <wrl.h>
-using namespace Microsoft::WRL;
-
-QT_BEGIN_NAMESPACE
-
-Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
-
-QDebug operator<<(QDebug d, const QFontDef &def)
-{
- QDebugStateSaver saver(d);
- d.nospace();
- d << "Family=" << def.family << " Stylename=" << def.styleName
- << " pointsize=" << def.pointSize << " pixelsize=" << def.pixelSize
- << " styleHint=" << def.styleHint << " weight=" << def.weight
- << " stretch=" << def.stretch << " hintingPreference="
- << def.hintingPreference;
- return d;
-}
-
-// Based on unicode range tables at http://www.microsoft.com/typography/otspec/os2.htm#ur
-static QFontDatabase::WritingSystem writingSystemFromUnicodeRange(const DWRITE_UNICODE_RANGE &range)
-{
- if (range.first >= 0x0000 && range.last <= 0x007F)
- return QFontDatabase::Latin;
- if (range.first >= 0x0370 && range.last <= 0x03FF)
- return QFontDatabase::Greek;
- if (range.first >= 0x0400 && range.last <= 0x04FF)
- return QFontDatabase::Cyrillic;
- if (range.first >= 0x0530 && range.last <= 0x058F)
- return QFontDatabase::Armenian;
- if (range.first >= 0x0590 && range.last <= 0x05FF)
- return QFontDatabase::Hebrew;
- if (range.first >= 0x0600 && range.last <= 0x06FF)
- return QFontDatabase::Arabic;
- if (range.first >= 0x0700 && range.last <= 0x074F)
- return QFontDatabase::Syriac;
- if (range.first >= 0x0780 && range.last <= 0x07BF)
- return QFontDatabase::Thaana;
- if (range.first >= 0x0900 && range.last <= 0x097F)
- return QFontDatabase::Devanagari;
- if (range.first >= 0x0980 && range.last <= 0x09FF)
- return QFontDatabase::Bengali;
- if (range.first >= 0x0A00 && range.last <= 0x0A7F)
- return QFontDatabase::Gurmukhi;
- if (range.first >= 0x0A80 && range.last <= 0x0AFF)
- return QFontDatabase::Gujarati;
- if (range.first >= 0x0B00 && range.last <= 0x0B7F)
- return QFontDatabase::Oriya;
- if (range.first >= 0x0B80 && range.last <= 0x0BFF)
- return QFontDatabase::Tamil;
- if (range.first >= 0x0C00 && range.last <= 0x0C7F)
- return QFontDatabase::Telugu;
- if (range.first >= 0x0C80 && range.last <= 0x0CFF)
- return QFontDatabase::Kannada;
- if (range.first >= 0x0D00 && range.last <= 0x0D7F)
- return QFontDatabase::Malayalam;
- if (range.first >= 0x0D80 && range.last <= 0x0DFF)
- return QFontDatabase::Sinhala;
- if (range.first >= 0x0E00 && range.last <= 0x0E7F)
- return QFontDatabase::Thai;
- if (range.first >= 0x0E80 && range.last <= 0x0EFF)
- return QFontDatabase::Lao;
- if (range.first >= 0x0F00 && range.last <= 0x0FFF)
- return QFontDatabase::Tibetan;
- if (range.first >= 0x1000 && range.last <= 0x109F)
- return QFontDatabase::Myanmar;
- if (range.first >= 0x10A0 && range.last <= 0x10FF)
- return QFontDatabase::Georgian;
- if (range.first >= 0x1780 && range.last <= 0x17FF)
- return QFontDatabase::Khmer;
- if (range.first >= 0x4E00 && range.last <= 0x9FFF)
- return QFontDatabase::SimplifiedChinese;
- if (range.first >= 0xAC00 && range.last <= 0xD7AF)
- return QFontDatabase::Korean;
- if (range.first >= 0x1680 && range.last <= 0x169F)
- return QFontDatabase::Ogham;
- if (range.first >= 0x16A0 && range.last <= 0x16FF)
- return QFontDatabase::Runic;
- if (range.first >= 0x07C0 && range.last <= 0x07FF)
- return QFontDatabase::Nko;
-
- return QFontDatabase::Other;
-}
-
-QWinRTFontDatabase::~QWinRTFontDatabase()
-{
- qCDebug(lcQpaFonts) << __FUNCTION__;
-
- foreach (IDWriteFontFile *fontFile, m_fonts.keys())
- fontFile->Release();
-
- foreach (IDWriteFontFamily *fontFamily, m_fontFamilies)
- fontFamily->Release();
-}
-
-QString QWinRTFontDatabase::fontDir() const
-{
- qCDebug(lcQpaFonts) << __FUNCTION__;
- QString fontDirectory = QFreeTypeFontDatabase::fontDir();
- if (!QFile::exists(fontDirectory)) {
- // Fall back to app directory + fonts, and just app directory after that
- const QString applicationDirPath = QCoreApplication::applicationDirPath();
- fontDirectory = applicationDirPath + QLatin1String("/fonts");
- if (!QFile::exists(fontDirectory)) {
- if (m_fontFamilies.isEmpty())
- qWarning("No fonts directory found in application package.");
- fontDirectory = applicationDirPath;
- }
- }
- return fontDirectory;
-}
-
-QFont QWinRTFontDatabase::defaultFont() const
-{
- return QFont(QStringLiteral("Segoe UI"));
-}
-
-bool QWinRTFontDatabase::fontsAlwaysScalable() const
-{
- return true;
-}
-
-void QWinRTFontDatabase::populateFontDatabase()
-{
- qCDebug(lcQpaFonts) << __FUNCTION__;
-
- ComPtr<IDWriteFactory1> factory;
- HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory1), &factory);
- if (FAILED(hr)) {
- qWarning("Failed to create DirectWrite factory: %s", qPrintable(qt_error_string(hr)));
- QFreeTypeFontDatabase::populateFontDatabase();
- return;
- }
-
- ComPtr<IDWriteFontCollection> fontCollection;
- hr = factory->GetSystemFontCollection(&fontCollection);
- if (FAILED(hr)) {
- qWarning("Failed to open system font collection: %s", qPrintable(qt_error_string(hr)));
- QFreeTypeFontDatabase::populateFontDatabase();
- return;
- }
-
- int fontFamilyCount = fontCollection->GetFontFamilyCount();
- for (int i = 0; i < fontFamilyCount; ++i) {
- ComPtr<IDWriteFontFamily> fontFamily;
- hr = fontCollection->GetFontFamily(i, &fontFamily);
- if (FAILED(hr)) {
- qWarning("Unable to get font family: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
-
- ComPtr<IDWriteLocalizedStrings> names;
- hr = fontFamily->GetFamilyNames(&names);
- if (FAILED(hr)) {
- qWarning("Unable to get font family names: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- quint32 familyNameLength;
- hr = names->GetStringLength(0, &familyNameLength);
- if (FAILED(hr)) {
- qWarning("Unable to get family name length: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- QVector<wchar_t> familyBuffer(familyNameLength + 1);
- hr = names->GetString(0, familyBuffer.data(), familyBuffer.size());
- if (FAILED(hr)) {
- qWarning("Unable to create font family name: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- QString familyName = QString::fromWCharArray(familyBuffer.data(), familyNameLength);
-
- m_fontFamilies.insert(familyName, fontFamily.Detach());
-
- registerFontFamily(familyName);
- }
-
- QFreeTypeFontDatabase::populateFontDatabase();
-}
-
-void QWinRTFontDatabase::populateFamily(const QString &familyName)
-{
- qCDebug(lcQpaFonts) << __FUNCTION__ << familyName;
-
- IDWriteFontFamily *fontFamily = m_fontFamilies.value(familyName);
- if (!fontFamily) {
- qWarning("The font family %s was not found.", qPrintable(familyName));
- return;
- }
-
- bool fontRegistered = false;
- const int fontCount = fontFamily->GetFontCount();
- for (int j = 0; j < fontCount; ++j) {
- ComPtr<IDWriteFont> font;
- HRESULT hr = fontFamily->GetFont(j, &font);
- if (FAILED(hr)) {
- qWarning("Unable to get font: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
-
- // Skip simulated faces
- if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE)
- continue;
-
- ComPtr<IDWriteFontFace> baseFontFace;
- hr = font->CreateFontFace(&baseFontFace);
- if (FAILED(hr)) {
- qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- ComPtr<IDWriteFontFace1> fontFace;
- hr = baseFontFace.As(&fontFace);
- if (FAILED(hr)) {
- qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
-
- // We can't deal with multi-file fonts
- quint32 fileCount;
- hr = fontFace->GetFiles(&fileCount, NULL);
- if (FAILED(hr)) {
- qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- if (fileCount != 1)
- continue;
-
- ComPtr<IDWriteLocalizedStrings> informationalStrings;
- BOOL exists;
- hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
- &informationalStrings, &exists);
- if (FAILED(hr)) {
- qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- QString foundryName;
- if (exists) {
- quint32 length;
- hr = informationalStrings->GetStringLength(0, &length);
- if (FAILED(hr))
- qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr)));
- if (SUCCEEDED(hr)) {
- QVector<wchar_t> buffer(length + 1);
- hr = informationalStrings->GetString(0, buffer.data(), buffer.size());
- if (FAILED(hr))
- qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr)));
- if (SUCCEEDED(hr))
- foundryName = QString::fromWCharArray(buffer.data(), length);
- }
- }
-
- QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(font->GetWeight());
-
- QFont::Style style;
- switch (font->GetStyle()) {
- default:
- case DWRITE_FONT_STYLE_NORMAL:
- style = QFont::StyleNormal;
- break;
- case DWRITE_FONT_STYLE_OBLIQUE:
- style = QFont::StyleOblique;
- break;
- case DWRITE_FONT_STYLE_ITALIC:
- style = QFont::StyleItalic;
- break;
- }
-
- QFont::Stretch stretch;
- switch (font->GetStretch()) {
- default:
- case DWRITE_FONT_STRETCH_UNDEFINED:
- case DWRITE_FONT_STRETCH_NORMAL:
- stretch = QFont::Unstretched;
- break;
- case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
- stretch = QFont::UltraCondensed;
- break;
- case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
- stretch = QFont::ExtraCondensed;
- break;
- case DWRITE_FONT_STRETCH_CONDENSED:
- stretch = QFont::Condensed;
- break;
- case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
- stretch = QFont::SemiCondensed;
- break;
- case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
- stretch = QFont::SemiExpanded;
- break;
- case DWRITE_FONT_STRETCH_EXPANDED:
- stretch = QFont::Expanded;
- break;
- case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
- stretch = QFont::ExtraExpanded;
- break;
- case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
- stretch = QFont::UltraExpanded;
- break;
- }
-
- const bool fixedPitch = fontFace->IsMonospacedFont();
-
- // Get writing systems from unicode ranges
- quint32 actualRangeCount;
- hr = fontFace->GetUnicodeRanges(0, nullptr, &actualRangeCount);
- Q_ASSERT(hr == E_NOT_SUFFICIENT_BUFFER);
- QVector<DWRITE_UNICODE_RANGE> unicodeRanges(actualRangeCount);
- hr = fontFace->GetUnicodeRanges(actualRangeCount, unicodeRanges.data(), &actualRangeCount);
- if (FAILED(hr)) {
- qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- QSupportedWritingSystems writingSystems;
- for (quint32 i = 0; i < actualRangeCount; ++i) {
- const QFontDatabase::WritingSystem writingSystem = writingSystemFromUnicodeRange(unicodeRanges.at(i));
- writingSystems.setSupported(writingSystem);
- }
- if (writingSystems.supported(QFontDatabase::SimplifiedChinese)) {
- writingSystems.setSupported(QFontDatabase::TraditionalChinese);
- writingSystems.setSupported(QFontDatabase::Japanese);
- }
- if (writingSystems.supported(QFontDatabase::Latin))
- writingSystems.setSupported(QFontDatabase::Vietnamese);
-
- IDWriteFontFile *fontFile;
- hr = fontFace->GetFiles(&fileCount, &fontFile);
- if (FAILED(hr)) {
- qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
-
- FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() };
- m_fonts.insert(fontFile, description);
- registerFont(familyName, QString(), foundryName, weight, style, stretch,
- true, true, 0, fixedPitch, writingSystems, fontFile);
- fontRegistered = true;
- }
-
- // Always populate something to avoid an assert
- if (!fontRegistered) {
- registerFont(familyName, QString(), QString(), QFont::Normal, QFont::StyleNormal,
- QFont::Unstretched, false, false, 0, false, QSupportedWritingSystems(), 0);
- }
-}
-
-QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
-{
- qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << handle;
-
- if (!handle) // Happens if a font family population failed
- return 0;
-
- IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
- if (!m_fonts.contains(fontFile))
- return QFreeTypeFontDatabase::fontEngine(fontDef, handle);
-
- const void *referenceKey;
- quint32 referenceKeySize;
- HRESULT hr = fontFile->GetReferenceKey(&referenceKey, &referenceKeySize);
- if (FAILED(hr)) {
- qWarning("Unable to get font file reference key: %s", qPrintable(qt_error_string(hr)));
- return 0;
- }
-
- ComPtr<IDWriteFontFileLoader> loader;
- hr = fontFile->GetLoader(&loader);
- if (FAILED(hr)) {
- qWarning("Unable to get font file loader: %s", qPrintable(qt_error_string(hr)));
- return 0;
- }
-
- ComPtr<IDWriteFontFileStream> stream;
- hr =loader->CreateStreamFromKey(referenceKey, referenceKeySize, &stream);
- if (FAILED(hr)) {
- qWarning("Unable to get font file stream: %s", qPrintable(qt_error_string(hr)));
- return 0;
- }
-
- quint64 fileSize;
- hr = stream->GetFileSize(&fileSize);
- if (FAILED(hr)) {
- qWarning("Unable to get font file size: %s", qPrintable(qt_error_string(hr)));
- return 0;
- }
-
- const void *data;
- void *context;
- hr = stream->ReadFileFragment(&data, 0, fileSize, &context);
- if (FAILED(hr)) {
- qWarning("Unable to get font file data: %s", qPrintable(qt_error_string(hr)));
- return 0;
- }
- const QByteArray fontData((const char *)data, fileSize);
- stream->ReleaseFileFragment(context);
-
- QFontEngine::FaceId faceId;
- const FontDescription description = m_fonts.value(fontFile);
- faceId.uuid = description.uuid;
- faceId.index = description.index;
-
- return QFontEngineFT::create(fontDef, faceId, fontData);
-}
-
-QString QWinRTFontDatabase::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("Segoe UI");
- case QFont::System:
- default:
- break;
- }
- return QStringLiteral("Segoe UI");
-}
-
-QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style,
- QFont::StyleHint styleHint,
- QChar::Script script) const
-{
- Q_UNUSED(style)
- Q_UNUSED(script)
-
- qCDebug(lcQpaFonts) << __FUNCTION__ << family;
-
- QStringList result;
- result.append(QWinRTFontDatabase::familyForStyleHint(styleHint));
- result.append(QFreeTypeFontDatabase::fallbacksForFamily(family, style, styleHint, script));
- return result;
-}
-
-void QWinRTFontDatabase::releaseHandle(void *handle)
-{
- qCDebug(lcQpaFonts) << __FUNCTION__ << handle;
-
- if (!handle)
- return;
-
- IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
- if (m_fonts.contains(fontFile)) {
- m_fonts.remove(fontFile);
- fontFile->Release();
- return;
- }
-
- QFreeTypeFontDatabase::releaseHandle(handle);
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h
deleted file mode 100644
index c21f411fff..0000000000
--- a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h
+++ /dev/null
@@ -1,92 +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 QWINRTFONTDATABASE_H
-#define QWINRTFONTDATABASE_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 <QtFontDatabaseSupport/private/qfreetypefontdatabase_p.h>
-#include <QtCore/QLoggingCategory>
-
-struct IDWriteFontFile;
-struct IDWriteFontFamily;
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts)
-
-struct FontDescription
-{
- quint32 index;
- QByteArray uuid;
-};
-
-class QWinRTFontDatabase : public QFreeTypeFontDatabase
-{
-public:
- ~QWinRTFontDatabase();
- QString fontDir() const override;
- QFont defaultFont() const override;
- bool fontsAlwaysScalable() const override;
- void populateFontDatabase() override;
- void populateFamily(const QString &familyName) override;
- QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override;
- QStringList fallbacksForFamily(const QString &family, QFont::Style style,
- QFont::StyleHint styleHint, QChar::Script script) const override;
- void releaseHandle(void *handle) override;
-
- static QString familyForStyleHint(QFont::StyleHint styleHint);
-private:
- QHash<IDWriteFontFile *, FontDescription> m_fonts;
- QHash<QString, IDWriteFontFamily *> m_fontFamilies;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINRTFONTDATABASE_H
diff --git a/src/platformsupport/fontdatabases/winrt/winrt.pri b/src/platformsupport/fontdatabases/winrt/winrt.pri
deleted file mode 100644
index 1cd417c1fd..0000000000
--- a/src/platformsupport/fontdatabases/winrt/winrt.pri
+++ /dev/null
@@ -1,11 +0,0 @@
-QT *= gui-private
-
-SOURCES += \
- $$PWD/qwinrtfontdatabase.cpp
-
-HEADERS += \
- $$PWD/qwinrtfontdatabase_p.h
-
-DEFINES += __WRL_NO_DEFAULT_LIB__
-
-QMAKE_USE_PRIVATE += dwrite_1 ws2_32