QTextEngine - treat a fullstop (0x2E) as the same script as the preceeding text when...
authorJohn Tapsell <john.tapsell.ext@basyskom.com>
Wed, 8 Feb 2012 10:12:16 +0000 (10:12 +0000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 23 Feb 2012 14:07:58 +0000 (15:07 +0100)
Many languages use a fullstop to indicate an abbreviation, making the
fullstop part of the word.  For languages like thai, it is required to
pass the fullstop along for correct word breaking.

Change-Id: I5ad0ddbc66ea96e08913446dad8fd3c5d5dd0905
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
src/gui/text/qtextengine.cpp
tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp

index bc7f4f7..3017075 100644 (file)
@@ -115,7 +115,20 @@ private:
             return;
         const int end = start + length;
         for (int i = start + 1; i < end; ++i) {
-            if ((m_analysis[i] == m_analysis[start])
+            // According to the unicode spec we should be treating characters in the Common script
+            // (punctuation, spaces, etc) as being the same script as the surrounding text for the
+            // purpose of splitting up text. This is important because, for example, a fullstop
+            // (0x2E) can be used to indicate an abbreviation and so must be treated as part of a
+            // word.  Thus it must be passed along with the word in languages that have to calculate
+            // word breaks.  For example the thai word "ครม." has no word breaks but the word "ครม"
+            // does.
+            // Unfortuntely because we split up the strings for both wordwrapping and for setting
+            // the font and because Japanese and Chinese are also aliases of the script "Common",
+            // doing this would break too many things.  So instead we only pass the full stop
+            // along, and nothing else.
+            if (m_analysis[i].bidiLevel == m_analysis[start].bidiLevel
+                && m_analysis[i].flags == m_analysis[start].flags
+                && (m_analysis[i].script == m_analysis[start].script || m_string[i] == QLatin1Char('.'))
                 && m_analysis[i].flags < QScriptAnalysis::SpaceTabOrObject
                 && i - start < MaxItemLength)
                 continue;
index 7db12ed..7c9a83e 100644 (file)
@@ -1283,7 +1283,7 @@ void tst_QTextScriptEngine::thaiIsolatedSaraAm()
 
 void tst_QTextScriptEngine::thaiWithZWJ()
 {
-    QString s(QString::fromUtf8("ร‍ร‌“ร…ร”ร\xA0ร本ร") + QChar(0x0363)/*superscript 'a', for testing Inherited class*/);
+    QString s(QString::fromUtf8("ร‍ร‌.ร.“ร…ร”ร\xA0ร本ร") + QChar(0x0363)/*superscript 'a', for testing Inherited class*/);
     QTextLayout layout(s);
     layout.beginLayout();
     layout.createLine();
@@ -1296,7 +1296,7 @@ void tst_QTextScriptEngine::thaiWithZWJ()
     // The current implementation hides them, so we test for that.
     // But make sure that we don't hide anything else
     QCOMPARE(e->layoutData->items.size(), 11);
-    QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(5));  // Thai: The ZWJ and ZWNJ characters are inherited, so should be part of the thai script
+    QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(7));  // Thai: The ZWJ and ZWNJ characters are inherited, so should be part of the thai script
     QCOMPARE(e->layoutData->items[1].num_glyphs, ushort(1));  // Common: The smart quotes cannot be handled by thai, so should be a seperate item
     QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(1));  // Thai: Thai character
     QCOMPARE(e->layoutData->items[3].num_glyphs, ushort(1));  // Common: Ellipsis
@@ -1310,15 +1310,15 @@ void tst_QTextScriptEngine::thaiWithZWJ()
 
     //A quick sanity check - check all the characters are individual clusters
     unsigned short *logClusters = e->layoutData->logClustersPtr;
-    for (int i = 0; i < 5; i++)
+    for (int i = 0; i < 7; i++)
         QCOMPARE(logClusters[i], ushort(i));
     for (int i = 0; i < 10; i++)
-        QCOMPARE(logClusters[i+5], ushort(0));
-    QCOMPARE(logClusters[15], ushort(1));
+        QCOMPARE(logClusters[i+7], ushort(0));
+    QCOMPARE(logClusters[17], ushort(1));
 
     // The only characters that we should be hiding are the ZWJ and ZWNJ characters in position 1
     // and 3.
-    for (int i = 0; i < 16; i++)
+    for (int i = 0; i < 18; i++)
         QCOMPARE((bool)e->layoutData->glyphLayout.attributes[i].dontPrint, (i == 1 || i == 3));
 }