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(¤t, 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