xref: /aosp_15_r20/external/skia/tools/unicode_comparison/cpp/bridge.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker // Copyright 2023 The Chromium Authors. All rights reserved.
2*c8dee2aaSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*c8dee2aaSAndroid Build Coastguard Worker // found in the LICENSE file.
4*c8dee2aaSAndroid Build Coastguard Worker 
5*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
6*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
7*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skunicode/include/SkUnicode.h"
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkBitmaskEnum.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkTime.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "tools/unicode_comparison/cpp/bridge.h"
11*c8dee2aaSAndroid Build Coastguard Worker 
12*c8dee2aaSAndroid Build Coastguard Worker namespace {
13*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkUnicode> gUnicode = nullptr;
14*c8dee2aaSAndroid Build Coastguard Worker static skia_private::TArray<SkUnicode::CodeUnitFlags, true> gCodeUnitFlags;
15*c8dee2aaSAndroid Build Coastguard Worker static std::vector<SkUnicode::Position> gSentences;
16*c8dee2aaSAndroid Build Coastguard Worker static std::vector<SkUnicode::Position> gWords;
17*c8dee2aaSAndroid Build Coastguard Worker }
18*c8dee2aaSAndroid Build Coastguard Worker 
init_skunicode_impl(char * impl)19*c8dee2aaSAndroid Build Coastguard Worker bool init_skunicode_impl(char* impl) {
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker     SkString unicodeName(impl);
22*c8dee2aaSAndroid Build Coastguard Worker     if (unicodeName.equals("icu")) {
23*c8dee2aaSAndroid Build Coastguard Worker         gUnicode = SkUnicode::ICU::Make();
24*c8dee2aaSAndroid Build Coastguard Worker     } else if (unicodeName.equals("icu4x")) {
25*c8dee2aaSAndroid Build Coastguard Worker         gUnicode = SkUnicode::ICU4X::Make();
26*c8dee2aaSAndroid Build Coastguard Worker     } else if (unicodeName.equals("libgrapheme")) {
27*c8dee2aaSAndroid Build Coastguard Worker         gUnicode = SkUnicode::Libgrapheme::Make();
28*c8dee2aaSAndroid Build Coastguard Worker     } else {
29*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("Implementation '%s' not supported\n", impl);
30*c8dee2aaSAndroid Build Coastguard Worker         return false;
31*c8dee2aaSAndroid Build Coastguard Worker     }
32*c8dee2aaSAndroid Build Coastguard Worker     auto ptr = reinterpret_cast<void*>(gUnicode.get());
33*c8dee2aaSAndroid Build Coastguard Worker     if (ptr == nullptr) {
34*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("Could not create Unicode object\n");
35*c8dee2aaSAndroid Build Coastguard Worker         return false;
36*c8dee2aaSAndroid Build Coastguard Worker     }
37*c8dee2aaSAndroid Build Coastguard Worker     return true;
38*c8dee2aaSAndroid Build Coastguard Worker }
39*c8dee2aaSAndroid Build Coastguard Worker 
cleanup_unicode_impl()40*c8dee2aaSAndroid Build Coastguard Worker void cleanup_unicode_impl() {
41*c8dee2aaSAndroid Build Coastguard Worker     if (gUnicode == nullptr) {
42*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("Unicode object does not exist\n");
43*c8dee2aaSAndroid Build Coastguard Worker         return;
44*c8dee2aaSAndroid Build Coastguard Worker     }
45*c8dee2aaSAndroid Build Coastguard Worker     delete gUnicode.get();
46*c8dee2aaSAndroid Build Coastguard Worker }
47*c8dee2aaSAndroid Build Coastguard Worker 
perf_compute_codeunit_flags(char * text)48*c8dee2aaSAndroid Build Coastguard Worker double perf_compute_codeunit_flags(char* text) {
49*c8dee2aaSAndroid Build Coastguard Worker     if (gUnicode == nullptr) {
50*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("Unicode object does not exist\n");
51*c8dee2aaSAndroid Build Coastguard Worker         return -1;
52*c8dee2aaSAndroid Build Coastguard Worker     }
53*c8dee2aaSAndroid Build Coastguard Worker     double time = SkTime::GetNSecs();
54*c8dee2aaSAndroid Build Coastguard Worker     gUnicode->computeCodeUnitFlags(text, strlen(text), false, &gCodeUnitFlags);
55*c8dee2aaSAndroid Build Coastguard Worker     if (gCodeUnitFlags.size() < strlen(text)) {
56*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("computeCodeUnitFlags failed: %d < %zu\n%s\n\n\n", gCodeUnitFlags.size(), strlen(text),  text);
57*c8dee2aaSAndroid Build Coastguard Worker         return -1;
58*c8dee2aaSAndroid Build Coastguard Worker     }
59*c8dee2aaSAndroid Build Coastguard Worker     std::vector<SkUnicode::Position> positions;
60*c8dee2aaSAndroid Build Coastguard Worker     gUnicode->getUtf8Words(text, strlen(text), nullptr, &positions);
61*c8dee2aaSAndroid Build Coastguard Worker     double result = SkTime::GetNSecs() - time;
62*c8dee2aaSAndroid Build Coastguard Worker     for (auto pos : positions) {
63*c8dee2aaSAndroid Build Coastguard Worker         gCodeUnitFlags[pos] |= SkUnicode::CodeUnitFlags::kWordBreak;
64*c8dee2aaSAndroid Build Coastguard Worker     }
65*c8dee2aaSAndroid Build Coastguard Worker     return result;
66*c8dee2aaSAndroid Build Coastguard Worker }
67*c8dee2aaSAndroid Build Coastguard Worker 
getFlags(int index)68*c8dee2aaSAndroid Build Coastguard Worker int getFlags(int index) {
69*c8dee2aaSAndroid Build Coastguard Worker     if (gUnicode == nullptr) {
70*c8dee2aaSAndroid Build Coastguard Worker         SK_ABORT("Unicode object does not exist");
71*c8dee2aaSAndroid Build Coastguard Worker     } else if (gCodeUnitFlags.size() == 0) {
72*c8dee2aaSAndroid Build Coastguard Worker         SK_ABORT("Unicode object is empty or not initialized\n");
73*c8dee2aaSAndroid Build Coastguard Worker     } else if (index < 0 || index >= gCodeUnitFlags.size()) {
74*c8dee2aaSAndroid Build Coastguard Worker         SK_ABORT("Index value %d outside of valid range [%d:%d)\n", index, 0, gCodeUnitFlags.size());
75*c8dee2aaSAndroid Build Coastguard Worker     }
76*c8dee2aaSAndroid Build Coastguard Worker     return gCodeUnitFlags[index];
77*c8dee2aaSAndroid Build Coastguard Worker }
78*c8dee2aaSAndroid Build Coastguard Worker 
getSentences(char * text,int * length)79*c8dee2aaSAndroid Build Coastguard Worker void* getSentences(char* text, int* length) {
80*c8dee2aaSAndroid Build Coastguard Worker     if (gUnicode == nullptr) {
81*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("Unicode object does not exist");
82*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
83*c8dee2aaSAndroid Build Coastguard Worker     }
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker     gSentences.clear();
86*c8dee2aaSAndroid Build Coastguard Worker     gUnicode->getSentences(text, strlen(text), nullptr, &gSentences);
87*c8dee2aaSAndroid Build Coastguard Worker     *length = gSentences.size();
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker     return reinterpret_cast<SkUnicode::Position*>(gSentences.data());
90*c8dee2aaSAndroid Build Coastguard Worker }
91*c8dee2aaSAndroid Build Coastguard Worker 
trimSentence(char * text,int * sentence,int wordLimit)92*c8dee2aaSAndroid Build Coastguard Worker bool trimSentence(char* text, int* sentence, int wordLimit) {
93*c8dee2aaSAndroid Build Coastguard Worker     *sentence = 0;
94*c8dee2aaSAndroid Build Coastguard Worker     if (gUnicode == nullptr) {
95*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("Unicode object does not exist");
96*c8dee2aaSAndroid Build Coastguard Worker         return true;
97*c8dee2aaSAndroid Build Coastguard Worker     }
98*c8dee2aaSAndroid Build Coastguard Worker 
99*c8dee2aaSAndroid Build Coastguard Worker     gWords.clear();
100*c8dee2aaSAndroid Build Coastguard Worker     gUnicode->getUtf8Words(text, strlen(text), nullptr, &gWords);
101*c8dee2aaSAndroid Build Coastguard Worker 
102*c8dee2aaSAndroid Build Coastguard Worker     for (auto word : gWords) {
103*c8dee2aaSAndroid Build Coastguard Worker         if (word > wordLimit) {
104*c8dee2aaSAndroid Build Coastguard Worker             return true;
105*c8dee2aaSAndroid Build Coastguard Worker         } else {
106*c8dee2aaSAndroid Build Coastguard Worker             *sentence = word;
107*c8dee2aaSAndroid Build Coastguard Worker         }
108*c8dee2aaSAndroid Build Coastguard Worker     }
109*c8dee2aaSAndroid Build Coastguard Worker     if (strlen(text) <= wordLimit) {
110*c8dee2aaSAndroid Build Coastguard Worker         *sentence = strlen(text);
111*c8dee2aaSAndroid Build Coastguard Worker         return false;
112*c8dee2aaSAndroid Build Coastguard Worker     }
113*c8dee2aaSAndroid Build Coastguard Worker     return true;
114*c8dee2aaSAndroid Build Coastguard Worker }
115*c8dee2aaSAndroid Build Coastguard Worker 
116*c8dee2aaSAndroid Build Coastguard Worker 
toUpper(char * str)117*c8dee2aaSAndroid Build Coastguard Worker void* toUpper(char* str) {
118*c8dee2aaSAndroid Build Coastguard Worker     if (gUnicode == nullptr) {
119*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("Unicode object does not exist");
120*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
121*c8dee2aaSAndroid Build Coastguard Worker     }
122*c8dee2aaSAndroid Build Coastguard Worker     auto res = new SkString(gUnicode->toUpper(SkString(str)));
123*c8dee2aaSAndroid Build Coastguard Worker     return reinterpret_cast<void*>(res);
124*c8dee2aaSAndroid Build Coastguard Worker }
125*c8dee2aaSAndroid Build Coastguard Worker 
print(void * str)126*c8dee2aaSAndroid Build Coastguard Worker void  print(void* str) {
127*c8dee2aaSAndroid Build Coastguard Worker     auto ptr = reinterpret_cast<SkString*>(str);
128*c8dee2aaSAndroid Build Coastguard Worker     SkDebugf("%s\n", ptr->c_str());
129*c8dee2aaSAndroid Build Coastguard Worker }
130