Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Macros | Functions
SkUnicodeTest.cpp File Reference
#include "include/core/SkSpan.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "src/base/SkBitmaskEnum.h"
#include "tests/Test.h"
#include "modules/skunicode/include/SkUnicode.h"
#include <vector>

Go to the source code of this file.

Macros

#define DEF_TEST_ICU(name, reporter)
 
#define DEF_TEST_ICU4X(name, reporter)
 
#define DEF_TEST_LIBGRAPHEME(name, reporter)
 
#define DEF_TEST_NOIMPL(name, reporter)
 
#define DEF_TEST_UNICODES(name, reporter)
 
#define DEF_TEST_ICU_UNICODES(name, reporter)
 

Functions

bool hasWordFlag (SkUnicode::CodeUnitFlags flags)
 
 DEF_TEST_ICU_UNICODES (SkUnicode_GetBidiRegionsLTR, reporter)
 
 DEF_TEST_ICU_UNICODES (SkUnicode_GetBidiRegionsRTL, reporter)
 
 DEF_TEST_ICU_UNICODES (SkUnicode_GetBidiRegionsMix1, reporter)
 
 DEF_TEST_ICU_UNICODES (SkUnicode_GetBidiRegionsMix2, reporter)
 
 DEF_TEST_ICU_UNICODES (SkUnicode_ToUpper, reporter)
 
 DEF_TEST_ICU_UNICODES (SkUnicode_ComputeCodeUnitFlags, reporter)
 
 DEF_TEST_UNICODES (SkUnicode_ReorderVisual, reporter)
 
static void SkUnicode_Emoji (SkUnicode *icu, skiatest::Reporter *reporter)
 
static void SkUnicode_Ideographic (SkUnicode *icu, skiatest::Reporter *reporter)
 

Macro Definition Documentation

◆ DEF_TEST_ICU

#define DEF_TEST_ICU (   name,
  reporter 
)

Definition at line 36 of file SkUnicodeTest.cpp.

◆ DEF_TEST_ICU4X

#define DEF_TEST_ICU4X (   name,
  reporter 
)

Definition at line 43 of file SkUnicodeTest.cpp.

◆ DEF_TEST_ICU_UNICODES

#define DEF_TEST_ICU_UNICODES (   name,
  reporter 
)
Value:
DEF_TEST_ICU(name, reporter) \
DEF_TEST_ICU4X(name, reporter) \
DEF_TEST_NOIMPL(name, reporter) \
reporter
const char * name
Definition fuchsia.cc:50

Definition at line 63 of file SkUnicodeTest.cpp.

