Flutter Engine
The Flutter Engine
SkPathPriv.h
Go to the documentation of this file.
1/*
2 * Copyright 2015 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
8#ifndef SkPathPriv_DEFINED
9#define SkPathPriv_DEFINED
10
11#include "include/core/SkArc.h"
12#include "include/core/SkPath.h"
16#include "include/core/SkRect.h"
24
25#include <cstdint>
26#include <iterator>
27#include <utility>
28
29class SkMatrix;
30class SkRRect;
31
32static_assert(0 == static_cast<int>(SkPathFillType::kWinding), "fill_type_mismatch");
33static_assert(1 == static_cast<int>(SkPathFillType::kEvenOdd), "fill_type_mismatch");
34static_assert(2 == static_cast<int>(SkPathFillType::kInverseWinding), "fill_type_mismatch");
35static_assert(3 == static_cast<int>(SkPathFillType::kInverseEvenOdd), "fill_type_mismatch");
36
38public:
39 // skbug.com/9906: Not a perfect solution for W plane clipping, but 1/16384 is a
40 // reasonable limit (roughly 5e-5)
41 inline static constexpr SkScalar kW0PlaneDistance = 1.f / (1 << 14);
42
44 // since we agree numerically for the values in Direction, we can just cast.
46 }
47
48 /**
49 * Return the opposite of the specified direction. kUnknown is its own
50 * opposite.
51 */
53 static const SkPathFirstDirection gOppositeDir[] = {
55 };
56 return gOppositeDir[(unsigned)dir];
57 }
58
59 /**
60 * Tries to compute the direction of the outer-most non-degenerate
61 * contour. If it can be computed, return that direction. If it cannot be determined,
62 * or the contour is known to be convex, return kUnknown. If the direction was determined,
63 * it is cached to make subsequent calls return quickly.
64 */
66
67 static bool IsClosedSingleContour(const SkPath& path) {
68 int verbCount = path.countVerbs();
69 if (verbCount == 0)
70 return false;
71 int moveCount = 0;
72 auto verbs = path.fPathRef->verbsBegin();
73 for (int i = 0; i < verbCount; i++) {
74 switch (verbs[i]) {
75 case SkPath::Verb::kMove_Verb:
76 moveCount += 1;
77 if (moveCount > 1) {
78 return false;
79 }
80 break;
81 case SkPath::Verb::kClose_Verb:
82 if (i == verbCount - 1) {
83 return true;
84 }
85 return false;
86 default: break;
87 }
88 }
89 return false;
90 }
91
92 // In some scenarios (e.g. fill or convexity checking all but the last leading move to are
93 // irrelevant to behavior). SkPath::injectMoveToIfNeeded should ensure that this is always at
94 // least 1.
95 static int LeadingMoveToCount(const SkPath& path) {
96 int verbCount = path.countVerbs();
97 auto verbs = path.fPathRef->verbsBegin();
98 for (int i = 0; i < verbCount; i++) {
99 if (verbs[i] != SkPath::Verb::kMove_Verb) {
100 return i;
101 }
102 }
103 return verbCount; // path is all move verbs
104 }
105
107 path.fPathRef->addGenIDChangeListener(std::move(listener));
108 }
109
110 /**
111 * This returns true for a rect that has a move followed by 3 or 4 lines and a close. If
112 * 'isSimpleFill' is true, an uncloseed rect will also be accepted as long as it starts and
113 * ends at the same corner. This does not permit degenerate line or point rectangles.
114 */
115 static bool IsSimpleRect(const SkPath& path, bool isSimpleFill, SkRect* rect,
116 SkPathDirection* direction, unsigned* start);
117
118 /**
119 * Creates a path from arc params using the semantics of SkCanvas::drawArc. This function
120 * assumes empty ovals and zero sweeps have already been filtered out.
121 */
122 static void CreateDrawArcPath(SkPath* path, const SkArc& arc, bool isFillNoPathEffect);
123
124 /**
125 * Determines whether an arc produced by CreateDrawArcPath will be convex. Assumes a non-empty
126 * oval.
127 */
128 static bool DrawArcIsConvex(SkScalar sweepAngle, SkArc::Type arcType, bool isFillNoPathEffect);
129
130 static void ShrinkToFit(SkPath* path) {
131 path->shrinkToFit();
132 }
133
134 /**
135 * Returns a C++11-iterable object that traverses a path's verbs in order. e.g:
136 *
137 * for (SkPath::Verb verb : SkPathPriv::Verbs(path)) {
138 * ...
139 * }
140 */
141 struct Verbs {
142 public:
143 Verbs(const SkPath& path) : fPathRef(path.fPathRef.get()) {}
144 struct Iter {
145 void operator++() { fVerb++; }
146 bool operator!=(const Iter& b) { return fVerb != b.fVerb; }
147 SkPath::Verb operator*() { return static_cast<SkPath::Verb>(*fVerb); }
148 const uint8_t* fVerb;
149 };
150 Iter begin() { return Iter{fPathRef->verbsBegin()}; }
151 Iter end() { return Iter{fPathRef->verbsEnd()}; }
152 private:
153 Verbs(const Verbs&) = delete;
154 Verbs& operator=(const Verbs&) = delete;
155 SkPathRef* fPathRef;
156 };
157
158 /**
159 * Iterates through a raw range of path verbs, points, and conics. All values are returned
160 * unaltered.
161 *
162 * NOTE: This class's definition will be moved into SkPathPriv once RangeIter is removed.
163 */
164 using RangeIter = SkPath::RangeIter;
165
166 /**
167 * Iterable object for traversing verbs, points, and conic weights in a path:
168 *
169 * for (auto [verb, pts, weights] : SkPathPriv::Iterate(skPath)) {
170 * ...
171 * }
172 */
173 struct Iterate {
174 public:
176 : Iterate(path.fPathRef->verbsBegin(),
177 // Don't allow iteration through non-finite points.
178 (!path.isFinite()) ? path.fPathRef->verbsBegin()
179 : path.fPathRef->verbsEnd(),
180 path.fPathRef->points(), path.fPathRef->conicWeights()) {
181 }
182 Iterate(const uint8_t* verbsBegin, const uint8_t* verbsEnd, const SkPoint* points,
183 const SkScalar* weights)
184 : fVerbsBegin(verbsBegin), fVerbsEnd(verbsEnd), fPoints(points), fWeights(weights) {
185 }
186 SkPath::RangeIter begin() { return {fVerbsBegin, fPoints, fWeights}; }
187 SkPath::RangeIter end() { return {fVerbsEnd, nullptr, nullptr}; }
188 private:
189 const uint8_t* fVerbsBegin;
190 const uint8_t* fVerbsEnd;
191 const SkPoint* fPoints;
192 const SkScalar* fWeights;
193 };
194
195 /**
196 * Returns a pointer to the verb data.
197 */
198 static const uint8_t* VerbData(const SkPath& path) {
199 return path.fPathRef->verbsBegin();
200 }
201
202 /** Returns a raw pointer to the path points */
203 static const SkPoint* PointData(const SkPath& path) {
204 return path.fPathRef->points();
205 }
206
207 /** Returns the number of conic weights in the path */
208 static int ConicWeightCnt(const SkPath& path) {
209 return path.fPathRef->countWeights();
210 }
211
212 /** Returns a raw pointer to the path conic weights. */
213 static const SkScalar* ConicWeightData(const SkPath& path) {
214 return path.fPathRef->conicWeights();
215 }
216
217 /** Returns true if the underlying SkPathRef has one single owner. */
218 static bool TestingOnly_unique(const SkPath& path) {
219 return path.fPathRef->unique();
220 }
221
222 // Won't be needed once we can make path's immutable (with their bounds always computed)
223 static bool HasComputedBounds(const SkPath& path) {
224 return path.hasComputedBounds();
225 }
226
227 /** Returns true if constructed by addCircle(), addOval(); and in some cases,
228 addRoundRect(), addRRect(). SkPath constructed with conicTo() or rConicTo() will not
229 return true though SkPath draws oval.
230
231 rect receives bounds of oval.
232 dir receives SkPathDirection of oval: kCW_Direction if clockwise, kCCW_Direction if
233 counterclockwise.
234 start receives start of oval: 0 for top, 1 for right, 2 for bottom, 3 for left.
235
236 rect, dir, and start are unmodified if oval is not found.
237
238 Triggers performance optimizations on some GPU surface implementations.
239
240 @param rect storage for bounding SkRect of oval; may be nullptr
241 @param dir storage for SkPathDirection; may be nullptr
242 @param start storage for start of oval; may be nullptr
243 @return true if SkPath was constructed by method that reduces to oval
244 */
245 static bool IsOval(const SkPath& path, SkRect* rect, SkPathDirection* dir, unsigned* start) {
246 bool isCCW = false;
247 bool result = path.fPathRef->isOval(rect, &isCCW, start);
248 if (dir && result) {
250 }
251 return result;
252 }
253
254 /** Returns true if constructed by addRoundRect(), addRRect(); and if construction
255 is not empty, not SkRect, and not oval. SkPath constructed with other calls
256 will not return true though SkPath draws SkRRect.
257
258 rrect receives bounds of SkRRect.
259 dir receives SkPathDirection of oval: kCW_Direction if clockwise, kCCW_Direction if
260 counterclockwise.
261 start receives start of SkRRect: 0 for top, 1 for right, 2 for bottom, 3 for left.
262
263 rrect, dir, and start are unmodified if SkRRect is not found.
264
265 Triggers performance optimizations on some GPU surface implementations.
266
267 @param rrect storage for bounding SkRect of SkRRect; may be nullptr
268 @param dir storage for SkPathDirection; may be nullptr
269 @param start storage for start of SkRRect; may be nullptr
270 @return true if SkPath contains only SkRRect
271 */
273 unsigned* start) {
274 bool isCCW = false;
275 bool result = path.fPathRef->isRRect(rrect, &isCCW, start);
276 if (dir && result) {
278 }
279 return result;
280 }
281
282 /**
283 * Sometimes in the drawing pipeline, we have to perform math on path coordinates, even after
284 * the path is in device-coordinates. Tessellation and clipping are two examples. Usually this
285 * is pretty modest, but it can involve subtracting/adding coordinates, or multiplying by
286 * small constants (e.g. 2,3,4). To try to preflight issues where these optionations could turn
287 * finite path values into infinities (or NaNs), we allow the upper drawing code to reject
288 * the path if its bounds (in device coordinates) is too close to max float.
289 */
290 static bool TooBigForMath(const SkRect& bounds) {
291 // This value is just a guess. smaller is safer, but we don't want to reject largish paths
292 // that we don't have to.
293 constexpr SkScalar scale_down_to_allow_for_small_multiplies = 0.25f;
294 constexpr SkScalar max = SK_ScalarMax * scale_down_to_allow_for_small_multiplies;
295
296 // use ! expression so we return true if bounds contains NaN
297 return !(bounds.fLeft >= -max && bounds.fTop >= -max &&
298 bounds.fRight <= max && bounds.fBottom <= max);
299 }
300 static bool TooBigForMath(const SkPath& path) {
301 return TooBigForMath(path.getBounds());
302 }
303
304 // Returns number of valid points for each SkPath::Iter verb
305 static int PtsInIter(unsigned verb) {
306 static const uint8_t gPtsInVerb[] = {
307 1, // kMove pts[0]
308 2, // kLine pts[0..1]
309 3, // kQuad pts[0..2]
310 3, // kConic pts[0..2]
311 4, // kCubic pts[0..3]
312 0, // kClose
313 0 // kDone
314 };
315
316 SkASSERT(verb < std::size(gPtsInVerb));
317 return gPtsInVerb[verb];
318 }
319
320 // Returns number of valid points for each verb, not including the "starter"
321 // point that the Iterator adds for line/quad/conic/cubic
322 static int PtsInVerb(unsigned verb) {
323 static const uint8_t gPtsInVerb[] = {
324 1, // kMove pts[0]
325 1, // kLine pts[0..1]
326 2, // kQuad pts[0..2]
327 2, // kConic pts[0..2]
328 3, // kCubic pts[0..3]
329 0, // kClose
330 0 // kDone
331 };
332
333 SkASSERT(verb < std::size(gPtsInVerb));
334 return gPtsInVerb[verb];
335 }
336
337 static bool IsAxisAligned(const SkPath& path);
338
339 static bool AllPointsEq(const SkPoint pts[], int count) {
340 for (int i = 1; i < count; ++i) {
341 if (pts[0] != pts[i]) {
342 return false;
343 }
344 }
345 return true;
346 }
347
348 static int LastMoveToIndex(const SkPath& path) { return path.fLastMoveToIndex; }
349
350 static bool IsRectContour(const SkPath&, bool allowPartial, int* currVerb,
351 const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
352 SkRect* rect);
353
354 /** Returns true if SkPath is equivalent to nested SkRect pair when filled.
355 If false, rect and dirs are unchanged.
356 If true, rect and dirs are written to if not nullptr:
357 setting rect[0] to outer SkRect, and rect[1] to inner SkRect;
358 setting dirs[0] to SkPathDirection of outer SkRect, and dirs[1] to SkPathDirection of
359 inner SkRect.
360
361 @param rect storage for SkRect pair; may be nullptr
362 @param dirs storage for SkPathDirection pair; may be nullptr
363 @return true if SkPath contains nested SkRect pair
364 */
365 static bool IsNestedFillRects(const SkPath&, SkRect rect[2],
366 SkPathDirection dirs[2] = nullptr);
367
369 return (static_cast<int>(fill) & 2) != 0;
370 }
371
372 /** Returns equivalent SkPath::FillType representing SkPath fill inside its bounds.
373 .
374
375 @param fill one of: kWinding_FillType, kEvenOdd_FillType,
376 kInverseWinding_FillType, kInverseEvenOdd_FillType
377 @return fill, or kWinding_FillType or kEvenOdd_FillType if fill is inverted
378 */
380 return (SkPathFillType)(static_cast<int>(fill) & 1);
381 }
382
383 /**
384 * If needed (to not blow-up under a perspective matrix), clip the path, returning the
385 * answer in "result", and return true.
386 *
387 * Note result might be empty (if the path was completely clipped out).
388 *
389 * If no clipping is needed, returns false and "result" is left unchanged.
390 */
391 static bool PerspectiveClip(const SkPath& src, const SkMatrix&, SkPath* result);
392
393 /**
394 * Gets the number of GenIDChangeListeners. If another thread has access to this path then
395 * this may be stale before return and only indicates that the count was the return value
396 * at some point during the execution of the function.
397 */
398 static int GenIDChangeListenersCount(const SkPath&);
399
400 static void UpdatePathPoint(SkPath* path, int index, const SkPoint& pt) {
401 SkASSERT(index < path->countPoints());
402 SkPathRef::Editor ed(&path->fPathRef);
403 ed.writablePoints()[index] = pt;
404 path->dirtyAfterEdit();
405 }
406
408 return path.getConvexity();
409 }
411 return path.getConvexityOrUnknown();
412 }
413 static void SetConvexity(const SkPath& path, SkPathConvexity c) {
414 path.setConvexity(c);
415 }
416 static void ForceComputeConvexity(const SkPath& path) {
417 path.setConvexity(SkPathConvexity::kUnknown);
418 (void)path.isConvex();
419 }
420
421 static void ReverseAddPath(SkPathBuilder* builder, const SkPath& reverseMe) {
422 builder->privateReverseAddPath(reverseMe);
423 }
424
425 static SkPath MakePath(const SkPathVerbAnalysis& analysis,
426 const SkPoint points[],
427 const uint8_t verbs[],
428 int verbCount,
429 const SkScalar conics[],
430 SkPathFillType fillType,
431 bool isVolatile) {
432 return SkPath::MakeInternal(analysis, points, verbs, verbCount, conics, fillType,
433 isVolatile);
434 }
435};
436
437// Lightweight variant of SkPath::Iter that only returns segments (e.g. lines/conics).
438// Does not return kMove or kClose.
439// Always "auto-closes" each contour.
440// Roughly the same as SkPath::Iter(path, true), but does not return moves or closes
441//
443 const uint8_t* fVerbs;
444 const uint8_t* fVerbsStop;
445 const SkPoint* fPts;
446 const SkPoint* fMoveToPtr;
447 const SkScalar* fConicWeights;
448 SkPoint fScratch[2]; // for auto-close lines
449 bool fNeedsCloseLine;
450 bool fNextIsNewContour;
451 SkDEBUGCODE(bool fIsConic;)
452
453 enum {
454 kIllegalEdgeValue = 99
455 };
456
457public:
458 SkPathEdgeIter(const SkPath& path);
459
461 SkASSERT(fIsConic);
462 return *fConicWeights;
463 }
464
465 enum class Edge {
466 kLine = SkPath::kLine_Verb,
467 kQuad = SkPath::kQuad_Verb,
469 kCubic = SkPath::kCubic_Verb,
470 };
471
473 return SkPath::Verb(e);
474 }
475
476 struct Result {
477 const SkPoint* fPts; // points for the segment, or null if done
480
481 // Returns true when it holds an Edge, false when the path is done.
482 explicit operator bool() { return fPts != nullptr; }
483 };
484
486 auto closeline = [&]() {
487 fScratch[0] = fPts[-1];
488 fScratch[1] = *fMoveToPtr;
489 fNeedsCloseLine = false;
490 fNextIsNewContour = true;
491 return Result{ fScratch, Edge::kLine, false };
492 };
493
494 for (;;) {
495 SkASSERT(fVerbs <= fVerbsStop);
496 if (fVerbs == fVerbsStop) {
497 return fNeedsCloseLine
498 ? closeline()
499 : Result{ nullptr, Edge(kIllegalEdgeValue), false };
500 }
501
502 SkDEBUGCODE(fIsConic = false;)
503
504 const auto v = *fVerbs++;
505 switch (v) {
506 case SkPath::kMove_Verb: {
507 if (fNeedsCloseLine) {
508 auto res = closeline();
509 fMoveToPtr = fPts++;
510 return res;
511 }
512 fMoveToPtr = fPts++;
513 fNextIsNewContour = true;
514 } break;
516 if (fNeedsCloseLine) return closeline();
517 break;
518 default: {
519 // Actual edge.
520 const int pts_count = (v+2) / 2,
521 cws_count = (v & (v-1)) / 2;
522 SkASSERT(pts_count == SkPathPriv::PtsInIter(v) - 1);
523
524 fNeedsCloseLine = true;
525 fPts += pts_count;
526 fConicWeights += cws_count;
527
528 SkDEBUGCODE(fIsConic = (v == SkPath::kConic_Verb);)
529 SkASSERT(fIsConic == (cws_count > 0));
530
531 bool isNewContour = fNextIsNewContour;
532 fNextIsNewContour = false;
533 return { &fPts[-(pts_count + 1)], Edge(v), isNewContour };
534 }
535 }
536 }
537 }
538};
539
540#endif
SkPoint fPts[2]
int count
Definition: FontMgrTest.cpp:50
static const int points[]
static bool isFinite(const SkRect &r)
Definition: MathBench.cpp:230
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkPathConvexity
Definition: SkPathEnums.h:13
SkPathFirstDirection
Definition: SkPathEnums.h:19
SkPathDirection
Definition: SkPathTypes.h:34
SkPathFillType
Definition: SkPathTypes.h:11
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
#define SK_ScalarMax
Definition: SkScalar.h:24
Result next()
Definition: SkPathPriv.h:485
SkPathEdgeIter(const SkPath &path)
Definition: SkPath.cpp:4010
SkScalar conicWeight() const
Definition: SkPathPriv.h:460
static SkPath::Verb EdgeToVerb(Edge e)
Definition: SkPathPriv.h:472
static bool IsInverseFillType(SkPathFillType fill)
Definition: SkPathPriv.h:368
static int PtsInVerb(unsigned verb)
Definition: SkPathPriv.h:322
static bool IsClosedSingleContour(const SkPath &path)
Definition: SkPathPriv.h:67
static SkPathConvexity GetConvexity(const SkPath &path)
Definition: SkPathPriv.h:407
static bool IsRRect(const SkPath &path, SkRRect *rrect, SkPathDirection *dir, unsigned *start)
Definition: SkPathPriv.h:272
static bool IsNestedFillRects(const SkPath &, SkRect rect[2], SkPathDirection dirs[2]=nullptr)
Definition: SkPath.cpp:3780
static int LastMoveToIndex(const SkPath &path)
Definition: SkPathPriv.h:348
static bool TooBigForMath(const SkPath &path)
Definition: SkPathPriv.h:300
static bool IsSimpleRect(const SkPath &path, bool isSimpleFill, SkRect *rect, SkPathDirection *direction, unsigned *start)
Definition: SkPath.cpp:3244
static int GenIDChangeListenersCount(const SkPath &)
Definition: SkPath.cpp:3988
static void SetConvexity(const SkPath &path, SkPathConvexity c)
Definition: SkPathPriv.h:413
static bool HasComputedBounds(const SkPath &path)
Definition: SkPathPriv.h:223
static const uint8_t * VerbData(const SkPath &path)
Definition: SkPathPriv.h:198
static SkPath MakePath(const SkPathVerbAnalysis &analysis, const SkPoint points[], const uint8_t verbs[], int verbCount, const SkScalar conics[], SkPathFillType fillType, bool isVolatile)
Definition: SkPathPriv.h:425
static void ForceComputeConvexity(const SkPath &path)
Definition: SkPathPriv.h:416
static bool IsOval(const SkPath &path, SkRect *rect, SkPathDirection *dir, unsigned *start)
Definition: SkPathPriv.h:245
static SkPathFirstDirection AsFirstDirection(SkPathDirection dir)
Definition: SkPathPriv.h:43
static bool IsAxisAligned(const SkPath &path)
Definition: SkPath.cpp:3992
static int PtsInIter(unsigned verb)
Definition: SkPathPriv.h:305
static bool TestingOnly_unique(const SkPath &path)
Definition: SkPathPriv.h:218
static void ReverseAddPath(SkPathBuilder *builder, const SkPath &reverseMe)
Definition: SkPathPriv.h:421
static void CreateDrawArcPath(SkPath *path, const SkArc &arc, bool isFillNoPathEffect)
Definition: SkPath.cpp:3356
static SkPathFirstDirection ComputeFirstDirection(const SkPath &)
Definition: SkPath.cpp:2627
static bool DrawArcIsConvex(SkScalar sweepAngle, SkArc::Type arcType, bool isFillNoPathEffect)
Definition: SkPath.cpp:3340
static int LeadingMoveToCount(const SkPath &path)
Definition: SkPathPriv.h:95
static constexpr SkScalar kW0PlaneDistance
Definition: SkPathPriv.h:41
static void AddGenIDChangeListener(const SkPath &path, sk_sp< SkIDChangeListener > listener)
Definition: SkPathPriv.h:106
static SkPathConvexity GetConvexityOrUnknown(const SkPath &path)
Definition: SkPathPriv.h:410
static void ShrinkToFit(SkPath *path)
Definition: SkPathPriv.h:130
static bool PerspectiveClip(const SkPath &src, const SkMatrix &, SkPath *result)
Definition: SkPath.cpp:3962
static void UpdatePathPoint(SkPath *path, int index, const SkPoint &pt)
Definition: SkPathPriv.h:400
static bool IsRectContour(const SkPath &, bool allowPartial, int *currVerb, const SkPoint **ptsPtr, bool *isClosed, SkPathDirection *direction, SkRect *rect)
Definition: SkPath.cpp:3639
static const SkScalar * ConicWeightData(const SkPath &path)
Definition: SkPathPriv.h:213
static const SkPoint * PointData(const SkPath &path)
Definition: SkPathPriv.h:203
static bool TooBigForMath(const SkRect &bounds)
Definition: SkPathPriv.h:290
static bool AllPointsEq(const SkPoint pts[], int count)
Definition: SkPathPriv.h:339
static int ConicWeightCnt(const SkPath &path)
Definition: SkPathPriv.h:208
SkPath::RangeIter RangeIter
Definition: SkPathPriv.h:164
static SkPathFirstDirection OppositeFirstDirection(SkPathFirstDirection dir)
Definition: SkPathPriv.h:52
static SkPathFillType ConvertToNonInverseFillType(SkPathFillType fill)
Definition: SkPathPriv.h:379
SkPoint * writablePoints()
Definition: SkPathRef.h:105
const uint8_t * verbsEnd() const
Definition: SkPathRef.h:321
const uint8_t * verbsBegin() const
Definition: SkPathRef.h:316
Definition: SkPath.h:59
@ kClose_Verb
Definition: SkPath.h:1471
@ kMove_Verb
Definition: SkPath.h:1466
@ kConic_Verb
Definition: SkPath.h:1469
@ kCubic_Verb
Definition: SkPath.h:1470
@ kQuad_Verb
Definition: SkPath.h:1468
@ kLine_Verb
Definition: SkPath.h:1467
float SkScalar
Definition: extension.cpp:12
static bool b
GAsyncResult * result
static float max(float r, float g, float b)
Definition: hsl.cpp:49
Optional< SkRect > bounds
Definition: SkRecords.h:189
SkRRect rrect
Definition: SkRecords.h:232
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
SkScalar sweepAngle
Definition: SkRecords.h:251
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
Definition: switches.h:57
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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
const myers::Point & get(const myers::Segment &)
Definition: SkArc.h:15
Type
Definition: SkArc.h:16
const SkPoint * fPts
Definition: SkPathPriv.h:477
Iterate(const uint8_t *verbsBegin, const uint8_t *verbsEnd, const SkPoint *points, const SkScalar *weights)
Definition: SkPathPriv.h:182
SkPath::RangeIter end()
Definition: SkPathPriv.h:187
Iterate(const SkPath &path)
Definition: SkPathPriv.h:175
SkPath::RangeIter begin()
Definition: SkPathPriv.h:186
bool operator!=(const Iter &b)
Definition: SkPathPriv.h:146
SkPath::Verb operator*()
Definition: SkPathPriv.h:147
const uint8_t * fVerb
Definition: SkPathPriv.h:148
Verbs(const SkPath &path)
Definition: SkPathPriv.h:143