• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 Google LLC.
2 #ifndef Types_DEFINED
3 #define Types_DEFINED
4 
5 #include <algorithm>
6 #include <cstddef>
7 #include "include/core/SkFont.h"
8 #include "include/core/SkSize.h"
9 #include "include/core/SkSpan.h"
10 #include "include/private/SkBitmaskEnum.h"
11 #include "include/private/SkTo.h"
12 
13 namespace skia {
14 namespace text {
15 enum class TextAlign {
16     kLeft,
17     kRight,
18     kCenter,
19     kJustify,
20     kStart,
21     kEnd,
22     kNothing,
23 };
24 
25 enum class TextDirection {
26     kRtl,
27     kLtr,
28 };
29 
30 // This enum lists all possible ways to query output positioning
31 enum class PositionType {
32     kRandomText,
33     kGraphemeCluster, // Both the edge of the glyph cluster and the text grapheme
34     kGlyphCluster,
35     kGlyph,
36     kGlyphPart
37 };
38 
39 enum class LineBreakType {
40   kSortLineBreakBefore,
41   kHardLineBreakBefore,
42 };
43 
44 enum class LogicalRunType {
45     kText,
46     kLineBreak
47 };
48 
49 enum class CodeUnitFlags : uint8_t {
50     kNoCodeUnitFlag = (1 << 0),
51     kPartOfWhiteSpace = (1 << 1),
52     kGraphemeStart = (1 << 2),
53     kSoftLineBreakBefore = (1 << 3),
54     kHardLineBreakBefore = (1 << 4),
55     kAllCodeUnitFlags = ((1 << 5) - 1),
56 };
57 
58 enum class GlyphUnitFlags : uint8_t {
59     kNoGlyphUnitFlag = (1 << 0),
60     //kPartOfWhiteSpace = (1 << 1),
61     //kGraphemeStart = (1 << 2),
62     //kSoftLineBreakBefore = (1 << 3),
63     //kHardLineBreakBefore = (1 << 4),
64     kGlyphClusterStart = (1 << 5),
65     kGraphemeClusterStart = (1 << 6),
66 };
67 
68 typedef size_t TextIndex;
69 typedef size_t GlyphIndex;
70 typedef size_t RunIndex;
71 typedef size_t LineIndex;
72 const size_t EMPTY_INDEX = std::numeric_limits<size_t>::max();
73 
74 template <typename T>
75 class Range {
76 public:
Range()77     Range() : fStart(0), fEnd(0) { }
Range(T start,T end)78     Range(T start, T end) : fStart(start) , fEnd(end) { }
79 
80     bool operator==(Range<T> other) {
81         return fStart == other.fStart && fEnd == other.fEnd;
82     }
83 
clean()84     void clean() {
85         fStart = 0;
86         fEnd = 0;
87     }
88 
isEmpty()89     bool isEmpty() const {
90         return fEnd == fStart;
91     }
92 
contains(T index)93     bool contains(T index) const {
94         return index >= fStart && index < fEnd;
95     }
96 
contains(Range<T> range)97     bool contains(Range<T> range) const {
98         return range.fStart >= fStart && range.fEnd < fEnd;
99     }
100 
101     // For RTL ranges start >= end
width()102     int width() const {
103         return SkToInt(fEnd - fStart);
104     }
105 
merge(Range tail)106     void merge(Range tail) {
107         SkASSERT(this->fEnd == tail.fStart || this->fStart == tail.fEnd);
108         this->fStart = std::min(this->fStart, tail.fStart);
109         this->fEnd = std::max(this->fEnd, tail.fEnd);
110     }
111 
intersect(Range other)112     void intersect(Range other) {
113         this->fStart = std::max(this->fStart, other.fStart);
114         this->fEnd = std::min(this->fEnd, other.fEnd);
115         if (this->fStart > this->fEnd) {
116             // There is nothing in the intersection; make it empty
117             this->fEnd = this->fStart;
118         }
119     }
120 
121     template<typename Visitor>
iterate(Visitor visitor)122     void iterate(Visitor visitor) {
123         if (this->leftToRight()) {
124             for (auto index = this->fStart; index < this->fEnd; ++index) {
125                 visitor(index);
126             }
127         } else {
128             for (auto index = this->fStart; index < this->fEnd; --index) {
129                 visitor(index);
130             }
131         }
132     }
133 
134     T fStart;
135     T fEnd;
136 };
137 
138 typedef Range<TextIndex> TextRange;
139 typedef Range<GlyphIndex> GlyphRange;
140 struct DirTextRange : public TextRange {
DirTextRangeDirTextRange141     DirTextRange(TextRange textRange, bool leftToRight)
142         : TextRange(textRange)
143         , fLeftToRight(leftToRight) { }
DirTextRangeDirTextRange144     DirTextRange(TextIndex start, TextIndex end, bool leftToRight)
145         : TextRange(start, end)
146         , fLeftToRight(leftToRight) { }
147 
beforeDirTextRange148     bool before(TextIndex index) const {
149         return fLeftToRight ? index >= fEnd : index < fStart;
150     }
afterDirTextRange151     bool after(TextIndex index) const {
152         return fLeftToRight ? index < fEnd : index >= fStart;
153     }
leftDirTextRange154     bool left() const {
155         return fLeftToRight ? fStart : fEnd;
156     }
rightDirTextRange157     bool right() const {
158         return fLeftToRight ? fEnd : fStart;
159     }
normalizedDirTextRange160     TextRange normalized() const {
161         return fLeftToRight ? TextRange(fStart, fEnd) : TextRange(fEnd, fStart);
162     }
163     bool fLeftToRight;
164 };
165 
166 const Range<size_t> EMPTY_RANGE = Range<size_t>(EMPTY_INDEX, EMPTY_INDEX);
167 
168 // Blocks
169 enum BlockType {
170     kFontChain,
171     kPlaceholder,
172 };
173 
174 struct Placeholder {
175     SkSize  dimensions;
176     float   yOffsetFromBaseline;
177 };
178 
179 class FontChain : public SkRefCnt {
180 public:
181     // Returns the number of faces in the chain. Always >= 1
182     virtual size_t count() const = 0;
183     virtual sk_sp<SkTypeface> operator[](size_t index) const = 0;
184     virtual float fontSize() const = 0;
185     virtual SkString locale() const = 0;
186 };
187 
188 struct FontBlock {
FontBlockFontBlock189     FontBlock(uint32_t count, sk_sp<FontChain> fontChain)
190         : type(BlockType::kFontChain)
191         , charCount(count)
192         , chain(fontChain) { }
FontBlockFontBlock193     FontBlock() : FontBlock(0, nullptr) { }
FontBlockFontBlock194     FontBlock(FontBlock& block) {
195         this->type = block.type;
196         this->charCount = block.charCount;
197         this->chain = block.chain;
198     }
~FontBlockFontBlock199     ~FontBlock() { }
200 
201     BlockType  type;
202     uint32_t   charCount;
203     union {
204         sk_sp<FontChain>  chain;
205         Placeholder placeholder;
206     };
207 };
208 
209 struct ResolvedFontBlock {
ResolvedFontBlockResolvedFontBlock210     ResolvedFontBlock(TextRange textRange, sk_sp<SkTypeface> typeface, SkScalar size, SkFontStyle fontStyle)
211         : textRange(textRange)
212         , typeface(typeface)
213         , size(size)
214         , style(fontStyle) { }
215 
216     TextRange textRange;
217     sk_sp<SkTypeface> typeface;
218     float size;
219     SkFontStyle style;
220 };
221 
222 }  // namespace text
223 }  // namespace skia
224 
225 namespace sknonstd {
226 template <> struct is_bitmask_enum<skia::text::CodeUnitFlags> : std::true_type {};
227 template <> struct is_bitmask_enum<skia::text::GlyphUnitFlags> : std::true_type {};
228 }
229 
230 #endif
231