summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoozbeh Pournader <roozbeh@google.com>2016-03-16 15:23:20 -0700
committerRoozbeh Pournader <roozbeh@google.com>2016-03-16 16:21:09 -0700
commitd8917c69a9f7b7ca52f7ac850922dab4322113f5 (patch)
tree0dc8985e1092a267b4c11e9833129ff974c5170f
parentcee83d40324b1f3b8e113eb8c9eda8e12ef36923 (diff)
downloadandroid_frameworks_minikin-d8917c69a9f7b7ca52f7ac850922dab4322113f5.tar.gz
android_frameworks_minikin-d8917c69a9f7b7ca52f7ac850922dab4322113f5.tar.bz2
android_frameworks_minikin-d8917c69a9f7b7ca52f7ac850922dab4322113f5.zip
Do not allow line breaks before currency symbols
Implement the change proposed in UTC document L2/16-043R (http://www.unicode.org/L2/L2016/16043r-line-break-pr-po.txt) to make sure we do not break between letters and currency symbols. Bug: 24959657 Change-Id: Ia29d0e5625f84870bd910d0c6e19036d17206704
-rw-r--r--libs/minikin/WordBreaker.cpp13
-rw-r--r--tests/WordBreakerTests.cpp16
2 files changed, 29 insertions, 0 deletions
diff --git a/libs/minikin/WordBreaker.cpp b/libs/minikin/WordBreaker.cpp
index 721c5bf..d420a6a 100644
--- a/libs/minikin/WordBreaker.cpp
+++ b/libs/minikin/WordBreaker.cpp
@@ -79,6 +79,18 @@ static bool isBreakValid(const uint16_t* buf, size_t bufEnd, size_t i) {
uint32_t next_codepoint;
size_t next_offset = i;
U16_NEXT(buf, next_offset, bufEnd, next_codepoint);
+
+ // Proposed change to LB24 from http://www.unicode.org/L2/L2016/16043r-line-break-pr-po.txt
+ //(AL | HL) × (PR | PO)
+ int32_t lineBreak = u_getIntPropertyValue(codePoint, UCHAR_LINE_BREAK);
+ if (lineBreak == U_LB_ALPHABETIC || lineBreak == U_LB_HEBREW_LETTER) {
+ lineBreak = u_getIntPropertyValue(next_codepoint, UCHAR_LINE_BREAK);
+ if (lineBreak == U_LB_PREFIX_NUMERIC || lineBreak == U_LB_POSTFIX_NUMERIC) {
+ return false;
+ }
+ }
+
+ // Known emoji ZWJ sequences
if (codePoint == CHAR_ZWJ) {
// Possible emoji ZWJ sequence
if (next_codepoint == 0x2764 || // HEAVY BLACK HEART
@@ -91,6 +103,7 @@ static bool isBreakValid(const uint16_t* buf, size_t bufEnd, size_t i) {
return false;
}
}
+
// Proposed Rule LB30b from http://www.unicode.org/L2/L2016/16011r3-break-prop-emoji.pdf
// EB x EM
if (isEmojiModifier(next_codepoint)) {
diff --git a/tests/WordBreakerTests.cpp b/tests/WordBreakerTests.cpp
index cb12722..480c57d 100644
--- a/tests/WordBreakerTests.cpp
+++ b/tests/WordBreakerTests.cpp
@@ -69,6 +69,22 @@ TEST_F(WordBreakerTest, softHyphen) {
EXPECT_EQ(0, breaker.breakBadness());
}
+TEST_F(WordBreakerTest, postfixAndPrefix) {
+ uint16_t buf[] = {'U', 'S', 0x00A2, ' ', 'J', 'P', 0x00A5}; // US¢ JP¥
+ WordBreaker breaker;
+ breaker.setLocale(icu::Locale::getEnglish());
+ breaker.setText(buf, NELEM(buf));
+ EXPECT_EQ(0, breaker.current());
+
+ EXPECT_EQ(4, breaker.next()); // after CENT SIGN
+ EXPECT_EQ(0, breaker.wordStart()); // "US¢"
+ EXPECT_EQ(3, breaker.wordEnd());
+
+ EXPECT_EQ((ssize_t)NELEM(buf), breaker.next()); // end of string
+ EXPECT_EQ(4, breaker.wordStart()); // "JP¥"
+ EXPECT_EQ((ssize_t)NELEM(buf), breaker.wordEnd());
+}
+
TEST_F(WordBreakerTest, zwjEmojiSequences) {
uint16_t buf[] = {
// man + zwj + heart + zwj + man