72 {
73 std::u16string text = u"\U000f2008";
74 auto utf8 = SkUnicode::convertUtf16ToUtf8(text.data(), text.size());
75 auto client = SkUnicodes::Client::Make
76 (SkSpan<char>(&utf8[0], utf8.size()), {}, {}, {});
78 client->computeCodeUnitFlags(utf8.data(), utf8.size(), false, &results);
79
80 for (auto flag : results) {
82 }
83}
84#endif
85
86#if defined(SK_UNICODE_ICU_IMPLEMENTATION)
87UNIX_ONLY_TEST(SkUnicode_Compiled_Native, reporter) {
88 auto icu = SkUnicodes::ICU::Make();
89 if (!icu) {
91 return;
92 }
93 std::u16string text = u"\U000f2008";
94 auto utf8 = SkUnicode::convertUtf16ToUtf8(text.data(), text.size());
96 icu->computeCodeUnitFlags(utf8.data(), utf8.size(), false, &results);
97 for (auto flag : results) {
99 }
100}
101#endif
102
103#if defined(SK_UNICODE_LIBGRAPHEME_IMPLEMENTATION)
104UNIX_ONLY_TEST(SkUnicode_GetUtf8Words, reporter) {
105 SkString text("1 22 333 4444 55555 666666 7777777");
106 std::vector<SkUnicode::Position> expected = { 0, 1, 2, 4, 5, 8, 9, 13, 14, 19, 20, 26, 27, 34 };
107 auto libgrapheme = SkUnicodes::Libgrapheme::Make();
108 std::vector<SkUnicode::Position> results;
109 auto result = libgrapheme->getUtf8Words(text.data(), text.size(), "en", &results);
111 REPORTER_ASSERT(reporter, results.size() == expected.size());
112 for (auto i = 0ul; i < results.size(); ++i) {
113 REPORTER_ASSERT(reporter, results[i] == expected[i]);
114 }
115}
116#endif
117
118#if defined(SK_UNICODE_ICU_IMPLEMENTATION)
119UNIX_ONLY_TEST(SkUnicode_Compiled_GetSentences, reporter) {
120 auto icu = SkUnicodes::ICU::Make();
121 if (!icu) {
123 return;
124 }
125 SkString text("Hello world! Hello world? Hello world... Not a sentence end: 3.1415926");
126 std::vector<SkUnicode::Position> expected = {0, 13, 26, 41, 70};
127 std::vector<SkUnicode::Position> results;
128 auto result = icu->getSentences(text.data(), text.size(), nullptr, &results);
130 REPORTER_ASSERT(reporter, results.size() == expected.size());
131 for (auto i = 0ul; i < results.size(); ++i) {
132 REPORTER_ASSERT(reporter, results[i] == expected[i]);
133 }
134}
135#endif
136
139}
140
141// On Windows libgrapheme produces different results
142DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsLTR, reporter) {
143 if (!unicode) {
144 return;
145 }
146 SkString text("1 22 333 4444 55555 666666 7777777");
147 std::vector<SkUnicode::BidiRegion> results;
148 auto result = unicode->getBidiRegions(text.data(),
149 text.size(),
151 &results);
153 REPORTER_ASSERT(reporter, results.size() == 1);
154 REPORTER_ASSERT(reporter, results[0].start == 0 &&
155 results[0].end == text.size() &&
156 results[0].level == 0);
157}
158
159DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsRTL, reporter) {
160 if (!unicode) {
161 return;
162 }
163 SkString text("الهيمنة على العالم عبارة قبيحة ، أفضل أن أسميها تحسين العالم.");
164 std::vector<SkUnicode::BidiRegion> results;
165 auto result = unicode->getBidiRegions(text.data(),
166 text.size(),
168 &results);
170 REPORTER_ASSERT(reporter, results.size() == 1);
171 REPORTER_ASSERT(reporter, results[0].start == 0 &&
172 results[0].end == text.size() &&
173 results[0].level == 1);
174}
175
176DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsMix1, reporter) {
177 if (!unicode) {
178 return;
179 }
180 // Spaces become Arabic (RTL) but numbers remain English (LTR)
181 SkString text("1 22 333 4444 55555 666666 7777777");
182 std::vector<SkUnicode::BidiRegion> expected = {
183 {0, 1, 2},
184 {1, 2, 1},
185 {2, 4, 2},
186 {4, 5, 1},
187 {5, 8, 2},
188 {8, 9, 1},
189 {9, 13, 2},
190 {13, 14, 1},
191 {14, 19, 2},
192 {19, 20, 1},
193 {20, 26, 2},
194 {26, 27, 1},
195 {27, 34, 2},
196 };
197 std::vector<SkUnicode::BidiRegion> results;
198 auto result = unicode->getBidiRegions(text.data(),
199 text.size(),
201 &results);
203 REPORTER_ASSERT(reporter, results.size() == expected.size());
204 for (auto i = 0ul; i < results.size(); ++i) {
205 REPORTER_ASSERT(reporter, results[i].start == expected[i].start &&
206 results[i].end == expected[i].end &&
207 results[i].level == expected[i].level);
208 }
209}
210
211DEF_TEST_ICU_UNICODES(SkUnicode_GetBidiRegionsMix2, reporter) {
212 if (!unicode) {
213 return;
214 }
215 // Few Russian/English words (ЛТР) in the mix
216 SkString text("World ЛТР Domination هي عبارة قبيحة ، أفضل أن أسميها World ЛТР Optimization.");
217 std::vector<SkUnicode::BidiRegion> expected = {
218 { 0, 24, 0},
219 { 24, 80, 1},
220 { 80, 107, 0},
221 };
222 std::vector<SkUnicode::BidiRegion> results;
223 auto result = unicode->getBidiRegions(text.data(),
224 text.size(),
226 &results);
228 REPORTER_ASSERT(reporter, results.size() == expected.size());
229 for (auto i = 0ul; i < results.size(); ++i) {
230 REPORTER_ASSERT(reporter, results[i].start == expected[i].start &&
231 results[i].end == expected[i].end &&
232 results[i].level == expected[i].level);
233 }
234}
235
236// Currently, libgrapheme uses different default rules and produces slightly
237// different results; it does not matter for text shaping
238DEF_TEST_ICU_UNICODES(SkUnicode_ToUpper, reporter) {
239 if (!unicode) {
240 return;
241 }
242 SkString lower("abcdefghijklmnopqrstuvwxyz");
243 SkString upper("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
244 auto icu_result1 = unicode->toUpper(lower);
245 REPORTER_ASSERT(reporter, icu_result1.equals(upper));
246 auto icu_result2 = unicode->toUpper(upper);
247 REPORTER_ASSERT(reporter, icu_result2.equals(upper));
248}
249
250DEF_TEST_ICU_UNICODES(SkUnicode_ComputeCodeUnitFlags, reporter) {
251 if (!unicode) {
252 return;
253 }
254 //SkString text("World domination is such an ugly phrase - I prefer to call it world optimisation");
255 SkString text("1\n22 333 4444 55555 666666 7777777");
256 // 4 8 13 19 24
258 auto result = unicode->computeCodeUnitFlags(text.data(),
259 text.size(),
260 /*replaceTabs=*/true,
261 &results);
263 REPORTER_ASSERT(reporter, results.size() == SkToS16(text.size() + 1));
264 for (auto i = 0; i < results.size(); ++i) {
265 auto flags = results[i];
267 if (i == 1) {
269 }
270 if (i == 2) {
272 }
273 if (i == 1 || i == 4 || i == 8 || i == 13 || i == 19 || i == 26) {
276 }
277 if (i == 0 || i == 2 || i == 5 || i == 9 || i == 14 || i == 20
278 || i == 27 || i == 34) {
280 }
281 REPORTER_ASSERT(reporter, flags == expected);
282 }
283}
284
285DEF_TEST_UNICODES(SkUnicode_ReorderVisual, reporter) {
286 if (!unicode) {
287 return;
288 }
289 auto reorder = [&](std::vector<SkUnicode::BidiLevel> levels,
290 std::vector<int32_t> expected) {
291 std::vector<int32_t> logicalOrder(levels.size());
292 unicode->reorderVisual(levels.data(), levels.size(), logicalOrder.data());
293 for (auto i = 0ul; i < levels.size(); ++i) {
294 REPORTER_ASSERT(reporter, expected[i] == logicalOrder[i]);
295 }
296 };
297 reorder({}, {});
298 reorder({0}, {0});
299 reorder({1}, {0});
300 reorder({0, 1, 0, 1}, {0, 1, 2, 3});
301}
302
303[[maybe_unused]] static void SkUnicode_Emoji(SkUnicode* icu, skiatest::Reporter* reporter) {
304 std::u32string emojis(U"😄😁😆😅😂🤣");
305 std::u32string not_emojis(U"満毎行昼本可");
306 for (auto e : emojis) {
308 }
309 for (auto n: not_emojis) {
311 }
312}
313
314#ifdef SK_UNICODE_ICU_IMPLEMENTATION
315UNIX_ONLY_TEST(SkUnicode_Compiled_Emoji, reporter) {
316 auto icu = SkUnicodes::ICU::Make();
317 if (!icu) {
319 return;
320 }
321 SkUnicode_Emoji(icu.get(), reporter);
322}
323#endif
324
325#ifdef SK_UNICODE_ICU4X_IMPLEMENTATION
326UNIX_ONLY_TEST(SkUnicode_ICU4X_Emoji, reporter) {
327 auto icu = SkUnicodes::ICU4X::Make();
328 if (!icu) {
330 return;
331 }
332 SkUnicode_Emoji(icu.get(), reporter);
333}
334#endif
335
336[[maybe_unused]] static void SkUnicode_Ideographic(SkUnicode* icu, skiatest::Reporter* reporter) {
337 std::u32string ideographic(U"満毎行昼本可");
338 std::u32string not_ideographic(U"😄😁😆😅😂🤣");
339 for (auto i : ideographic) {
341 }
342 for (auto n: not_ideographic) {
344 }
345}
346
347#ifdef SK_UNICODE_ICU_IMPLEMENTATION
348UNIX_ONLY_TEST(SkUnicode_Compiled_Ideographic, reporter) {
349 auto icu = SkUnicodes::ICU::Make();
350 if (!icu) {
352 return;
353 }
355}
356#endif
357
358#ifdef SK_UNICODE_ICU4X_IMPLEMENTATION
359UNIX_ONLY_TEST(SkUnicode_ICU4X_Ideographic, reporter) {
360 auto icu = SkUnicodes::ICU4X::Make();
361 if (!icu) {
363 return;
364 }
366}
367#endif
constexpr int16_t SkToS16(S x)
Definition SkTo.h:23
#define DEF_TEST_ICU_UNICODES(name, reporter)
static void SkUnicode_Emoji(SkUnicode *icu, skiatest::Reporter *reporter)
static void SkUnicode_Ideographic(SkUnicode *icu, skiatest::Reporter *reporter)
bool hasWordFlag(SkUnicode::CodeUnitFlags flags)
#define DEF_TEST_UNICODES(name, reporter)
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define UNIX_ONLY_TEST
Definition Test.h:319
virtual bool isIdeographic(SkUnichar utf8)=0
static bool hasPartOfWhiteSpaceBreakFlag(SkUnicode::CodeUnitFlags flags)
Definition SkUnicode.cpp:71
@ kPartOfWhiteSpaceBreak
Definition SkUnicode.h:81
@ kHardLineBreakBefore
Definition SkUnicode.h:84
@ kGraphemeStart
Definition SkUnicode.h:82
@ kSoftLineBreakBefore
Definition SkUnicode.h:83
@ kPartOfIntraWordBreak
Definition SkUnicode.h:85
static SkString convertUtf16ToUtf8(const char16_t *utf16, int utf16Units)
Definition SkUnicode.cpp:14
virtual bool isEmoji(SkUnichar utf8)=0
int size() const
Definition SkTArray.h:416
FlutterSemanticsFlag flag
FlutterSemanticsFlag flags
glong glong end
GAsyncResult * result
std::u16string text
SKUNICODE_API sk_sp< SkUnicode > Make(SkSpan< char > text, std::vector< SkUnicode::Position > words, std::vector< SkUnicode::Position > graphemeBreaks, std::vector< SkUnicode::LineBreakBefore > lineBreaks)
SKUNICODE_API sk_sp< SkUnicode > Make()
SKUNICODE_API sk_sp< SkUnicode > Make()
SKUNICODE_API sk_sp< SkUnicode > Make()

◆ DEF_TEST_LIBGRAPHEME

#define DEF_TEST_LIBGRAPHEME (   name,
  reporter 
)

