Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Run.h
Go to the documentation of this file.
1// Copyright 2019 Google LLC.
2#ifndef Run_DEFINED
3#define Run_DEFINED
4
10#include "include/core/SkSpan.h"
16
17#include <math.h>
18#include <algorithm>
19#include <functional>
20#include <limits>
21#include <tuple>
22
24
25namespace skia {
26namespace textlayout {
27
28class Cluster;
29class InternalLineMetrics;
30class ParagraphImpl;
31
32typedef size_t RunIndex;
33const size_t EMPTY_RUN = EMPTY_INDEX;
34
35typedef size_t ClusterIndex;
39
40typedef size_t GraphemeIndex;
42
43typedef size_t GlyphIndex;
45
46// LTR: [start: end) where start <= end
47// RTL: [end: start) where start >= end
48class DirText {
49 DirText(bool dir, size_t s, size_t e) : start(s), end(e) { }
50 bool isLeftToRight() const { return start <= end; }
51 size_t start;
52 size_t end;
53};
54
55class Run {
56public:
59 size_t firstChar,
61 bool useHalfLeading,
63 size_t index,
64 SkScalar shiftX);
65 Run(const Run&) = default;
66 Run& operator=(const Run&) = delete;
67 Run(Run&&) = default;
68 Run& operator=(Run&&) = delete;
69 ~Run() = default;
70
71 void setOwner(ParagraphImpl* owner) { fOwner = owner; }
72
74
75 SkScalar posX(size_t index) const { return fPositions[index].fX; }
76 void addX(size_t index, SkScalar shift) { fPositions[index].fX += shift; }
77 SkScalar posY(size_t index) const { return fPositions[index].fY; }
78 size_t size() const { return fGlyphs.size(); }
79 void setWidth(SkScalar width) { fAdvance.fX = width; }
80 void setHeight(SkScalar height) { fAdvance.fY = height; }
81 void shift(SkScalar shiftX, SkScalar shiftY) {
82 fOffset.fX += shiftX;
83 fOffset.fY += shiftY;
84 }
85 SkVector advance() const {
86 return SkVector::Make(fAdvance.fX, fFontMetrics.fDescent - fFontMetrics.fAscent + fFontMetrics.fLeading);
87 }
88 SkVector offset() const { return fOffset; }
89 SkScalar ascent() const { return fFontMetrics.fAscent + fBaselineShift; }
90 SkScalar descent() const { return fFontMetrics.fDescent + fBaselineShift; }
91 SkScalar leading() const { return fFontMetrics.fLeading; }
92 SkScalar correctAscent() const { return fCorrectAscent + fBaselineShift; }
93 SkScalar correctDescent() const { return fCorrectDescent + fBaselineShift; }
94 SkScalar correctLeading() const { return fCorrectLeading; }
95 const SkFont& font() const { return fFont; }
96 bool leftToRight() const { return fBidiLevel % 2 == 0; }
98 size_t index() const { return fIndex; }
99 SkScalar heightMultiplier() const { return fHeightMultiplier; }
100 bool useHalfLeading() const { return fUseHalfLeading; }
101 SkScalar baselineShift() const { return fBaselineShift; }
103 bool isPlaceholder() const { return fPlaceholderIndex != std::numeric_limits<size_t>::max(); }
104 size_t clusterIndex(size_t pos) const { return fClusterIndexes[pos]; }
105 size_t globalClusterIndex(size_t pos) const { return fClusterStart + fClusterIndexes[pos]; }
106 SkScalar positionX(size_t pos) const;
107
108 TextRange textRange() const { return fTextRange; }
109 ClusterRange clusterRange() const { return fClusterRange; }
110
111 ParagraphImpl* owner() const { return fOwner; }
112
113 bool isEllipsis() const { return fEllipsis; }
114
115 void calculateMetrics();
116 void updateMetrics(InternalLineMetrics* endlineMetrics);
117
118 void setClusterRange(size_t from, size_t to) { fClusterRange = ClusterRange(from, to); }
119 SkRect clip() const {
120 return SkRect::MakeXYWH(fOffset.fX, fOffset.fY, fAdvance.fX, fAdvance.fY);
121 }
122
123 void addSpacesAtTheEnd(SkScalar space, Cluster* cluster);
124 SkScalar addSpacesEvenly(SkScalar space, Cluster* cluster);
126 void shift(const Cluster* cluster, SkScalar offset);
127 void extend(const Cluster* cluster, SkScalar offset);
128
129 SkScalar calculateHeight(LineMetricStyle ascentStyle, LineMetricStyle descentStyle) const {
130 auto ascent = ascentStyle == LineMetricStyle::Typographic ? this->ascent()
131 : this->correctAscent();
132 auto descent = descentStyle == LineMetricStyle::Typographic ? this->descent()
133 : this->correctDescent();
134 return descent - ascent;
135 }
136 SkScalar calculateWidth(size_t start, size_t end, bool clip) const;
137
138 void copyTo(SkTextBlobBuilder& builder, size_t pos, size_t size) const;
139
140 template<typename Visitor>
141 void iterateThroughClustersInTextOrder(Visitor visitor);
142
143 using ClusterVisitor = std::function<void(Cluster* cluster)>;
144 void iterateThroughClusters(const ClusterVisitor& visitor);
145
146 std::tuple<bool, ClusterIndex, ClusterIndex> findLimitingClusters(TextRange text) const;
147 std::tuple<bool, TextIndex, TextIndex> findLimitingGlyphClusters(TextRange text) const;
148 std::tuple<bool, TextIndex, TextIndex> findLimitingGraphemes(TextRange text) const;
150 return SkSpan<const SkGlyphID>(fGlyphs.begin(), fGlyphs.size());
151 }
153 return SkSpan<const SkPoint>(fPositions.begin(), fPositions.size());
154 }
156 return SkSpan<const SkPoint>(fOffsets.begin(), fOffsets.size());
157 }
159 return SkSpan<const uint32_t>(fClusterIndexes.begin(), fClusterIndexes.size());
160 }
161
162 void commit() { }
163
165 fJustificationShifts.clear();
166 }
167
168 bool isResolved() const;
169private:
170 friend class ParagraphImpl;
171 friend class TextLine;
173 friend class ParagraphCache;
174 friend class OneLineShaper;
175
176 ParagraphImpl* fOwner;
177 TextRange fTextRange;
178 ClusterRange fClusterRange;
179
180 SkFont fFont;
181 size_t fPlaceholderIndex;
182 size_t fIndex;
183 SkVector fAdvance;
184 SkVector fOffset;
185 TextIndex fClusterStart;
187
188 // These fields are not modified after shaping completes and can safely be
189 // shared among copies of the run that are held by different paragraphs.
190 struct GlyphData {
195 };
196 std::shared_ptr<GlyphData> fGlyphData;
201
202 skia_private::STArray<64, SkPoint, true> fJustificationShifts; // For justification
203 // (current and prev shifts)
204
205 SkFontMetrics fFontMetrics;
206 const SkScalar fHeightMultiplier;
207 const bool fUseHalfLeading;
208 const SkScalar fBaselineShift;
209 SkScalar fCorrectAscent;
210 SkScalar fCorrectDescent;
211 SkScalar fCorrectLeading;
212
213 bool fEllipsis;
214 uint8_t fBidiLevel;
215};
216
217template<typename Visitor>
219 // Can't figure out how to do it with one code for both cases without 100 ifs
220 // Can't go through clusters because there are no cluster table yet
221 if (leftToRight()) {
222 size_t start = 0;
223 size_t cluster = this->clusterIndex(start);
224 for (size_t glyph = 1; glyph <= this->size(); ++glyph) {
225 auto nextCluster = this->clusterIndex(glyph);
226 if (nextCluster <= cluster) {
227 continue;
228 }
229
230 visitor(start,
231 glyph,
232 fClusterStart + cluster,
233 fClusterStart + nextCluster,
234 this->calculateWidth(start, glyph, glyph == size()),
236
237 start = glyph;
238 cluster = nextCluster;
239 }
240 } else {
241 size_t glyph = this->size();
242 size_t cluster = this->fUtf8Range.begin();
243 for (int32_t start = this->size() - 1; start >= 0; --start) {
244 size_t nextCluster =
245 start == 0 ? this->fUtf8Range.end() : this->clusterIndex(start - 1);
246 if (nextCluster <= cluster) {
247 continue;
248 }
249
250 visitor(start,
251 glyph,
252 fClusterStart + cluster,
253 fClusterStart + nextCluster,
254 this->calculateWidth(start, glyph, glyph == 0),
256
257 glyph = start;
258 cluster = nextCluster;
259 }
260 }
261}
262
263class Cluster {
264public:
267 GraphemeBreak, // calculated for all clusters (UBRK_CHARACTER)
268 SoftLineBreak, // calculated for all clusters (UBRK_LINE & UBRK_CHARACTER)
269 HardLineBreak, // calculated for all clusters (UBRK_LINE)
270 };
271
273 : fOwner(nullptr)
274 , fRunIndex(EMPTY_RUN)
275 , fTextRange(EMPTY_TEXT)
276 , fGraphemeRange(EMPTY_RANGE)
277 , fStart(0)
278 , fEnd()
279 , fWidth()
280 , fHeight()
281 , fHalfLetterSpacing(0.0) {}
282
285 size_t start,
286 size_t end,
290
291 Cluster(TextRange textRange) : fTextRange(textRange), fGraphemeRange(EMPTY_RANGE) { }
292
293 Cluster(const Cluster&) = default;
294 ~Cluster() = default;
295
296 SkScalar sizeToChar(TextIndex ch) const;
298
299 size_t roundPos(SkScalar s) const;
300
301 void space(SkScalar shift) {
302 fWidth += shift;
303 }
304
305 ParagraphImpl* getOwner() const { return fOwner; }
306 void setOwner(ParagraphImpl* owner) { fOwner = owner; }
307
308 bool isWhitespaceBreak() const { return fIsWhiteSpaceBreak; }
309 bool isIntraWordBreak() const { return fIsIntraWordBreak; }
310 bool isHardBreak() const { return fIsHardBreak; }
311 bool isIdeographic() const { return fIsIdeographic; }
312
313 bool isSoftBreak() const;
314 bool isGraphemeBreak() const;
315 bool canBreakLineAfter() const { return isHardBreak() || isSoftBreak(); }
316 size_t startPos() const { return fStart; }
317 size_t endPos() const { return fEnd; }
318 SkScalar width() const { return fWidth; }
319 SkScalar height() const { return fHeight; }
320 size_t size() const { return fEnd - fStart; }
321
322 void setHalfLetterSpacing(SkScalar halfLetterSpacing) { fHalfLetterSpacing = halfLetterSpacing; }
323 SkScalar getHalfLetterSpacing() const { return fHalfLetterSpacing; }
324
325 TextRange textRange() const { return fTextRange; }
326
327 RunIndex runIndex() const { return fRunIndex; }
328 ParagraphImpl* owner() const { return fOwner; }
329
330 Run* runOrNull() const;
331 Run& run() const;
332 SkFont font() const;
333
334 SkScalar trimmedWidth(size_t pos) const;
335
336 bool contains(TextIndex ch) const { return ch >= fTextRange.start && ch < fTextRange.end; }
337
338 bool belongs(TextRange text) const {
339 return fTextRange.start >= text.start && fTextRange.end <= text.end;
340 }
341
342 bool startsIn(TextRange text) const {
343 return fTextRange.start >= text.start && fTextRange.start < text.end;
344 }
345
346private:
347
348 friend ParagraphImpl;
349
350 ParagraphImpl* fOwner;
351 RunIndex fRunIndex;
352 TextRange fTextRange;
353 GraphemeRange fGraphemeRange;
354
355 size_t fStart;
356 size_t fEnd;
357 SkScalar fWidth;
358 SkScalar fHeight;
359 SkScalar fHalfLetterSpacing;
360
361 bool fIsWhiteSpaceBreak;
362 bool fIsIntraWordBreak;
363 bool fIsHardBreak;
364 bool fIsIdeographic;
365};
366
368public:
369
371 clean();
372 fForceStrut = false;
373 }
374
375 InternalLineMetrics(bool forceStrut) {
376 clean();
377 fForceStrut = forceStrut;
378 }
379
381 fAscent = a;
382 fDescent = d;
383 fLeading = l;
384 fRawAscent = a;
385 fRawDescent = d;
386 fRawLeading = l;
387 fForceStrut = false;
388 }
389
391 fAscent = a;
392 fDescent = d;
393 fLeading = l;
394 fRawAscent = ra;
395 fRawDescent = rd;
396 fRawLeading = rl;
397 fForceStrut = false;
398 }
399
400 InternalLineMetrics(const SkFont& font, bool forceStrut) {
401 SkFontMetrics metrics;
402 font.getMetrics(&metrics);
403 fAscent = metrics.fAscent;
404 fDescent = metrics.fDescent;
405 fLeading = metrics.fLeading;
406 fRawAscent = metrics.fAscent;
407 fRawDescent = metrics.fDescent;
408 fRawLeading = metrics.fLeading;
409 fForceStrut = forceStrut;
410 }
411
412 void add(Run* run) {
413 if (fForceStrut) {
414 return;
415 }
416 fAscent = std::min(fAscent, run->correctAscent());
417 fDescent = std::max(fDescent, run->correctDescent());
418 fLeading = std::max(fLeading, run->correctLeading());
419
420 fRawAscent = std::min(fRawAscent, run->ascent());
421 fRawDescent = std::max(fRawDescent, run->descent());
422 fRawLeading = std::max(fRawLeading, run->leading());
423 }
424
426 fAscent = std::min(fAscent, other.fAscent);
427 fDescent = std::max(fDescent, other.fDescent);
428 fLeading = std::max(fLeading, other.fLeading);
429 fRawAscent = std::min(fRawAscent, other.fRawAscent);
430 fRawDescent = std::max(fRawDescent, other.fRawDescent);
431 fRawLeading = std::max(fRawLeading, other.fRawLeading);
432 }
433
434 void clean() {
435 fAscent = SK_ScalarMax;
436 fDescent = SK_ScalarMin;
437 fLeading = 0;
438 fRawAscent = SK_ScalarMax;
439 fRawDescent = SK_ScalarMin;
440 fRawLeading = 0;
441 }
442
443 bool isClean() {
444 return (fAscent == SK_ScalarMax &&
445 fDescent == SK_ScalarMin &&
446 fLeading == 0 &&
447 fRawAscent == SK_ScalarMax &&
448 fRawDescent == SK_ScalarMin &&
449 fRawLeading == 0);
450 }
451
452 SkScalar delta() const { return height() - ideographicBaseline(); }
453
455 if (metrics.fForceStrut) {
456 metrics.fAscent = fAscent;
457 metrics.fDescent = fDescent;
458 metrics.fLeading = fLeading;
459 metrics.fRawAscent = fRawAscent;
460 metrics.fRawDescent = fRawDescent;
461 metrics.fRawLeading = fRawLeading;
462 } else {
463 // This is another of those flutter changes. To be removed...
464 metrics.fAscent = std::min(metrics.fAscent, fAscent - fLeading / 2.0f);
465 metrics.fDescent = std::max(metrics.fDescent, fDescent + fLeading / 2.0f);
466 metrics.fRawAscent = std::min(metrics.fRawAscent, fRawAscent - fRawLeading / 2.0f);
467 metrics.fRawDescent = std::max(metrics.fRawDescent, fRawDescent + fRawLeading / 2.0f);
468 }
469 }
470
471 SkScalar runTop(const Run* run, LineMetricStyle ascentStyle) const {
472 return fLeading / 2 - fAscent +
473 (ascentStyle == LineMetricStyle::Typographic ? run->ascent() : run->correctAscent()) + delta();
474 }
475
476 SkScalar height() const {
477 return ::round((double)fDescent - fAscent + fLeading);
478 }
479
481 fAscent = a;
482 fDescent = d;
483 fLeading = l;
484 }
485
487 fRawAscent = ra;
488 fRawDescent = rd;
489 }
490
491 SkScalar alphabeticBaseline() const { return fLeading / 2 - fAscent; }
492 SkScalar ideographicBaseline() const { return fDescent - fAscent + fLeading; }
493 SkScalar deltaBaselines() const { return fLeading / 2 + fDescent; }
494 SkScalar baseline() const { return fLeading / 2 - fAscent; }
495 SkScalar ascent() const { return fAscent; }
496 SkScalar descent() const { return fDescent; }
497 SkScalar leading() const { return fLeading; }
498 SkScalar rawAscent() const { return fRawAscent; }
499 SkScalar rawDescent() const { return fRawDescent; }
500 void setForceStrut(bool value) { fForceStrut = value; }
501 bool getForceStrut() const { return fForceStrut; }
502
503private:
504
505 friend class ParagraphImpl;
506 friend class TextWrapper;
507 friend class TextLine;
508
509 SkScalar fAscent;
510 SkScalar fDescent;
511 SkScalar fLeading;
512
513 SkScalar fRawAscent;
514 SkScalar fRawDescent;
515 SkScalar fRawLeading;
516
517 bool fForceStrut;
518};
519} // namespace textlayout
520} // namespace skia
521
522#endif // Run_DEFINED
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
uint16_t glyphs[5]
SkPoint pos
#define SK_ScalarMin
Definition SkScalar.h:25
#define SK_ScalarMax
Definition SkScalar.h:24
SkFont font() const
Definition Run.cpp:341
bool isIntraWordBreak() const
Definition Run.h:309
size_t startPos() const
Definition Run.h:316
SkScalar trimmedWidth(size_t pos) const
Definition Run.cpp:301
ParagraphImpl * getOwner() const
Definition Run.h:305
bool isIdeographic() const
Definition Run.h:311
void setOwner(ParagraphImpl *owner)
Definition Run.h:306
size_t roundPos(SkScalar s) const
Definition Run.cpp:296
SkScalar sizeFromChar(TextIndex ch) const
Definition Run.cpp:286
SkScalar getHalfLetterSpacing() const
Definition Run.h:323
bool isSoftBreak() const
Definition Run.cpp:346
bool isGraphemeBreak() const
Definition Run.cpp:351
SkScalar sizeToChar(TextIndex ch) const
Definition Run.cpp:276
TextRange textRange() const
Definition Run.h:325
Run * runOrNull() const
Definition Run.cpp:329
bool canBreakLineAfter() const
Definition Run.h:315
bool contains(TextIndex ch) const
Definition Run.h:336
ParagraphImpl * owner() const
Definition Run.h:328
size_t endPos() const
Definition Run.h:317
bool startsIn(TextRange text) const
Definition Run.h:342
bool isHardBreak() const
Definition Run.h:310
RunIndex runIndex() const
Definition Run.h:327
Cluster(const Cluster &)=default
bool belongs(TextRange text) const
Definition Run.h:338
void space(SkScalar shift)
Definition Run.h:301
size_t size() const
Definition Run.h:320
SkScalar width() const
Definition Run.h:318
void setHalfLetterSpacing(SkScalar halfLetterSpacing)
Definition Run.h:322
Run & run() const
Definition Run.cpp:336
Cluster(TextRange textRange)
Definition Run.h:291
SkScalar height() const
Definition Run.h:319
bool isWhitespaceBreak() const
Definition Run.h:308
void updateRawData(SkScalar ra, SkScalar rd)
Definition Run.h:486
InternalLineMetrics(SkScalar a, SkScalar d, SkScalar l)
Definition Run.h:380
InternalLineMetrics(SkScalar a, SkScalar d, SkScalar l, SkScalar ra, SkScalar rd, SkScalar rl)
Definition Run.h:390
void add(InternalLineMetrics other)
Definition Run.h:425
void updateLineMetrics(InternalLineMetrics &metrics)
Definition Run.h:454
SkScalar alphabeticBaseline() const
Definition Run.h:491
SkScalar ideographicBaseline() const
Definition Run.h:492
void setForceStrut(bool value)
Definition Run.h:500
void update(SkScalar a, SkScalar d, SkScalar l)
Definition Run.h:480
SkScalar runTop(const Run *run, LineMetricStyle ascentStyle) const
Definition Run.h:471
InternalLineMetrics(const SkFont &font, bool forceStrut)
Definition Run.h:400
InternalLineMetrics(bool forceStrut)
Definition Run.h:375
SkScalar deltaBaselines() const
Definition Run.h:493
void calculateMetrics()
Definition Run.cpp:61
SkSpan< const uint32_t > clusterIndexes() const
Definition Run.h:158
SkScalar calculateHeight(LineMetricStyle ascentStyle, LineMetricStyle descentStyle) const
Definition Run.h:129
size_t index() const
Definition Run.h:98
Run(const Run &)=default
void updateMetrics(InternalLineMetrics *endlineMetrics)
Definition Run.cpp:220
void copyTo(SkTextBlobBuilder &builder, size_t pos, size_t size) const
Definition Run.cpp:88
ClusterRange clusterRange() const
Definition Run.h:109
bool isPlaceholder() const
Definition Run.h:103
TextRange textRange() const
Definition Run.h:108
size_t globalClusterIndex(size_t pos) const
Definition Run.h:105
SkRect clip() const
Definition Run.h:119
SkSpan< const SkGlyphID > glyphs() const
Definition Run.h:149
SkVector advance() const
Definition Run.h:85
void setWidth(SkScalar width)
Definition Run.h:79
SkScalar descent() const
Definition Run.h:90
SkShaper::RunHandler::Buffer newRunBuffer()
Definition Run.cpp:84
void setClusterRange(size_t from, size_t to)
Definition Run.h:118
size_t clusterIndex(size_t pos) const
Definition Run.h:104
SkScalar correctDescent() const
Definition Run.h:93
std::tuple< bool, TextIndex, TextIndex > findLimitingGlyphClusters(TextRange text) const
Definition Run.cpp:140
SkScalar positionX(size_t pos) const
Definition Run.cpp:308
void shift(SkScalar shiftX, SkScalar shiftY)
Definition Run.h:81
SkScalar posY(size_t index) const
Definition Run.h:77
bool useHalfLeading() const
Definition Run.h:100
Run(Run &&)=default
bool isEllipsis() const
Definition Run.h:113
std::tuple< bool, TextIndex, TextIndex > findLimitingGraphemes(TextRange text) const
Definition Run.cpp:149
SkScalar ascent() const
Definition Run.h:89
void addX(size_t index, SkScalar shift)
Definition Run.h:76
void setOwner(ParagraphImpl *owner)
Definition Run.h:71
SkSpan< const SkPoint > offsets() const
Definition Run.h:155
Run & operator=(Run &&)=delete
std::tuple< bool, ClusterIndex, ClusterIndex > findLimitingClusters(TextRange text) const
Definition Run.cpp:106
void setHeight(SkScalar height)
Definition Run.h:80
const SkFont & font() const
Definition Run.h:95
SkScalar correctLeading() const
Definition Run.h:94
void resetJustificationShifts()
Definition Run.h:164
Run & operator=(const Run &)=delete
SkScalar leading() const
Definition Run.h:91
bool isResolved() const
Definition Run.cpp:320
SkVector offset() const
Definition Run.h:88
SkScalar baselineShift() const
Definition Run.h:101
SkScalar calculateWidth(size_t start, size_t end, bool clip) const
std::function< void(Cluster *cluster)> ClusterVisitor
Definition Run.h:143
SkScalar correctAscent() const
Definition Run.h:92
ParagraphImpl * owner() const
Definition Run.h:111
SkScalar heightMultiplier() const
Definition Run.h:99
void iterateThroughClustersInTextOrder(Visitor visitor)
Definition Run.h:218
void addSpacesAtTheEnd(SkScalar space, Cluster *cluster)
Definition Run.cpp:164
TextDirection getTextDirection() const
Definition Run.h:97
SkSpan< const SkPoint > positions() const
Definition Run.h:152
void extend(const Cluster *cluster, SkScalar offset)
Definition Run.cpp:215
void iterateThroughClusters(const ClusterVisitor &visitor)
Definition Run.cpp:155
PlaceholderStyle * placeholderStyle() const
Definition Run.cpp:312
SkScalar addSpacesEvenly(SkScalar space, Cluster *cluster)
Definition Run.cpp:182
size_t size() const
Definition Run.h:78
bool leftToRight() const
Definition Run.h:96
SkScalar posX(size_t index) const
Definition Run.h:75
int size() const
Definition SkTArray.h:416
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
float SkScalar
Definition extension.cpp:12
struct MyStruct s
struct MyStruct a[10]
glong glong end
uint8_t value
std::u16string text
Definition run.py:1
const SkRange< size_t > EMPTY_CLUSTERS
Definition Run.h:38
const size_t EMPTY_INDEX
Definition DartTypes.h:91
const size_t EMPTY_CLUSTER
Definition Run.h:37
const SkRange< size_t > EMPTY_TEXT
Definition TextStyle.h:338
SkRange< size_t > ClusterRange
Definition Run.h:36
const SkRange< size_t > EMPTY_RANGE
Definition DartTypes.h:128
SkRange< GlyphIndex > GlyphRange
Definition Run.h:44
size_t ClusterIndex
Definition Run.h:35
size_t GlyphIndex
Definition Run.h:43
const size_t EMPTY_RUN
Definition Run.h:33
size_t RunIndex
Definition Run.h:32
SkRange< GraphemeIndex > GraphemeRange
Definition Run.h:41
size_t GraphemeIndex
Definition Run.h:40
int32_t height
int32_t width
SkScalar fLeading
distance to add between lines, typically positive or zero
SkScalar fAscent
distance to reserve above baseline, typically negative
SkScalar fDescent
distance to reserve below baseline, typically positive
float fX
x-axis value
static constexpr SkPoint Make(float x, float y)
float fY
y-axis value
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
constexpr size_t begin() const
Definition SkShaper.h:198
constexpr size_t end() const
Definition SkShaper.h:199