Flutter Engine
The Flutter Engine
Classes | Functions
SkPathRef.h File Reference
#include "include/core/SkArc.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/SkIDChangeListener.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkSpan_impl.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTo.h"
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <tuple>

Go to the source code of this file.

Classes

struct  SkPathVerbAnalysis
 
class  SkPathRef
 
class  SkPathRef::Editor
 
class  SkPathRef::Iter
 

Functions

SkPathVerbAnalysis sk_path_analyze_verbs (const uint8_t verbs[], int count)
 

Function Documentation

◆ sk_path_analyze_verbs()

SkPathVerbAnalysis sk_path_analyze_verbs ( const uint8_t  verbs[],
int  count 
)

Definition at line 3515 of file SkPath.cpp.

3515 {
3516 SkPathVerbAnalysis info = {false, 0, 0, 0};
3517 bool needMove = true;
3518 bool invalid = false;
3519
3520 if (verbCount >= (INT_MAX / 3)) SK_UNLIKELY {
3521 // A path with an extremely high number of quad, conic or cubic verbs could cause
3522 // `info.points` to overflow. To prevent against this, we reject extremely large paths. This
3523 // check is conservative and assumes the worst case (in particular, it assumes that every
3524 // verb consumes 3 points, which would only happen for a path composed entirely of cubics).
3525 // This limits us to 700 million verbs, which is large enough for any reasonable use case.
3526 invalid = true;
3527 } else {
3528 for (int i = 0; i < verbCount; ++i) {
3529 switch ((SkPathVerb)vbs[i]) {
3530 case SkPathVerb::kMove:
3531 needMove = false;
3532 info.points += 1;
3533 break;
3534 case SkPathVerb::kLine:
3535 invalid |= needMove;
3536 info.segmentMask |= kLine_SkPathSegmentMask;
3537 info.points += 1;
3538 break;
3539 case SkPathVerb::kQuad:
3540 invalid |= needMove;
3541 info.segmentMask |= kQuad_SkPathSegmentMask;
3542 info.points += 2;
3543 break;
3544 case SkPathVerb::kConic:
3545 invalid |= needMove;
3546 info.segmentMask |= kConic_SkPathSegmentMask;
3547 info.points += 2;
3548 info.weights += 1;
3549 break;
3550 case SkPathVerb::kCubic:
3551 invalid |= needMove;
3552 info.segmentMask |= kCubic_SkPathSegmentMask;
3553 info.points += 3;
3554 break;
3555 case SkPathVerb::kClose:
3556 invalid |= needMove;
3557 needMove = true;
3558 break;
3559 default:
3560 invalid = true;
3561 break;
3562 }
3563 }
3564 }
3565 info.valid = !invalid;
3566 return info;
3567}
static bool invalid(const SkISize &size)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define SK_UNLIKELY
Definition: SkAssert.h:28
@ kCubic_SkPathSegmentMask
Definition: SkPathTypes.h:45
@ kConic_SkPathSegmentMask
Definition: SkPathTypes.h:44
@ kQuad_SkPathSegmentMask
Definition: SkPathTypes.h:43
@ kLine_SkPathSegmentMask
Definition: SkPathTypes.h:42
SkPathVerb
Definition: SkPathTypes.h:48
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.