Guarantee QPFDB::fontEngine() always return non-multi font engine

After QPA refactoring, QWindowsFontDatabase::fontEngine() was returning
a multi font engine w/o any particular reason.
This makes the code more obvious and opens the road to further improvements.

Change-Id: I4858026ddf774d3159c89357b1c905f5112b1c51
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
Konstantin Ritt 2014-03-07 02:46:45 +02:00 committed by The Qt Project
parent 4b3d11efc0
commit c3b2425791
5 changed files with 41 additions and 41 deletions

View File

@ -790,6 +790,7 @@ QFontEngine *loadSingleEngine(int script,
if (!engine) { if (!engine) {
engine = pfdb->fontEngine(def, size->handle); engine = pfdb->fontEngine(def, size->handle);
if (engine) { if (engine) {
Q_ASSERT(engine->type() != QFontEngine::Multi);
// Also check for OpenType tables when using complex scripts // Also check for OpenType tables when using complex scripts
if (!engine->supportsScript(QChar::Script(script))) { if (!engine->supportsScript(QChar::Script(script))) {
qWarning(" OpenType support missing for script %d", script); qWarning(" OpenType support missing for script %d", script);
@ -809,12 +810,10 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
QtFontFamily *family, QtFontFoundry *foundry, QtFontFamily *family, QtFontFoundry *foundry,
QtFontStyle *style, QtFontSize *size) QtFontStyle *style, QtFontSize *size)
{ {
QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size); QFontEngine *engine = loadSingleEngine(script, request, foundry, style, size);
Q_ASSERT(!engine || engine->type() != QFontEngine::Multi);
if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
// make sure that the db has all fallback families // make sure that the db has all fallback families
if (engine && engine->type() != QFontEngine::Multi
&& !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol ) {
if (family && !family->askedForFallback) { if (family && !family->askedForFallback) {
QFont::Style fontStyle = QFont::Style(style->key.style); QFont::Style fontStyle = QFont::Style(style->key.style);
QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint); QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);

View File

@ -1038,11 +1038,17 @@ QWindowsFontDatabase::~QWindowsFontDatabase()
removeApplicationFonts(); removeApplicationFonts();
} }
QFontEngineMulti *QWindowsFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
{
Q_UNUSED(script)
return new QWindowsMultiFontEngine(fontEngine, QStringList());
}
QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle) QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
{ {
QFontEngine *fe = QWindowsFontDatabase::createEngine(QChar::Script_Common, fontDef, QFontEngine *fe = QWindowsFontDatabase::createEngine(fontDef, 0,
0, QWindowsContext::instance()->defaultDPI(), false, QWindowsContext::instance()->defaultDPI(),
QStringList(), sharedFontData()); false, sharedFontData());
qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << fe << handle; qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << fe << handle;
return fe; return fe;
} }
@ -1087,12 +1093,12 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal
QFontDef request; QFontDef request;
request.family = uniqueFamilyName; request.family = uniqueFamilyName;
request.pixelSize = pixelSize; request.pixelSize = pixelSize;
request.styleStrategy = QFont::NoFontMerging | QFont::PreferMatch; request.styleStrategy = QFont::PreferMatch;
request.hintingPreference = hintingPreference; request.hintingPreference = hintingPreference;
fontEngine = QWindowsFontDatabase::createEngine(QChar::Script_Common, request, 0, fontEngine = QWindowsFontDatabase::createEngine(request, 0,
QWindowsContext::instance()->defaultDPI(), false, QStringList(), QWindowsContext::instance()->defaultDPI(),
sharedFontData()); false, sharedFontData());
if (fontEngine) { if (fontEngine) {
if (request.family != fontEngine->fontDef.family) { if (request.family != fontEngine->fontDef.family) {
@ -1623,9 +1629,8 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFon
} }
QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &request, QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request,
HDC fontHdc, int dpi, bool rawMode, HDC fontHdc, int dpi, bool rawMode,
const QStringList &family_list,
const QSharedPointer<QWindowsFontEngineData> &data) const QSharedPointer<QWindowsFontEngineData> &data)
{ {
LOGFONT lf; LOGFONT lf;
@ -1769,17 +1774,6 @@ QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &requ
directWriteFont->Release(); directWriteFont->Release();
#endif #endif
if ((script == QChar::Script_Common || script == QChar::Script_Han)
&& !(request.styleStrategy & QFont::NoFontMerging)) {
const QStringList extraFonts = QWindowsFontDatabase::extraTryFontsForFamily(request.family);
if (extraFonts.size()) {
QStringList list = family_list;
list.append(extraFonts);
QFontEngine *mfe = new QWindowsMultiFontEngine(fe, list);
mfe->fontDef = fe->fontDef;
fe = mfe;
}
}
return fe; return fe;
} }

View File

@ -78,6 +78,7 @@ public:
~QWindowsFontDatabase(); ~QWindowsFontDatabase();
virtual void populateFontDatabase(); virtual void populateFontDatabase();
virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
virtual QFontEngine *fontEngine(const QFontDef &fontDef, void *handle); virtual QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const; virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
@ -92,9 +93,8 @@ public:
static QFont systemDefaultFont(); static QFont systemDefaultFont();
static QFontEngine *createEngine(int script, const QFontDef &request, static QFontEngine *createEngine(const QFontDef &request,
HDC fontHdc, int dpi, bool rawMode, HDC fontHdc, int dpi, bool rawMode,
const QStringList &family_list,
const QSharedPointer<QWindowsFontEngineData> &data); const QSharedPointer<QWindowsFontEngineData> &data);
static HFONT systemFont(); static HFONT systemFont();

View File

@ -1233,15 +1233,11 @@ QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const
if (!uniqueFamilyName.isEmpty()) if (!uniqueFamilyName.isEmpty())
request.family = uniqueFamilyName; request.family = uniqueFamilyName;
request.pixelSize = pixelSize; request.pixelSize = pixelSize;
// Disable font merging, as otherwise createEngine will return a multi-engine
// instance instead of the specific engine we wish to clone.
request.styleStrategy |= QFont::NoFontMerging;
QFontEngine *fontEngine = QFontEngine *fontEngine =
QWindowsFontDatabase::createEngine(QChar::Script_Common, request, 0, QWindowsFontDatabase::createEngine(request, 0,
QWindowsContext::instance()->defaultDPI(), QWindowsContext::instance()->defaultDPI(),
false, false, m_fontEngineData);
QStringList(), m_fontEngineData);
if (fontEngine) { if (fontEngine) {
fontEngine->fontDef.family = actualFontName; fontEngine->fontDef.family = actualFontName;
if (!uniqueFamilyName.isEmpty()) { if (!uniqueFamilyName.isEmpty()) {
@ -1285,18 +1281,28 @@ void QWindowsFontEngine::initFontInfo(const QFontDef &request,
QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks) QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks)
: QFontEngineMulti(fallbacks.size() + 1), : QFontEngineMulti(fallbacks.size() + 1),
fallbacks(fallbacks) fallbackFamilies(fallbacks)
{ {
qCDebug(lcQpaFonts) << __FUNCTION__ << engines.size() << first << first->fontDef.family << fallbacks;
engines[0] = first; engines[0] = first;
first->ref.ref(); first->ref.ref();
fontDef = engines[0]->fontDef; fontDef = engines[0]->fontDef;
cache_cost = first->cache_cost; cache_cost = first->cache_cost;
} }
QWindowsMultiFontEngine::~QWindowsMultiFontEngine() void QWindowsMultiFontEngine::setFallbackFamiliesList(const QStringList &fallbacks)
{ {
qCDebug(lcQpaFonts) << __FUNCTION__; // Original FontEngine to restore after the fill.
QFontEngine *fe = engines[0];
fallbackFamilies = fallbacks;
if (!fallbackFamilies.isEmpty()) {
engines.fill(0, fallbackFamilies.size() + 1);
engines[0] = fe;
} else {
// Turns out we lied about having any fallback at all.
fallbackFamilies << fe->fontDef.family;
engines[1] = fe;
fe->ref.ref();
}
} }
void QWindowsMultiFontEngine::loadEngine(int at) void QWindowsMultiFontEngine::loadEngine(int at)
@ -1323,7 +1329,7 @@ void QWindowsMultiFontEngine::loadEngine(int at)
data = fe->fontEngineData(); data = fe->fontEngineData();
} }
const QString fam = fallbacks.at(at-1); const QString fam = fallbackFamilies.at(at-1);
memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
#ifndef QT_NO_DIRECTWRITE #ifndef QT_NO_DIRECTWRITE

View File

@ -170,10 +170,11 @@ class QWindowsMultiFontEngine : public QFontEngineMulti
{ {
public: public:
QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks); QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks);
virtual ~QWindowsMultiFontEngine();
void setFallbackFamiliesList(const QStringList &fallbacks);
void loadEngine(int at); void loadEngine(int at);
QStringList fallbacks; QStringList fallbackFamilies;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE