diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2021-01-13 23:57:51 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2021-01-13 23:57:51 +0000 |
commit | 996e2a986098a2fafdb0a26d4d1adb90c011e48a (patch) | |
tree | cc760592822d295652a6f09cc869fbcd02b0a04e | |
parent | d26e5a84987f46b1c8f726b068dbce438b9073a3 (diff) | |
parent | c3bd9a03ecb1a19393046c522f5b6c91d615f7c5 (diff) | |
download | minikin-android11-mainline-conscrypt-release.tar.gz |
Snap for 7080740 from c3bd9a03ecb1a19393046c522f5b6c91d615f7c5 to mainline-conscrypt-releaseandroid-mainline-11.0.0_r31android-mainline-11.0.0_r20android11-mainline-conscrypt-release
Change-Id: Ica9fbced992ff1748202895a7b7b1fecb1fa6f9b
-rw-r--r-- | libs/minikin/LayoutUtils.cpp | 5 | ||||
-rw-r--r-- | tests/unittest/LayoutSplitterTest.cpp | 35 |
2 files changed, 40 insertions, 0 deletions
diff --git a/libs/minikin/LayoutUtils.cpp b/libs/minikin/LayoutUtils.cpp index 3c258cf..acf07e2 100644 --- a/libs/minikin/LayoutUtils.cpp +++ b/libs/minikin/LayoutUtils.cpp @@ -36,6 +36,11 @@ static bool isWordBreakAfter(uint16_t c) { // spaces return true; } + // Break layout context before and after BiDi control character. + if ((0x2066 <= c && c <= 0x2069) || (0x202A <= c && c <= 0x202E) || c == 0x200E || + c == 0x200F) { + return true; + } // Note: kana is not included, as sophisticated fonts may kern kana return false; } diff --git a/tests/unittest/LayoutSplitterTest.cpp b/tests/unittest/LayoutSplitterTest.cpp index 4b75d9c..9b88de0 100644 --- a/tests/unittest/LayoutSplitterTest.cpp +++ b/tests/unittest/LayoutSplitterTest.cpp @@ -323,5 +323,40 @@ TEST(LayoutSplitterTest, RTL_CJK) { } } +TEST(LayoutSplitterTest, BidiCtrl) { + struct TestCase { + std::string testStr; + std::vector<std::string> expects; + } testCases[] = { + {// Repeated Bidi sequence + "(a\u2066\u2069\u202A\u202E\u200E\u200Fb)", + { + "[(a)]\u2066\u2069\u202A\u202E\u200E\u200Fb", + "a[(\u2066)]\u2069\u202A\u202E\u200E\u200Fb", + "a\u2066[(\u2069)]\u202A\u202E\u200E\u200Fb", + "a\u2066\u2069[(\u202A)]\u202E\u200E\u200Fb", + "a\u2066\u2069\u202A[(\u202E)]\u200E\u200Fb", + "a\u2066\u2069\u202A\u202E[(\u200E)]\u200Fb", + "a\u2066\u2069\u202A\u202E\u200E[(\u200F)]b", + "a\u2066\u2069\u202A\u202E\u200E\u200F[(b)]", + }}, + }; + + for (const auto& testCase : testCases) { + auto [text, range] = parseTestString(testCase.testStr); + uint32_t expectationIndex = 0; + for (auto [acContext, acPiece] : LayoutSplitter(text, range, false /* isRtl */)) { + ASSERT_NE(expectationIndex, testCase.expects.size()); + const std::string expectString = testCase.expects[expectationIndex++]; + auto [exContext, exPiece] = parseExpectString(expectString); + EXPECT_EQ(acContext, exContext) + << expectString << " vs " << buildDebugString(text, acContext, acPiece); + EXPECT_EQ(acPiece, exPiece) + << expectString << " vs " << buildDebugString(text, acContext, acPiece); + } + EXPECT_EQ(expectationIndex, testCase.expects.size()) << "Expectations Remains"; + } +} + } // namespace } // namespace minikin |