Definition at line 50 of file SkUnicodeTest.cpp.

◆ DEF_TEST_NOIMPL

#define DEF_TEST_NOIMPL (   name,
  reporter 
)

Definition at line 53 of file SkUnicodeTest.cpp.

◆ DEF_TEST_UNICODES

#define DEF_TEST_UNICODES (   name,
  reporter 
)
Value:
DEF_TEST_ICU(name, reporter) \
DEF_TEST_ICU4X(name, reporter) \
DEF_TEST_LIBGRAPHEME(name, reporter) \
DEF_TEST_NOIMPL(name, reporter) \

Definition at line 55 of file SkUnicodeTest.cpp.

Function Documentation

◆ DEF_TEST_ICU_UNICODES() [1/6]

DEF_TEST_ICU_UNICODES ( SkUnicode_ComputeCodeUnitFlags  ,
reporter   
)

Definition at line 251 of file SkUnicodeTest.cpp.

251 {
252 if (!unicode) {
253 return;
254 }
255 //SkString text("World domination is such an ugly phrase - I prefer to call it world optimisation");
256 SkString text("1\n22 333 4444 55555 666666 7777777");
257 // 4 8 13 19 24
259 auto result = unicode->computeCodeUnitFlags(text.data(),
260 text.size(),
261 /*replaceTabs=*/true,
262 &results);
264 REPORTER_ASSERT(reporter, results.size() == SkToS16(text.size() + 1));
265 for (auto i = 0; i < results.size(); ++i) {
266 auto flags = results[i];
268 if (i == 1) {
270 }
271 if (i == 2) {
273 }
274 if (i == 1 || i == 4 || i == 8 || i == 13 || i == 19 || i == 26) {
277 }
278 if (i == 0 || i == 2 || i == 5 || i == 9 || i == 14 || i == 20
279 || i == 27 || i == 34) {
281 }
282 REPORTER_ASSERT(reporter, flags == expected);
283 }
284}

