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,7 +188,7 @@ protected:
|
|||||||
case MakeType::kArray: {
|
case MakeType::kArray: {
|
||||||
// ArrayPath<N*12> arrays;
|
// ArrayPath<N*12> arrays;
|
||||||
// run_builder(arrays, false, N);
|
// run_builder(arrays, false, N);
|
||||||
return SkPathBuilder::Make(fArrays.fPts, fArrays.fPIndex,
|
return SkPath::Make(fArrays.fPts, fArrays.fPIndex,
|
||||||
fArrays.fVbs, fArrays.fVIndex,
|
fArrays.fVbs, fArrays.fVIndex,
|
||||||
nullptr, 0, SkPathFillType::kWinding);
|
nullptr, 0, SkPathFillType::kWinding);
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,29 @@ class SkWStream;
|
|||||||
*/
|
*/
|
||||||
class SK_API SkPath {
|
class SK_API SkPath {
|
||||||
public:
|
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.
|
/** Constructs an empty SkPath. By default, SkPath has no verbs, no SkPoint, and no weights.
|
||||||
FillType is set to kWinding.
|
FillType is set to kWinding.
|
||||||
|
@ -71,11 +71,6 @@ public:
|
|||||||
this->incReserve(extraPtCount, extraPtCount);
|
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:
|
private:
|
||||||
SkTDArray<SkPoint> fPts;
|
SkTDArray<SkPoint> fPts;
|
||||||
SkTDArray<uint8_t> fVerbs;
|
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,
|
bool SkPathPriv::IsRectContour(const SkPath& path, bool allowPartial, int* currVerb,
|
||||||
const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
|
const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
|
||||||
SkRect* rect) {
|
SkRect* rect) {
|
||||||
|
@ -281,78 +281,3 @@ SkPathBuilder& SkPathBuilder::addRRect(const SkRRect& rrect, SkPathDirection dir
|
|||||||
}
|
}
|
||||||
return *this;
|
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;
|
pts[i] = {x, y}; vbs[i] = (uint8_t)SkPathVerb::kLine;
|
||||||
}
|
}
|
||||||
auto p0 = b.detach();
|
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);
|
REPORTER_ASSERT(reporter, p0 == p1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user