diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowsfontdatabase.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowsfontdatabase.cpp | 134 |
1 files changed, 82 insertions, 52 deletions
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index bf42ca190b..743408949d 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1,31 +1,37 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** 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:LGPL21$ +** $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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** 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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** 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. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** 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$ ** @@ -44,6 +50,7 @@ #include <QtCore/qmath.h> #include <QtCore/QDebug> +#include <QtCore/QFile> #include <QtCore/QtEndian> #include <QtCore/QThreadStorage> #include <QtCore/private/qsystemlibrary_p.h> @@ -269,10 +276,10 @@ namespace { quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 }; int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount; - int newFamilyNameSize = newFamilyName.size() * sizeof(quint16); + int newFamilyNameSize = newFamilyName.size() * int(sizeof(quint16)); const QString regularString = QString::fromLatin1("Regular"); - int regularStringSize = regularString.size() * sizeof(quint16); + 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; @@ -634,11 +641,24 @@ 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; + 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 @@ -792,7 +812,7 @@ static QString getEnglishName(const uchar *table, quint32 bytes) length /= 2; i18n_name.resize(length); - QChar *uc = (QChar *) i18n_name.unicode(); + QChar *uc = const_cast<QChar *>(i18n_name.unicode()); const unsigned char *string = table + string_offset + offset; for (int i = 0; i < length; ++i) uc[i] = getUShort(string + 2*i); @@ -800,10 +820,10 @@ static QString getEnglishName(const uchar *table, quint32 bytes) // Apple Roman i18n_name.resize(length); - QChar *uc = (QChar *) i18n_name.unicode(); + QChar *uc = const_cast<QChar *>(i18n_name.unicode()); const unsigned char *string = table + string_offset + offset; for (int i = 0; i < length; ++i) - uc[i] = QLatin1Char(string[i]); + uc[i] = QLatin1Char(char(string[i])); } } } @@ -870,14 +890,13 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet, static const int SMOOTH_SCALABLE = 0xffff; const QString foundryName; // No such concept. - const NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; - const bool fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - const bool ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - const bool scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal; + 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(tm->tmWeight); + const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(textmetric->tmWeight); const QFont::Stretch stretch = QFont::Unstretched; #ifndef QT_NO_DEBUG_OUTPUT @@ -957,18 +976,21 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet, return true; } -static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, - int type, LPARAM registerAlias) +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 uchar charSet = f->elfLogFont.lfCharSet; + const bool registerAlias = bool(lParam); - const FONTSIGNATURE signature = textmetric->ntmFontSig; - - // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is - // identical to a TEXTMETRIC except for the last four members, which we don't use - // anyway - addFontToDatabase(familyName, charSet, (TEXTMETRIC *)textmetric, &signature, type, registerAlias); + // NEWTEXTMETRICEX (passed for TT fonts) is a NEWTEXTMETRIC, which according + // to the documentation is identical to a TEXTMETRIC except for the last four + // members, which we don't use anyway + const FONTSIGNATURE *signature = Q_NULLPTR; + if (type & TRUETYPE_FONTTYPE) + signature = &reinterpret_cast<const NEWTEXTMETRICEX *>(textmetric)->ntmFontSig; + addFontToDatabase(familyName, charSet, textmetric, signature, type, registerAlias); // keep on enumerating return 1; @@ -987,7 +1009,7 @@ void QWindowsFontDatabase::populateFamily(const QString &familyName, bool regist familyName.toWCharArray(lf.lfFaceName); lf.lfFaceName[familyName.size()] = 0; lf.lfPitchAndFamily = 0; - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, (LPARAM)registerAlias, 0); + EnumFontFamiliesEx(dummy, &lf, storeFont, LPARAM(registerAlias), 0); ReleaseDC(0, dummy); } @@ -1008,9 +1030,11 @@ struct PopulateFamiliesContext }; } // namespace -static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *tm, int, LPARAM lparam) +static int QT_WIN_CALLBACK populateFontFamilies(const LOGFONT *logFont, const TEXTMETRIC *textmetric, + DWORD, LPARAM lparam) { // the "@family" fonts are just the same as "family". Ignore them. + const ENUMLOGFONTEX *f = reinterpret_cast<const ENUMLOGFONTEX *>(logFont); const wchar_t *faceNameW = f->elfLogFont.lfFaceName; if (faceNameW[0] && faceNameW[0] != L'@' && wcsncmp(faceNameW, L"WST_", 4)) { const QString faceName = QString::fromWCharArray(faceNameW); @@ -1020,7 +1044,7 @@ static int QT_WIN_CALLBACK populateFontFamilies(ENUMLOGFONTEX* f, NEWTEXTMETRICE context->seenSystemDefaultFont = true; // Register current font's english name as alias - const bool ttf = (tm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE); + const bool ttf = textmetric->tmPitchAndFamily & TMPF_TRUETYPE; if (ttf && localizedName(faceName)) { const QString englishName = getEnglishName(faceName); if (!englishName.isEmpty()) { @@ -1044,7 +1068,7 @@ void QWindowsFontDatabase::populateFontDatabase() lf.lfFaceName[0] = 0; lf.lfPitchAndFamily = 0; PopulateFamiliesContext context(QWindowsFontDatabase::systemDefaultFont().family()); - EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); + EnumFontFamiliesEx(dummy, &lf, populateFontFamilies, reinterpret_cast<LPARAM>(&context), 0); ReleaseDC(0, dummy); // Work around EnumFontFamiliesEx() not listing the system font. if (!context.seenSystemDefaultFont) @@ -1062,7 +1086,7 @@ QSharedPointer<QWindowsFontEngineData> sharedFontData() { FontEngineThreadLocalData *data = fontEngineThreadLocalData(); if (!data->hasLocalData()) - data->setLocalData(QSharedPointer<QWindowsFontEngineData>(new QWindowsFontEngineData)); + data->setLocalData(QSharedPointer<QWindowsFontEngineData>::create()); return data->localData(); } #else // !QT_NO_THREAD @@ -1072,7 +1096,7 @@ QWindowsFontEngineDataPtr sharedFontData() { QWindowsFontEngineDataPtr *data = fontEngineData(); if (data->isNull()) - *data = QWindowsFontEngineDataPtr(new QWindowsFontEngineData); + *data = QWindowsFontEngineDataPtr::create(); return *data; } #endif // QT_NO_THREAD @@ -1150,8 +1174,9 @@ QT_WARNING_POP DWORD count = 0; QByteArray newFontData = font.data(); - HANDLE fontHandle = AddFontMemResourceEx((void *)newFontData.constData(), newFontData.size(), 0, - &count); + HANDLE fontHandle = + AddFontMemResourceEx(const_cast<char *>(newFontData.constData()), + DWORD(newFontData.size()), 0, &count); if (count == 0 && fontHandle != 0) { RemoveFontMemResourceEx(fontHandle); fontHandle = 0; @@ -1369,8 +1394,9 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, return families; DWORD dummy = 0; - font.handle = AddFontMemResourceEx((void *)fontData.constData(), fontData.size(), 0, - &dummy); + font.handle = + AddFontMemResourceEx(const_cast<char *>(fontData.constData()), + DWORD(fontData.size()), 0, &dummy); if (font.handle == 0) return QStringList(); @@ -1605,7 +1631,7 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request) lf.lfPitchAndFamily = DEFAULT_PITCH | hint; QString fam = request.family; - if (fam.size() >= LF_FACESIZE) { + if (Q_UNLIKELY(fam.size() >= LF_FACESIZE)) { qCritical("%s: Family name '%s' is too long.", __FUNCTION__, qPrintable(fam)); fam.truncate(LF_FACESIZE - 1); } @@ -1746,12 +1772,16 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, IDWriteFont *directWriteFont = 0; HRESULT hr = data->directWriteGdiInterop->CreateFontFromLOGFONT(&lf, &directWriteFont); if (FAILED(hr)) { - qErrnoWarning("%s: CreateFontFromLOGFONT failed", __FUNCTION__); + const QString errorString = qt_error_string(int(GetLastError())); + qWarning().noquote().nospace() << "DirectWrite: CreateFontFromLOGFONT() failed (" + << errorString << ") for " << request << ' ' << lf << " dpi=" << dpi; } else { IDWriteFontFace *directWriteFontFace = NULL; hr = directWriteFont->CreateFontFace(&directWriteFontFace); if (FAILED(hr)) { - qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__); + const QString errorString = qt_error_string(int(GetLastError())); + qWarning().noquote() << "DirectWrite: CreateFontFace() failed (" + << errorString << ") for " << request << ' ' << lf << " dpi=" << dpi; } else { QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace, request.pixelSize, |