summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows/qwindowsfontdatabase.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp218
1 files changed, 81 insertions, 137 deletions
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 9c26a227b8..56adae8ffb 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
@@ -10,9 +10,9 @@
** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** 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.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** 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.
**
** $QT_END_LICENSE$
@@ -618,20 +618,6 @@ QDebug operator<<(QDebug d, const QFontDef &def)
return d;
}
-// convert 0 ~ 1000 integer to QFont::Weight
-static inline QFont::Weight weightFromInteger(long weight)
-{
- if (weight < 400)
- return QFont::Light;
- if (weight < 600)
- return QFont::Normal;
- if (weight < 700)
- return QFont::DemiBold;
- if (weight < 800)
- return QFont::Bold;
- return QFont::Black;
-}
-
static inline QFontDatabase::WritingSystem writingSystemFromCharSet(uchar charSet)
{
switch (charSet) {
@@ -808,7 +794,7 @@ QString getEnglishName(const QString &familyName)
HDC hdc = GetDC( 0 );
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
- memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length()) * sizeof(wchar_t));
+ memcpy(lf.lfFaceName, familyName.utf16(), qMin(familyName.length(), LF_FACESIZE - 1) * sizeof(wchar_t));
lf.lfCharSet = DEFAULT_CHARSET;
HFONT hfont = CreateFontIndirect(&lf);
@@ -865,7 +851,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
const int size = scalable ? SMOOTH_SCALABLE : tm->tmHeight;
const QFont::Style style = tm->tmItalic ? QFont::StyleItalic : QFont::StyleNormal;
const bool antialias = false;
- const QFont::Weight weight = weightFromInteger(tm->tmWeight);
+ const QFont::Weight weight = QPlatformFontDatabase::weightFromInteger(tm->tmWeight);
const QFont::Stretch stretch = QFont::Unstretched;
#ifndef QT_NO_DEBUG_OUTPUT
@@ -1078,15 +1064,15 @@ QFontEngineMulti *QWindowsFontDatabase::fontEngineMulti(QFontEngine *fontEngine,
if (script == QChar::Script_Common)
return new QWindowsMultiFontEngine(fontEngine, script);
// ### as long as fallbacksForFamily() does not take script parameter into account,
- // prefer QFontEngineMultiBasicImpl's loadEngine() implementation for complex scripts
+ // prefer QFontEngineMulti's loadEngine() implementation for complex scripts
return QPlatformFontDatabase::fontEngineMulti(fontEngine, script);
}
QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
{
- QFontEngine *fe = QWindowsFontDatabase::createEngine(fontDef, 0,
+ QFontEngine *fe = QWindowsFontDatabase::createEngine(fontDef,
QWindowsContext::instance()->defaultDPI(),
- false, sharedFontData());
+ sharedFontData());
qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << fe << handle;
return fe;
}
@@ -1134,9 +1120,9 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal
request.styleStrategy = QFont::PreferMatch;
request.hintingPreference = hintingPreference;
- fontEngine = QWindowsFontDatabase::createEngine(request, 0,
+ fontEngine = QWindowsFontDatabase::createEngine(request,
QWindowsContext::instance()->defaultDPI(),
- false, sharedFontData());
+ sharedFontData());
if (fontEngine) {
if (request.family != fontEngine->fontDef.family) {
@@ -1238,7 +1224,7 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal
else
fontEngine->fontDef.style = QFont::StyleNormal;
- fontEngine->fontDef.weight = weightFromInteger(qFromBigEndian<quint16>(os2Table->weightClass));
+ fontEngine->fontDef.weight = QPlatformFontDatabase::weightFromInteger(qFromBigEndian<quint16>(os2Table->weightClass));
}
}
@@ -1349,7 +1335,7 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
HDC hdc = GetDC(0);
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
- memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE, familyName.size()));
+ memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE - 1, familyName.size()));
lf.lfCharSet = DEFAULT_CHARSET;
HFONT hfont = CreateFontIndirect(&lf);
HGDIOBJ oldobj = SelectObject(hdc, hfont);
@@ -1436,7 +1422,7 @@ void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont)
HFONT QWindowsFontDatabase::systemFont()
{
- static const HFONT stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT);
+ static const HFONT stock_sysfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
return stock_sysfont;
}
@@ -1574,6 +1560,10 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request)
lf.lfPitchAndFamily = DEFAULT_PITCH | hint;
QString fam = request.family;
+ if (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");
@@ -1585,7 +1575,7 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request)
if (fam == QLatin1String("Courier") && !(request.styleStrategy & QFont::PreferBitmap))
fam = QStringLiteral("Courier New");
- memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
+ memcpy(lf.lfFaceName, fam.utf16(), fam.size() * sizeof(wchar_t));
return lf;
}
@@ -1668,21 +1658,9 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFon
QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request,
- HDC fontHdc, int dpi, bool rawMode,
+ int dpi,
const QSharedPointer<QWindowsFontEngineData> &data)
{
- LOGFONT lf;
- memset(&lf, 0, sizeof(LOGFONT));
-
- const bool useDevice = (request.styleStrategy & QFont::PreferDevice) && fontHdc;
-
- const HDC hdc = useDevice ? fontHdc : data->hdc;
-
- bool stockFont = false;
- bool preferClearTypeAA = false;
-
- HFONT hfont = 0;
-
#if !defined(QT_NO_DIRECTWRITE)
bool useDirectWrite = (request.hintingPreference == QFont::PreferNoHinting)
|| (request.hintingPreference == QFont::PreferVerticalHinting);
@@ -1691,105 +1669,71 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request,
bool useDirectWrite = false;
#endif
- if (rawMode) { // will choose a stock font
- int f = SYSTEM_FONT;
- const QString fam = request.family.toLower();
- if (fam == QLatin1String("default") || fam == QLatin1String("system"))
- f = SYSTEM_FONT;
-#ifndef Q_OS_WINCE
- else if (fam == QLatin1String("system_fixed"))
- f = SYSTEM_FIXED_FONT;
- else if (fam == QLatin1String("ansi_fixed"))
- f = ANSI_FIXED_FONT;
- else if (fam == QLatin1String("ansi_var"))
- f = ANSI_VAR_FONT;
- else if (fam == QLatin1String("device_default"))
- f = DEVICE_DEFAULT_FONT;
- else if (fam == QLatin1String("oem_fixed"))
- f = OEM_FIXED_FONT;
-#endif
- else if (fam.at(0) == QLatin1Char('#'))
- f = fam.right(fam.length()-1).toInt();
- hfont = (HFONT)GetStockObject(f);
- if (!hfont) {
- qErrnoWarning("%s: GetStockObject failed", __FUNCTION__);
- hfont = QWindowsFontDatabase::systemFont();
- }
- stockFont = true;
- } else {
- lf = fontDefToLOGFONT(request);
- preferClearTypeAA = lf.lfQuality == CLEARTYPE_QUALITY;
-
- hfont = CreateFontIndirect(&lf);
- if (!hfont)
- qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__);
-
- stockFont = (hfont == 0);
- bool ttf = false;
- int avWidth = 0;
- BOOL res;
- HGDIOBJ oldObj = SelectObject(hdc, hfont);
-
- TEXTMETRIC tm;
- res = GetTextMetrics(hdc, &tm);
- avWidth = tm.tmAveCharWidth;
- ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE;
- SelectObject(hdc, oldObj);
-
- if (!useDirectWrite) {
- if (hfont && (!ttf || request.stretch != 100)) {
- DeleteObject(hfont);
- if (!res)
- qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed");
- lf.lfWidth = avWidth * request.stretch/100;
- hfont = CreateFontIndirect(&lf);
- if (!hfont)
- qErrnoWarning("%s: CreateFontIndirect with stretch failed", __FUNCTION__);
- }
+ LOGFONT lf = fontDefToLOGFONT(request);
+ const bool preferClearTypeAA = lf.lfQuality == CLEARTYPE_QUALITY;
-#ifndef Q_OS_WINCE
- if (hfont == 0) {
- hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
- stockFont = true;
- }
-#else
- if (hfont == 0) {
- hfont = (HFONT)GetStockObject(SYSTEM_FONT);
- stockFont = true;
+ HFONT hfont = 0;
+ hfont = CreateFontIndirect(&lf);
+ if (!hfont) {
+ qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__);
+ hfont = QWindowsFontDatabase::systemFont();
+ }
+
+ bool ttf = false;
+ int avWidth = 0;
+ BOOL res;
+ HGDIOBJ oldObj = SelectObject(data->hdc, hfont);
+
+ TEXTMETRIC tm;
+ res = GetTextMetrics(data->hdc, &tm);
+ avWidth = tm.tmAveCharWidth;
+ ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE;
+ SelectObject(data->hdc, oldObj);
+
+ if (!useDirectWrite) {
+ if (!ttf || request.stretch != 100) {
+ DeleteObject(hfont);
+ if (!res)
+ qErrnoWarning("%s: GetTextMetrics failed", __FUNCTION__);
+ lf.lfWidth = avWidth * request.stretch/100;
+ hfont = CreateFontIndirect(&lf);
+ if (!hfont) {
+ qErrnoWarning("%s: CreateFontIndirect with stretch failed", __FUNCTION__);
+ hfont = QWindowsFontDatabase::systemFont();
}
-#endif
}
+ }
#if !defined(QT_NO_DIRECTWRITE)
- else {
- // Default to false for DirectWrite (and re-enable once/if everything
- // turns out okay)
- useDirectWrite = false;
- if (initDirectWrite(data.data())) {
- const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(QString::fromWCharArray(lf.lfFaceName));
- memcpy(lf.lfFaceName, nameSubstitute.utf16(),
- sizeof(wchar_t) * qMin(nameSubstitute.length() + 1, LF_FACESIZE));
-
- HRESULT hr = data->directWriteGdiInterop->CreateFontFromLOGFONT(
- &lf,
- &directWriteFont);
- if (FAILED(hr)) {
- qErrnoWarning("%s: CreateFontFromLOGFONT failed", __FUNCTION__);
- } else {
- DeleteObject(hfont);
- useDirectWrite = true;
- }
- }
+ else {
+ // Default to false for DirectWrite (and re-enable once/if everything turns out okay)
+ useDirectWrite = false;
+ 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;
+ }
+
+ HRESULT hr = data->directWriteGdiInterop->CreateFontFromLOGFONT(&lf, &directWriteFont);
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: CreateFontFromLOGFONT failed", __FUNCTION__);
+ } else {
+ DeleteObject(hfont);
+ useDirectWrite = true;
+ }
}
-#endif
}
+#endif
QFontEngine *fe = 0;
- if (!useDirectWrite) {
- QWindowsFontEngine *few = new QWindowsFontEngine(request.family, hfont, stockFont, lf, data);
+ if (!useDirectWrite) {
+ QWindowsFontEngine *few = new QWindowsFontEngine(request.family, hfont, lf, data);
if (preferClearTypeAA)
few->glyphFormat = QFontEngine::Format_A32;
- few->initFontInfo(request, fontHdc, dpi);
+ few->initFontInfo(request, dpi);
fe = few;
}
@@ -1806,10 +1750,10 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request,
} else {
qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__);
}
- }
- if (directWriteFont != 0)
directWriteFont->Release();
+ }
+
#endif
return fe;
@@ -1823,7 +1767,7 @@ static inline int verticalDPI()
QFont QWindowsFontDatabase::systemDefaultFont()
{
LOGFONT lf;
- GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &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"))
@@ -1839,7 +1783,7 @@ QFont QWindowsFontDatabase::LOGFONT_to_QFont(const LOGFONT& logFont, int vertica
QFont qFont(QString::fromWCharArray(logFont.lfFaceName));
qFont.setItalic(logFont.lfItalic);
if (logFont.lfWeight != FW_DONTCARE)
- qFont.setWeight(weightFromInteger(logFont.lfWeight));
+ qFont.setWeight(QPlatformFontDatabase::weightFromInteger(logFont.lfWeight));
const qreal logFontHeight = qAbs(logFont.lfHeight);
qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
qFont.setUnderline(logFont.lfUnderline);