• 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/base/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 GlyphUnitFlags : uint8_t {
50     kNoGlyphUnitFlag = (1 << 0),
51     //kPartOfWhiteSpace = (1 << 1),
52     //kGraphemeStart = (1 << 2),
53     //kSoftLineBreakBefore = (1 << 3),
54     //kHardLineBreakBefore = (1 << 4),
55     kGlyphClusterStart = (1 << 5),
56     kGraphemeClusterStart = (1 << 6),
57 };
58 
59 typedef size_t TextIndex;
60 typedef size_t GlyphIndex;
61 typedef size_t RunIndex;
62 typedef size_t LineIndex;
63 const size_t EMPTY_INDEX = std::numeric_limits<size_t>::max();
64 
65 template <typename T>
66 class Range {
67 public:
Range()68     Range() : fStart(0), fEnd(0) { }
Range(T start,T end)69     Range(T start, T end) : fStart(start) , fEnd(end) { }
70 
71     bool operator==(Range<T> other) {
72         return fStart == other.fStart && fEnd == other.fEnd;
73     }
74 
clean()75     void clean() {
76         fStart = 0;
77         fEnd = 0;
78     }
79 
isEmpty()80     bool isEmpty() const {
81         return fEnd == fStart;
82     }
83 
contains(T index)84     bool contains(T index) const {
85         return index >= fStart && index < fEnd;
86     }
87 
contains(Range<T> range)88     bool contains(Range<T> range) const {
89         return range.fStart >= fStart && range.fEnd < fEnd;
90     }
91 
92     // For RTL ranges start >= end
width()93     int width() const {
94         return SkToInt(fEnd - fStart);
95     }
96 
merge(Range tail)97     void merge(Range tail) {
98         SkASSERT(this->fEnd == tail.fStart || this->fStart == tail.fEnd);
99         this->fStart = std::min(this->fStart, tail.fStart);
100         this->fEnd = std::max(this->fEnd, tail.fEnd);
101     }
102 
intersect(Range other)103     void intersect(Range other) {
104         this->fStart = std::max(this->fStart, other.fStart);
105         this->fEnd = std::min(this->fEnd, other.fEnd);
106         if (this->fStart > this->fEnd) {
107             // There is nothing in the intersection; make it empty
108             this->fEnd = this->fStart;
109         }
110     }
111 
112     template<typename Visitor>
iterate(Visitor visitor)113     void iterate(Visitor visitor) {
114         if (this->leftToRight()) {
115             for (auto index = this->fStart; index < this->fEnd; ++index) {
116                 visitor(index);
117             }
118         } else {
119             for (auto index = this->fStart; index < this->fEnd; --index) {
120                 visitor(index);
121             }
122         }
123     }
124 
125     T fStart;
126     T fEnd;
127 };
128 
129 typedef Range<TextIndex> TextRange;
130 typedef Range<GlyphIndex> GlyphRange;
131 struct DirTextRange : public TextRange {
DirTextRangeDirTextRange132     DirTextRange(TextRange textRange, bool leftToRight)
133         : TextRange(textRange)
134         , fLeftToRight(leftToRight) { }
DirTextRangeDirTextRange135     DirTextRange(TextIndex start, TextIndex end, bool leftToRight)
136         : TextRange(start, end)
137         , fLeftToRight(leftToRight) { }
138 
beforeDirTextRange139     bool before(TextIndex index) const {
140         return fLeftToRight ? index >= fEnd : index < fStart;
141     }
afterDirTextRange142     bool after(TextIndex index) const {
143         return fLeftToRight ? index < fEnd : index >= fStart;
144     }
leftDirTextRange145     bool left() const {
146         return fLeftToRight ? fStart : fEnd;
147     }
rightDirTextRange148     bool right() const {
149         return fLeftToRight ? fEnd : fStart;
150     }
normalizedDirTextRange151     TextRange normalized() const {
152         return fLeftToRight ? TextRange(fStart, fEnd) : TextRange(fEnd, fStart);
153     }
154     bool fLeftToRight;
155 };
156 
157 const Range<size_t> EMPTY_RANGE = Range<size_t>(EMPTY_INDEX, EMPTY_INDEX);
158 
159 // Blocks
160 enum BlockType {
161     kFontChain,
162     kPlaceholder,
163 };
164 
165 struct Placeholder {
166     SkSize  dimensions;
167     float   yOffsetFromBaseline;
168 };
169 
170 class FontChain : public SkRefCnt {
171 public:
172     // Returns the number of faces in the chain. Always >= 1
173     virtual size_t count() const = 0;
174     virtual sk_sp<SkTypeface> operator[](size_t index) const = 0;
175     virtual float fontSize() const = 0;
176     virtual SkString locale() const = 0;
177 };
178 
179 struct FontBlock {
FontBlockFontBlock180     FontBlock(uint32_t count, sk_sp<FontChain> fontChain)
181         : type(BlockType::kFontChain)
182         , charCount(count)
183         , chain(fontChain) { }
FontBlockFontBlock184     FontBlock() : FontBlock(0, nullptr) { }
FontBlockFontBlock185     FontBlock(FontBlock& block) {
186         this->type = block.type;
187         this->charCount = block.charCount;
188         this->chain = block.chain;
189     }
~FontBlockFontBlock190     ~FontBlock() { }
191 
192     BlockType  type;
193     uint32_t   charCount;
194     union {
195         sk_sp<FontChain>  chain;
196         Placeholder placeholder;
197     };
198 };
199 
200 struct ResolvedFontBlock {
ResolvedFontBlockResolvedFontBlock201     ResolvedFontBlock(TextRange textRange, sk_sp<SkTypeface> typeface, SkScalar size, SkFontStyle fontStyle)
202         : textRange(textRange)
203         , typeface(typeface)
204         , size(size)
205         , style(fontStyle) { }
206 
207     TextRange textRange;
208     sk_sp<SkTypeface> typeface;
209     float size;
210     SkFontStyle style;
211 };
212 
213 }  // namespace text
214 }  // namespace skia
215 
216 namespace sknonstd {
217 template <> struct is_bitmask_enum<skia::text::GlyphUnitFlags> : std::true_type {};
218 }
219 
220 #endif
221