summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qfontengine.cpp
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2018-01-09 08:33:12 +0100
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2018-01-09 12:16:57 +0000
commit02557c07da2ac251f36cb6bf7f424071c53f8b45 (patch)
treefe6f3dec3528d7994c54487742b15f33eed0bbcf /src/gui/text/qfontengine.cpp
parent12687ccfd5a6056ab24a792dbe28f1d5829fd88c (diff)
Fix ZWJ and ZWNJ when fallback font is in use
When applying fallback fonts to characters that are joined by ZWJ or ZWNJ, we also have to set the same font for the control characters, otherwise we will split the text and the necessary shaping will not take place. This was reported for emojis, but will probably also happen for Indic scripts where joiners are used predominately. [ChangeLog][QtGui][Text] Fixed ZWJ and ZWNJ control characters when fallback fonts are in use. Task-number: QTBUG-65519 Change-Id: Ia37233f3319b95af68ae6053c29997eac65448e0 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/gui/text/qfontengine.cpp')
-rw-r--r--src/gui/text/qfontengine.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index ebaeb9b49b..29c48da7be 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1905,8 +1905,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
@@ -1935,6 +1960,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;