• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 Google Inc.
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
9 
10 #include "include/core/SkSpan.h"
11 #include "include/core/SkTypes.h"
12 #include "src/utils/SkUTF.h"
13 #include <vector>
14 
15 #if !defined(SKUNICODE_IMPLEMENTATION)
16     #define SKUNICODE_IMPLEMENTATION 0
17 #endif
18 
19 #if !defined(SKUNICODE_API)
20     #if defined(SKSHAPER_DLL)
21         #if defined(_MSC_VER)
22             #if SKUNICODE_IMPLEMENTATION
23                 #define SKUNICODE_API __declspec(dllexport)
24             #else
25                 #define SKUNICODE_API __declspec(dllimport)
26             #endif
27         #else
28             #define SKUNICODE_API __attribute__((visibility("default")))
29         #endif
30     #else
31         #define SKUNICODE_API
32     #endif
33 #endif
34 
35 class SKUNICODE_API SkBidiIterator {
36 public:
37     typedef int32_t Position;
38     typedef uint8_t Level;
39     struct Region {
RegionRegion40         Region(Position start, Position end, Level level)
41             : start(start), end(end), level(level) { }
42         Position start;
43         Position end;
44         Level level;
45     };
46     enum Direction {
47         kLTR,
48         kRTL,
49     };
50     virtual ~SkBidiIterator() = default;
51     virtual Position getLength() = 0;
52     virtual Level getLevelAt(Position) = 0;
53     static void ReorderVisual(const Level runLevels[], int levelsCount, int32_t logicalFromVisual[]);
54 };
55 
56 class SKUNICODE_API SkBreakIterator {
57 public:
58     typedef int32_t Position;
59     typedef int32_t Status;
60     virtual ~SkBreakIterator() = default;
61     virtual Position first() = 0;
62     virtual Position current() = 0;
63     virtual Position next() = 0;
64     virtual Position preceding(Position offset) = 0;
65     virtual Position following(Position offset) = 0;
66     virtual Status status() = 0;
67     virtual bool isDone() = 0;
68     virtual bool setText(const char utftext8[], int utf8Units) = 0;
69 };
70 
71 class SKUNICODE_API SkScriptIterator {
72  public:
73     typedef uint32_t ScriptID;
74     virtual ~SkScriptIterator() = default;
75     virtual bool getScript(SkUnichar u, ScriptID* script) = 0;
76 };
77 
78 class SKUNICODE_API SkUnicode {
79     public:
80         typedef uint32_t CombiningClass;
81         typedef uint32_t GeneralCategory;
82         enum class TextDirection {
83             kLTR,
84             kRTL,
85         };
86         typedef size_t Position;
87         typedef uint8_t BidiLevel;
88         struct BidiRegion {
BidiRegionBidiRegion89             BidiRegion(Position start, Position end, BidiLevel level)
90               : start(start), end(end), level(level) { }
91             Position start;
92             Position end;
93             BidiLevel level;
94         };
95         enum class LineBreakType {
96             kSoftLineBreak,
97             kHardLineBreak
98         };
99 
100         enum class BreakType {
101             kWords,
102             kGraphemes,
103             kLines
104         };
105         struct LineBreakBefore {
LineBreakBeforeLineBreakBefore106             LineBreakBefore(Position pos, LineBreakType breakType)
107               : pos(pos), breakType(breakType) { }
108             Position pos;
109             LineBreakType breakType;
110         };
111 
112         virtual ~SkUnicode() = default;
113 
114         virtual bool isControl(SkUnichar utf8) = 0;
115         virtual bool isWhitespace(SkUnichar utf8) = 0;
116         virtual bool isSpace(SkUnichar utf8) = 0;
117         virtual SkString convertUtf16ToUtf8(const std::u16string& utf16) = 0;
118 
119         // Methods used in SkShaper
120         virtual std::unique_ptr<SkBidiIterator> makeBidiIterator
121             (const uint16_t text[], int count, SkBidiIterator::Direction) = 0;
122         virtual std::unique_ptr<SkBidiIterator> makeBidiIterator
123             (const char text[], int count, SkBidiIterator::Direction) = 0;
124         virtual std::unique_ptr<SkBreakIterator> makeBreakIterator
125             (const char locale[], BreakType breakType) = 0;
126         virtual std::unique_ptr<SkScriptIterator> makeScriptIterator() = 0;
127 
128         // High level methods (that we actually use somewhere=SkParagraph)
129         virtual bool getBidiRegions
130                (const char utf8[], int utf8Units, TextDirection dir, std::vector<BidiRegion>* results) = 0;
131         virtual bool getLineBreaks
132                (const char utf8[], int utf8Units, std::vector<LineBreakBefore>* results) = 0;
133         virtual bool getWords
134                (const char utf8[], int utf8Units, std::vector<Position>* results) = 0;
135         virtual bool getGraphemes
136                (const char utf8[], int utf8Units, std::vector<Position>* results) = 0;
137 
138         template <typename Callback>
forEachCodepoint(const char * utf8,int32_t utf8Units,Callback && callback)139         void forEachCodepoint(const char* utf8, int32_t utf8Units, Callback&& callback) {
140             const char* current = utf8;
141             const char* end = utf8 + utf8Units;
142             while (current < end) {
143                 auto before = current - utf8;
144                 SkUnichar unichar = SkUTF::NextUTF8(&current, end);
145                 if (unichar < 0) unichar = 0xFFFD;
146                 auto after = current - utf8;
147                 callback(unichar, before, after);
148             }
149         }
150 
151         virtual void reorderVisual(const BidiLevel runLevels[], int levelsCount, int32_t logicalFromVisual[]) = 0;
152 
153         static std::unique_ptr<SkUnicode> Make();
154 };
155 
156 #endif // SkUnicode_DEFINED
157