summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/kernel/qevent.cpp1
-rw-r--r--src/gui/text/qfontdatabase.cpp35
-rw-r--r--src/gui/text/qfontengine.cpp37
3 files changed, 71 insertions, 2 deletions
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 916b13df44..139b36ef71 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -972,6 +972,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
\li scrolling is about to begin, but the distance did not yet change (Qt::ScrollBegin),
\li or scrolling has ended and the distance did not change anymore (Qt::ScrollEnd).
\endlist
+ \note On X11 this value is driver specific and unreliable, use angleDelta() instead
*/
/*!
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 2cc071d67b..33dc27983a 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -2837,6 +2837,41 @@ QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
return QGuiApplicationPrivate::platformIntegration()->fontDatabase()->resolveFontFamilyAlias(family);
}
+Q_GUI_EXPORT QStringList qt_sort_families_by_writing_system(QChar::Script script, const QStringList &families)
+{
+ size_t writingSystem = std::find(scriptForWritingSystem,
+ scriptForWritingSystem + QFontDatabase::WritingSystemsCount,
+ script) - scriptForWritingSystem;
+ if (writingSystem == QFontDatabase::Any
+ || writingSystem >= QFontDatabase::WritingSystemsCount) {
+ return families;
+ }
+
+ QFontDatabasePrivate *db = privateDb();
+ QMultiMap<uint, QString> supported;
+ for (int i = 0; i < families.size(); ++i) {
+ const QString &family = families.at(i);
+
+ QtFontFamily *testFamily = nullptr;
+ for (int x = 0; x < db->count; ++x) {
+ if (Q_UNLIKELY(matchFamilyName(family, db->families[x]))) {
+ testFamily = db->families[x];
+ testFamily->ensurePopulated();
+ break;
+ }
+ }
+
+ uint order = i;
+ if (testFamily == nullptr
+ || (testFamily->writingSystems[writingSystem] & QtFontFamily::Supported) == 0) {
+ order |= 1 << 31;
+ }
+
+ supported.insert(order, family);
+ }
+
+ return supported.values();
+}
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index e4f9b8b9d4..33df020a6c 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -1845,7 +1845,12 @@ QFontEngine *QFontEngineMulti::loadEngine(int at)
request.styleStrategy |= QFont::NoFontMerging;
request.family = fallbackFamilyAt(at - 1);
- if (QFontEngine *engine = QFontDatabase::findFont(request, m_script)) {
+ // At this point, the main script of the text has already been considered
+ // when fetching the list of fallback families from the database, and the
+ // info about the actual script of the characters may have been discarded,
+ // so we do not check for writing system support, but instead just load
+ // the family indiscriminately.
+ if (QFontEngine *engine = QFontDatabase::findFont(request, QFontDatabase::Any)) {
engine->fontDef.weight = request.weight;
if (request.style > QFont::StyleNormal)
engine->fontDef.style = request.style;
@@ -1898,8 +1903,33 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
int glyph_pos = 0;
QStringIterator it(str, str + len);
+
+ int lastFallback = -1;
while (it.hasNext()) {
const uint ucs4 = it.peekNext();
+
+ // If we applied a fallback font to previous glyph, and the current is either
+ // ZWJ or ZWNJ, we should also try applying the same fallback font to that, in order
+ // to get the correct shaping rules applied.
+ if (lastFallback >= 0 && (ucs4 == QChar(0x200d) || ucs4 == QChar(0x200c))) {
+ QFontEngine *engine = m_engines.at(lastFallback);
+ glyph_t glyph = engine->glyphIndex(ucs4);
+ if (glyph != 0) {
+ glyphs->glyphs[glyph_pos] = glyph;
+ if (!(flags & GlyphIndicesOnly)) {
+ QGlyphLayout g = glyphs->mid(glyph_pos, 1);
+ engine->recalcAdvances(&g, flags);
+ }
+
+ // set the high byte to indicate which engine the glyph came from
+ glyphs->glyphs[glyph_pos] |= (lastFallback << 24);
+ } else {
+ lastFallback = -1;
+ }
+ } else {
+ lastFallback = -1;
+ }
+
if (glyphs->glyphs[glyph_pos] == 0
&& ucs4 != QChar::LineSeparator
&& ucs4 != QChar::LineFeed
@@ -1928,6 +1958,9 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
QGlyphLayout g = glyphs->mid(glyph_pos, 1);
engine->recalcAdvances(&g, flags);
}
+
+ lastFallback = x;
+
// set the high byte to indicate which engine the glyph came from
glyphs->glyphs[glyph_pos] |= (x << 24);
break;