Revert "SkPathView for ownerless (can live on stack) SkPaths"
This reverts commit 375721d7bb
.
Some manual edits needed due to time elapsed.
Bug: chromium:1141332, skia:10566
Change-Id: Iadb15d3f5334d9eed4e7053e9c19d75a0bbeb9de
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330196
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
ca107f3287
commit
71f1266664
@ -18,7 +18,6 @@
|
|||||||
class SkAutoPathBoundsUpdate;
|
class SkAutoPathBoundsUpdate;
|
||||||
class SkData;
|
class SkData;
|
||||||
class SkRRect;
|
class SkRRect;
|
||||||
struct SkPathView;
|
|
||||||
class SkWStream;
|
class SkWStream;
|
||||||
|
|
||||||
// WIP -- define this locally, and fix call-sites to use SkPathBuilder (skbug.com/9000)
|
// WIP -- define this locally, and fix call-sites to use SkPathBuilder (skbug.com/9000)
|
||||||
@ -1540,8 +1539,6 @@ public:
|
|||||||
Verb autoClose(SkPoint pts[2]);
|
Verb autoClose(SkPoint pts[2]);
|
||||||
};
|
};
|
||||||
|
|
||||||
SkPathView view() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** \class SkPath::RangeIter
|
/** \class SkPath::RangeIter
|
||||||
Iterates through a raw range of path verbs, points, and conics. All values are returned
|
Iterates through a raw range of path verbs, points, and conics. All values are returned
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#define SkPathRef_DEFINED
|
#define SkPathRef_DEFINED
|
||||||
|
|
||||||
#include "include/core/SkMatrix.h"
|
#include "include/core/SkMatrix.h"
|
||||||
#include "include/core/SkPathTypes.h"
|
|
||||||
#include "include/core/SkPoint.h"
|
#include "include/core/SkPoint.h"
|
||||||
#include "include/core/SkRRect.h"
|
#include "include/core/SkRRect.h"
|
||||||
#include "include/core/SkRect.h"
|
#include "include/core/SkRect.h"
|
||||||
@ -24,7 +23,6 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
struct SkPathView;
|
|
||||||
class SkRBuffer;
|
class SkRBuffer;
|
||||||
class SkWBuffer;
|
class SkWBuffer;
|
||||||
|
|
||||||
@ -352,8 +350,6 @@ public:
|
|||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
SkDEBUGCODE(void validate() const { SkASSERT(this->isValid()); } )
|
SkDEBUGCODE(void validate() const { SkASSERT(this->isValid()); } )
|
||||||
|
|
||||||
SkPathView view(SkPathFillType, SkPathConvexity) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum SerializationOffsets {
|
enum SerializationOffsets {
|
||||||
kLegacyRRectOrOvalStartIdx_SerializationShift = 28, // requires 3 bits, ignored.
|
kLegacyRRectOrOvalStartIdx_SerializationShift = 28, // requires 3 bits, ignored.
|
||||||
|
@ -227,7 +227,7 @@ static SkPath clip(const SkPath& path, SkPoint p0, SkPoint p1) {
|
|||||||
SkPoint fPrev = {0, 0};
|
SkPoint fPrev = {0, 0};
|
||||||
} rec;
|
} rec;
|
||||||
|
|
||||||
SkEdgeClipper::ClipPath(rotated.view(), clip, false,
|
SkEdgeClipper::ClipPath(rotated, clip, false,
|
||||||
[](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
|
[](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
|
||||||
Rec* rec = (Rec*)ctx;
|
Rec* rec = (Rec*)ctx;
|
||||||
|
|
||||||
|
@ -1334,12 +1334,11 @@ bool SkAAClip::setPath(const SkPath& path, const SkRegion* clip, bool doAA) {
|
|||||||
|
|
||||||
Builder builder(ibounds);
|
Builder builder(ibounds);
|
||||||
BuilderBlitter blitter(&builder);
|
BuilderBlitter blitter(&builder);
|
||||||
const SkPathView view = path.view();
|
|
||||||
|
|
||||||
if (doAA) {
|
if (doAA) {
|
||||||
SkScan::AntiFillPath(view, snugClip, &blitter, true);
|
SkScan::AntiFillPath(path, snugClip, &blitter, true);
|
||||||
} else {
|
} else {
|
||||||
SkScan::FillPath(view, snugClip, &blitter);
|
SkScan::FillPath(path, snugClip, &blitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
blitter.finish();
|
blitter.finish();
|
||||||
|
@ -834,7 +834,7 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void (*proc)(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||||
if (doFill) {
|
if (doFill) {
|
||||||
if (paint.isAntiAlias()) {
|
if (paint.isAntiAlias()) {
|
||||||
proc = SkScan::AntiFillPath;
|
proc = SkScan::AntiFillPath;
|
||||||
@ -875,7 +875,7 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc(devPath.view(), *fRC, blitter);
|
proc(devPath, *fRC, blitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
|
void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include "src/core/SkScan.h"
|
#include "src/core/SkScan.h"
|
||||||
|
|
||||||
static void fill_rect(const SkMatrix& ctm, const SkRasterClip& rc,
|
static void fill_rect(const SkMatrix& ctm, const SkRasterClip& rc,
|
||||||
const SkRect& r, SkBlitter* blitter) {
|
const SkRect& r, SkBlitter* blitter, SkPath* scratchPath) {
|
||||||
if (ctm.rectStaysRect()) {
|
if (ctm.rectStaysRect()) {
|
||||||
SkRect dr;
|
SkRect dr;
|
||||||
ctm.mapRect(&dr, r);
|
ctm.mapRect(&dr, r);
|
||||||
@ -32,10 +32,9 @@ static void fill_rect(const SkMatrix& ctm, const SkRasterClip& rc,
|
|||||||
r.toQuad(pts);
|
r.toQuad(pts);
|
||||||
ctm.mapPoints(pts, pts, 4);
|
ctm.mapPoints(pts, pts, 4);
|
||||||
|
|
||||||
SkRect bounds;
|
scratchPath->rewind();
|
||||||
bounds.setBounds(pts, 4);
|
scratchPath->addPoly(pts, 4, true);
|
||||||
|
SkScan::FillPath(*scratchPath, rc, blitter);
|
||||||
SkScan::FillPath(SkPathView_quad(pts, bounds), rc, blitter);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +103,8 @@ void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRe
|
|||||||
|
|
||||||
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, &alloc,
|
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, &alloc,
|
||||||
fRC->clipShader())) {
|
fRC->clipShader())) {
|
||||||
|
SkPath scratchPath;
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
if (colors) {
|
if (colors) {
|
||||||
SkColor4f c4 = SkColor4f::FromColor(colors[i]);
|
SkColor4f c4 = SkColor4f::FromColor(colors[i]);
|
||||||
@ -117,7 +118,7 @@ void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRe
|
|||||||
mx.postConcat(fMatrixProvider->localToDevice());
|
mx.postConcat(fMatrixProvider->localToDevice());
|
||||||
|
|
||||||
if (updator->update(mx, nullptr)) {
|
if (updator->update(mx, nullptr)) {
|
||||||
fill_rect(mx, *fRC, textures[i], blitter);
|
fill_rect(mx, *fRC, textures[i], blitter, &scratchPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "src/core/SkGeometry.h"
|
#include "src/core/SkGeometry.h"
|
||||||
#include "src/core/SkLineClipper.h"
|
#include "src/core/SkLineClipper.h"
|
||||||
#include "src/core/SkPathPriv.h"
|
#include "src/core/SkPathPriv.h"
|
||||||
#include "src/core/SkPathView.h"
|
|
||||||
#include "src/core/SkSafeMath.h"
|
#include "src/core/SkSafeMath.h"
|
||||||
|
|
||||||
SkEdgeBuilder::Combine SkBasicEdgeBuilder::combineVertical(const SkEdge* edge, SkEdge* last) {
|
SkEdgeBuilder::Combine SkBasicEdgeBuilder::combineVertical(const SkEdge* edge, SkEdge* last) {
|
||||||
@ -219,8 +218,8 @@ char* SkAnalyticEdgeBuilder::allocEdges(size_t n, size_t* size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: maybe get rid of buildPoly() entirely?
|
// TODO: maybe get rid of buildPoly() entirely?
|
||||||
int SkEdgeBuilder::buildPoly(const SkPathView& path, const SkIRect* iclip, bool canCullToTheRight) {
|
int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, bool canCullToTheRight) {
|
||||||
size_t maxEdgeCount = path.fPoints.size();
|
size_t maxEdgeCount = path.countPoints();
|
||||||
if (iclip) {
|
if (iclip) {
|
||||||
// clipping can turn 1 line into (up to) kMaxClippedLineSegments, since
|
// clipping can turn 1 line into (up to) kMaxClippedLineSegments, since
|
||||||
// we turn portions that are clipped out on the left/right into vertical
|
// we turn portions that are clipped out on the left/right into vertical
|
||||||
@ -287,7 +286,7 @@ int SkEdgeBuilder::buildPoly(const SkPathView& path, const SkIRect* iclip, bool
|
|||||||
return SkToInt(edgePtr - (char**)fEdgeList);
|
return SkToInt(edgePtr - (char**)fEdgeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SkEdgeBuilder::build(const SkPathView& path, const SkIRect* iclip, bool canCullToTheRight) {
|
int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, bool canCullToTheRight) {
|
||||||
SkAutoConicToQuads quadder;
|
SkAutoConicToQuads quadder;
|
||||||
const SkScalar conicTol = SK_Scalar1 / 4;
|
const SkScalar conicTol = SK_Scalar1 / 4;
|
||||||
bool is_finite = true;
|
bool is_finite = true;
|
||||||
@ -361,14 +360,14 @@ int SkEdgeBuilder::build(const SkPathView& path, const SkIRect* iclip, bool canC
|
|||||||
return is_finite ? fList.count() : 0;
|
return is_finite ? fList.count() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SkEdgeBuilder::buildEdges(const SkPathView& path,
|
int SkEdgeBuilder::buildEdges(const SkPath& path,
|
||||||
const SkIRect* shiftedClip) {
|
const SkIRect* shiftedClip) {
|
||||||
// If we're convex, then we need both edges, even if the right edge is past the clip.
|
// If we're convex, then we need both edges, even if the right edge is past the clip.
|
||||||
const bool canCullToTheRight = !path.isConvex();
|
const bool canCullToTheRight = !path.isConvex();
|
||||||
|
|
||||||
// We can use our buildPoly() optimization if all the segments are lines.
|
// We can use our buildPoly() optimization if all the segments are lines.
|
||||||
// (Edges are homogeneous and stored contiguously in memory, no need for indirection.)
|
// (Edges are homogeneous and stored contiguously in memory, no need for indirection.)
|
||||||
const int count = SkPath::kLine_SegmentMask == path.fSegmentMask
|
const int count = SkPath::kLine_SegmentMask == path.getSegmentMasks()
|
||||||
? this->buildPoly(path, shiftedClip, canCullToTheRight)
|
? this->buildPoly(path, shiftedClip, canCullToTheRight)
|
||||||
: this->build (path, shiftedClip, canCullToTheRight);
|
: this->build (path, shiftedClip, canCullToTheRight);
|
||||||
|
|
||||||
|
@ -13,11 +13,12 @@
|
|||||||
#include "src/core/SkArenaAlloc.h"
|
#include "src/core/SkArenaAlloc.h"
|
||||||
#include "src/core/SkEdge.h"
|
#include "src/core/SkEdge.h"
|
||||||
|
|
||||||
struct SkPathView;
|
class SkPath;
|
||||||
|
|
||||||
class SkEdgeBuilder {
|
class SkEdgeBuilder {
|
||||||
public:
|
public:
|
||||||
int buildEdges(const SkPathView&, const SkIRect* shiftedClip);
|
int buildEdges(const SkPath& path,
|
||||||
|
const SkIRect* shiftedClip);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SkEdgeBuilder() = default;
|
SkEdgeBuilder() = default;
|
||||||
@ -36,8 +37,8 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int build (const SkPathView&, const SkIRect* clip, bool clipToTheRight);
|
int build (const SkPath& path, const SkIRect* clip, bool clipToTheRight);
|
||||||
int buildPoly(const SkPathView&, const SkIRect* clip, bool clipToTheRight);
|
int buildPoly(const SkPath& path, const SkIRect* clip, bool clipToTheRight);
|
||||||
|
|
||||||
virtual char* allocEdges(size_t n, size_t* sizeof_edge) = 0;
|
virtual char* allocEdges(size_t n, size_t* sizeof_edge) = 0;
|
||||||
virtual SkRect recoverClip(const SkIRect&) const = 0;
|
virtual SkRect recoverClip(const SkIRect&) const = 0;
|
||||||
|
@ -560,13 +560,14 @@ void sk_assert_monotonic_x(const SkPoint pts[], int count) {
|
|||||||
|
|
||||||
#include "src/core/SkPathPriv.h"
|
#include "src/core/SkPathPriv.h"
|
||||||
|
|
||||||
void SkEdgeClipper::ClipPath(const SkPathView& view, const SkRect& clip, bool canCullToTheRight,
|
void SkEdgeClipper::ClipPath(const SkPath& path, const SkRect& clip, bool canCullToTheRight,
|
||||||
void (*consume)(SkEdgeClipper*, bool newCtr, void* ctx), void* ctx) {
|
void (*consume)(SkEdgeClipper*, bool newCtr, void* ctx), void* ctx) {
|
||||||
SkASSERT(view.isFinite());
|
SkASSERT(path.isFinite());
|
||||||
|
|
||||||
SkAutoConicToQuads quadder;
|
SkAutoConicToQuads quadder;
|
||||||
const SkScalar conicTol = SK_Scalar1 / 4;
|
const SkScalar conicTol = SK_Scalar1 / 4;
|
||||||
|
|
||||||
SkPathEdgeIter iter(view);
|
SkPathEdgeIter iter(path);
|
||||||
SkEdgeClipper clipper(canCullToTheRight);
|
SkEdgeClipper clipper(canCullToTheRight);
|
||||||
|
|
||||||
while (auto e = iter.next()) {
|
while (auto e = iter.next()) {
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#define SkEdgeClipper_DEFINED
|
#define SkEdgeClipper_DEFINED
|
||||||
|
|
||||||
#include "include/core/SkPath.h"
|
#include "include/core/SkPath.h"
|
||||||
#include "src/core/SkPathView.h"
|
|
||||||
|
|
||||||
/** This is basically an iterator. It is initialized with an edge and a clip,
|
/** This is basically an iterator. It is initialized with an edge and a clip,
|
||||||
and then next() is called until it returns kDone_Verb.
|
and then next() is called until it returns kDone_Verb.
|
||||||
@ -31,7 +30,7 @@ public:
|
|||||||
* Clips each segment from the path, and passes the result (in a clipper) to the
|
* Clips each segment from the path, and passes the result (in a clipper) to the
|
||||||
* consume proc.
|
* consume proc.
|
||||||
*/
|
*/
|
||||||
static void ClipPath(const SkPathView& path, const SkRect& clip, bool canCullToTheRight,
|
static void ClipPath(const SkPath& path, const SkRect& clip, bool canCullToTheRight,
|
||||||
void (*consume)(SkEdgeClipper*, bool newCtr, void* ctx), void* ctx);
|
void (*consume)(SkEdgeClipper*, bool newCtr, void* ctx), void* ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -231,12 +231,6 @@ void SkPath::swap(SkPath& that) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPathView SkPath::view() const {
|
|
||||||
return fPathRef->view(this->getFillType(), this->getConvexity());
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool SkPath::isInterpolatable(const SkPath& compare) const {
|
bool SkPath::isInterpolatable(const SkPath& compare) const {
|
||||||
// need the same structure (verbs, conicweights) and same point-count
|
// need the same structure (verbs, conicweights) and same point-count
|
||||||
return fPathRef->fPoints.count() == compare.fPathRef->fPoints.count() &&
|
return fPathRef->fPoints.count() == compare.fPathRef->fPoints.count() &&
|
||||||
@ -474,7 +468,7 @@ bool SkPath::isRect(SkRect* rect, bool* isClosed, SkPathDirection* direction) co
|
|||||||
SkDEBUGCODE(this->validate();)
|
SkDEBUGCODE(this->validate();)
|
||||||
int currVerb = 0;
|
int currVerb = 0;
|
||||||
const SkPoint* pts = fPathRef->points();
|
const SkPoint* pts = fPathRef->points();
|
||||||
return SkPathPriv::IsRectContour(this->view(), false, &currVerb, &pts, isClosed, direction, rect);
|
return SkPathPriv::IsRectContour(*this, false, &currVerb, &pts, isClosed, direction, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkPath::isOval(SkRect* bounds) const {
|
bool SkPath::isOval(SkRect* bounds) const {
|
||||||
@ -3428,7 +3422,7 @@ SkPath SkPath::Polygon(const SkPoint pts[], int count, bool isClosed,
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool SkPathPriv::IsRectContour(const SkPathView& 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) {
|
||||||
int corners = 0;
|
int corners = 0;
|
||||||
@ -3445,9 +3439,9 @@ bool SkPathPriv::IsRectContour(const SkPathView& path, bool allowPartial, int* c
|
|||||||
bool closedOrMoved = false;
|
bool closedOrMoved = false;
|
||||||
bool autoClose = false;
|
bool autoClose = false;
|
||||||
bool insertClose = false;
|
bool insertClose = false;
|
||||||
int verbCnt = path.fVerbs.count();
|
int verbCnt = path.fPathRef->countVerbs();
|
||||||
while (*currVerb < verbCnt && (!allowPartial || !autoClose)) {
|
while (*currVerb < verbCnt && (!allowPartial || !autoClose)) {
|
||||||
uint8_t verb = insertClose ? (uint8_t) SkPath::kClose_Verb : path.fVerbs[*currVerb];
|
uint8_t verb = insertClose ? (uint8_t) SkPath::kClose_Verb : path.fPathRef->atVerb(*currVerb);
|
||||||
switch (verb) {
|
switch (verb) {
|
||||||
case SkPath::kClose_Verb:
|
case SkPath::kClose_Verb:
|
||||||
savePts = pts;
|
savePts = pts;
|
||||||
@ -3569,9 +3563,10 @@ bool SkPathPriv::IsRectContour(const SkPathView& path, bool allowPartial, int* c
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SkPathPriv::IsNestedFillRects(const SkPathView& path, SkRect rects[2], SkPathDirection dirs[2]) {
|
bool SkPathPriv::IsNestedFillRects(const SkPath& path, SkRect rects[2], SkPathDirection dirs[2]) {
|
||||||
|
SkDEBUGCODE(path.validate();)
|
||||||
int currVerb = 0;
|
int currVerb = 0;
|
||||||
const SkPoint* pts = path.fPoints.begin();
|
const SkPoint* pts = path.fPathRef->points();
|
||||||
SkPathDirection testDirs[2];
|
SkPathDirection testDirs[2];
|
||||||
SkRect testRects[2];
|
SkRect testRects[2];
|
||||||
if (!IsRectContour(path, true, &currVerb, &pts, nullptr, &testDirs[0], &testRects[0])) {
|
if (!IsRectContour(path, true, &currVerb, &pts, nullptr, &testDirs[0], &testRects[0])) {
|
||||||
@ -3706,7 +3701,7 @@ static SkPath clip(const SkPath& path, const SkHalfPlane& plane) {
|
|||||||
SkPoint fPrev = {0,0};
|
SkPoint fPrev = {0,0};
|
||||||
} rec;
|
} rec;
|
||||||
|
|
||||||
SkEdgeClipper::ClipPath(rotated.view(), clip, false,
|
SkEdgeClipper::ClipPath(rotated, clip, false,
|
||||||
[](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
|
[](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
|
||||||
Rec* rec = (Rec*)ctx;
|
Rec* rec = (Rec*)ctx;
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
#include "include/core/SkPathBuilder.h"
|
#include "include/core/SkPathBuilder.h"
|
||||||
#include "include/private/SkIDChangeListener.h"
|
#include "include/private/SkIDChangeListener.h"
|
||||||
#include "src/core/SkPathView.h"
|
|
||||||
|
|
||||||
static_assert(0 == static_cast<int>(SkPathFillType::kWinding), "fill_type_mismatch");
|
static_assert(0 == static_cast<int>(SkPathFillType::kWinding), "fill_type_mismatch");
|
||||||
static_assert(1 == static_cast<int>(SkPathFillType::kEvenOdd), "fill_type_mismatch");
|
static_assert(1 == static_cast<int>(SkPathFillType::kEvenOdd), "fill_type_mismatch");
|
||||||
@ -154,13 +153,6 @@ public:
|
|||||||
: path.fPathRef->verbsEnd(),
|
: path.fPathRef->verbsEnd(),
|
||||||
path.fPathRef->points(), path.fPathRef->conicWeights()) {
|
path.fPathRef->points(), path.fPathRef->conicWeights()) {
|
||||||
}
|
}
|
||||||
Iterate(const SkPathView& path)
|
|
||||||
: Iterate(path.fVerbs.begin(),
|
|
||||||
// Don't allow iteration through non-finite points.
|
|
||||||
(!path.isFinite()) ? path.fVerbs.begin()
|
|
||||||
: path.fVerbs.end(),
|
|
||||||
path.fPoints.begin(), path.fWeights.begin()) {
|
|
||||||
}
|
|
||||||
Iterate(const uint8_t* verbsBegin, const uint8_t* verbsEnd, const SkPoint* points,
|
Iterate(const uint8_t* verbsBegin, const uint8_t* verbsEnd, const SkPoint* points,
|
||||||
const SkScalar* weights)
|
const SkScalar* weights)
|
||||||
: fVerbsBegin(verbsBegin), fVerbsEnd(verbsEnd), fPoints(points), fWeights(weights) {
|
: fVerbsBegin(verbsBegin), fVerbsEnd(verbsEnd), fPoints(points), fWeights(weights) {
|
||||||
@ -339,7 +331,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsRectContour(const SkPathView&, bool allowPartial, int* currVerb,
|
static bool IsRectContour(const SkPath&, bool allowPartial, int* currVerb,
|
||||||
const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
|
const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
|
||||||
SkRect* rect);
|
SkRect* rect);
|
||||||
|
|
||||||
@ -354,14 +346,9 @@ public:
|
|||||||
@param dirs storage for SkPathDirection pair; may be nullptr
|
@param dirs storage for SkPathDirection pair; may be nullptr
|
||||||
@return true if SkPath contains nested SkRect pair
|
@return true if SkPath contains nested SkRect pair
|
||||||
*/
|
*/
|
||||||
static bool IsNestedFillRects(const SkPathView&, SkRect rect[2],
|
static bool IsNestedFillRects(const SkPath&, SkRect rect[2],
|
||||||
SkPathDirection dirs[2] = nullptr);
|
SkPathDirection dirs[2] = nullptr);
|
||||||
|
|
||||||
static bool IsNestedFillRects(const SkPath& path, SkRect rect[2],
|
|
||||||
SkPathDirection dirs[2] = nullptr) {
|
|
||||||
return IsNestedFillRects(path.view(), rect, dirs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IsInverseFillType(SkPathFillType fill) {
|
static bool IsInverseFillType(SkPathFillType fill) {
|
||||||
return (static_cast<int>(fill) & 2) != 0;
|
return (static_cast<int>(fill) & 2) != 0;
|
||||||
}
|
}
|
||||||
@ -444,8 +431,7 @@ class SkPathEdgeIter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SkPathEdgeIter(const SkPath&);
|
SkPathEdgeIter(const SkPath& path);
|
||||||
SkPathEdgeIter(const SkPathView&);
|
|
||||||
|
|
||||||
SkScalar conicWeight() const {
|
SkScalar conicWeight() const {
|
||||||
SkASSERT(fIsConic);
|
SkASSERT(fIsConic);
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include "include/private/SkTo.h"
|
#include "include/private/SkTo.h"
|
||||||
#include "src/core/SkBuffer.h"
|
#include "src/core/SkBuffer.h"
|
||||||
#include "src/core/SkPathPriv.h"
|
#include "src/core/SkPathPriv.h"
|
||||||
#include "src/core/SkPathView.h"
|
|
||||||
#include "src/core/SkSafeMath.h"
|
#include "src/core/SkSafeMath.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -684,21 +683,6 @@ bool SkPathRef::isValid() const {
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "src/core/SkPathView.h"
|
|
||||||
|
|
||||||
SkPathView SkPathRef::view(SkPathFillType ft, SkPathConvexity ct) const {
|
|
||||||
return {
|
|
||||||
{ fPoints.begin(), fPoints.size() },
|
|
||||||
{ fVerbs.begin(), fVerbs.size() },
|
|
||||||
{ fConicWeights.begin(), fConicWeights.size() },
|
|
||||||
ft,
|
|
||||||
ct,
|
|
||||||
this->getBounds(), // don't use fBounds, in case our bounds are dirty
|
|
||||||
fSegmentMask,
|
|
||||||
this->isFinite(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
SkPathEdgeIter::SkPathEdgeIter(const SkPath& path) {
|
SkPathEdgeIter::SkPathEdgeIter(const SkPath& path) {
|
||||||
fMoveToPtr = fPts = path.fPathRef->points();
|
fMoveToPtr = fPts = path.fPathRef->points();
|
||||||
fVerbs = path.fPathRef->verbsBegin();
|
fVerbs = path.fPathRef->verbsBegin();
|
||||||
@ -712,55 +696,3 @@ SkPathEdgeIter::SkPathEdgeIter(const SkPath& path) {
|
|||||||
fNextIsNewContour = false;
|
fNextIsNewContour = false;
|
||||||
SkDEBUGCODE(fIsConic = false;)
|
SkDEBUGCODE(fIsConic = false;)
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPathEdgeIter::SkPathEdgeIter(const SkPathView& path) {
|
|
||||||
fMoveToPtr = fPts = path.fPoints.cbegin();
|
|
||||||
fVerbs = path.fVerbs.cbegin();
|
|
||||||
fVerbsStop = path.fVerbs.cend();
|
|
||||||
fConicWeights = path.fWeights.cbegin();
|
|
||||||
if (fConicWeights) {
|
|
||||||
fConicWeights -= 1; // begin one behind
|
|
||||||
}
|
|
||||||
|
|
||||||
fNeedsCloseLine = false;
|
|
||||||
fNextIsNewContour = false;
|
|
||||||
SkDEBUGCODE(fIsConic = false;)
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SkPathView::isRect(SkRect* rect) const {
|
|
||||||
SkPathDirection direction;
|
|
||||||
bool isClosed;
|
|
||||||
|
|
||||||
int currVerb = 0;
|
|
||||||
const SkPoint* pts = fPoints.begin();
|
|
||||||
return SkPathPriv::IsRectContour(*this, false, &currVerb, &pts, &isClosed, &direction, rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SK_DEBUG
|
|
||||||
void SkPathView::validate() const {
|
|
||||||
bool finite = SkScalarsAreFinite((const SkScalar*)fPoints.begin(), fPoints.count() * 2)
|
|
||||||
&& SkScalarsAreFinite( fWeights.begin(), fWeights.count());
|
|
||||||
|
|
||||||
SkASSERT(fIsFinite == finite);
|
|
||||||
|
|
||||||
if (fIsFinite) {
|
|
||||||
SkRect bounds;
|
|
||||||
bounds.setBounds(fPoints.begin(), fPoints.count());
|
|
||||||
SkASSERT(bounds == fBounds);
|
|
||||||
} else {
|
|
||||||
SkASSERT(fBounds.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned mask = 0;
|
|
||||||
for (auto v : fVerbs) {
|
|
||||||
switch (static_cast<SkPathVerb>(v)) {
|
|
||||||
default: break;
|
|
||||||
case SkPathVerb::kLine: mask |= kLine_SkPathSegmentMask; break;
|
|
||||||
case SkPathVerb::kQuad: mask |= kQuad_SkPathSegmentMask; break;
|
|
||||||
case SkPathVerb::kConic: mask |= kConic_SkPathSegmentMask; break;
|
|
||||||
case SkPathVerb::kCubic: mask |= kCubic_SkPathSegmentMask; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SkASSERT(mask == fSegmentMask);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020 Google Inc.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license that can be
|
|
||||||
* found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "include/core/SkPathTypes.h"
|
|
||||||
#include "include/core/SkPoint.h"
|
|
||||||
#include "include/core/SkRect.h"
|
|
||||||
#include "include/private/SkPathRef.h"
|
|
||||||
#include "src/core/SkSpan.h"
|
|
||||||
|
|
||||||
struct SkPathView {
|
|
||||||
SkPathView(SkSpan<const SkPoint> points, SkSpan<const uint8_t> verbs, SkSpan<const float> weights,
|
|
||||||
SkPathFillType ft, SkPathConvexity ct, const SkRect& bounds, unsigned segmentMask,
|
|
||||||
bool isFinite)
|
|
||||||
: fPoints(points)
|
|
||||||
, fVerbs(verbs)
|
|
||||||
, fWeights(weights)
|
|
||||||
, fBounds(bounds)
|
|
||||||
, fFillType(ft)
|
|
||||||
, fConvexity(ct)
|
|
||||||
, fSegmentMask(segmentMask)
|
|
||||||
, fIsFinite(isFinite)
|
|
||||||
{
|
|
||||||
this->validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isInverseFillType() const { return SkPathFillType_IsInverse(fFillType); }
|
|
||||||
bool isConvex() const { return fConvexity == SkPathConvexity::kConvex; }
|
|
||||||
|
|
||||||
bool isEmpty() const { return fPoints.size() == 0; }
|
|
||||||
|
|
||||||
bool isRect(SkRect*) const;
|
|
||||||
bool isFinite() const { return fIsFinite; }
|
|
||||||
|
|
||||||
SkSpan<const SkPoint> fPoints;
|
|
||||||
SkSpan<const uint8_t> fVerbs;
|
|
||||||
SkSpan<const float> fWeights;
|
|
||||||
|
|
||||||
SkRect fBounds;
|
|
||||||
|
|
||||||
SkPathFillType fFillType;
|
|
||||||
SkPathConvexity fConvexity;
|
|
||||||
uint8_t fSegmentMask;
|
|
||||||
bool fIsFinite;
|
|
||||||
|
|
||||||
#ifdef SK_DEBUG
|
|
||||||
void validate() const;
|
|
||||||
#else
|
|
||||||
void validate() const {}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline SkPathView SkPathView_triangle(const SkPoint pts[3], const SkRect& bounds) {
|
|
||||||
static constexpr uint8_t verbs[] = {
|
|
||||||
(uint8_t)SkPathVerb::kMove,
|
|
||||||
(uint8_t)SkPathVerb::kLine,
|
|
||||||
(uint8_t)SkPathVerb::kLine,
|
|
||||||
};
|
|
||||||
return SkPathView({pts, 3}, SkSpan(verbs), {},
|
|
||||||
SkPathFillType::kWinding, SkPathConvexity::kConvex,
|
|
||||||
bounds, kLine_SkPathSegmentMask, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline SkPathView SkPathView_quad(const SkPoint pts[4], const SkRect& bounds) {
|
|
||||||
static constexpr uint8_t verbs[] = {
|
|
||||||
(uint8_t)SkPathVerb::kMove,
|
|
||||||
(uint8_t)SkPathVerb::kLine,
|
|
||||||
(uint8_t)SkPathVerb::kLine,
|
|
||||||
(uint8_t)SkPathVerb::kLine,
|
|
||||||
};
|
|
||||||
return SkPathView({pts, 4}, SkSpan(verbs), {},
|
|
||||||
SkPathFillType::kWinding, SkPathConvexity::kConvex,
|
|
||||||
bounds, kLine_SkPathSegmentMask, true);
|
|
||||||
};
|
|
@ -365,7 +365,7 @@ bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) {
|
|||||||
return this->setEmpty();
|
return this->setEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
SkScan::FillPath(path.view(), clip, &builder);
|
SkScan::FillPath(path, clip, &builder);
|
||||||
builder.done();
|
builder.done();
|
||||||
|
|
||||||
int count = builder.computeRunCount();
|
int count = builder.computeRunCount();
|
||||||
|
@ -11,13 +11,12 @@
|
|||||||
|
|
||||||
#include "include/core/SkRect.h"
|
#include "include/core/SkRect.h"
|
||||||
#include "include/private/SkFixed.h"
|
#include "include/private/SkFixed.h"
|
||||||
#include "src/core/SkPathView.h"
|
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
class SkRasterClip;
|
class SkRasterClip;
|
||||||
class SkRegion;
|
class SkRegion;
|
||||||
class SkBlitter;
|
class SkBlitter;
|
||||||
|
class SkPath;
|
||||||
|
|
||||||
/** Defines a fixed-point rectangle, identical to the integer SkIRect, but its
|
/** Defines a fixed-point rectangle, identical to the integer SkIRect, but its
|
||||||
coordinates are treated as SkFixed rather than int32_t.
|
coordinates are treated as SkFixed rather than int32_t.
|
||||||
@ -40,7 +39,7 @@ public:
|
|||||||
typedef void (*HairRgnProc)(const SkPoint[], int count, const SkRegion*, SkBlitter*);
|
typedef void (*HairRgnProc)(const SkPoint[], int count, const SkRegion*, SkBlitter*);
|
||||||
typedef void (*HairRCProc)(const SkPoint[], int count, const SkRasterClip&, SkBlitter*);
|
typedef void (*HairRCProc)(const SkPoint[], int count, const SkRasterClip&, SkBlitter*);
|
||||||
|
|
||||||
static void FillPath(const SkPathView&, const SkIRect&, SkBlitter*);
|
static void FillPath(const SkPath&, const SkIRect&, SkBlitter*);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// rasterclip
|
// rasterclip
|
||||||
@ -50,8 +49,8 @@ public:
|
|||||||
static void FillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
static void FillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
||||||
static void AntiFillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
static void AntiFillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
||||||
static void AntiFillXRect(const SkXRect&, const SkRasterClip&, SkBlitter*);
|
static void AntiFillXRect(const SkXRect&, const SkRasterClip&, SkBlitter*);
|
||||||
static void FillPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
static void FillPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||||
static void AntiFillPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
static void AntiFillPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||||
static void FrameRect(const SkRect&, const SkPoint& strokeSize,
|
static void FrameRect(const SkRect&, const SkPoint& strokeSize,
|
||||||
const SkRasterClip&, SkBlitter*);
|
const SkRasterClip&, SkBlitter*);
|
||||||
static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize,
|
static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize,
|
||||||
@ -61,15 +60,15 @@ public:
|
|||||||
static void AntiHairLine(const SkPoint[], int count, const SkRasterClip&, SkBlitter*);
|
static void AntiHairLine(const SkPoint[], int count, const SkRasterClip&, SkBlitter*);
|
||||||
static void HairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
static void HairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
||||||
static void AntiHairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
static void AntiHairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
||||||
static void HairPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
static void HairPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||||
static void AntiHairPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
static void AntiHairPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||||
static void HairSquarePath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
static void HairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||||
static void AntiHairSquarePath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
static void AntiHairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||||
static void HairRoundPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
static void HairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||||
static void AntiHairRoundPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
static void AntiHairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||||
|
|
||||||
// Needed by do_fill_path in SkScanPriv.h
|
// Needed by do_fill_path in SkScanPriv.h
|
||||||
static void FillPath(const SkPathView&, const SkRegion& clip, SkBlitter*);
|
static void FillPath(const SkPath&, const SkRegion& clip, SkBlitter*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class SkAAClip;
|
friend class SkAAClip;
|
||||||
@ -80,16 +79,16 @@ private:
|
|||||||
static void FillRect(const SkRect&, const SkRegion* clip, SkBlitter*);
|
static void FillRect(const SkRect&, const SkRegion* clip, SkBlitter*);
|
||||||
static void AntiFillRect(const SkRect&, const SkRegion* clip, SkBlitter*);
|
static void AntiFillRect(const SkRect&, const SkRegion* clip, SkBlitter*);
|
||||||
static void AntiFillXRect(const SkXRect&, const SkRegion*, SkBlitter*);
|
static void AntiFillXRect(const SkXRect&, const SkRegion*, SkBlitter*);
|
||||||
static void AntiFillPath(const SkPathView&, const SkRegion& clip, SkBlitter*, bool forceRLE);
|
static void AntiFillPath(const SkPath&, const SkRegion& clip, SkBlitter*, bool forceRLE);
|
||||||
static void FillTriangle(const SkPoint pts[], const SkRegion*, SkBlitter*);
|
static void FillTriangle(const SkPoint pts[], const SkRegion*, SkBlitter*);
|
||||||
|
|
||||||
static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize,
|
static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize,
|
||||||
const SkRegion*, SkBlitter*);
|
const SkRegion*, SkBlitter*);
|
||||||
static void HairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*);
|
static void HairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*);
|
||||||
static void AntiHairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*);
|
static void AntiHairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*);
|
||||||
static void AAAFillPath(const SkPathView& path, SkBlitter* blitter, const SkIRect& pathIR,
|
static void AAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect& pathIR,
|
||||||
const SkIRect& clipBounds, bool forceRLE);
|
const SkIRect& clipBounds, bool forceRLE);
|
||||||
static void SAAFillPath(const SkPathView& path, SkBlitter* blitter, const SkIRect& pathIR,
|
static void SAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect& pathIR,
|
||||||
const SkIRect& clipBounds, bool forceRLE);
|
const SkIRect& clipBounds, bool forceRLE);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ private:
|
|||||||
const SkIRect* fClipRect;
|
const SkIRect* fClipRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
void sk_fill_path(const SkPathView&, const SkIRect& clipRect,
|
void sk_fill_path(const SkPath& path, const SkIRect& clipRect,
|
||||||
SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
|
SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
|
||||||
bool pathContainedInClip);
|
bool pathContainedInClip);
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ static EdgeType* backward_insert_start(EdgeType* prev, SkFixed x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the path is a rect and fat enough after clipping; if so, blit it.
|
// Check if the path is a rect and fat enough after clipping; if so, blit it.
|
||||||
static inline bool TryBlitFatAntiRect(SkBlitter* blitter, const SkPathView& path, const SkIRect& clip) {
|
static inline bool TryBlitFatAntiRect(SkBlitter* blitter, const SkPath& path, const SkIRect& clip) {
|
||||||
SkRect rect;
|
SkRect rect;
|
||||||
if (!path.isRect(&rect)) {
|
if (!path.isRect(&rect)) {
|
||||||
return false; // not rect
|
return false; // not rect
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#if defined(SK_DISABLE_AAA)
|
#if defined(SK_DISABLE_AAA)
|
||||||
void SkScan::AAAFillPath(const SkPathView&, SkBlitter*, const SkIRect&, const SkIRect&, bool) {
|
void SkScan::AAAFillPath(const SkPath&, SkBlitter*, const SkIRect&, const SkIRect&, bool) {
|
||||||
SkDEBUGFAIL("AAA Disabled");
|
SkDEBUGFAIL("AAA Disabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1837,10 +1837,8 @@ static void aaa_walk_edges(SkAnalyticEdge* prevHead,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "src/core/SkPathView.h"
|
|
||||||
|
|
||||||
static SK_ALWAYS_INLINE void aaa_fill_path(
|
static SK_ALWAYS_INLINE void aaa_fill_path(
|
||||||
const SkPathView& path,
|
const SkPath& path,
|
||||||
const SkIRect& clipRect,
|
const SkIRect& clipRect,
|
||||||
AdditiveBlitter* blitter,
|
AdditiveBlitter* blitter,
|
||||||
int start_y,
|
int start_y,
|
||||||
@ -1916,7 +1914,7 @@ static SK_ALWAYS_INLINE void aaa_fill_path(
|
|||||||
// If we're using mask, then we have to limit the bound within the path bounds.
|
// If we're using mask, then we have to limit the bound within the path bounds.
|
||||||
// Otherwise, the edge drift may access an invalid address inside the mask.
|
// Otherwise, the edge drift may access an invalid address inside the mask.
|
||||||
SkIRect ir;
|
SkIRect ir;
|
||||||
path.fBounds.roundOut(&ir);
|
path.getBounds().roundOut(&ir);
|
||||||
leftBound = std::max(leftBound, SkIntToFixed(ir.fLeft));
|
leftBound = std::max(leftBound, SkIntToFixed(ir.fLeft));
|
||||||
rightBound = std::min(rightBound, SkIntToFixed(ir.fRight));
|
rightBound = std::min(rightBound, SkIntToFixed(ir.fRight));
|
||||||
}
|
}
|
||||||
@ -1932,11 +1930,11 @@ static SK_ALWAYS_INLINE void aaa_fill_path(
|
|||||||
|
|
||||||
// We skip intersection computation if there are many points which probably already
|
// We skip intersection computation if there are many points which probably already
|
||||||
// give us enough fractional scan lines.
|
// give us enough fractional scan lines.
|
||||||
bool skipIntersect = path.fPoints.count() > (stop_y - start_y) * 2;
|
bool skipIntersect = path.countPoints() > (stop_y - start_y) * 2;
|
||||||
|
|
||||||
aaa_walk_edges(&headEdge,
|
aaa_walk_edges(&headEdge,
|
||||||
&tailEdge,
|
&tailEdge,
|
||||||
path.fFillType,
|
path.getFillType(),
|
||||||
blitter,
|
blitter,
|
||||||
start_y,
|
start_y,
|
||||||
stop_y,
|
stop_y,
|
||||||
@ -1949,7 +1947,7 @@ static SK_ALWAYS_INLINE void aaa_fill_path(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::AAAFillPath(const SkPathView& path,
|
void SkScan::AAAFillPath(const SkPath& path,
|
||||||
SkBlitter* blitter,
|
SkBlitter* blitter,
|
||||||
const SkIRect& ir,
|
const SkIRect& ir,
|
||||||
const SkIRect& clipBounds,
|
const SkIRect& clipBounds,
|
||||||
|
@ -602,18 +602,18 @@ constexpr int kSampleSize = 8;
|
|||||||
constexpr SkScalar kComplexityThreshold = 0.25;
|
constexpr SkScalar kComplexityThreshold = 0.25;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void compute_complexity(const SkPathView& path, SkScalar& avgLength, SkScalar& complexity) {
|
static void compute_complexity(const SkPath& path, SkScalar& avgLength, SkScalar& complexity) {
|
||||||
int n = path.fPoints.count();
|
int n = path.countPoints();
|
||||||
if (n < kSampleSize || path.fBounds.isEmpty()) {
|
if (n < kSampleSize || path.getBounds().isEmpty()) {
|
||||||
// set to invalid value to indicate that we failed to compute
|
// set to invalid value to indicate that we failed to compute
|
||||||
avgLength = complexity = -1;
|
avgLength = complexity = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkScalar sumLength = 0;
|
SkScalar sumLength = 0;
|
||||||
SkPoint lastPoint = path.fPoints[0];
|
SkPoint lastPoint = path.getPoint(0);
|
||||||
for(int i = 1; i < kSampleSize; ++i) {
|
for(int i = 1; i < kSampleSize; ++i) {
|
||||||
SkPoint point = path.fPoints[i];
|
SkPoint point = path.getPoint(i);
|
||||||
sumLength += SkPoint::Distance(lastPoint, point);
|
sumLength += SkPoint::Distance(lastPoint, point);
|
||||||
lastPoint = point;
|
lastPoint = point;
|
||||||
}
|
}
|
||||||
@ -621,21 +621,21 @@ static void compute_complexity(const SkPathView& path, SkScalar& avgLength, SkSc
|
|||||||
|
|
||||||
auto sqr = [](SkScalar x) { return x*x; };
|
auto sqr = [](SkScalar x) { return x*x; };
|
||||||
|
|
||||||
SkScalar diagonalSqr = sqr(path.fBounds.width()) + sqr(path.fBounds.height());
|
SkScalar diagonalSqr = sqr(path.getBounds().width()) + sqr(path.getBounds().height());
|
||||||
|
|
||||||
// If the path consists of random line segments, the number of intersections should be
|
// If the path consists of random line segments, the number of intersections should be
|
||||||
// proportional to this.
|
// proportional to this.
|
||||||
SkScalar intersections = sk_ieee_float_divide(sqr(n) * sqr(avgLength), diagonalSqr);
|
SkScalar intersections = sk_ieee_float_divide(sqr(n) * sqr(avgLength), diagonalSqr);
|
||||||
|
|
||||||
// The number of intersections per scanline should be proportional to this number.
|
// The number of intersections per scanline should be proportional to this number.
|
||||||
complexity = sk_ieee_float_divide(intersections, path.fBounds.height());
|
complexity = sk_ieee_float_divide(intersections, path.getBounds().height());
|
||||||
|
|
||||||
if (sk_float_isnan(complexity)) { // it may be possible to have 0.0 / 0.0; inf is fine for us.
|
if (sk_float_isnan(complexity)) { // it may be possible to have 0.0 / 0.0; inf is fine for us.
|
||||||
complexity = -1;
|
complexity = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar complexity) {
|
static bool ShouldUseAAA(const SkPath& path, SkScalar avgLength, SkScalar complexity) {
|
||||||
#if defined(SK_DISABLE_AAA)
|
#if defined(SK_DISABLE_AAA)
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
@ -650,16 +650,16 @@ static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar co
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SK_SUPPORT_LEGACY_AAA_CHOICE
|
#ifdef SK_SUPPORT_LEGACY_AAA_CHOICE
|
||||||
const SkRect& bounds = path.fBounds;
|
const SkRect& bounds = path.getBounds();
|
||||||
// When the path have so many points compared to the size of its
|
// When the path have so many points compared to the size of its
|
||||||
// bounds/resolution, it indicates that the path is not quite smooth in
|
// bounds/resolution, it indicates that the path is not quite smooth in
|
||||||
// the current resolution: the expected number of turning points in
|
// the current resolution: the expected number of turning points in
|
||||||
// every pixel row/column is significantly greater than zero. Hence
|
// every pixel row/column is significantly greater than zero. Hence
|
||||||
// Aanlytic AA is not likely to produce visible quality improvements,
|
// Aanlytic AA is not likely to produce visible quality improvements,
|
||||||
// and Analytic AA might be slower than supersampling.
|
// and Analytic AA might be slower than supersampling.
|
||||||
return path.fPoints.count() < std::max(bounds.width(), bounds.height()) / 2 - 10;
|
return path.countPoints() < std::max(bounds.width(), bounds.height()) / 2 - 10;
|
||||||
#else
|
#else
|
||||||
if (path.fPoints.count() >= path.fBounds.height()) {
|
if (path.countPoints() >= path.getBounds().height()) {
|
||||||
// SAA is faster than AAA in this case even if there are no
|
// SAA is faster than AAA in this case even if there are no
|
||||||
// intersections because AAA will have too many scan lines. See
|
// intersections because AAA will have too many scan lines. See
|
||||||
// skbug.com/8272
|
// skbug.com/8272
|
||||||
@ -671,7 +671,7 @@ static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar co
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::SAAFillPath(const SkPathView& path, SkBlitter* blitter, const SkIRect& ir,
|
void SkScan::SAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect& ir,
|
||||||
const SkIRect& clipBounds, bool forceRLE) {
|
const SkIRect& clipBounds, bool forceRLE) {
|
||||||
bool containedInClip = clipBounds.contains(ir);
|
bool containedInClip = clipBounds.contains(ir);
|
||||||
bool isInverse = path.isInverseFillType();
|
bool isInverse = path.isInverseFillType();
|
||||||
@ -680,7 +680,7 @@ void SkScan::SAAFillPath(const SkPathView& path, SkBlitter* blitter, const SkIRe
|
|||||||
// if we're an inverse filltype
|
// if we're an inverse filltype
|
||||||
if (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) {
|
if (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) {
|
||||||
MaskSuperBlitter superBlit(blitter, ir, clipBounds, isInverse);
|
MaskSuperBlitter superBlit(blitter, ir, clipBounds, isInverse);
|
||||||
SkASSERT(SkIntToScalar(ir.fTop) <= path.fBounds.fTop);
|
SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
|
||||||
sk_fill_path(path, clipBounds, &superBlit, ir.fTop, ir.fBottom, SHIFT, containedInClip);
|
sk_fill_path(path, clipBounds, &superBlit, ir.fTop, ir.fBottom, SHIFT, containedInClip);
|
||||||
} else {
|
} else {
|
||||||
SuperBlitter superBlit(blitter, ir, clipBounds, isInverse);
|
SuperBlitter superBlit(blitter, ir, clipBounds, isInverse);
|
||||||
@ -711,14 +711,14 @@ static int rect_overflows_short_shift(SkIRect rect, int shift) {
|
|||||||
overflows_short_shift(rect.fBottom, shift);
|
overflows_short_shift(rect.fBottom, shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::AntiFillPath(const SkPathView& path, const SkRegion& origClip,
|
void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
|
||||||
SkBlitter* blitter, bool forceRLE) {
|
SkBlitter* blitter, bool forceRLE) {
|
||||||
if (origClip.isEmpty()) {
|
if (origClip.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isInverse = path.isInverseFillType();
|
const bool isInverse = path.isInverseFillType();
|
||||||
SkIRect ir = safeRoundOut(path.fBounds);
|
SkIRect ir = safeRoundOut(path.getBounds());
|
||||||
if (ir.isEmpty()) {
|
if (ir.isEmpty()) {
|
||||||
if (isInverse) {
|
if (isInverse) {
|
||||||
blitter->blitRegion(origClip);
|
blitter->blitRegion(origClip);
|
||||||
@ -802,7 +802,7 @@ void SkScan::AntiFillPath(const SkPathView& path, const SkRegion& origClip,
|
|||||||
|
|
||||||
#include "src/core/SkRasterClip.h"
|
#include "src/core/SkRasterClip.h"
|
||||||
|
|
||||||
void SkScan::FillPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
void SkScan::FillPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
||||||
if (clip.isEmpty() || !path.isFinite()) {
|
if (clip.isEmpty() || !path.isFinite()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -819,7 +819,7 @@ void SkScan::FillPath(const SkPathView& path, const SkRasterClip& clip, SkBlitte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::AntiFillPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
void SkScan::AntiFillPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
||||||
if (clip.isEmpty() || !path.isFinite()) {
|
if (clip.isEmpty() || !path.isFinite()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -507,7 +507,7 @@ void extend_pts(SkPath::Verb prevVerb, SkPath::Verb nextVerb, SkPoint* pts, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <SkPaint::Cap capStyle>
|
template <SkPaint::Cap capStyle>
|
||||||
void hair_path(const SkPathView& path, const SkRasterClip& rclip, SkBlitter* blitter,
|
void hair_path(const SkPath& path, const SkRasterClip& rclip, SkBlitter* blitter,
|
||||||
SkScan::HairRgnProc lineproc) {
|
SkScan::HairRgnProc lineproc) {
|
||||||
if (path.isEmpty()) {
|
if (path.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@ -521,7 +521,7 @@ void hair_path(const SkPathView& path, const SkRasterClip& rclip, SkBlitter* bli
|
|||||||
|
|
||||||
{
|
{
|
||||||
const int capOut = SkPaint::kButt_Cap == capStyle ? 1 : 2;
|
const int capOut = SkPaint::kButt_Cap == capStyle ? 1 : 2;
|
||||||
const SkIRect ibounds = path.fBounds.roundOut().makeOutset(capOut, capOut);
|
const SkIRect ibounds = path.getBounds().roundOut().makeOutset(capOut, capOut);
|
||||||
if (rclip.quickReject(ibounds)) {
|
if (rclip.quickReject(ibounds)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -643,27 +643,27 @@ void hair_path(const SkPathView& path, const SkRasterClip& rclip, SkBlitter* bli
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::HairPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
void SkScan::HairPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
||||||
hair_path<SkPaint::kButt_Cap>(path, clip, blitter, SkScan::HairLineRgn);
|
hair_path<SkPaint::kButt_Cap>(path, clip, blitter, SkScan::HairLineRgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::AntiHairPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
void SkScan::AntiHairPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
||||||
hair_path<SkPaint::kButt_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn);
|
hair_path<SkPaint::kButt_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::HairSquarePath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
void SkScan::HairSquarePath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
||||||
hair_path<SkPaint::kSquare_Cap>(path, clip, blitter, SkScan::HairLineRgn);
|
hair_path<SkPaint::kSquare_Cap>(path, clip, blitter, SkScan::HairLineRgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::AntiHairSquarePath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
void SkScan::AntiHairSquarePath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
||||||
hair_path<SkPaint::kSquare_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn);
|
hair_path<SkPaint::kSquare_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::HairRoundPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
void SkScan::HairRoundPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
||||||
hair_path<SkPaint::kRound_Cap>(path, clip, blitter, SkScan::HairLineRgn);
|
hair_path<SkPaint::kRound_Cap>(path, clip, blitter, SkScan::HairLineRgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::AntiHairRoundPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
void SkScan::AntiHairRoundPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
|
||||||
hair_path<SkPaint::kRound_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn);
|
hair_path<SkPaint::kRound_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,10 +391,8 @@ static SkEdge* sort_edges(SkEdge* list[], int count, SkEdge** last) {
|
|||||||
return list[0];
|
return list[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "src/core/SkPathView.h"
|
|
||||||
|
|
||||||
// clipRect has not been shifted up
|
// clipRect has not been shifted up
|
||||||
void sk_fill_path(const SkPathView& path, const SkIRect& clipRect, SkBlitter* blitter,
|
void sk_fill_path(const SkPath& path, const SkIRect& clipRect, SkBlitter* blitter,
|
||||||
int start_y, int stop_y, int shiftEdgesUp, bool pathContainedInClip) {
|
int start_y, int stop_y, int shiftEdgesUp, bool pathContainedInClip) {
|
||||||
SkASSERT(blitter);
|
SkASSERT(blitter);
|
||||||
|
|
||||||
@ -472,7 +470,8 @@ void sk_fill_path(const SkPathView& path, const SkIRect& clipRect, SkBlitter* bl
|
|||||||
if (path.isConvex() && (nullptr == proc) && count >= 2) {
|
if (path.isConvex() && (nullptr == proc) && count >= 2) {
|
||||||
walk_simple_edges(&headEdge, blitter, start_y, stop_y);
|
walk_simple_edges(&headEdge, blitter, start_y, stop_y);
|
||||||
} else {
|
} else {
|
||||||
walk_edges(&headEdge, path.fFillType, blitter, start_y, stop_y, proc, shiftedClip.right());
|
walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc,
|
||||||
|
shiftedClip.right());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,7 +613,8 @@ static SkIRect conservative_round_to_int(const SkRect& src) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::FillPath(const SkPathView& path, const SkRegion& origClip, SkBlitter* blitter) {
|
void SkScan::FillPath(const SkPath& path, const SkRegion& origClip,
|
||||||
|
SkBlitter* blitter) {
|
||||||
if (origClip.isEmpty()) {
|
if (origClip.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -632,7 +632,7 @@ void SkScan::FillPath(const SkPathView& path, const SkRegion& origClip, SkBlitte
|
|||||||
// don't reference "origClip" any more, just use clipPtr
|
// don't reference "origClip" any more, just use clipPtr
|
||||||
|
|
||||||
|
|
||||||
SkRect bounds = path.fBounds;
|
SkRect bounds = path.getBounds();
|
||||||
bool irPreClipped = false;
|
bool irPreClipped = false;
|
||||||
if (!SkRectPriv::MakeLargeS32().contains(bounds)) {
|
if (!SkRectPriv::MakeLargeS32().contains(bounds)) {
|
||||||
if (!bounds.intersect(SkRectPriv::MakeLargeS32())) {
|
if (!bounds.intersect(SkRectPriv::MakeLargeS32())) {
|
||||||
@ -670,7 +670,7 @@ void SkScan::FillPath(const SkPathView& path, const SkRegion& origClip, SkBlitte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::FillPath(const SkPathView& path, const SkIRect& ir,
|
void SkScan::FillPath(const SkPath& path, const SkIRect& ir,
|
||||||
SkBlitter* blitter) {
|
SkBlitter* blitter) {
|
||||||
SkRegion rgn(ir);
|
SkRegion rgn(ir);
|
||||||
FillPath(path, rgn, blitter);
|
FillPath(path, rgn, blitter);
|
||||||
@ -737,7 +737,8 @@ static void sk_fill_triangle(const SkPoint pts[], const SkIRect* clipRect,
|
|||||||
walk_simple_edges(&headEdge, blitter, start_y, stop_y);
|
walk_simple_edges(&headEdge, blitter, start_y, stop_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip, SkBlitter* blitter) {
|
void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip,
|
||||||
|
SkBlitter* blitter) {
|
||||||
if (clip.isEmpty()) {
|
if (clip.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -749,7 +750,9 @@ void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip, SkBlitt
|
|||||||
// Use FixedMax/2 as the limit so we can subtract two edges and still store that in Fixed.
|
// Use FixedMax/2 as the limit so we can subtract two edges and still store that in Fixed.
|
||||||
const SkScalar limit = SK_MaxS16 >> 1;
|
const SkScalar limit = SK_MaxS16 >> 1;
|
||||||
if (!SkRect::MakeLTRB(-limit, -limit, limit, limit).contains(r)) {
|
if (!SkRect::MakeLTRB(-limit, -limit, limit, limit).contains(r)) {
|
||||||
FillPath(SkPathView_triangle(pts, r), clip, blitter);
|
SkPath path;
|
||||||
|
path.addPoly(pts, 3, false);
|
||||||
|
FillPath(path, clip, blitter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ DEF_TEST(FillPathInverse, reporter) {
|
|||||||
SkIntToScalar(width), 0.0f)
|
SkIntToScalar(width), 0.0f)
|
||||||
.close()
|
.close()
|
||||||
.setFillType(SkPathFillType::kInverseWinding);
|
.setFillType(SkPathFillType::kInverseWinding);
|
||||||
SkScan::FillPath(path.view(), clip, &blitter);
|
SkScan::FillPath(path, clip, &blitter);
|
||||||
|
|
||||||
REPORTER_ASSERT(reporter, blitter.m_blitCount == expected_lines);
|
REPORTER_ASSERT(reporter, blitter.m_blitCount == expected_lines);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "src/core/SkAutoMalloc.h"
|
#include "src/core/SkAutoMalloc.h"
|
||||||
#include "src/core/SkGeometry.h"
|
#include "src/core/SkGeometry.h"
|
||||||
#include "src/core/SkPathPriv.h"
|
#include "src/core/SkPathPriv.h"
|
||||||
#include "src/core/SkPathView.h"
|
|
||||||
#include "src/core/SkReadBuffer.h"
|
#include "src/core/SkReadBuffer.h"
|
||||||
#include "src/core/SkWriteBuffer.h"
|
#include "src/core/SkWriteBuffer.h"
|
||||||
#include "tests/Test.h"
|
#include "tests/Test.h"
|
||||||
@ -5658,18 +5657,12 @@ static void test_edger(skiatest::Reporter* r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkPathEdgeIter iter(path);
|
SkPathEdgeIter iter(path);
|
||||||
SkPathEdgeIter iter2(path.view());
|
|
||||||
for (auto v : expected) {
|
for (auto v : expected) {
|
||||||
auto e = iter.next();
|
auto e = iter.next();
|
||||||
REPORTER_ASSERT(r, e);
|
REPORTER_ASSERT(r, e);
|
||||||
REPORTER_ASSERT(r, SkPathEdgeIter::EdgeToVerb(e.fEdge) == v);
|
REPORTER_ASSERT(r, SkPathEdgeIter::EdgeToVerb(e.fEdge) == v);
|
||||||
|
|
||||||
e = iter2.next();
|
|
||||||
REPORTER_ASSERT(r, e);
|
|
||||||
REPORTER_ASSERT(r, SkPathEdgeIter::EdgeToVerb(e.fEdge) == v);
|
|
||||||
}
|
}
|
||||||
REPORTER_ASSERT(r, !iter.next());
|
REPORTER_ASSERT(r, !iter.next());
|
||||||
REPORTER_ASSERT(r, !iter2.next());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_TEST(pathedger, r) {
|
DEF_TEST(pathedger, r) {
|
||||||
|
Loading…
Reference in New Issue
Block a user