diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowsfontdatabase.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowsfontdatabase.cpp | 103 |
1 files changed, 31 insertions, 72 deletions
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 9c26a227b8..91bc4c64a5 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -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); @@ -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,17 +1658,12 @@ 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; @@ -1691,32 +1676,7 @@ 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; @@ -1724,17 +1684,16 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, if (!hfont) qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__); - stockFont = (hfont == 0); bool ttf = false; int avWidth = 0; BOOL res; - HGDIOBJ oldObj = SelectObject(hdc, hfont); + HGDIOBJ oldObj = SelectObject(data->hdc, hfont); TEXTMETRIC tm; - res = GetTextMetrics(hdc, &tm); + res = GetTextMetrics(data->hdc, &tm); avWidth = tm.tmAveCharWidth; ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE; - SelectObject(hdc, oldObj); + SelectObject(data->hdc, oldObj); if (!useDirectWrite) { if (hfont && (!ttf || request.stretch != 100)) { @@ -1748,15 +1707,11 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, } #ifndef Q_OS_WINCE - if (hfont == 0) { + if (hfont == 0) hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); - stockFont = true; - } #else - if (hfont == 0) { + if (hfont == 0) hfont = (HFONT)GetStockObject(SYSTEM_FONT); - stockFont = true; - } #endif } @@ -1766,9 +1721,13 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, // 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)); + 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, @@ -1786,10 +1745,10 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, QFontEngine *fe = 0; if (!useDirectWrite) { - QWindowsFontEngine *few = new QWindowsFontEngine(request.family, hfont, stockFont, lf, data); + 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; } @@ -1839,7 +1798,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); |