From 95d127354887425b616a5087c24b6765b7bf907b Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 24 Oct 2016 15:53:06 +0200 Subject: Windows: Don't claim bitmap fonts support all standard sizes We were throwing away important information by claiming that all fonts support all the standard sizes in QFontDatabase on Windows This caused the font dialog to list unsupported sizes for bitmap fonts, unlike the native font dialog. We would also claim to support creating bitmap fonts at unsupported sizes, which would lead to 1. QFontInfo(font).pointSize() would return the requested size, not the actual rendered size. 2. Bitmap fonts created at 64 pixels and higher would be invisible. On Mac, there are no system bitmap fonts, and the use is not very common, but installing some bitmap fonts on the system, it does seem to ignore the sizes supported in the font and just displays the standard list instead, so we keep the current behavior there. [ChangeLog][QtGui][Text] Fixed list of supported sizes for bitmap fonts on Windows. Task-number: QTBUG-56672 Change-Id: Idbec2db9eb3381ab5ddf6259bd2befcba9b93564 Reviewed-by: Lars Knoll --- src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/platformsupport') diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index 434aa16d16..ad4dd3c944 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -1583,7 +1583,7 @@ QString QWindowsFontDatabase::fontDir() const bool QWindowsFontDatabase::fontsAlwaysScalable() const { - return true; + return false; } void QWindowsFontDatabase::derefUniqueFont(const QString &uniqueFont) -- cgit v1.2.3 From 92805a0e9c488e47280e93f65e5378818e340ad1 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 7 Nov 2016 11:23:21 +0100 Subject: Fix EGL break on Debian X32 Change to QT_POINTER_SIZE instead of Q_PROCESSOR_WORDSIZE. The latter is 8 due to targeting 64-bit, but pointers are 32-bit still in such builds. For the condition in question it is the pointer size that matters. Task-number: QTBUG-56686 Change-Id: I96c203cae91ceb8404606de605c4fdb1a02a9d5f Reviewed-by: Dmitry Shachnev Reviewed-by: Thiago Macieira --- src/platformsupport/eglconvenience/qt_egl_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/platformsupport') diff --git a/src/platformsupport/eglconvenience/qt_egl_p.h b/src/platformsupport/eglconvenience/qt_egl_p.h index 615ee4b80a..b1495c9f9d 100644 --- a/src/platformsupport/eglconvenience/qt_egl_p.h +++ b/src/platformsupport/eglconvenience/qt_egl_p.h @@ -83,7 +83,7 @@ struct QtEglConverter { return v; } }; -#if Q_PROCESSOR_WORDSIZE > 4 +#if QT_POINTER_SIZE > 4 template <> struct QtEglConverter { -- cgit v1.2.3 From b559b5646359e6fd9c208c29b7524352784e6177 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 10 Oct 2016 20:27:36 +0200 Subject: QFontconfigDatabase: remove 200 unneeded relocations Same change as in QColor (d38f86e50b01c6dd60f5a97355031e08d6a47d18). No text and data reduction numbers (ubsan build). Change-Id: I7280a511e785c9442a3a6a1ed55e10011ce0a84e Reviewed-by: Edward Welbourne --- .../fontconfig/qfontconfigdatabase.cpp | 52 +++++++++++----------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'src/platformsupport') diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 1c2c3288a0..71236227de 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -110,7 +110,7 @@ static inline int stretchFromFcWidth(int fcwidth) return qtstretch; } -static const char *specialLanguages[] = { +static const char specialLanguages[][6] = { "", // Unknown "", // Inherited "", // Common @@ -244,12 +244,12 @@ static const char *specialLanguages[] = { "", // OldHungarian "" // SignWriting }; -Q_STATIC_ASSERT(sizeof(specialLanguages) / sizeof(const char *) == QChar::ScriptCount); +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[] = { - 0, // Any +static const char languageForWritingSystem[][6] = { + "", // Any "en", // Latin "el", // Greek "ru", // Cyrillic @@ -279,25 +279,25 @@ static const char *languageForWritingSystem[] = { "ja", // Japanese "ko", // Korean "vi", // Vietnamese - 0, // Symbol + "", // Symbol "sga", // Ogham "non", // Runic "man" // N'Ko }; -Q_STATIC_ASSERT(sizeof(languageForWritingSystem) / sizeof(const char *) == QFontDatabase::WritingSystemsCount); +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[] = { - 0, // Any - 0, // Latin - 0, // Greek - 0, // Cyrillic - 0, // Armenian - 0, // Hebrew - 0, // Arabic +static const char capabilityForWritingSystem[][5] = { + "", // Any + "", // Latin + "", // Greek + "", // Cyrillic + "", // Armenian + "", // Hebrew + "", // Arabic "syrc", // Syriac "thaa", // Thaana "deva", // Devanagari @@ -310,20 +310,20 @@ static const char *capabilityForWritingSystem[] = { "knda", // Kannada "mlym", // Malayalam "sinh", // Sinhala - 0, // Thai - 0, // Lao + "", // Thai + "", // Lao "tibt", // Tibetan "mymr", // Myanmar - 0, // Georgian + "", // Georgian "khmr", // Khmer - 0, // SimplifiedChinese - 0, // TraditionalChinese - 0, // Japanese - 0, // Korean - 0, // Vietnamese - 0, // Symbol - 0, // Ogham - 0, // Runic + "", // SimplifiedChinese + "", // TraditionalChinese + "", // Japanese + "", // Korean + "", // Vietnamese + "", // Symbol + "", // Ogham + "", // Runic "nko " // N'Ko }; Q_STATIC_ASSERT(sizeof(capabilityForWritingSystem) / sizeof(*capabilityForWritingSystem) == QFontDatabase::WritingSystemsCount); @@ -425,7 +425,7 @@ static void populateFromPattern(FcPattern *pattern) FcLangResult langRes = FcLangSetHasLang(langset, lang); if (langRes != FcLangDifferentLang) { #if FC_VERSION >= 20297 - if (capabilityForWritingSystem[j] != Q_NULLPTR && requiresOpenType(j)) { + if (*capabilityForWritingSystem[j] && requiresOpenType(j)) { if (cap == Q_NULLPTR) capRes = FcPatternGetString(pattern, FC_CAPABILITY, 0, &cap); if (capRes == FcResultMatch && strstr(reinterpret_cast(cap), capabilityForWritingSystem[j]) == 0) -- cgit v1.2.3 From a192ee0c379cd16512460bc45b1d492078f49aba Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 26 Oct 2016 11:37:24 -0700 Subject: Move WinRT font database to QtFontDatabaseSupport Similar to what we recently did with the Windows font databases. The goal, again, is to add platform font database support for the minimal QPA plugin. Change-Id: Ide5f4ec452c920f169cc31c617cbcf19d8d1764d Reviewed-by: Oswald Buddenhagen Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint Reviewed-by: Maurice Kalinowski --- .../fontdatabases/fontdatabases.pro | 4 + .../fontdatabases/winrt/qwinrtfontdatabase.cpp | 491 +++++++++++++++++++++ .../fontdatabases/winrt/qwinrtfontdatabase_p.h | 90 ++++ src/platformsupport/fontdatabases/winrt/winrt.pri | 11 + 4 files changed, 596 insertions(+) create mode 100644 src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp create mode 100644 src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h create mode 100644 src/platformsupport/fontdatabases/winrt/winrt.pri (limited to 'src/platformsupport') diff --git a/src/platformsupport/fontdatabases/fontdatabases.pro b/src/platformsupport/fontdatabases/fontdatabases.pro index 7fc4ecc115..9376c3b702 100644 --- a/src/platformsupport/fontdatabases/fontdatabases.pro +++ b/src/platformsupport/fontdatabases/fontdatabases.pro @@ -24,6 +24,10 @@ darwin:!if(watchos:CONFIG(simulator, simulator|device)) { win32:!winrt { include($$PWD/windows/windows.pri) } + + winrt { + include($$PWD/winrt/winrt.pri) + } } load(qt_module) diff --git a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp new file mode 100644 index 0000000000..f214184c36 --- /dev/null +++ b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp @@ -0,0 +1,491 @@ +/**************************************************************************** +** +** 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 +#include + +#include +#include +#include +#include +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; +} + +QString QWinRTFontDatabase::fontDir() const +{ + qCDebug(lcQpaFonts) << __FUNCTION__; + QString fontDirectory = QBasicFontDatabase::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; +} + +QWinRTFontDatabase::~QWinRTFontDatabase() +{ + qCDebug(lcQpaFonts) << __FUNCTION__; + + foreach (IDWriteFontFile *fontFile, m_fonts.keys()) + fontFile->Release(); + + foreach (IDWriteFontFamily *fontFamily, m_fontFamilies) + fontFamily->Release(); +} + +QFont QWinRTFontDatabase::defaultFont() const +{ + return QFont(QStringLiteral("Segoe UI")); +} + +bool QWinRTFontDatabase::fontsAlwaysScalable() const +{ + return true; +} + +void QWinRTFontDatabase::populateFontDatabase() +{ + qCDebug(lcQpaFonts) << __FUNCTION__; + + ComPtr 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))); + QBasicFontDatabase::populateFontDatabase(); + return; + } + + ComPtr fontCollection; + hr = factory->GetSystemFontCollection(&fontCollection); + if (FAILED(hr)) { + qWarning("Failed to open system font collection: %s", qPrintable(qt_error_string(hr))); + QBasicFontDatabase::populateFontDatabase(); + return; + } + + int fontFamilyCount = fontCollection->GetFontFamilyCount(); + for (int i = 0; i < fontFamilyCount; ++i) { + ComPtr fontFamily; + hr = fontCollection->GetFontFamily(i, &fontFamily); + if (FAILED(hr)) { + qWarning("Unable to get font family: %s", qPrintable(qt_error_string(hr))); + continue; + } + + ComPtr 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 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); + } + + QBasicFontDatabase::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 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 baseFontFace; + hr = font->CreateFontFace(&baseFontFace); + if (FAILED(hr)) { + qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr))); + continue; + } + ComPtr 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 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 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 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(handle); + if (!m_fonts.contains(fontFile)) + return QBasicFontDatabase::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 loader; + hr = fontFile->GetLoader(&loader); + if (FAILED(hr)) { + qWarning("Unable to get font file loader: %s", qPrintable(qt_error_string(hr))); + return 0; + } + + ComPtr 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; + const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); + QFontEngineFT::GlyphFormat format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono; + QFontEngineFT *engine = new QFontEngineFT(fontDef); + if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) { + delete engine; + return 0; + } + + return engine; +} + +QStringList QWinRTFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, + QFont::StyleHint styleHint, + QChar::Script script) const +{ + Q_UNUSED(style) + Q_UNUSED(styleHint) + Q_UNUSED(script) + + qCDebug(lcQpaFonts) << __FUNCTION__ << family; + + QStringList result; + if (family == QLatin1String("Helvetica")) + result.append(QStringLiteral("Arial")); + result.append(QBasicFontDatabase::fallbacksForFamily(family, style, styleHint, script)); + return result; +} + +void QWinRTFontDatabase::releaseHandle(void *handle) +{ + qCDebug(lcQpaFonts) << __FUNCTION__ << handle; + + if (!handle) + return; + + IDWriteFontFile *fontFile = reinterpret_cast(handle); + if (m_fonts.contains(fontFile)) { + m_fonts.remove(fontFile); + fontFile->Release(); + return; + } + + QBasicFontDatabase::releaseHandle(handle); +} + +QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h new file mode 100644 index 0000000000..9559bac0a8 --- /dev/null +++ b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** 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 +#include + +struct IDWriteFontFile; +struct IDWriteFontFamily; + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) + +struct FontDescription +{ + quint32 index; + QByteArray uuid; +}; + +class QWinRTFontDatabase : public QBasicFontDatabase +{ +public: + QString fontDir() const; + ~QWinRTFontDatabase(); + QFont defaultFont() const Q_DECL_OVERRIDE; + bool fontsAlwaysScalable() const Q_DECL_OVERRIDE; + void populateFontDatabase() Q_DECL_OVERRIDE; + void populateFamily(const QString &familyName) Q_DECL_OVERRIDE; + QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE; + QStringList fallbacksForFamily(const QString &family, QFont::Style style, + QFont::StyleHint styleHint, QChar::Script script) const Q_DECL_OVERRIDE; + void releaseHandle(void *handle) Q_DECL_OVERRIDE; +private: + QHash m_fonts; + QHash m_fontFamilies; +}; + +QT_END_NAMESPACE + +#endif // QWINRTFONTDATABASE_H diff --git a/src/platformsupport/fontdatabases/winrt/winrt.pri b/src/platformsupport/fontdatabases/winrt/winrt.pri new file mode 100644 index 0000000000..4875338182 --- /dev/null +++ b/src/platformsupport/fontdatabases/winrt/winrt.pri @@ -0,0 +1,11 @@ +QT *= gui-private + +SOURCES += \ + $$PWD/qwinrtfontdatabase.cpp + +HEADERS += \ + $$PWD/qwinrtfontdatabase_p.h + +DEFINES += __WRL_NO_DEFAULT_LIB__ + +LIBS += $$QMAKE_LIBS_CORE -ldwrite -- cgit v1.2.3 From 467b15a20c3d6eb611ea5f6ccffd5fc0df81b0c4 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 10 Nov 2016 12:45:49 +0100 Subject: Improve use of QHash to minimize double hashing Avoid looking up by key twice in a row in various locations, but instead using iterators and index lookup. Change-Id: I61a079115199ab9c041ad3a26d36b45ee3f775e0 Reviewed-by: Thiago Macieira --- src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/platformsupport') diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index ad4dd3c944..b8d997bc35 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -524,10 +524,11 @@ namespace { const void *key = *reinterpret_cast(fontFileReferenceKey); *fontFileStream = NULL; - if (!m_fontDatas.contains(key)) + auto it = m_fontDatas.constFind(key); + if (it == m_fontDatas.constEnd()) return E_FAIL; - QByteArray fontData = m_fontDatas.value(key); + QByteArray fontData = it.value(); DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData); stream->AddRef(); *fontFileStream = stream; -- cgit v1.2.3