document Make for paths, and move from pathbuilder into path
Change-Id: I812b5315e06e38ec2c812c76634fe07227a30b39 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/300356 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
parent
ad0b2b8dd1
commit
92c33f329a
@ -188,9 +188,9 @@ protected:
|
||||
case MakeType::kArray: {
|
||||
// ArrayPath<N*12> arrays;
|
||||
// run_builder(arrays, false, N);
|
||||
return SkPathBuilder::Make(fArrays.fPts, fArrays.fPIndex,
|
||||
fArrays.fVbs, fArrays.fVIndex,
|
||||
nullptr, 0, SkPathFillType::kWinding);
|
||||
return SkPath::Make(fArrays.fPts, fArrays.fPIndex,
|
||||
fArrays.fVbs, fArrays.fVIndex,
|
||||
nullptr, 0, SkPathFillType::kWinding);
|
||||
}
|
||||
}
|
||||
return SkPath();
|
||||
|
@ -40,6 +40,29 @@ class SkWStream;
|
||||
*/
|
||||
class SK_API SkPath {
|
||||
public:
|
||||
/**
|
||||
* Create a new path with the specified segments.
|
||||
*
|
||||
* The points and weights arrays are read in order, based on the sequence of verbs.
|
||||
*
|
||||
* Move 1 point
|
||||
* Line 1 point
|
||||
* Quad 2 points
|
||||
* Conic 2 points and 1 weight
|
||||
* Cubic 3 points
|
||||
* Close 0 points
|
||||
*
|
||||
* If an illegal sequence of verbs is encountered, or the specified number of points
|
||||
* or weights is not sufficient given the verbs, an empty Path is returned.
|
||||
*
|
||||
* A legal sequence of verbs consists of any number of Contours. A contour always begins
|
||||
* with a Move verb, followed by 0 or more segments: Line, Quad, Conic, Cubic, followed
|
||||
* by an optional Close.
|
||||
*/
|
||||
static SkPath Make(const SkPoint[], int pointCount,
|
||||
const uint8_t[], int verbCount,
|
||||
const SkScalar[], int conicWeightCount,
|
||||
SkPathFillType, bool isVolatile = false);
|
||||
|
||||
/** Constructs an empty SkPath. By default, SkPath has no verbs, no SkPoint, and no weights.
|
||||
FillType is set to kWinding.
|
||||
|
@ -71,11 +71,6 @@ public:
|
||||
this->incReserve(extraPtCount, extraPtCount);
|
||||
}
|
||||
|
||||
static SkPath Make(const SkPoint[], int pointCount,
|
||||
const uint8_t[], int verbCount,
|
||||
const SkScalar[], int conicWeightCount,
|
||||
SkPathFillType, bool isVolatile = false);
|
||||
|
||||
private:
|
||||
SkTDArray<SkPoint> fPts;
|
||||
SkTDArray<uint8_t> fVerbs;
|
||||
|
@ -3332,6 +3332,80 @@ bool SkPath::IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2,
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PathInfo {
|
||||
bool valid;
|
||||
int points, weights;
|
||||
unsigned segmentMask;
|
||||
};
|
||||
|
||||
static PathInfo validate_verbs(const uint8_t vbs[], int verbCount) {
|
||||
PathInfo info = {false, 0, 0, 0};
|
||||
|
||||
bool needMove = true;
|
||||
bool invalid = false;
|
||||
for (int i = 0; i < verbCount; ++i) {
|
||||
switch ((SkPathVerb)vbs[i]) {
|
||||
case SkPathVerb::kMove:
|
||||
needMove = false;
|
||||
info.points += 1;
|
||||
break;
|
||||
case SkPathVerb::kLine:
|
||||
invalid |= needMove;
|
||||
info.segmentMask |= kLine_SkPathSegmentMask;
|
||||
info.points += 1;
|
||||
break;
|
||||
case SkPathVerb::kQuad:
|
||||
invalid |= needMove;
|
||||
info.segmentMask |= kQuad_SkPathSegmentMask;
|
||||
info.points += 2;
|
||||
break;
|
||||
case SkPathVerb::kConic:
|
||||
invalid |= needMove;
|
||||
info.segmentMask |= kConic_SkPathSegmentMask;
|
||||
info.points += 2;
|
||||
info.weights += 1;
|
||||
break;
|
||||
case SkPathVerb::kCubic:
|
||||
invalid |= needMove;
|
||||
info.segmentMask |= kCubic_SkPathSegmentMask;
|
||||
info.points += 3;
|
||||
break;
|
||||
case SkPathVerb::kClose:
|
||||
invalid |= needMove;
|
||||
needMove = true;
|
||||
break;
|
||||
default:
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
info.valid = !invalid;
|
||||
return info;
|
||||
}
|
||||
|
||||
SkPath SkPath::Make(const SkPoint pts[], int pointCount,
|
||||
const uint8_t vbs[], int verbCount,
|
||||
const SkScalar ws[], int wCount,
|
||||
SkPathFillType ft, bool isVolatile) {
|
||||
if (verbCount <= 0) {
|
||||
return SkPath();
|
||||
}
|
||||
|
||||
const auto info = validate_verbs(vbs, verbCount);
|
||||
if (!info.valid || info.points > pointCount || info.weights > wCount) {
|
||||
SkDEBUGFAIL("invalid verbs and number of points/weights");
|
||||
return SkPath();
|
||||
}
|
||||
|
||||
return SkPath(sk_sp<SkPathRef>(new SkPathRef(SkTDArray<SkPoint>(pts, info.points),
|
||||
SkTDArray<uint8_t>(vbs, verbCount),
|
||||
SkTDArray<SkScalar>(ws, info.weights),
|
||||
info.segmentMask)),
|
||||
ft, isVolatile);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkPathPriv::IsRectContour(const SkPath& path, bool allowPartial, int* currVerb,
|
||||
const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
|
||||
SkRect* rect) {
|
||||
|
@ -281,78 +281,3 @@ SkPathBuilder& SkPathBuilder::addRRect(const SkRRect& rrect, SkPathDirection dir
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct PathInfo {
|
||||
bool valid;
|
||||
int points, weights;
|
||||
unsigned segmentMask;
|
||||
};
|
||||
|
||||
static PathInfo validate_verbs(const uint8_t vbs[], int verbCount) {
|
||||
PathInfo info = {false, 0, 0, 0};
|
||||
|
||||
bool needMove = true;
|
||||
bool invalid = false;
|
||||
for (int i = 0; i < verbCount; ++i) {
|
||||
switch ((SkPathVerb)vbs[i]) {
|
||||
case SkPathVerb::kMove:
|
||||
needMove = false;
|
||||
info.points += 1;
|
||||
break;
|
||||
case SkPathVerb::kLine:
|
||||
invalid |= needMove;
|
||||
info.segmentMask |= kLine_SkPathSegmentMask;
|
||||
info.points += 1;
|
||||
break;
|
||||
case SkPathVerb::kQuad:
|
||||
invalid |= needMove;
|
||||
info.segmentMask |= kQuad_SkPathSegmentMask;
|
||||
info.points += 2;
|
||||
break;
|
||||
case SkPathVerb::kConic:
|
||||
invalid |= needMove;
|
||||
info.segmentMask |= kConic_SkPathSegmentMask;
|
||||
info.points += 2;
|
||||
info.weights += 1;
|
||||
break;
|
||||
case SkPathVerb::kCubic:
|
||||
invalid |= needMove;
|
||||
info.segmentMask |= kCubic_SkPathSegmentMask;
|
||||
info.points += 3;
|
||||
break;
|
||||
case SkPathVerb::kClose:
|
||||
invalid |= needMove;
|
||||
needMove = true;
|
||||
break;
|
||||
default:
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
info.valid = !invalid;
|
||||
return info;
|
||||
}
|
||||
|
||||
SkPath SkPathBuilder::Make(const SkPoint pts[], int pointCount,
|
||||
const uint8_t vbs[], int verbCount,
|
||||
const SkScalar ws[], int wCount,
|
||||
SkPathFillType ft, bool isVolatile) {
|
||||
if (verbCount <= 0) {
|
||||
return SkPath();
|
||||
}
|
||||
|
||||
const auto info = validate_verbs(vbs, verbCount);
|
||||
if (!info.valid || info.points > pointCount || info.weights > wCount) {
|
||||
SkDEBUGFAIL("invalid verbs and number of points/weights");
|
||||
return SkPath();
|
||||
}
|
||||
|
||||
return SkPath(sk_sp<SkPathRef>(new SkPathRef(SkTDArray<SkPoint>(pts, info.points),
|
||||
SkTDArray<uint8_t>(vbs, verbCount),
|
||||
SkTDArray<SkScalar>(ws, info.weights),
|
||||
info.segmentMask)),
|
||||
ft, isVolatile);
|
||||
}
|
||||
|
||||
|
@ -163,6 +163,6 @@ DEF_TEST(pathbuilder_make, reporter) {
|
||||
pts[i] = {x, y}; vbs[i] = (uint8_t)SkPathVerb::kLine;
|
||||
}
|
||||
auto p0 = b.detach();
|
||||
auto p1 = SkPathBuilder::Make(pts, N, vbs, N, nullptr, 0, p0.getFillType());
|
||||
auto p1 = SkPath::Make(pts, N, vbs, N, nullptr, 0, p0.getFillType());
|
||||
REPORTER_ASSERT(reporter, p0 == p1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user