summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-thai.c33
-rw-r--r--tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp24
2 files changed, 50 insertions, 7 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c
index 262cee6a8e..deff61be7e 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-thai.c
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-thai.c
@@ -258,20 +258,39 @@ static HB_Bool HB_ThaiConvertStringToGlyphIndices (HB_ShaperItem *item)
/* Add glyphs to glyphs string and setting some attributes */
for (int lgi = 0; lgi < lgn; lgi++) {
if ( rglyphs[lgi] == 0xdd/*TH_BLANK_BASE_GLYPH*/ ) {
- //if ( !item->fixedPitch ) {
- glyphString[slen++] = C_DOTTED_CIRCLE;
- item->attributes[slen-1].dontPrint = true; // FIXME this will hide all dotted circle
- //}
+ glyphString[slen++] = C_DOTTED_CIRCLE;
}
else {
glyphString[slen++] = (HB_UChar16) thai_get_glyph_index (font_type, rglyphs[lgi]);
}
}
+ /* Special case to handle U+0E33 (SARA AM, āļģ): SARA AM is normally written at the end of a
+ * word with a base character and an optional top character before it. For example, U+0E0B
+ * (base), U+0E49 (top), U+0E33 (SARA AM). The sequence should be converted to 4 glyphs:
+ * base, hilo (the little circle in the top left part of SARA AM, NIKHAHIT), top, then the
+ * right part of SARA AM (SARA AA).
+ *
+ * The painting process finds out the starting glyph and ending glyph of a character
+ * sequence by checking the logClusters array. In this case, logClusters array should
+ * ideally be [ 0, 1, 3 ] so that glyphsStart = 0 and glyphsEnd = 3 (slen - 1) to paint out
+ * all the glyphs generated.
+ *
+ * A special case in this special case is when we have no base character. When an isolated
+ * SARA AM is processed (cell_length = 1), libthai will produce 3 glyphs: dotted circle
+ * (indicates that the base is empty), NIKHAHIT then SARA AA. If logClusters[0] = 1, it will
+ * paint from the second glyph in the glyphs array. So in this case logClusters[0] should
+ * point to the first glyph it produces, aka. the dotted circle. */
if (haveSaraAm) {
- logClusters[i + cell_length - 1] = slen - 1; // Set logClusters before NIKAHIT
- if (tis_cell.top != 0)
- logClusters[i + cell_length - 2] = slen - 2; // Set logClusters before NIKAHIT when tis_cell has top
+ logClusters[i + cell_length - 1] = cell_length == 1 ? slen - 3 : slen - 1;
+ if (tis_cell.top != 0) {
+ if (cell_length > 1) {
+ /* set the logClusters[top character] to slen - 2 as it points to the second to
+ * lastglyph (slen - 2) */
+ logClusters[i + cell_length - 2] = slen - 2;
+ }
+ }
+ /* check for overflow */
if (logClusters[i + cell_length - 1] > slen)
logClusters[i + cell_length - 1] = 0;
}
diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
index 638f13aea2..73678585d6 100644
--- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
+++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
@@ -103,6 +103,8 @@ private slots:
void mirroredChars_data();
void mirroredChars();
+ void thaiIsolatedSaraAm();
+
private:
bool haveTestFonts;
};
@@ -1256,5 +1258,27 @@ void tst_QTextScriptEngine::mirroredChars()
}
}
+void tst_QTextScriptEngine::thaiIsolatedSaraAm()
+{
+ if (QFontDatabase().families(QFontDatabase::Any).contains("Waree")) {
+ QString s;
+ s.append(QChar(0x0e33));
+
+ QTextLayout layout(s, QFont("Waree"));
+ layout.beginLayout();
+ layout.createLine();
+ layout.endLayout();
+
+ QTextEngine *e = layout.engine();
+ e->itemize();
+ e->shape(0);
+ QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(3));
+
+ unsigned short *logClusters = e->layoutData->logClustersPtr;
+ QCOMPARE(logClusters[0], ushort(0));
+ } else
+ QSKIP("Cannot find Waree.");
+}
+
QTEST_MAIN(tst_QTextScriptEngine)
#include "tst_qtextscriptengine.moc"