summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2012-10-04 06:52:13 +0300
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-10 13:26:13 +0200
commitf0ee31dc93813808a59a0fe576da120de2caf074 (patch)
tree4894feb2cdf725f4bf31b7c04b91e213ed08e217
parent008e5ba61a68846ad29c65a2fe10b8c19c74f6eb (diff)
QTextBoundaryFinder: Introduce BoundaryReason::MandatoryBreak flag
that will be returned by boundaryReasons() when the boundary finder is at the line end position (CR, LF, NewLine Function, End of Text, etc.). The MandatoryBreak flag, if set, means the text should be wrapped at a given position. Change-Id: I32d4f570935d2e015bfc5f18915396a15f009fde Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shaper.h2
-rw-r--r--src/corelib/tools/qtextboundaryfinder.cpp7
-rw-r--r--src/corelib/tools/qtextboundaryfinder.h7
-rw-r--r--src/corelib/tools/qunicodetools.cpp6
-rw-r--r--src/corelib/tools/qunicodetools_p.h2
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp37
6 files changed, 52 insertions, 9 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h
index 5a3329dd4b..e2891d047e 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h
@@ -135,7 +135,7 @@ typedef struct {
hb_bitfield whiteSpace : 1; /* A unicode whitespace character */
hb_bitfield wordStart : 1;
hb_bitfield wordEnd : 1;
- hb_bitfield unused : 1;
+ hb_bitfield mandatoryBreak : 1;
} HB_CharAttributes;
void HB_GetTailoredCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength,
diff --git a/src/corelib/tools/qtextboundaryfinder.cpp b/src/corelib/tools/qtextboundaryfinder.cpp
index 7f120323fe..416a14a35a 100644
--- a/src/corelib/tools/qtextboundaryfinder.cpp
+++ b/src/corelib/tools/qtextboundaryfinder.cpp
@@ -162,6 +162,8 @@ static void init(QTextBoundaryFinder::BoundaryType type, const QChar *chars, int
\value NotAtBoundary The boundary finder is not at a boundary position.
\value StartWord The boundary finder is at the start of a word.
\value EndWord The boundary finder is at the end of a word.
+ \value MandatoryBreak Since 5.0. The boundary finder is at the end of line
+ (can occur for a Line boundary type only).
\value SoftHyphen The boundary finder is at the soft hyphen
(can occur for a Line boundary type only).
*/
@@ -477,7 +479,10 @@ QTextBoundaryFinder::BoundaryReasons QTextBoundaryFinder::boundaryReasons() cons
reasons |= EndWord;
break;
case Line:
- if (pos > 0 && chars[pos - 1].unicode() == QChar::SoftHyphen)
+ // ### TR#14 LB2 prohibits break at sot
+ if (d->attributes[pos].mandatoryBreak || pos == 0)
+ reasons |= MandatoryBreak;
+ else if (pos > 0 && chars[pos - 1].unicode() == QChar::SoftHyphen)
reasons |= SoftHyphen;
// fall through
case Grapheme:
diff --git a/src/corelib/tools/qtextboundaryfinder.h b/src/corelib/tools/qtextboundaryfinder.h
index 57c2fda3ea..c752623844 100644
--- a/src/corelib/tools/qtextboundaryfinder.h
+++ b/src/corelib/tools/qtextboundaryfinder.h
@@ -69,9 +69,10 @@ public:
enum BoundaryReason {
NotAtBoundary = 0,
- StartWord = 1,
- EndWord = 2,
- SoftHyphen = 4
+ StartWord = 0x10,
+ EndWord = 0x20,
+ MandatoryBreak = 0x40,
+ SoftHyphen = 0x80
};
Q_DECLARE_FLAGS( BoundaryReasons, BoundaryReason )
diff --git a/src/corelib/tools/qunicodetools.cpp b/src/corelib/tools/qunicodetools.cpp
index 1f45575016..3d58f16d19 100644
--- a/src/corelib/tools/qunicodetools.cpp
+++ b/src/corelib/tools/qunicodetools.cpp
@@ -497,7 +497,7 @@ static void getLineBreaks(const ushort *string, quint32 len, QCharAttributes *at
if (Q_UNLIKELY(lcls >= QUnicodeTables::LineBreak_CR)) {
// LB4: BK!, LB5: (CRxLF|CR|LF|NL)!
if (lcls > QUnicodeTables::LineBreak_CR || ncls != QUnicodeTables::LineBreak_LF)
- attributes[pos].lineBreak = true;
+ attributes[pos].lineBreak = attributes[pos].mandatoryBreak = true;
goto next;
}
@@ -547,8 +547,8 @@ static void getLineBreaks(const ushort *string, quint32 len, QCharAttributes *at
attributes[j].lineBreak = false;
}
- attributes[0].lineBreak = false; // LB2
- attributes[len].lineBreak = true; // LB3
+ attributes[0].lineBreak = attributes[0].mandatoryBreak = false; // LB2
+ attributes[len].lineBreak = attributes[len].mandatoryBreak = true; // LB3
}
diff --git a/src/corelib/tools/qunicodetools_p.h b/src/corelib/tools/qunicodetools_p.h
index b1e9127662..143a4fd7be 100644
--- a/src/corelib/tools/qunicodetools_p.h
+++ b/src/corelib/tools/qunicodetools_p.h
@@ -66,7 +66,7 @@ struct Q_PACKED QCharAttributes
uchar whiteSpace : 1;
uchar wordStart : 1;
uchar wordEnd : 1;
- uchar unused : 1;
+ uchar mandatoryBreak : 1;
};
Q_DECLARE_TYPEINFO(QCharAttributes, Q_PRIMITIVE_TYPE);
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp b/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp
index 22d3465823..a0aab340a3 100644
--- a/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp
+++ b/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp
@@ -76,6 +76,8 @@ private slots:
void wordBoundaries_qtbug6498();
void isAtSoftHyphen_data();
void isAtSoftHyphen();
+ void isAtMandatoryBreak_data();
+ void isAtMandatoryBreak();
void thaiLineBreak();
};
@@ -659,6 +661,41 @@ void tst_QTextBoundaryFinder::isAtSoftHyphen()
}
}
+void tst_QTextBoundaryFinder::isAtMandatoryBreak_data()
+{
+ QTest::addColumn<QString>("testString");
+ QTest::addColumn<QList<int> >("expectedBreakPositions");
+
+ {
+ QChar s[] = { 0x000D, 0x0308, 0x000A, 0x000A };
+ QString testString(s, sizeof(s)/sizeof(s[0]));
+ QList<int> expectedBreakPositions;
+ expectedBreakPositions << 0 << 1 << 3 << 4;
+
+ QTest::newRow("+CR+FExLF+LF+") << testString << expectedBreakPositions;
+ }
+ {
+ QString testString(QString::fromUtf8("Aaa bbb ccc.\r\nDdd eee fff."));
+ QList<int> expectedBreakPositions;
+ expectedBreakPositions << 0 << 14 << 26;
+
+ QTest::newRow("data1") << testString << expectedBreakPositions;
+ }
+}
+
+void tst_QTextBoundaryFinder::isAtMandatoryBreak()
+{
+ QFETCH(QString, testString);
+ QFETCH(QList<int>, expectedBreakPositions);
+
+ QTextBoundaryFinder boundaryFinder(QTextBoundaryFinder::Line, testString);
+ for (int i = 0; i <= testString.size(); ++i) {
+ boundaryFinder.setPosition(i);
+ if (boundaryFinder.boundaryReasons() & QTextBoundaryFinder::MandatoryBreak)
+ QVERIFY(expectedBreakPositions.contains(i));
+ }
+}
+
#include <qlibrary.h>
#define LIBTHAI_MAJOR 0