From 2b23d7214f1bb90369ee418a30958fcc5d96cd8f Mon Sep 17 00:00:00 2001 From: John Tapsell Date: Wed, 8 Feb 2012 10:12:16 +0000 Subject: QTextEngine - treat a fullstop (0x2E) as the same script as the preceeding text when dividing up strings 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 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextengine.cpp | 15 ++++++++++++++- .../gui/text/qtextscriptengine/tst_qtextscriptengine.cpp | 12 ++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index bc7f4f7ad6..30170759a0 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -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; diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index 7db12ed2b4..7c9a83eaa4 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -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)); } -- cgit v1.2.3