◆ DEF_TEST_ICU_UNICODES() [2/6]

DEF_TEST_ICU_UNICODES ( SkUnicode_GetBidiRegionsLTR  ,
reporter   
)

Definition at line 143 of file SkUnicodeTest.cpp.

143 {
144 if (!unicode) {
145 return;
146 }
147 SkString text("1 22 333 4444 55555 666666 7777777");
148 std::vector<SkUnicode::BidiRegion> results;
149 auto result = unicode->getBidiRegions(text.data(),
150 text.size(),
152 &results);
154 REPORTER_ASSERT(reporter, results.size() == 1);
155 REPORTER_ASSERT(reporter, results[0].start == 0 &&
156 results[0].end == text.size() &&
157 results[0].level == 0);
158}

◆ DEF_TEST_ICU_UNICODES() [3/6]

DEF_TEST_ICU_UNICODES ( SkUnicode_GetBidiRegionsMix1  ,
reporter   
)

Definition at line 177 of file SkUnicodeTest.cpp.

177 {
178 if (!unicode) {
179 return;
180 }
181 // Spaces become Arabic (RTL) but numbers remain English (LTR)
182 SkString text("1 22 333 4444 55555 666666 7777777");
183 std::vector<SkUnicode::BidiRegion> expected = {
184 {0, 1, 2},
185 {1, 2, 1},
186 {2, 4, 2},
187 {4, 5, 1},
188 {5, 8, 2},
189 {8, 9, 1},
190 {9, 13, 2},
191 {13, 14, 1},
192 {14, 19, 2},
193 {19, 20, 1},
194 {20, 26, 2},
195 {26, 27, 1},
196 {27, 34, 2},
197 };
198 std::vector<SkUnicode::BidiRegion> results;
199 auto result = unicode->getBidiRegions(text.data(),
200 text.size(),
202 &results);
204 REPORTER_ASSERT(reporter, results.size() == expected.size());
205 for (auto i = 0ul; i < results.size(); ++i) {
206 REPORTER_ASSERT(reporter, results[i].start == expected[i].start &&
207 results[i].end == expected[i].end &&
208 results[i].level == expected[i].level);
209 }
210}

