diff options
author | Tor Arne Vestbø <tor.arne.vestbo@digia.com> | 2014-05-12 14:57:35 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-05-15 02:51:06 +0200 |
commit | a5ea74b98ba6b321f4c6cf87d01e8264d9f98818 (patch) | |
tree | 62e1d6ba49837c249a5fc4e7e9295a11bad96436 /src/gui/text/qfontengine.cpp | |
parent | cd910e9254e07d2c1cc7b9aadeeef24ba96fbf78 (diff) |
qpa: Clean up and refactor qfontengine_qpa
QFontEngineQPA was really QFontEngineQPF2, and has been renamed. The
multi font engine in qfontengine_qpa.cpp was really a base implementation
of a multi font engine, used by other multi font engines, and has been
renamed and moved accordingly into qfontengine_p.h/cpp.
Change-Id: Iac7409c4dbf0fdc3ee993ce4f7dc96cb00a422e6
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
Diffstat (limited to 'src/gui/text/qfontengine.cpp')
-rw-r--r-- | src/gui/text/qfontengine.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 078e16574f..6b05fa254f 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -42,6 +42,10 @@ #include <qdebug.h> #include <private/qfontengine_p.h> #include <private/qfontengineglyphcache_p.h> +#include <private/qguiapplication_p.h> + +#include <qpa/qplatformfontdatabase.h> +#include <qpa/qplatformintegration.h> #include "qbitmap.h" #include "qpainter.h" @@ -1985,4 +1989,115 @@ QImage QFontEngineMulti::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPosit return engine(which)->alphaRGBMapForGlyph(stripped(glyph), subPixelPosition, t); } +/* + Creates a new multi engine. + + This function takes ownership of the QFontEngine, increasing it's refcount. +*/ +QFontEngineMultiBasicImpl::QFontEngineMultiBasicImpl(QFontEngine *fe, int _script, const QStringList &fallbacks) + : QFontEngineMulti(fallbacks.size() + 1), + fallbackFamilies(fallbacks), script(_script) + , fallbacksQueried(true) +{ + init(fe); +} + +QFontEngineMultiBasicImpl::QFontEngineMultiBasicImpl(QFontEngine *fe, int _script) + : QFontEngineMulti(2) + , script(_script) + , fallbacksQueried(false) +{ + fallbackFamilies << QString(); + init(fe); +} + +void QFontEngineMultiBasicImpl::init(QFontEngine *fe) +{ + Q_ASSERT(fe && fe->type() != QFontEngine::Multi); + engines[0] = fe; + fe->ref.ref(); + fontDef = engines[0]->fontDef; + cache_cost = fe->cache_cost; +} + +void QFontEngineMultiBasicImpl::loadEngine(int at) +{ + ensureFallbackFamiliesQueried(); + Q_ASSERT(at < engines.size()); + Q_ASSERT(engines.at(at) == 0); + QFontDef request = fontDef; + request.styleStrategy |= QFont::NoFontMerging; + request.family = fallbackFamilies.at(at-1); + engines[at] = QFontDatabase::findFont(script, + /*fontprivate = */0, + request, /*multi = */false); + Q_ASSERT(engines[at]); + engines[at]->ref.ref(); + engines[at]->fontDef = request; +} +void QFontEngineMultiBasicImpl::ensureFallbackFamiliesQueried() +{ + if (fallbacksQueried) + return; + QStringList fallbacks = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fallbacksForFamily(engine(0)->fontDef.family, QFont::Style(engine(0)->fontDef.style) + , QFont::AnyStyle, QChar::Script(script)); + setFallbackFamiliesList(fallbacks); +} + +void QFontEngineMultiBasicImpl::setFallbackFamiliesList(const QStringList &fallbacks) +{ + // 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(); + } + fallbacksQueried = true; +} + +/* + This is used indirectly by Qt WebKit when using QTextLayout::setRawFont + + The purpose of this is to provide the necessary font fallbacks when drawing complex + text. Since Qt WebKit ends up repeatedly creating QTextLayout instances and passing them + the same raw font over and over again, we want to cache the corresponding multi font engine + as it may contain fallback font engines already. +*/ +QFontEngine* QFontEngineMultiBasicImpl::createMultiFontEngine(QFontEngine *fe, int script) +{ + QFontEngine *engine = 0; + QFontCache::Key key(fe->fontDef, script, /*multi = */true); + QFontCache *fc = QFontCache::instance(); + // We can't rely on the fontDef (and hence the cache Key) + // alone to distinguish webfonts, since these should not be + // accidentally shared, even if the resulting fontcache key + // is strictly identical. See: + // http://www.w3.org/TR/css3-fonts/#font-face-rule + const bool faceIsLocal = !fe->faceId().filename.isEmpty(); + QFontCache::EngineCache::Iterator it = fc->engineCache.find(key), + end = fc->engineCache.end(); + while (it != end && it.key() == key) { + Q_ASSERT(it.value().data->type() == QFontEngine::Multi); + QFontEngineMulti *cachedEngine = static_cast<QFontEngineMulti *>(it.value().data); + if (faceIsLocal || fe == cachedEngine->engine(0)) { + engine = cachedEngine; + fc->updateHitCountAndTimeStamp(it.value()); + break; + } + it++; + } + if (!engine) { + engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script)); + QFontCache::instance()->insertEngine(key, engine, /* insertMulti */ !faceIsLocal); + } + Q_ASSERT(engine); + return engine; +} + QT_END_NAMESPACE |