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