Flutter Engine
The Flutter Engine
SkUnicode.h
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#ifndef SkUnicode_DEFINED
8#define SkUnicode_DEFINED
10#include "include/core/SkSpan.h"
15#include "src/base/SkUTF.h"
16#include <cstddef>
17#include <cstdint>
18#include <memory>
19#include <string>
20#include <vector>
21namespace sknonstd { template <typename T> struct is_bitmask_enum; }
22
23#if !defined(SKUNICODE_IMPLEMENTATION)
24 #define SKUNICODE_IMPLEMENTATION 0
25#endif
26
27#if !defined(SKUNICODE_API)
28 #if defined(SKUNICODE_DLL)
29 #if defined(_MSC_VER)
30 #if SKUNICODE_IMPLEMENTATION
31 #define SKUNICODE_API __declspec(dllexport)
32 #else
33 #define SKUNICODE_API __declspec(dllimport)
34 #endif
35 #else
36 #define SKUNICODE_API __attribute__((visibility("default")))
37 #endif
38 #else
39 #define SKUNICODE_API
40 #endif
41#endif
42
44public:
45 typedef int32_t Position;
46 typedef uint8_t Level;
47 struct Region {
49 : start(start), end(end), level(level) { }
53 };
54 enum Direction {
57 };
58 virtual ~SkBidiIterator() = default;
59 virtual Position getLength() = 0;
61};
62
64public:
65 typedef int32_t Position;
66 typedef int32_t Status;
67 virtual ~SkBreakIterator() = default;
68 virtual Position first() = 0;
69 virtual Position current() = 0;
70 virtual Position next() = 0;
71 virtual Status status() = 0;
72 virtual bool isDone() = 0;
73 virtual bool setText(const char utftext8[], int utf8Units) = 0;
74 virtual bool setText(const char16_t utftext16[], int utf16Units) = 0;
75};
76
78 public:
80 kNoCodeUnitFlag = 0x00,
81 kPartOfWhiteSpaceBreak = 0x01,
82 kGraphemeStart = 0x02,
83 kSoftLineBreakBefore = 0x04,
84 kHardLineBreakBefore = 0x08,
85 kPartOfIntraWordBreak = 0x10,
86 kControl = 0x20,
87 kTabulation = 0x40,
88 kGlyphClusterStart = 0x80,
89 kIdeographic = 0x100,
90 kEmoji = 0x200,
91 kWordBreak = 0x400,
92 kSentenceBreak = 0x800,
93 };
94 enum class TextDirection {
95 kLTR,
96 kRTL,
97 };
98 typedef size_t Position;
99 typedef uint8_t BidiLevel;
100 struct BidiRegion {
102 : start(start), end(end), level(level) { }
106 };
107 enum class LineBreakType {
108 kSoftLineBreak = 0,
109 kHardLineBreak = 100,
110 };
111
112 enum class BreakType { kWords, kGraphemes, kLines, kSentences };
115 : pos(pos), breakType(breakType) { }
118 };
119
120 ~SkUnicode() override = default;
121
122 // deprecated
123 virtual SkString toUpper(const SkString&) = 0;
124 virtual SkString toUpper(const SkString&, const char* locale) = 0;
125
126 virtual bool isControl(SkUnichar utf8) = 0;
127 virtual bool isWhitespace(SkUnichar utf8) = 0;
128 virtual bool isSpace(SkUnichar utf8) = 0;
129 virtual bool isTabulation(SkUnichar utf8) = 0;
130 virtual bool isHardBreak(SkUnichar utf8) = 0;
131 /**
132 * Returns if a code point may start an emoji sequence.
133 * Returns true for '#', '*', and '0'-'9' since they may start an emoji sequence.
134 * To determine if a list of code points begins with an emoji sequence, use
135 * getEmojiSequence.
136 **/
137 virtual bool isEmoji(SkUnichar utf8) = 0;
138 virtual bool isEmojiComponent(SkUnichar utf8) = 0;
140 virtual bool isEmojiModifier(SkUnichar utf8) = 0;
142 virtual bool isIdeographic(SkUnichar utf8) = 0;
143
144 // Methods used in SkShaper and SkText
145 virtual std::unique_ptr<SkBidiIterator> makeBidiIterator
146 (const uint16_t text[], int count, SkBidiIterator::Direction) = 0;
147 virtual std::unique_ptr<SkBidiIterator> makeBidiIterator
148 (const char text[], int count, SkBidiIterator::Direction) = 0;
149 virtual std::unique_ptr<SkBreakIterator> makeBreakIterator
150 (const char locale[], BreakType breakType) = 0;
151 virtual std::unique_ptr<SkBreakIterator> makeBreakIterator(BreakType type) = 0;
152
153 // Methods used in SkParagraph
154 static bool hasTabulationFlag(SkUnicode::CodeUnitFlags flags);
155 static bool hasHardLineBreakFlag(SkUnicode::CodeUnitFlags flags);
156 static bool hasSoftLineBreakFlag(SkUnicode::CodeUnitFlags flags);
157 static bool hasGraphemeStartFlag(SkUnicode::CodeUnitFlags flags);
158 static bool hasControlFlag(SkUnicode::CodeUnitFlags flags);
159 static bool hasPartOfWhiteSpaceBreakFlag(SkUnicode::CodeUnitFlags flags);
160
161 static bool extractBidi(const char utf8[],
162 int utf8Units,
164 std::vector<BidiRegion>* bidiRegions);
165 virtual bool getBidiRegions(const char utf8[],
166 int utf8Units,
168 std::vector<BidiRegion>* results) = 0;
169 // Returns results in utf16
170 virtual bool getWords(const char utf8[], int utf8Units, const char* locale,
171 std::vector<Position>* results) = 0;
172 virtual bool getUtf8Words(const char utf8[],
173 int utf8Units,
174 const char* locale,
175 std::vector<Position>* results) = 0;
176 virtual bool getSentences(const char utf8[],
177 int utf8Units,
178 const char* locale,
179 std::vector<Position>* results) = 0;
181 char utf8[], int utf8Units, bool replaceTabs,
184 char16_t utf16[], int utf16Units, bool replaceTabs,
186
187 static SkString convertUtf16ToUtf8(const char16_t * utf16, int utf16Units);
188 static SkString convertUtf16ToUtf8(const std::u16string& utf16);
189 static std::u16string convertUtf8ToUtf16(const char* utf8, int utf8Units);
190 static std::u16string convertUtf8ToUtf16(const SkString& utf8);
191
192 template <typename Appender8, typename Appender16>
193 static bool extractUtfConversionMapping(SkSpan<const char> utf8, Appender8&& appender8, Appender16&& appender16) {
194 size_t size8 = 0;
195 size_t size16 = 0;
196 auto ptr = utf8.begin();
197 auto end = utf8.end();
198 while (ptr < end) {
199
200 size_t index = SkToSizeT(ptr - utf8.begin());
201 SkUnichar u = SkUTF::NextUTF8(&ptr, end);
202
203 // All UTF8 code units refer to the same codepoint
204 size_t next = SkToSizeT(ptr - utf8.begin());
205 for (auto i = index; i < next; ++i) {
206 //fUTF16IndexForUTF8Index.emplace_back(fUTF8IndexForUTF16Index.size());
207 appender16(size8);
208 ++size16;
209 }
210 //SkASSERT(fUTF16IndexForUTF8Index.size() == next);
211 SkASSERT(size16 == next);
212 if (size16 != next) {
213 return false;
214 }
215
216 // One or two UTF16 code units refer to the same codepoint
217 uint16_t buffer[2];
218 size_t count = SkUTF::ToUTF16(u, buffer);
219 //fUTF8IndexForUTF16Index.emplace_back(index);
220 appender8(index);
221 ++size8;
222 if (count > 1) {
223 //fUTF8IndexForUTF16Index.emplace_back(index);
224 appender8(index);
225 ++size8;
226 }
227 }
228 //fUTF16IndexForUTF8Index.emplace_back(fUTF8IndexForUTF16Index.size());
229 appender16(size8);
230 ++size16;
231 //fUTF8IndexForUTF16Index.emplace_back(fText.size());
232 appender8(utf8.size());
233 ++size8;
234
235 return true;
236 }
237
238 template <typename Callback>
239 void forEachCodepoint(const char* utf8, int32_t utf8Units, Callback&& callback) {
240 const char* current = utf8;
241 const char* end = utf8 + utf8Units;
242 while (current < end) {
243 auto before = current - utf8;
244 SkUnichar unichar = SkUTF::NextUTF8(&current, end);
245 if (unichar < 0) unichar = 0xFFFD;
246 auto after = current - utf8;
247 uint16_t buffer[2];
248 size_t count = SkUTF::ToUTF16(unichar, buffer);
249 callback(unichar, before, after, count);
250 }
251 }
252
253 template <typename Callback>
254 void forEachCodepoint(const char16_t* utf16, int32_t utf16Units, Callback&& callback) {
255 const char16_t* current = utf16;
256 const char16_t* end = utf16 + utf16Units;
257 while (current < end) {
258 auto before = current - utf16;
259 SkUnichar unichar = SkUTF::NextUTF16((const uint16_t**)&current, (const uint16_t*)end);
260 auto after = current - utf16;
261 callback(unichar, before, after);
262 }
263 }
264
265 template <typename Callback>
266 void forEachBidiRegion(const uint16_t utf16[], int utf16Units, SkBidiIterator::Direction dir, Callback&& callback) {
267 auto iter = makeBidiIterator(utf16, utf16Units, dir);
268 const uint16_t* start16 = utf16;
269 const uint16_t* end16 = utf16 + utf16Units;
270 SkBidiIterator::Level currentLevel = 0;
271
272 SkBidiIterator::Position pos16 = 0;
273 while (pos16 <= iter->getLength()) {
274 auto level = iter->getLevelAt(pos16);
275 if (pos16 == 0) {
276 currentLevel = level;
277 } else if (level != currentLevel) {
278 callback(pos16, start16 - utf16, currentLevel);
279 currentLevel = level;
280 }
281 if (start16 == end16) {
282 break;
283 }
284 SkUnichar u = SkUTF::NextUTF16(&start16, end16);
285 pos16 += SkUTF::ToUTF16(u);
286 }
287 }
288
289 template <typename Callback>
290 void forEachBreak(const char16_t utf16[], int utf16Units, SkUnicode::BreakType type, Callback&& callback) {
291 auto iter = makeBreakIterator(type);
292 iter->setText(utf16, utf16Units);
293 auto pos = iter->first();
294 do {
295 callback(pos, iter->status());
296 pos = iter->next();
297 } while (!iter->isDone());
298 }
299
300 virtual void reorderVisual(const BidiLevel runLevels[], int levelsCount, int32_t logicalFromVisual[]) = 0;
301};
302
303namespace sknonstd {
304template <> struct is_bitmask_enum<SkUnicode::CodeUnitFlags> : std::true_type {};
305} // namespace sknonstd
306
307#endif // SkUnicode_DEFINED
int count
Definition: FontMgrTest.cpp:50
SkPoint pos
static float next(float f)
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr size_t SkToSizeT(S x)
Definition: SkTo.h:31
int32_t SkUnichar
Definition: SkTypes.h:175
#define SKUNICODE_API
Definition: SkUnicode.h:39
GLenum type
virtual Level getLevelAt(Position)=0
virtual ~SkBidiIterator()=default
int32_t Position
Definition: SkUnicode.h:45
virtual Position getLength()=0
uint8_t Level
Definition: SkUnicode.h:46
virtual bool setText(const char16_t utftext16[], int utf16Units)=0
virtual Position first()=0
virtual Position current()=0
virtual bool setText(const char utftext8[], int utf8Units)=0
virtual Status status()=0
int32_t Position
Definition: SkUnicode.h:65
virtual Position next()=0
virtual ~SkBreakIterator()=default
int32_t Status
Definition: SkUnicode.h:66
virtual bool isDone()=0
virtual bool computeCodeUnitFlags(char16_t utf16[], int utf16Units, bool replaceTabs, skia_private::TArray< SkUnicode::CodeUnitFlags, true > *results)=0
virtual bool isEmojiModifier(SkUnichar utf8)=0
virtual bool isIdeographic(SkUnichar utf8)=0
~SkUnicode() override=default
virtual bool isEmojiModifierBase(SkUnichar utf8)=0
virtual bool isWhitespace(SkUnichar utf8)=0
void forEachCodepoint(const char16_t *utf16, int32_t utf16Units, Callback &&callback)
Definition: SkUnicode.h:254
void forEachBidiRegion(const uint16_t utf16[], int utf16Units, SkBidiIterator::Direction dir, Callback &&callback)
Definition: SkUnicode.h:266
virtual bool isRegionalIndicator(SkUnichar utf8)=0
virtual bool getWords(const char utf8[], int utf8Units, const char *locale, std::vector< Position > *results)=0
virtual void reorderVisual(const BidiLevel runLevels[], int levelsCount, int32_t logicalFromVisual[])=0
virtual std::unique_ptr< SkBreakIterator > makeBreakIterator(const char locale[], BreakType breakType)=0
virtual bool isEmojiComponent(SkUnichar utf8)=0
virtual bool isTabulation(SkUnichar utf8)=0
virtual std::unique_ptr< SkBreakIterator > makeBreakIterator(BreakType type)=0
static bool extractBidi(const char utf8[], int utf8Units, TextDirection dir, std::vector< BidiRegion > *bidiRegions)
size_t Position
Definition: SkUnicode.h:98
virtual std::unique_ptr< SkBidiIterator > makeBidiIterator(const uint16_t text[], int count, SkBidiIterator::Direction)=0
virtual SkString toUpper(const SkString &)=0
uint8_t BidiLevel
Definition: SkUnicode.h:99
virtual std::unique_ptr< SkBidiIterator > makeBidiIterator(const char text[], int count, SkBidiIterator::Direction)=0
virtual bool isSpace(SkUnichar utf8)=0
virtual bool isControl(SkUnichar utf8)=0
virtual bool getSentences(const char utf8[], int utf8Units, const char *locale, std::vector< Position > *results)=0
void forEachCodepoint(const char *utf8, int32_t utf8Units, Callback &&callback)
Definition: SkUnicode.h:239
static bool extractUtfConversionMapping(SkSpan< const char > utf8, Appender8 &&appender8, Appender16 &&appender16)
Definition: SkUnicode.h:193
virtual bool isEmoji(SkUnichar utf8)=0
virtual SkString toUpper(const SkString &, const char *locale)=0
void forEachBreak(const char16_t utf16[], int utf16Units, SkUnicode::BreakType type, Callback &&callback)
Definition: SkUnicode.h:290
virtual bool getBidiRegions(const char utf8[], int utf8Units, TextDirection dir, std::vector< BidiRegion > *results)=0
virtual bool computeCodeUnitFlags(char utf8[], int utf8Units, bool replaceTabs, skia_private::TArray< SkUnicode::CodeUnitFlags, true > *results)=0
virtual bool getUtf8Words(const char utf8[], int utf8Units, const char *locale, std::vector< Position > *results)=0
virtual bool isHardBreak(SkUnichar utf8)=0
FlutterSemanticsFlag flags
glong glong end
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
std::u16string text
SK_SPI SkUnichar NextUTF16(const uint16_t **ptr, const uint16_t *end)
Definition: SkUTF.cpp:159
SK_SPI SkUnichar NextUTF8(const char **ptr, const char *end)
Definition: SkUTF.cpp:118
SK_SPI size_t ToUTF16(SkUnichar uni, uint16_t utf16[2]=nullptr)
Definition: SkUTF.cpp:243
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition: switches.h:145
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
constexpr int kControl
std::function< void(MTLRenderPipelineDescriptor *)> Callback
@ kIdeographic
Definition: text_baseline.h:24
Region(Position start, Position end, Level level)
Definition: SkUnicode.h:48
BidiRegion(Position start, Position end, BidiLevel level)
Definition: SkUnicode.h:101
LineBreakType breakType
Definition: SkUnicode.h:117
LineBreakBefore(Position pos, LineBreakType breakType)
Definition: SkUnicode.h:114