◆ DEF_TEST_ICU_UNICODES() [4/6]

DEF_TEST_ICU_UNICODES ( SkUnicode_GetBidiRegionsMix2  ,
reporter   
)

Definition at line 212 of file SkUnicodeTest.cpp.

212 {
213 if (!unicode) {
214 return;
215 }
216 // Few Russian/English words (ЛТР) in the mix
217 SkString text("World ЛТР Domination هي عبارة قبيحة ، أفضل أن أسميها World ЛТР Optimization.");
218 std::vector<SkUnicode::BidiRegion> expected = {
219 { 0, 24, 0},
220 { 24, 80, 1},
221 { 80, 107, 0},
222 };
223 std::vector<SkUnicode::BidiRegion> results;
224 auto result = unicode->getBidiRegions(text.data(),
225 text.size(),
227 &results);
229 REPORTER_ASSERT(reporter, results.size() == expected.size());
230 for (auto i = 0ul; i < results.size(); ++i) {
231 REPORTER_ASSERT(reporter, results[i].start == expected[i].start &&
232 results[i].end == expected[i].end &&
233 results[i].level == expected[i].level);
234 }
235}

◆ DEF_TEST_ICU_UNICODES() [5/6]

DEF_TEST_ICU_UNICODES ( SkUnicode_GetBidiRegionsRTL  ,
reporter   
)

