Flutter Engine
The Flutter Engine
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>
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
static void round(SkPoint *p)
SkPoint pos
#define SK_ScalarMin
Definition: SkScalar.h:25
#define SK_ScalarMax
Definition: SkScalar.h:24
Definition: SkFont.h:35
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
SkScalar rawAscent() const
Definition: Run.h:498
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
SkScalar rawDescent() const
Definition: Run.h:499
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
Run(ParagraphImpl *owner, const SkShaper::RunHandler::RunInfo &info, size_t firstChar, SkScalar heightMultiplier, bool useHalfLeading, SkScalar baselineShift, size_t index, SkScalar shiftX)
Definition: Run.cpp:17
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:421
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]
uint8_t value
Dart_NativeFunction function
Definition: fuchsia.cc:51
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
std::u16string text
Visitor(Ts...) -> Visitor< Ts... >
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
Definition: switches.h:145
font
Font Metadata and Metrics.
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
size_t TextIndex
Definition: TextStyle.h:336
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
Definition: DartTypes.h:13
int32_t height
int32_t width
SkScalar fLeading
distance to add between lines, typically positive or zero
Definition: SkFontMetrics.h:57
SkScalar fAscent
distance to reserve above baseline, typically negative
Definition: SkFontMetrics.h:54
SkScalar fDescent
distance to reserve below baseline, typically positive
Definition: SkFontMetrics.h:55
float fX
x-axis value
Definition: SkPoint_impl.h:164
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
float fY
y-axis value
Definition: SkPoint_impl.h:165
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
constexpr size_t begin() const
Definition: SkShaper.h:203
constexpr size_t end() const
Definition: SkShaper.h:204