1*c8dee2aaSAndroid Build Coastguard Worker
2*c8dee2aaSAndroid Build Coastguard Worker /*
3*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2023 Google LLC
4*c8dee2aaSAndroid Build Coastguard Worker *
5*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
6*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
7*c8dee2aaSAndroid Build Coastguard Worker */
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkBitmaskEnum.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
14*c8dee2aaSAndroid Build Coastguard Worker
15*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode.h"
16*c8dee2aaSAndroid Build Coastguard Worker
17*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
18*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_icu.h"
19*c8dee2aaSAndroid Build Coastguard Worker #endif
20*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION)
21*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_libgrapheme.h"
22*c8dee2aaSAndroid Build Coastguard Worker #endif
23*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU4X_IMPLEMENTATION)
24*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_icu4x.h"
25*c8dee2aaSAndroid Build Coastguard Worker #endif
26*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_CLIENT_IMPLEMENTATION)
27*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode_client.h"
28*c8dee2aaSAndroid Build Coastguard Worker #endif
29*c8dee2aaSAndroid Build Coastguard Worker
30*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_UNICODE_ICU_IMPLEMENTATION
33*c8dee2aaSAndroid Build Coastguard Worker #define DEF_TEST_ICU(name, reporter) \
34*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(name##ICU, reporter) { name(reporter, SkUnicodes::ICU::Make()); }
35*c8dee2aaSAndroid Build Coastguard Worker #else
36*c8dee2aaSAndroid Build Coastguard Worker #define DEF_TEST_ICU(name, reporter)
37*c8dee2aaSAndroid Build Coastguard Worker #endif
38*c8dee2aaSAndroid Build Coastguard Worker
39*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_UNICODE_ICU4X_IMPLEMENTATION
40*c8dee2aaSAndroid Build Coastguard Worker #define DEF_TEST_ICU4X(name, reporter) \
41*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(name##ICU4X, reporter) { name(reporter, SkUnicodes::ICU4X::Make()); }
42*c8dee2aaSAndroid Build Coastguard Worker #else
43*c8dee2aaSAndroid Build Coastguard Worker #define DEF_TEST_ICU4X(name, reporter)
44*c8dee2aaSAndroid Build Coastguard Worker #endif
45*c8dee2aaSAndroid Build Coastguard Worker
46*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION
47*c8dee2aaSAndroid Build Coastguard Worker #define DEF_TEST_LIBGRAPHEME(name, reporter) \
48*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(name##LIBGRAPHEME, reporter) { name(reporter, SkUnicodes::Libgrapheme::Make()); }
49*c8dee2aaSAndroid Build Coastguard Worker #else
50*c8dee2aaSAndroid Build Coastguard Worker #define DEF_TEST_LIBGRAPHEME(name, reporter)
51*c8dee2aaSAndroid Build Coastguard Worker #endif
52*c8dee2aaSAndroid Build Coastguard Worker
53*c8dee2aaSAndroid Build Coastguard Worker #define DEF_TEST_NOIMPL(name, reporter)
54*c8dee2aaSAndroid Build Coastguard Worker
55*c8dee2aaSAndroid Build Coastguard Worker #define DEF_TEST_UNICODES(name, reporter) \
56*c8dee2aaSAndroid Build Coastguard Worker static void name(skiatest::Reporter* reporter, sk_sp<SkUnicode> unicode); \
57*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU(name, reporter) \
58*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU4X(name, reporter) \
59*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_LIBGRAPHEME(name, reporter) \
60*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_NOIMPL(name, reporter) \
61*c8dee2aaSAndroid Build Coastguard Worker void name(skiatest::Reporter* reporter, sk_sp<SkUnicode> unicode)
62*c8dee2aaSAndroid Build Coastguard Worker
63*c8dee2aaSAndroid Build Coastguard Worker #define DEF_TEST_ICU_UNICODES(name, reporter) \
64*c8dee2aaSAndroid Build Coastguard Worker static void name(skiatest::Reporter* reporter, sk_sp<SkUnicode> unicode); \
65*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU(name, reporter) \
66*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU4X(name, reporter) \
67*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_NOIMPL(name, reporter) \
68*c8dee2aaSAndroid Build Coastguard Worker void name(skiatest::Reporter* reporter, sk_sp<SkUnicode> unicode)
69*c8dee2aaSAndroid Build Coastguard Worker
70*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_UNICODE_CLIENT_IMPLEMENTATION
UNIX_ONLY_TEST(SkUnicode_Client,reporter)73*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkUnicode_Client, reporter) {
74*c8dee2aaSAndroid Build Coastguard Worker std::u16string text = u"\U000f2008";
75*c8dee2aaSAndroid Build Coastguard Worker auto utf8 = SkUnicode::convertUtf16ToUtf8(text.data(), text.size());
76*c8dee2aaSAndroid Build Coastguard Worker auto client = SkUnicodes::Client::Make
77*c8dee2aaSAndroid Build Coastguard Worker (SkSpan<char>(&utf8[0], utf8.size()), {}, {}, {});
78*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<SkUnicode::CodeUnitFlags, true> results;
79*c8dee2aaSAndroid Build Coastguard Worker client->computeCodeUnitFlags(utf8.data(), utf8.size(), false, &results);
80*c8dee2aaSAndroid Build Coastguard Worker
81*c8dee2aaSAndroid Build Coastguard Worker for (auto flag : results) {
82*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !SkUnicode::hasPartOfWhiteSpaceBreakFlag(flag));
83*c8dee2aaSAndroid Build Coastguard Worker }
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker #endif
86*c8dee2aaSAndroid Build Coastguard Worker
87*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
UNIX_ONLY_TEST(SkUnicode_Compiled_Native,reporter)88*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkUnicode_Compiled_Native, reporter) {
89*c8dee2aaSAndroid Build Coastguard Worker auto icu = SkUnicodes::ICU::Make();
90*c8dee2aaSAndroid Build Coastguard Worker if (!icu) {
91*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu);
92*c8dee2aaSAndroid Build Coastguard Worker return;
93*c8dee2aaSAndroid Build Coastguard Worker }
94*c8dee2aaSAndroid Build Coastguard Worker std::u16string text = u"\U000f2008";
95*c8dee2aaSAndroid Build Coastguard Worker auto utf8 = SkUnicode::convertUtf16ToUtf8(text.data(), text.size());
96*c8dee2aaSAndroid Build Coastguard Worker skia_private::TArray<SkUnicode::CodeUnitFlags, true> results;
97*c8dee2aaSAndroid Build Coastguard Worker icu->computeCodeUnitFlags(utf8.data(), utf8.size(), false, &results);
98*c8dee2aaSAndroid Build Coastguard Worker for (auto flag : results) {
99*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !SkUnicode::hasPartOfWhiteSpaceBreakFlag(flag));
100*c8dee2aaSAndroid Build Coastguard Worker }
101*c8dee2aaSAndroid Build Coastguard Worker }
102*c8dee2aaSAndroid Build Coastguard Worker #endif
103*c8dee2aaSAndroid Build Coastguard Worker
104*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION)
UNIX_ONLY_TEST(SkUnicode_GetUtf8Words,reporter)105*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkUnicode_GetUtf8Words, reporter) {
106*c8dee2aaSAndroid Build Coastguard Worker SkString text("1 22 333 4444 55555 666666 7777777");
107*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::Position> expected = { 0, 1, 2, 4, 5, 8, 9, 13, 14, 19, 20, 26, 27, 34 };
108*c8dee2aaSAndroid Build Coastguard Worker auto libgrapheme = SkUnicodes::Libgrapheme::Make();
109*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::Position> results;
110*c8dee2aaSAndroid Build Coastguard Worker auto result = libgrapheme->getUtf8Words(text.data(), text.size(), "en", &results);
111*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result);
112*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results.size() == expected.size());
113*c8dee2aaSAndroid Build Coastguard Worker for (auto i = 0ul; i < results.size(); ++i) {
114*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results[i] == expected[i]);
115*c8dee2aaSAndroid Build Coastguard Worker }
116*c8dee2aaSAndroid Build Coastguard Worker }
117*c8dee2aaSAndroid Build Coastguard Worker #endif
118*c8dee2aaSAndroid Build Coastguard Worker
119*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_UNICODE_ICU_IMPLEMENTATION)
UNIX_ONLY_TEST(SkUnicode_Compiled_GetSentences,reporter)120*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkUnicode_Compiled_GetSentences, reporter) {
121*c8dee2aaSAndroid Build Coastguard Worker auto icu = SkUnicodes::ICU::Make();
122*c8dee2aaSAndroid Build Coastguard Worker if (!icu) {
123*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu);
124*c8dee2aaSAndroid Build Coastguard Worker return;
125*c8dee2aaSAndroid Build Coastguard Worker }
126*c8dee2aaSAndroid Build Coastguard Worker SkString text("Hello world! Hello world? Hello world... Not a sentence end: 3.1415926");
127*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::Position> expected = {0, 13, 26, 41, 70};
128*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::Position> results;
129*c8dee2aaSAndroid Build Coastguard Worker auto result = icu->getSentences(text.data(), text.size(), nullptr, &results);
130*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result);
131*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results.size() == expected.size());
132*c8dee2aaSAndroid Build Coastguard Worker for (auto i = 0ul; i < results.size(); ++i) {
133*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results[i] == expected[i]);
134*c8dee2aaSAndroid Build Coastguard Worker }
135*c8dee2aaSAndroid Build Coastguard Worker }
136*c8dee2aaSAndroid Build Coastguard Worker #endif
137*c8dee2aaSAndroid Build Coastguard Worker
hasWordFlag(SkUnicode::CodeUnitFlags flags)138*c8dee2aaSAndroid Build Coastguard Worker bool hasWordFlag(SkUnicode::CodeUnitFlags flags) {
139*c8dee2aaSAndroid Build Coastguard Worker return (flags & SkUnicode::kWordBreak) == SkUnicode::kWordBreak;
140*c8dee2aaSAndroid Build Coastguard Worker }
141*c8dee2aaSAndroid Build Coastguard Worker
142*c8dee2aaSAndroid Build Coastguard Worker // On Windows libgrapheme produces different results
DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsLTR,reporter)143*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsLTR, reporter) {
144*c8dee2aaSAndroid Build Coastguard Worker if (!unicode) {
145*c8dee2aaSAndroid Build Coastguard Worker return;
146*c8dee2aaSAndroid Build Coastguard Worker }
147*c8dee2aaSAndroid Build Coastguard Worker SkString text("1 22 333 4444 55555 666666 7777777");
148*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::BidiRegion> results;
149*c8dee2aaSAndroid Build Coastguard Worker auto result = unicode->getBidiRegions(text.data(),
150*c8dee2aaSAndroid Build Coastguard Worker text.size(),
151*c8dee2aaSAndroid Build Coastguard Worker SkUnicode::TextDirection::kLTR,
152*c8dee2aaSAndroid Build Coastguard Worker &results);
153*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result);
154*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results.size() == 1);
155*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results[0].start == 0 &&
156*c8dee2aaSAndroid Build Coastguard Worker results[0].end == text.size() &&
157*c8dee2aaSAndroid Build Coastguard Worker results[0].level == 0);
158*c8dee2aaSAndroid Build Coastguard Worker }
159*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsRTL,reporter)160*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsRTL, reporter) {
161*c8dee2aaSAndroid Build Coastguard Worker if (!unicode) {
162*c8dee2aaSAndroid Build Coastguard Worker return;
163*c8dee2aaSAndroid Build Coastguard Worker }
164*c8dee2aaSAndroid Build Coastguard Worker SkString text("الهيمنة على العالم عبارة قبيحة ، أفضل أن أسميها تحسين العالم.");
165*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::BidiRegion> results;
166*c8dee2aaSAndroid Build Coastguard Worker auto result = unicode->getBidiRegions(text.data(),
167*c8dee2aaSAndroid Build Coastguard Worker text.size(),
168*c8dee2aaSAndroid Build Coastguard Worker SkUnicode::TextDirection::kRTL,
169*c8dee2aaSAndroid Build Coastguard Worker &results);
170*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result);
171*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results.size() == 1);
172*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results[0].start == 0 &&
173*c8dee2aaSAndroid Build Coastguard Worker results[0].end == text.size() &&
174*c8dee2aaSAndroid Build Coastguard Worker results[0].level == 1);
175*c8dee2aaSAndroid Build Coastguard Worker }
176*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsMix1,reporter)177*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsMix1, reporter) {
178*c8dee2aaSAndroid Build Coastguard Worker if (!unicode) {
179*c8dee2aaSAndroid Build Coastguard Worker return;
180*c8dee2aaSAndroid Build Coastguard Worker }
181*c8dee2aaSAndroid Build Coastguard Worker // Spaces become Arabic (RTL) but numbers remain English (LTR)
182*c8dee2aaSAndroid Build Coastguard Worker SkString text("1 22 333 4444 55555 666666 7777777");
183*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::BidiRegion> expected = {
184*c8dee2aaSAndroid Build Coastguard Worker {0, 1, 2},
185*c8dee2aaSAndroid Build Coastguard Worker {1, 2, 1},
186*c8dee2aaSAndroid Build Coastguard Worker {2, 4, 2},
187*c8dee2aaSAndroid Build Coastguard Worker {4, 5, 1},
188*c8dee2aaSAndroid Build Coastguard Worker {5, 8, 2},
189*c8dee2aaSAndroid Build Coastguard Worker {8, 9, 1},
190*c8dee2aaSAndroid Build Coastguard Worker {9, 13, 2},
191*c8dee2aaSAndroid Build Coastguard Worker {13, 14, 1},
192*c8dee2aaSAndroid Build Coastguard Worker {14, 19, 2},
193*c8dee2aaSAndroid Build Coastguard Worker {19, 20, 1},
194*c8dee2aaSAndroid Build Coastguard Worker {20, 26, 2},
195*c8dee2aaSAndroid Build Coastguard Worker {26, 27, 1},
196*c8dee2aaSAndroid Build Coastguard Worker {27, 34, 2},
197*c8dee2aaSAndroid Build Coastguard Worker };
198*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::BidiRegion> results;
199*c8dee2aaSAndroid Build Coastguard Worker auto result = unicode->getBidiRegions(text.data(),
200*c8dee2aaSAndroid Build Coastguard Worker text.size(),
201*c8dee2aaSAndroid Build Coastguard Worker SkUnicode::TextDirection::kRTL,
202*c8dee2aaSAndroid Build Coastguard Worker &results);
203*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result);
204*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results.size() == expected.size());
205*c8dee2aaSAndroid Build Coastguard Worker for (auto i = 0ul; i < results.size(); ++i) {
206*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results[i].start == expected[i].start &&
207*c8dee2aaSAndroid Build Coastguard Worker results[i].end == expected[i].end &&
208*c8dee2aaSAndroid Build Coastguard Worker results[i].level == expected[i].level);
209*c8dee2aaSAndroid Build Coastguard Worker }
210*c8dee2aaSAndroid Build Coastguard Worker }
211*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsMix2,reporter)212*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsMix2, reporter) {
213*c8dee2aaSAndroid Build Coastguard Worker if (!unicode) {
214*c8dee2aaSAndroid Build Coastguard Worker return;
215*c8dee2aaSAndroid Build Coastguard Worker }
216*c8dee2aaSAndroid Build Coastguard Worker // Few Russian/English words (ЛТР) in the mix
217*c8dee2aaSAndroid Build Coastguard Worker SkString text("World ЛТР Domination هي عبارة قبيحة ، أفضل أن أسميها World ЛТР Optimization.");
218*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::BidiRegion> expected = {
219*c8dee2aaSAndroid Build Coastguard Worker { 0, 24, 0},
220*c8dee2aaSAndroid Build Coastguard Worker { 24, 80, 1},
221*c8dee2aaSAndroid Build Coastguard Worker { 80, 107, 0},
222*c8dee2aaSAndroid Build Coastguard Worker };
223*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkUnicode::BidiRegion> results;
224*c8dee2aaSAndroid Build Coastguard Worker auto result = unicode->getBidiRegions(text.data(),
225*c8dee2aaSAndroid Build Coastguard Worker text.size(),
226*c8dee2aaSAndroid Build Coastguard Worker SkUnicode::TextDirection::kLTR,
227*c8dee2aaSAndroid Build Coastguard Worker &results);
228*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result);
229*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results.size() == expected.size());
230*c8dee2aaSAndroid Build Coastguard Worker for (auto i = 0ul; i < results.size(); ++i) {
231*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results[i].start == expected[i].start &&
232*c8dee2aaSAndroid Build Coastguard Worker results[i].end == expected[i].end &&
233*c8dee2aaSAndroid Build Coastguard Worker results[i].level == expected[i].level);
234*c8dee2aaSAndroid Build Coastguard Worker }
235*c8dee2aaSAndroid Build Coastguard Worker }
236*c8dee2aaSAndroid Build Coastguard Worker
237*c8dee2aaSAndroid Build Coastguard Worker // Currently, libgrapheme uses different default rules and produces slightly
238*c8dee2aaSAndroid Build Coastguard Worker // different results; it does not matter for text shaping
DEF_TEST_ICU_UNICODES(SkUnicode_ToUpper,reporter)239*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU_UNICODES(SkUnicode_ToUpper, reporter) {
240*c8dee2aaSAndroid Build Coastguard Worker if (!unicode) {
241*c8dee2aaSAndroid Build Coastguard Worker return;
242*c8dee2aaSAndroid Build Coastguard Worker }
243*c8dee2aaSAndroid Build Coastguard Worker SkString lower("abcdefghijklmnopqrstuvwxyz");
244*c8dee2aaSAndroid Build Coastguard Worker SkString upper("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
245*c8dee2aaSAndroid Build Coastguard Worker auto icu_result1 = unicode->toUpper(lower);
246*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu_result1.equals(upper));
247*c8dee2aaSAndroid Build Coastguard Worker auto icu_result2 = unicode->toUpper(upper);
248*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu_result2.equals(upper));
249*c8dee2aaSAndroid Build Coastguard Worker }
250*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST_ICU_UNICODES(SkUnicode_ComputeCodeUnitFlags,reporter)251*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_ICU_UNICODES(SkUnicode_ComputeCodeUnitFlags, reporter) {
252*c8dee2aaSAndroid Build Coastguard Worker if (!unicode) {
253*c8dee2aaSAndroid Build Coastguard Worker return;
254*c8dee2aaSAndroid Build Coastguard Worker }
255*c8dee2aaSAndroid Build Coastguard Worker //SkString text("World domination is such an ugly phrase - I prefer to call it world optimisation");
256*c8dee2aaSAndroid Build Coastguard Worker SkString text("1\n22 333 4444 55555 666666 7777777");
257*c8dee2aaSAndroid Build Coastguard Worker // 4 8 13 19 24
258*c8dee2aaSAndroid Build Coastguard Worker TArray<SkUnicode::CodeUnitFlags> results;
259*c8dee2aaSAndroid Build Coastguard Worker auto result = unicode->computeCodeUnitFlags(text.data(),
260*c8dee2aaSAndroid Build Coastguard Worker text.size(),
261*c8dee2aaSAndroid Build Coastguard Worker /*replaceTabs=*/true,
262*c8dee2aaSAndroid Build Coastguard Worker &results);
263*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, result);
264*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, results.size() == SkToS16(text.size() + 1));
265*c8dee2aaSAndroid Build Coastguard Worker for (auto i = 0; i < results.size(); ++i) {
266*c8dee2aaSAndroid Build Coastguard Worker auto flags = results[i];
267*c8dee2aaSAndroid Build Coastguard Worker auto expected = SkUnicode::CodeUnitFlags::kGraphemeStart;
268*c8dee2aaSAndroid Build Coastguard Worker if (i == 1) {
269*c8dee2aaSAndroid Build Coastguard Worker expected |= SkUnicode::CodeUnitFlags::kControl;
270*c8dee2aaSAndroid Build Coastguard Worker }
271*c8dee2aaSAndroid Build Coastguard Worker if (i == 2) {
272*c8dee2aaSAndroid Build Coastguard Worker expected |= SkUnicode::CodeUnitFlags::kHardLineBreakBefore;
273*c8dee2aaSAndroid Build Coastguard Worker }
274*c8dee2aaSAndroid Build Coastguard Worker if (i == 1 || i == 4 || i == 8 || i == 13 || i == 19 || i == 26) {
275*c8dee2aaSAndroid Build Coastguard Worker expected |= SkUnicode::CodeUnitFlags::kPartOfWhiteSpaceBreak;
276*c8dee2aaSAndroid Build Coastguard Worker expected |= SkUnicode::CodeUnitFlags::kPartOfIntraWordBreak;
277*c8dee2aaSAndroid Build Coastguard Worker }
278*c8dee2aaSAndroid Build Coastguard Worker if (i == 0 || i == 2 || i == 5 || i == 9 || i == 14 || i == 20
279*c8dee2aaSAndroid Build Coastguard Worker || i == 27 || i == 34) {
280*c8dee2aaSAndroid Build Coastguard Worker expected |= SkUnicode::CodeUnitFlags::kSoftLineBreakBefore;
281*c8dee2aaSAndroid Build Coastguard Worker }
282*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, flags == expected);
283*c8dee2aaSAndroid Build Coastguard Worker }
284*c8dee2aaSAndroid Build Coastguard Worker }
285*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST_UNICODES(SkUnicode_ReorderVisual,reporter)286*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST_UNICODES(SkUnicode_ReorderVisual, reporter) {
287*c8dee2aaSAndroid Build Coastguard Worker if (!unicode) {
288*c8dee2aaSAndroid Build Coastguard Worker return;
289*c8dee2aaSAndroid Build Coastguard Worker }
290*c8dee2aaSAndroid Build Coastguard Worker auto reorder = [&](std::vector<SkUnicode::BidiLevel> levels,
291*c8dee2aaSAndroid Build Coastguard Worker std::vector<int32_t> expected) {
292*c8dee2aaSAndroid Build Coastguard Worker std::vector<int32_t> logicalOrder(levels.size());
293*c8dee2aaSAndroid Build Coastguard Worker unicode->reorderVisual(levels.data(), levels.size(), logicalOrder.data());
294*c8dee2aaSAndroid Build Coastguard Worker for (auto i = 0ul; i < levels.size(); ++i) {
295*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, expected[i] == logicalOrder[i]);
296*c8dee2aaSAndroid Build Coastguard Worker }
297*c8dee2aaSAndroid Build Coastguard Worker };
298*c8dee2aaSAndroid Build Coastguard Worker reorder({}, {});
299*c8dee2aaSAndroid Build Coastguard Worker reorder({0}, {0});
300*c8dee2aaSAndroid Build Coastguard Worker reorder({1}, {0});
301*c8dee2aaSAndroid Build Coastguard Worker reorder({0, 1, 0, 1}, {0, 1, 2, 3});
302*c8dee2aaSAndroid Build Coastguard Worker }
303*c8dee2aaSAndroid Build Coastguard Worker
SkUnicode_Emoji(SkUnicode * icu,skiatest::Reporter * reporter)304*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]] static void SkUnicode_Emoji(SkUnicode* icu, skiatest::Reporter* reporter) {
305*c8dee2aaSAndroid Build Coastguard Worker std::u32string emojis(U"");
306*c8dee2aaSAndroid Build Coastguard Worker std::u32string not_emojis(U"満毎行昼本可");
307*c8dee2aaSAndroid Build Coastguard Worker for (auto e : emojis) {
308*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu->isEmoji(e));
309*c8dee2aaSAndroid Build Coastguard Worker }
310*c8dee2aaSAndroid Build Coastguard Worker for (auto n: not_emojis) {
311*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !icu->isEmoji(n));
312*c8dee2aaSAndroid Build Coastguard Worker }
313*c8dee2aaSAndroid Build Coastguard Worker }
314*c8dee2aaSAndroid Build Coastguard Worker
315*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_UNICODE_ICU_IMPLEMENTATION
UNIX_ONLY_TEST(SkUnicode_Compiled_Emoji,reporter)316*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkUnicode_Compiled_Emoji, reporter) {
317*c8dee2aaSAndroid Build Coastguard Worker auto icu = SkUnicodes::ICU::Make();
318*c8dee2aaSAndroid Build Coastguard Worker if (!icu) {
319*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu);
320*c8dee2aaSAndroid Build Coastguard Worker return;
321*c8dee2aaSAndroid Build Coastguard Worker }
322*c8dee2aaSAndroid Build Coastguard Worker SkUnicode_Emoji(icu.get(), reporter);
323*c8dee2aaSAndroid Build Coastguard Worker }
324*c8dee2aaSAndroid Build Coastguard Worker #endif
325*c8dee2aaSAndroid Build Coastguard Worker
326*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_UNICODE_ICU4X_IMPLEMENTATION
UNIX_ONLY_TEST(SkUnicode_ICU4X_Emoji,reporter)327*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkUnicode_ICU4X_Emoji, reporter) {
328*c8dee2aaSAndroid Build Coastguard Worker auto icu = SkUnicodes::ICU4X::Make();
329*c8dee2aaSAndroid Build Coastguard Worker if (!icu) {
330*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu);
331*c8dee2aaSAndroid Build Coastguard Worker return;
332*c8dee2aaSAndroid Build Coastguard Worker }
333*c8dee2aaSAndroid Build Coastguard Worker SkUnicode_Emoji(icu.get(), reporter);
334*c8dee2aaSAndroid Build Coastguard Worker }
335*c8dee2aaSAndroid Build Coastguard Worker #endif
336*c8dee2aaSAndroid Build Coastguard Worker
SkUnicode_Ideographic(SkUnicode * icu,skiatest::Reporter * reporter)337*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]] static void SkUnicode_Ideographic(SkUnicode* icu, skiatest::Reporter* reporter) {
338*c8dee2aaSAndroid Build Coastguard Worker std::u32string ideographic(U"満毎行昼本可");
339*c8dee2aaSAndroid Build Coastguard Worker std::u32string not_ideographic(U"");
340*c8dee2aaSAndroid Build Coastguard Worker for (auto i : ideographic) {
341*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu->isIdeographic(i));
342*c8dee2aaSAndroid Build Coastguard Worker }
343*c8dee2aaSAndroid Build Coastguard Worker for (auto n: not_ideographic) {
344*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !icu->isIdeographic(n));
345*c8dee2aaSAndroid Build Coastguard Worker }
346*c8dee2aaSAndroid Build Coastguard Worker }
347*c8dee2aaSAndroid Build Coastguard Worker
348*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_UNICODE_ICU_IMPLEMENTATION
UNIX_ONLY_TEST(SkUnicode_Compiled_Ideographic,reporter)349*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkUnicode_Compiled_Ideographic, reporter) {
350*c8dee2aaSAndroid Build Coastguard Worker auto icu = SkUnicodes::ICU::Make();
351*c8dee2aaSAndroid Build Coastguard Worker if (!icu) {
352*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu);
353*c8dee2aaSAndroid Build Coastguard Worker return;
354*c8dee2aaSAndroid Build Coastguard Worker }
355*c8dee2aaSAndroid Build Coastguard Worker SkUnicode_Ideographic(icu.get(), reporter);
356*c8dee2aaSAndroid Build Coastguard Worker }
357*c8dee2aaSAndroid Build Coastguard Worker #endif
358*c8dee2aaSAndroid Build Coastguard Worker
359*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_UNICODE_ICU4X_IMPLEMENTATION
UNIX_ONLY_TEST(SkUnicode_ICU4X_Ideographic,reporter)360*c8dee2aaSAndroid Build Coastguard Worker UNIX_ONLY_TEST(SkUnicode_ICU4X_Ideographic, reporter) {
361*c8dee2aaSAndroid Build Coastguard Worker auto icu = SkUnicodes::ICU4X::Make();
362*c8dee2aaSAndroid Build Coastguard Worker if (!icu) {
363*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, icu);
364*c8dee2aaSAndroid Build Coastguard Worker return;
365*c8dee2aaSAndroid Build Coastguard Worker }
366*c8dee2aaSAndroid Build Coastguard Worker SkUnicode_Ideographic(icu.get(), reporter);
367*c8dee2aaSAndroid Build Coastguard Worker }
368*c8dee2aaSAndroid Build Coastguard Worker #endif
369