Definition at line 160 of file SkUnicodeTest.cpp.

160 {
161 if (!unicode) {
162 return;
163 }
164 SkString text("الهيمنة على العالم عبارة قبيحة ، أفضل أن أسميها تحسين العالم.");
165 std::vector<SkUnicode::BidiRegion> results;
166 auto result = unicode->getBidiRegions(text.data(),
167 text.size(),
169 &results);
171 REPORTER_ASSERT(reporter, results.size() == 1);
172 REPORTER_ASSERT(reporter, results[0].start == 0 &&
173 results[0].end == text.size() &&
174 results[0].level == 1);
175}

◆ DEF_TEST_ICU_UNICODES() [6/6]

DEF_TEST_ICU_UNICODES ( SkUnicode_ToUpper  ,
reporter   
)

Definition at line 239 of file SkUnicodeTest.cpp.

239 {
240 if (!unicode) {
241 return;
242 }
243 SkString lower("abcdefghijklmnopqrstuvwxyz");
244 SkString upper("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
245 auto icu_result1 = unicode->toUpper(lower);
246 REPORTER_ASSERT(reporter, icu_result1.equals(upper));
247 auto icu_result2 = unicode->toUpper(upper);
248 REPORTER_ASSERT(reporter, icu_result2.equals(upper));
249}

◆ DEF_TEST_UNICODES()

DEF_TEST_UNICODES ( SkUnicode_ReorderVisual  ,
reporter   
)

Definition at line 286 of file SkUnicodeTest.cpp.

286 {
287 if (!unicode) {
288 return;
289 }
290 auto reorder = [&](std::vector<SkUnicode::BidiLevel> levels,
291 std::vector<int32_t> expected) {
292 std::vector<int32_t> logicalOrder(levels.size());
293 unicode->reorderVisual(levels.data(), levels.size(), logicalOrder.data());
294 for (auto i = 0ul; i < levels.size(); ++i) {
295 REPORTER_ASSERT(reporter, expected[i] == logicalOrder[i]);
296 }
297 };
298 reorder({}, {});
299 reorder({0}, {0});
300 reorder({1}, {0});
301 reorder({0, 1, 0, 1}, {0, 1, 2, 3});
302}

◆ hasWordFlag()

bool hasWordFlag ( SkUnicode::CodeUnitFlags  flags)

Definition at line 138 of file SkUnicodeTest.cpp.

138 {
140}

◆ SkUnicode_Emoji()

static void SkUnicode_Emoji ( SkUnicode icu,
skiatest::Reporter reporter 
)
static

Definition at line 304 of file SkUnicodeTest.cpp.

304 {
305 std::u32string emojis(U"😄😁😆😅😂🤣");
306 std::u32string not_emojis(U"満毎行昼本可");
307 for (auto e : emojis) {
309 }
310 for (auto n: not_emojis) {
312 }
313}

◆ SkUnicode_Ideographic()

static void SkUnicode_Ideographic ( SkUnicode icu,
skiatest::Reporter reporter 
)
static

Definition at line 337 of file SkUnicodeTest.cpp.

337 {
338 std::u32string ideographic(U"満毎行昼本可");
339 std::u32string not_ideographic(U"😄😁😆😅😂🤣");
340 for (auto i : ideographic) {
342 }
343 for (auto n: not_ideographic) {
345 }
346}