diff options
16 files changed, 700 insertions, 27 deletions
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 1ce73023b1..9ed3906f4a 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -644,7 +644,11 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd) antialias = true; freetype = 0; default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; +#ifndef Q_OS_WIN default_hint_style = HintNone; +#else + default_hint_style = HintFull; +#endif subpixelType = Subpixel_None; lcdFilterType = 0; #if defined(FT_LCD_FILTER_H) diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index a236b79f68..f22a043548 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -62,7 +62,9 @@ #include <private/qt_x11_p.h> #endif +#ifndef Q_OS_WIN #include <unistd.h> +#endif #ifndef QT_NO_FONTCONFIG #include <fontconfig/fontconfig.h> @@ -123,7 +125,7 @@ struct QFreetypeFace private: friend class QFontEngineFT; - friend class QScopedPointerDeleter<QFreetypeFace>; + friend struct QScopedPointerDeleter<QFreetypeFace>; QFreetypeFace() : _lock(QMutex::Recursive) {} ~QFreetypeFace() {} QAtomicInt ref; @@ -131,7 +133,13 @@ private: QByteArray fontData; }; +// If this is exported this breaks compilation of the windows +// plugin as qfontengine_ft_p.h/.cpp are also compiled there +#ifndef Q_OS_WIN class Q_GUI_EXPORT QFontEngineFT : public QFontEngine +#else +class QFontEngineFT : public QFontEngine +#endif { public: diff --git a/src/platformsupport/fontdatabases/basicunix/basicunix.pri b/src/platformsupport/fontdatabases/basic/basic.pri index f83b89063b..2bff36d434 100644 --- a/src/platformsupport/fontdatabases/basicunix/basicunix.pri +++ b/src/platformsupport/fontdatabases/basic/basic.pri @@ -2,11 +2,11 @@ DEFINES += QT_NO_FONTCONFIG QT += gui-private core-private HEADERS += \ - $$PWD/qbasicunixfontdatabase_p.h \ + $$PWD/qbasicfontdatabase_p.h \ $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h SOURCES += \ - $$PWD/qbasicunixfontdatabase.cpp \ + $$PWD/qbasicfontdatabase.cpp \ $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp CONFIG += opentype @@ -58,7 +58,7 @@ contains(QT_CONFIG, freetype) { $$QT_FREETYPE_DIR/src/autofit/afloader.c\ $$QT_FREETYPE_DIR/src/autofit/autofit.c - symbian { + symbian|win32 { SOURCES += \ $$QT_FREETYPE_DIR/src/base/ftsystem.c } else { diff --git a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp index bca40591f6..329a1176c6 100644 --- a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp @@ -39,7 +39,7 @@ ** ****************************************************************************/ -#include "qbasicunixfontdatabase_p.h" +#include "qbasicfontdatabase_p.h" #include <QtGui/private/qguiapplication_p.h> #include <QtGui/QPlatformScreen> @@ -132,7 +132,7 @@ static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { { 14, 127 }, }; -static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2]) +QSupportedWritingSystems QBasicFontDatabase::determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2]) { QSupportedWritingSystems writingSystems; bool hasScript = false; @@ -186,7 +186,7 @@ static inline bool scriptRequiresOpenType(int script) || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko); } -void QBasicUnixFontDatabase::populateFontDatabase() +void QBasicFontDatabase::populateFontDatabase() { QPlatformFontDatabase::populateFontDatabase(); QString fontpath = fontDir(); @@ -208,7 +208,7 @@ void QBasicUnixFontDatabase::populateFontDatabase() } } -QFontEngine *QBasicUnixFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *usrPtr) +QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *usrPtr) { QFontEngineFT *engine; FontFile *fontfile = static_cast<FontFile *> (usrPtr); @@ -271,7 +271,7 @@ namespace { } -QFontEngine *QBasicUnixFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, +QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { QFontDef fontDef; @@ -303,7 +303,7 @@ QFontEngine *QBasicUnixFontDatabase::fontEngine(const QByteArray &fontData, qrea return fe; } -QStringList QBasicUnixFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const +QStringList QBasicFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const { Q_UNUSED(family); Q_UNUSED(style); @@ -312,18 +312,18 @@ QStringList QBasicUnixFontDatabase::fallbacksForFamily(const QString family, con return QStringList(); } -QStringList QBasicUnixFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) +QStringList QBasicFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) { return addTTFile(fontData,fileName.toLocal8Bit()); } -void QBasicUnixFontDatabase::releaseHandle(void *handle) +void QBasicFontDatabase::releaseHandle(void *handle) { FontFile *file = static_cast<FontFile *>(handle); delete file; } -QStringList QBasicUnixFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file) +QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file) { extern FT_Library qt_getFreetype(); FT_Library library = qt_getFreetype(); diff --git a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h index ee1cda3abd..2a529be2d5 100644 --- a/src/platformsupport/fontdatabases/basicunix/qbasicunixfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QBASICUNIXFONTDATABASE_H -#define QBASICUNIXFONTDATABASE_H +#ifndef QBASICFONTDATABASE_H +#define QBASICFONTDATABASE_H #include <QPlatformFontDatabase> #include <QtCore/QByteArray> @@ -53,7 +53,7 @@ struct FontFile int hintStyle; }; -class QBasicUnixFontDatabase : public QPlatformFontDatabase +class QBasicFontDatabase : public QPlatformFontDatabase { public: void populateFontDatabase(); @@ -64,6 +64,7 @@ public: void releaseHandle(void *handle); static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file); + static QSupportedWritingSystems determineWritingSystemsFromTrueTypeBits(quint32 unicodeRange[4], quint32 codePageRange[2]); }; -#endif // QBASICUNIXFONTDATABASE_H +#endif // QBASICFONTDATABASE_H diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h index c6983e1a8b..2b1e512298 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h @@ -43,9 +43,9 @@ #define QFONTCONFIGDATABASE_H #include <QPlatformFontDatabase> -#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h> +#include <QtPlatformSupport/private/qbasicfontdatabase_p.h> -class QFontconfigDatabase : public QBasicUnixFontDatabase +class QFontconfigDatabase : public QBasicFontDatabase { public: void populateFontDatabase(); diff --git a/src/platformsupport/fontdatabases/fontdatabases.pri b/src/platformsupport/fontdatabases/fontdatabases.pri index a31f050158..3e4b0e9970 100644 --- a/src/platformsupport/fontdatabases/fontdatabases.pri +++ b/src/platformsupport/fontdatabases/fontdatabases.pri @@ -2,10 +2,14 @@ DEFINES += QT_COMPILES_IN_HARFBUZZ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src CONFIG += qpa/genericunixfontdatabase +!win32|contains(QT_CONFIG, freetype) { + include($$PWD/basic/basic.pri) +} + unix { - include($$PWD/basicunix/basicunix.pri) include($$PWD/genericunix/genericunix.pri) contains(QT_CONFIG,fontconfig) { include($$PWD/fontconfig/fontconfig.pri) } } + diff --git a/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h b/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h index 63f214df54..ef2414a2d5 100644 --- a/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/genericunix/qgenericunixfontdatabase_p.h @@ -46,8 +46,8 @@ #include <QtPlatformSupport/private/qfontconfigdatabase_p.h> typedef QFontconfigDatabase QGenericUnixFontDatabase; #else -#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h> -typedef QBasicUnixFontDatabase QGenericUnixFontDatabase; +#include <QtPlatformSupport/private/qbasicfontdatabase_p.h> +typedef QBasicFontDatabase QGenericUnixFontDatabase; #endif //Q_FONTCONFIGDATABASE #endif // QGENERICUNIXFONTDATABASE_H diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 68567a3c70..18fa968ce1 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -53,7 +53,7 @@ #include <QtCore/qcoreapplication.h> -#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h> +#include <QtPlatformSupport/private/qbasicfontdatabase_p.h> QT_BEGIN_NAMESPACE @@ -78,7 +78,7 @@ QCocoaScreen::~QCocoaScreen() } QCocoaIntegration::QCocoaIntegration() - : mFontDb(new QBasicUnixFontDatabase()) + : mFontDb(new QBasicFontDatabase()) , mEventDispatcher(new QCocoaEventDispatcher()) { mPool = new QCocoaAutoReleasePool; diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp new file mode 100644 index 0000000000..1c4a855255 --- /dev/null +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -0,0 +1,492 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwindowsfontdatabase_ft.h" +#include "qwindowscontext.h" + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H + +#include <QtCore/QDir> +#include <QtCore/QSettings> +#include <QtGui/private/qfontengine_ft_p.h> +#include <QtGui/QGuiApplication> +#include <QtGui/QFontDatabase> + +static inline QFontDatabase::WritingSystem writingSystemFromScript(const QString &scriptName) +{ + if (scriptName == QStringLiteral("Western") + || scriptName == QStringLiteral("Baltic") + || scriptName == QStringLiteral("Central European") + || scriptName == QStringLiteral("Turkish") + || scriptName == QStringLiteral("Vietnamese") + || scriptName == QStringLiteral("OEM/Dos")) + return QFontDatabase::Latin; + if (scriptName == QStringLiteral("Thai")) + return QFontDatabase::Thai; + if (scriptName == QStringLiteral("Symbol") + || scriptName == QStringLiteral("Other")) + return QFontDatabase::Symbol; + if (scriptName == QStringLiteral("CHINESE_GB2312")) + return QFontDatabase::SimplifiedChinese; + if (scriptName == QStringLiteral("CHINESE_BIG5")) + return QFontDatabase::TraditionalChinese; + if (scriptName == QStringLiteral("Cyrillic")) + return QFontDatabase::Cyrillic; + if (scriptName == QStringLiteral("Hangul")) + return QFontDatabase::Korean; + if (scriptName == QStringLiteral("Hebrew")) + return QFontDatabase::Hebrew; + if (scriptName == QStringLiteral("Greek")) + return QFontDatabase::Greek; + if (scriptName == QStringLiteral("Japanese")) + return QFontDatabase::Japanese; + if (scriptName == QStringLiteral("Arabic")) + return QFontDatabase::Arabic; + return QFontDatabase::Any; +} + +// 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 bool addFontToDatabase(QString familyName, const QString &scriptName, + const TEXTMETRIC *textmetric, + const FONTSIGNATURE *signature, + int type) +{ + // the "@family" fonts are just the same as "family". Ignore them. + if (familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QStringLiteral("WST_"))) + return false; + + const int separatorPos = familyName.indexOf("::"); + const QString faceName = + separatorPos != -1 ? familyName.left(separatorPos) : familyName; + const QString fullName = + separatorPos != -1 ? familyName.mid(separatorPos + 2) : QString(); + 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 antialias = false; + const QFont::Weight weight = weightFromInteger(tm->tmWeight); + const QFont::Stretch stretch = QFont::Unstretched; + + if (QWindowsContext::verboseFonts > 2) { + QDebug nospace = qDebug().nospace(); + nospace << __FUNCTION__ << faceName << fullName << scriptName + << "TTF=" << ttf; + if (type & DEVICE_FONTTYPE) + nospace << " DEVICE"; + if (type & RASTER_FONTTYPE) + nospace << " RASTER"; + if (type & TRUETYPE_FONTTYPE) + nospace << " TRUETYPE"; + nospace << " scalable=" << scalable << " Size=" << size + << " Style=" << style << " Weight=" << weight + << " stretch=" << stretch; + } + +/* Fixme: omitted for the moment + if(ttf && localizedName(faceName) && family->english_name.isEmpty()) + family->english_name = getEnglishName(faceName); +*/ + QSupportedWritingSystems writingSystems; + if (type & TRUETYPE_FONTTYPE) { + 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 = QBasicFontDatabase::determineWritingSystemsFromTrueTypeBits(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 == QStringLiteral("Segoe UI")) + writingSystems.setSupported(QFontDatabase::Thai, false); + } else { + const QFontDatabase::WritingSystem ws = writingSystemFromScript(scriptName); + if (ws != QFontDatabase::Any) + writingSystems.setSupported(ws); + } + + const QSettings fontRegistry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts", + QSettings::NativeFormat); + + QByteArray value; + int index = 0; + foreach (const QString &key, fontRegistry.allKeys()) { + QString realKey = key; + realKey = realKey.replace("(TrueType)", ""); + realKey = realKey.trimmed(); + QStringList fonts = realKey.split('&'); + for (int i = 0; i < fonts.length(); ++i) { + const QString font = fonts[i].trimmed(); + if (font == faceName || (faceName != fullName && fullName == font)) { + value = fontRegistry.value(key).toByteArray(); + index = i; + break; + } + } + if (!value.isEmpty()) + break; + } + + if (value.isEmpty()) + return false; + + if (!QDir::isAbsolutePath(value)) + value = qgetenv("windir") + "\\Fonts\\" + value; + + // Pointer is deleted in QBasicFontDatabase::releaseHandle(void *handle) + FontFile *fontFile = new FontFile; + fontFile->fileName = value; + fontFile->indexValue = index; + + QPlatformFontDatabase::registerFont(faceName, foundryName, weight, + style, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); + // add fonts windows can generate for us: + if (weight <= QFont::DemiBold) + QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, + style, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); + if (style != QFont::StyleItalic) + QPlatformFontDatabase::registerFont(faceName, foundryName, weight, + QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); + if (weight <= QFont::DemiBold && style != QFont::StyleItalic) + QPlatformFontDatabase::registerFont(faceName, foundryName, QFont::Bold, + QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, fontFile); + return true; +} + +static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, + int type, LPARAM namesSetIn) +{ + typedef QSet<QString> StringSet; + const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName) + "::" + QString::fromWCharArray(f->elfFullName); + const QString script = QString::fromWCharArray(f->elfScript); + + 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 + if (addFontToDatabase(familyName, script, (TEXTMETRIC *)textmetric, &signature, type)) + reinterpret_cast<StringSet *>(namesSetIn)->insert(familyName); + + // keep on enumerating + return 1; +} + +void QWindowsFontDatabaseFT::populateFontDatabase() +{ + if (m_families.isEmpty()) { + QPlatformFontDatabase::populateFontDatabase(); + populate(); // Called multiple times. + // Work around EnumFontFamiliesEx() not listing the system font, see below. + const QString sysFontFamily = QGuiApplication::font().family(); + if (!m_families.contains(sysFontFamily)) + populate(sysFontFamily); + } +} + +/*! + \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::populate(const QString &family) + { + + if (QWindowsContext::verboseFonts) + qDebug() << __FUNCTION__ << m_families.size() << family; + + HDC dummy = GetDC(0); + LOGFONT lf; + lf.lfCharSet = DEFAULT_CHARSET; + if (family.size() >= LF_FACESIZE) { + qWarning("%s: Unable to enumerate family '%s'.", + __FUNCTION__, qPrintable(family)); + return; + } + wmemcpy(lf.lfFaceName, reinterpret_cast<const wchar_t*>(family.utf16()), + family.size() + 1); + lf.lfPitchAndFamily = 0; + EnumFontFamiliesEx(dummy, &lf, (FONTENUMPROC)storeFont, + (LPARAM)&m_families, 0); + ReleaseDC(0, dummy); +} + +QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle) +{ + QFontEngine *fe = QBasicFontDatabase::fontEngine(fontDef, script, handle); + if (QWindowsContext::verboseFonts) + qDebug() << __FUNCTION__ << "FONTDEF" << /*fontDef <<*/ script << fe << handle; + return fe; +} + +QFontEngine *QWindowsFontDatabaseFT::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) +{ + QFontEngine *fe = QPlatformFontDatabase::fontEngine(fontData, pixelSize, hintingPreference); + if (QWindowsContext::verboseFonts) + qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe; + return fe; +} + +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; + +QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const +{ + if(script == QUnicodeTables::Common) { +// && !(request.styleStrategy & QFont::NoFontMerging)) { + QFontDatabase db; + if (!db.writingSystems(family).contains(QFontDatabase::Symbol)) { + if(!tryFonts) { + LANGID lid = GetUserDefaultLangID(); + switch( lid&0xff ) { + case LANG_CHINESE: // Chinese (Taiwan) + if ( lid == 0x0804 ) // Taiwan + tryFonts = ch_TW_tryFonts; + else + tryFonts = ch_CN_tryFonts; + break; + case LANG_JAPANESE: + tryFonts = jp_tryFonts; + break; + case LANG_KOREAN: + tryFonts = kr_tryFonts; + break; + default: + tryFonts = other_tryFonts; + break; + } + } + QStringList list; + const char **tf = tryFonts; + while(tf && *tf) { + if(m_families.contains(QLatin1String(*tf))) + list << QLatin1String(*tf); + ++tf; + } + if (!list.isEmpty()) + return list; + } + } + QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script); + if (!result.isEmpty()) + return result; + if (QWindowsContext::verboseFonts) + qDebug() << __FUNCTION__ << family << style << styleHint + << script << result << m_families; + return result; +} + +QStringList QWindowsFontDatabaseFT::addApplicationFont(const QByteArray &fontData, const QString &fileName) +{ + const QStringList result = QPlatformFontDatabase::addApplicationFont(fontData, fileName); + Q_UNIMPLEMENTED(); + return result; +} + +QString QWindowsFontDatabaseFT::fontDir() const +{ + const QString result = QLatin1String(qgetenv("windir")) + QLatin1String("/Fonts");//QPlatformFontDatabase::fontDir(); + if (QWindowsContext::verboseFonts) + qDebug() << __FUNCTION__ << result; + return result; +} + +HFONT QWindowsFontDatabaseFT::systemFont() +{ + static const HFONT stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT); + return stock_sysfont; +} + +// Creation functions + +static inline bool scriptRequiresOpenType(int script) +{ + return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala) + || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko); +} + +static inline int verticalDPI() +{ + return GetDeviceCaps(QWindowsContext::instance()->displayContext(), LOGPIXELSY); +} + +QFont QWindowsFontDatabaseFT::defaultFont() const +{ + LOGFONT lf; + GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf); + QFont systemFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(lf); + // "MS Shell Dlg 2" is the correct system font >= Win2k + if (systemFont.family() == QStringLiteral("MS Shell Dlg")) + systemFont.setFamily(QStringLiteral("MS Shell Dlg 2")); + if (QWindowsContext::verboseFonts) + qDebug() << __FUNCTION__ << systemFont; + return systemFont; +} + +QHash<QByteArray, QFont> QWindowsFontDatabaseFT::defaultFonts() const +{ + QHash<QByteArray, QFont> result; + NONCLIENTMETRICS ncm; + ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); + + const int verticalRes = verticalDPI(); + + const QFont menuFont = LOGFONT_to_QFont(ncm.lfMenuFont, verticalRes); + const QFont messageFont = LOGFONT_to_QFont(ncm.lfMessageFont, verticalRes); + const QFont statusFont = LOGFONT_to_QFont(ncm.lfStatusFont, verticalRes); + const QFont titleFont = LOGFONT_to_QFont(ncm.lfCaptionFont, verticalRes); + + LOGFONT lfIconTitleFont; + SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0); + const QFont iconTitleFont = LOGFONT_to_QFont(lfIconTitleFont, verticalRes); + + result.insert(QByteArray("QMenu"), menuFont); + result.insert(QByteArray("QMenuBar"), menuFont); + result.insert(QByteArray("QMessageBox"), messageFont); + result.insert(QByteArray("QTipLabel"), statusFont); + result.insert(QByteArray("QStatusBar"), statusFont); + result.insert(QByteArray("Q3TitleBar"), titleFont); + result.insert(QByteArray("QWorkspaceTitleBar"), titleFont); + result.insert(QByteArray("QAbstractItemView"), iconTitleFont); + result.insert(QByteArray("QDockWidgetTitle"), iconTitleFont); + if (QWindowsContext::verboseFonts) { + typedef QHash<QByteArray, QFont>::const_iterator CIT; + QDebug nsp = qDebug().nospace(); + nsp << __FUNCTION__ << " DPI=" << verticalRes << "\n"; + const CIT cend = result.constEnd(); + for (CIT it = result.constBegin(); it != cend; ++it) + nsp << it.key() << ' ' << it.value() << '\n'; + } + return result; +} + +QFont QWindowsFontDatabaseFT::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In) +{ + if (verticalDPI_In <= 0) + verticalDPI_In = verticalDPI(); + QFont qFont(QString::fromWCharArray(logFont.lfFaceName)); + qFont.setItalic(logFont.lfItalic); + if (logFont.lfWeight != FW_DONTCARE) + qFont.setWeight(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; +} diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h new file mode 100644 index 0000000000..d9b8106227 --- /dev/null +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt 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 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSFONTDATABASEFT_H +#define QWINDOWSFONTDATABASEFT_H + +#include <QtPlatformSupport/private/qbasicfontdatabase_p.h> +#include <QtCore/QSharedPointer> +#include "qtwindows_additional.h" + +class QWindowsFontDatabaseFT : public QBasicFontDatabase +{ +public: + void populateFontDatabase(); + QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle); + QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); + + QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const; + QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); + + virtual QString fontDir() const; + virtual QFont defaultFont() const; + virtual QHash<QByteArray, QFont> defaultFonts() const; + static HFONT systemFont(); + static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0); + +private: + void populate(const QString &family = QString()); + + QSet<QString> m_families; +}; + +#endif // QWINDOWSFONTDATABASEFT_H diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 0f20e3590b..b4faf597e1 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -1221,3 +1221,4 @@ void QWindowsMultiFontEngine::loadEngine(int at) } QT_END_NAMESPACE + diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index f017cc916e..9831d568ea 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -184,3 +184,4 @@ public: QT_END_NAMESPACE #endif // QWINDOWSFONTENGINE_H + diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 7bd4e2a0b4..3ad91cdb45 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -45,6 +45,9 @@ #include "qwindowscontext.h" #include "qwindowsglcontext.h" #include "qwindowsscreen.h" +#ifndef QT_NO_FREETYPE +#include "qwindowsfontdatabase_ft.h" +#endif #include "qwindowsfontdatabase.h" #include "qwindowsguieventdispatcher.h" #include "qwindowsclipboard.h" @@ -129,10 +132,11 @@ struct QWindowsIntegrationPrivate typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr; explicit QWindowsIntegrationPrivate(bool openGL); + ~QWindowsIntegrationPrivate(); const bool m_openGL; QWindowsContext m_context; - QWindowsFontDatabase m_fontDatabase; + QPlatformFontDatabase *m_fontDatabase; QWindowsNativeInterface m_nativeInterface; QWindowsClipboard m_clipboard; QWindowsDrag m_drag; @@ -146,9 +150,16 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(bool openGL) : m_openGL(openGL) , m_context(openGL) , m_eventDispatcher(new QWindowsGuiEventDispatcher) + , m_fontDatabase(0) { } +QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() +{ + if (m_fontDatabase) + delete m_fontDatabase; +} + QWindowsIntegration::QWindowsIntegration(bool openGL) : d(new QWindowsIntegrationPrivate(openGL)) { @@ -235,7 +246,18 @@ QPlatformOpenGLContext QPlatformFontDatabase *QWindowsIntegration::fontDatabase() const { - return &d->m_fontDatabase; + if (!d->m_fontDatabase) { +#ifndef QT_NO_FREETYPE + if (d->m_nativeInterface.property("fontengine").toString() == QLatin1String("native")) + d->m_fontDatabase = new QWindowsFontDatabase(); + else + d->m_fontDatabase = new QWindowsFontDatabaseFT(); +#else + d->m_fontDatabase = new QWindowsFontDatabase(); +#endif + } + return d->m_fontDatabase; + } QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index ad97c88bc2..17bcae58eb 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -3,6 +3,7 @@ load(qt_plugin) QT *= core-private QT *= gui-private +QT *= platformsupport-private INCLUDEPATH += ../../../3rdparty/harfbuzz/src QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms @@ -68,5 +69,73 @@ HEADERS += \ qwindowsinputcontext.h \ qwindowsaccessibility.h +contains(QT_CONFIG, freetype) { + DEFINES *= QT_NO_FONTCONFIG + DEFINES *= QT_COMPILES_IN_HARFBUZZ + QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype + + HEADERS += \ + qwindowsfontdatabase_ft.h \ + $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h + SOURCES += \ + qwindowsfontdatabase_ft.cpp \ + $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp \ + $$QT_FREETYPE_DIR/src/base/ftbase.c \ + $$QT_FREETYPE_DIR/src/base/ftbbox.c \ + $$QT_FREETYPE_DIR/src/base/ftdebug.c \ + $$QT_FREETYPE_DIR/src/base/ftglyph.c \ + $$QT_FREETYPE_DIR/src/base/ftinit.c \ + $$QT_FREETYPE_DIR/src/base/ftmm.c \ + $$QT_FREETYPE_DIR/src/base/fttype1.c \ + $$QT_FREETYPE_DIR/src/base/ftsynth.c \ + $$QT_FREETYPE_DIR/src/base/ftbitmap.c \ + $$QT_FREETYPE_DIR/src/bdf/bdf.c \ + $$QT_FREETYPE_DIR/src/cache/ftcache.c \ + $$QT_FREETYPE_DIR/src/cff/cff.c \ + $$QT_FREETYPE_DIR/src/cid/type1cid.c \ + $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \ + $$QT_FREETYPE_DIR/src/pcf/pcf.c \ + $$QT_FREETYPE_DIR/src/pfr/pfr.c \ + $$QT_FREETYPE_DIR/src/psaux/psaux.c \ + $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \ + $$QT_FREETYPE_DIR/src/psnames/psmodule.c \ + $$QT_FREETYPE_DIR/src/raster/raster.c \ + $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \ + $$QT_FREETYPE_DIR/src/smooth/smooth.c \ + $$QT_FREETYPE_DIR/src/truetype/truetype.c \ + $$QT_FREETYPE_DIR/src/type1/type1.c \ + $$QT_FREETYPE_DIR/src/type42/type42.c \ + $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \ + $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\ + $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\ + $$QT_FREETYPE_DIR/src/autofit/afangles.c\ + $$QT_FREETYPE_DIR/src/autofit/afglobal.c\ + $$QT_FREETYPE_DIR/src/autofit/aflatin.c\ + $$QT_FREETYPE_DIR/src/autofit/afmodule.c\ + $$QT_FREETYPE_DIR/src/autofit/afdummy.c\ + $$QT_FREETYPE_DIR/src/autofit/afhints.c\ + $$QT_FREETYPE_DIR/src/autofit/afloader.c\ + $$QT_FREETYPE_DIR/src/autofit/autofit.c + + SOURCES += $$QT_FREETYPE_DIR/src/base/ftsystem.c + + + INCLUDEPATH += \ + $$QT_FREETYPE_DIR/src \ + $$QT_FREETYPE_DIR/include + + DEFINES += FT2_BUILD_LIBRARY + contains(QT_CONFIG, system-zlib) { + DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB + } +} + target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 60b87106b6..fc7a7f75db 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -342,7 +342,7 @@ Configure::Configure(int& argc, char** argv) dictionary[ "LIBJPEG" ] = "auto"; dictionary[ "LIBPNG" ] = "auto"; dictionary[ "LIBMNG" ] = "auto"; - dictionary[ "FREETYPE" ] = "no"; + dictionary[ "FREETYPE" ] = "yes"; dictionary[ "QT3SUPPORT" ] = "no"; dictionary[ "ACCESSIBILITY" ] = "yes"; |