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 SkData;
|
||||
class SkRRect;
|
||||
struct SkPathView;
|
||||
class SkWStream;
|
||||
|
||||
// WIP -- define this locally, and fix call-sites to use SkPathBuilder (skbug.com/9000)
|
||||
@ -1540,8 +1539,6 @@ public:
|
||||
Verb autoClose(SkPoint pts[2]);
|
||||
};
|
||||
|
||||
SkPathView view() const;
|
||||
|
||||
private:
|
||||
/** \class SkPath::RangeIter
|
||||
Iterates through a raw range of path verbs, points, and conics. All values are returned
|
||||
|
@ -9,7 +9,6 @@
|
||||
#define SkPathRef_DEFINED
|
||||
|
||||
#include "include/core/SkMatrix.h"
|
||||
#include "include/core/SkPathTypes.h"
|
||||
#include "include/core/SkPoint.h"
|
||||
#include "include/core/SkRRect.h"
|
||||
#include "include/core/SkRect.h"
|
||||
@ -24,7 +23,6 @@
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
|
||||
struct SkPathView;
|
||||
class SkRBuffer;
|
||||
class SkWBuffer;
|
||||
|
||||
@ -352,8 +350,6 @@ public:
|
||||
bool isValid() const;
|
||||
SkDEBUGCODE(void validate() const { SkASSERT(this->isValid()); } )
|
||||
|
||||
SkPathView view(SkPathFillType, SkPathConvexity) const;
|
||||
|
||||
private:
|
||||
enum SerializationOffsets {
|
||||
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};
|
||||
} rec;
|
||||
|
||||
SkEdgeClipper::ClipPath(rotated.view(), clip, false,
|
||||
SkEdgeClipper::ClipPath(rotated, clip, false,
|
||||
[](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
|
||||
Rec* rec = (Rec*)ctx;
|
||||
|
||||
|
@ -1334,12 +1334,11 @@ bool SkAAClip::setPath(const SkPath& path, const SkRegion* clip, bool doAA) {
|
||||
|
||||
Builder builder(ibounds);
|
||||
BuilderBlitter blitter(&builder);
|
||||
const SkPathView view = path.view();
|
||||
|
||||
if (doAA) {
|
||||
SkScan::AntiFillPath(view, snugClip, &blitter, true);
|
||||
SkScan::AntiFillPath(path, snugClip, &blitter, true);
|
||||
} else {
|
||||
SkScan::FillPath(view, snugClip, &blitter);
|
||||
SkScan::FillPath(path, snugClip, &blitter);
|
||||
}
|
||||
|
||||
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 (paint.isAntiAlias()) {
|
||||
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,
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "src/core/SkScan.h"
|
||||
|
||||
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()) {
|
||||
SkRect dr;
|
||||
ctm.mapRect(&dr, r);
|
||||
@ -32,10 +32,9 @@ static void fill_rect(const SkMatrix& ctm, const SkRasterClip& rc,
|
||||
r.toQuad(pts);
|
||||
ctm.mapPoints(pts, pts, 4);
|
||||
|
||||
SkRect bounds;
|
||||
bounds.setBounds(pts, 4);
|
||||
|
||||
SkScan::FillPath(SkPathView_quad(pts, bounds), rc, blitter);
|
||||
scratchPath->rewind();
|
||||
scratchPath->addPoly(pts, 4, true);
|
||||
SkScan::FillPath(*scratchPath, 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,
|
||||
fRC->clipShader())) {
|
||||
SkPath scratchPath;
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (colors) {
|
||||
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());
|
||||
|
||||
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/SkLineClipper.h"
|
||||
#include "src/core/SkPathPriv.h"
|
||||
#include "src/core/SkPathView.h"
|
||||
#include "src/core/SkSafeMath.h"
|
||||
|
||||
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?
|
||||
int SkEdgeBuilder::buildPoly(const SkPathView& path, const SkIRect* iclip, bool canCullToTheRight) {
|
||||
size_t maxEdgeCount = path.fPoints.size();
|
||||
int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, bool canCullToTheRight) {
|
||||
size_t maxEdgeCount = path.countPoints();
|
||||
if (iclip) {
|
||||
// clipping can turn 1 line into (up to) kMaxClippedLineSegments, since
|
||||
// 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);
|
||||
}
|
||||
|
||||
int SkEdgeBuilder::build(const SkPathView& path, const SkIRect* iclip, bool canCullToTheRight) {
|
||||
int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, bool canCullToTheRight) {
|
||||
SkAutoConicToQuads quadder;
|
||||
const SkScalar conicTol = SK_Scalar1 / 4;
|
||||
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;
|
||||
}
|
||||
|
||||
int SkEdgeBuilder::buildEdges(const SkPathView& path,
|
||||
int SkEdgeBuilder::buildEdges(const SkPath& path,
|
||||
const SkIRect* shiftedClip) {
|
||||
// If we're convex, then we need both edges, even if the right edge is past the clip.
|
||||
const bool canCullToTheRight = !path.isConvex();
|
||||
|
||||
// We can use our buildPoly() optimization if all the segments are lines.
|
||||
// (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->build (path, shiftedClip, canCullToTheRight);
|
||||
|
||||
|
@ -13,11 +13,12 @@
|
||||
#include "src/core/SkArenaAlloc.h"
|
||||
#include "src/core/SkEdge.h"
|
||||
|
||||
struct SkPathView;
|
||||
class SkPath;
|
||||
|
||||
class SkEdgeBuilder {
|
||||
public:
|
||||
int buildEdges(const SkPathView&, const SkIRect* shiftedClip);
|
||||
int buildEdges(const SkPath& path,
|
||||
const SkIRect* shiftedClip);
|
||||
|
||||
protected:
|
||||
SkEdgeBuilder() = default;
|
||||
@ -36,8 +37,8 @@ protected:
|
||||
};
|
||||
|
||||
private:
|
||||
int build (const SkPathView&, const SkIRect* clip, bool clipToTheRight);
|
||||
int buildPoly(const SkPathView&, const SkIRect* clip, bool clipToTheRight);
|
||||
int build (const SkPath& path, 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 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"
|
||||
|
||||
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) {
|
||||
SkASSERT(view.isFinite());
|
||||
SkASSERT(path.isFinite());
|
||||
|
||||
SkAutoConicToQuads quadder;
|
||||
const SkScalar conicTol = SK_Scalar1 / 4;
|
||||
|
||||
SkPathEdgeIter iter(view);
|
||||
SkPathEdgeIter iter(path);
|
||||
SkEdgeClipper clipper(canCullToTheRight);
|
||||
|
||||
while (auto e = iter.next()) {
|
||||
|
@ -10,7 +10,6 @@
|
||||
#define SkEdgeClipper_DEFINED
|
||||
|
||||
#include "include/core/SkPath.h"
|
||||
#include "src/core/SkPathView.h"
|
||||
|
||||
/** This is basically an iterator. It is initialized with an edge and a clip,
|
||||
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
|
||||
* 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);
|
||||
|
||||
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 {
|
||||
// need the same structure (verbs, conicweights) and same point-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();)
|
||||
int currVerb = 0;
|
||||
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 {
|
||||
@ -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,
|
||||
SkRect* rect) {
|
||||
int corners = 0;
|
||||
@ -3445,9 +3439,9 @@ bool SkPathPriv::IsRectContour(const SkPathView& path, bool allowPartial, int* c
|
||||
bool closedOrMoved = false;
|
||||
bool autoClose = false;
|
||||
bool insertClose = false;
|
||||
int verbCnt = path.fVerbs.count();
|
||||
int verbCnt = path.fPathRef->countVerbs();
|
||||
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) {
|
||||
case SkPath::kClose_Verb:
|
||||
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;
|
||||
const SkPoint* pts = path.fPoints.begin();
|
||||
const SkPoint* pts = path.fPathRef->points();
|
||||
SkPathDirection testDirs[2];
|
||||
SkRect testRects[2];
|
||||
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};
|
||||
} rec;
|
||||
|
||||
SkEdgeClipper::ClipPath(rotated.view(), clip, false,
|
||||
SkEdgeClipper::ClipPath(rotated, clip, false,
|
||||
[](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
|
||||
Rec* rec = (Rec*)ctx;
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "include/core/SkPathBuilder.h"
|
||||
#include "include/private/SkIDChangeListener.h"
|
||||
#include "src/core/SkPathView.h"
|
||||
|
||||
static_assert(0 == static_cast<int>(SkPathFillType::kWinding), "fill_type_mismatch");
|
||||
static_assert(1 == static_cast<int>(SkPathFillType::kEvenOdd), "fill_type_mismatch");
|
||||
@ -154,13 +153,6 @@ public:
|
||||
: path.fPathRef->verbsEnd(),
|
||||
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,
|
||||
const SkScalar* weights)
|
||||
: fVerbsBegin(verbsBegin), fVerbsEnd(verbsEnd), fPoints(points), fWeights(weights) {
|
||||
@ -339,7 +331,7 @@ public:
|
||||
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,
|
||||
SkRect* rect);
|
||||
|
||||
@ -354,14 +346,9 @@ public:
|
||||
@param dirs storage for SkPathDirection pair; may be nullptr
|
||||
@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);
|
||||
|
||||
static bool IsNestedFillRects(const SkPath& path, SkRect rect[2],
|
||||
SkPathDirection dirs[2] = nullptr) {
|
||||
return IsNestedFillRects(path.view(), rect, dirs);
|
||||
}
|
||||
|
||||
static bool IsInverseFillType(SkPathFillType fill) {
|
||||
return (static_cast<int>(fill) & 2) != 0;
|
||||
}
|
||||
@ -444,8 +431,7 @@ class SkPathEdgeIter {
|
||||
};
|
||||
|
||||
public:
|
||||
SkPathEdgeIter(const SkPath&);
|
||||
SkPathEdgeIter(const SkPathView&);
|
||||
SkPathEdgeIter(const SkPath& path);
|
||||
|
||||
SkScalar conicWeight() const {
|
||||
SkASSERT(fIsConic);
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "include/private/SkTo.h"
|
||||
#include "src/core/SkBuffer.h"
|
||||
#include "src/core/SkPathPriv.h"
|
||||
#include "src/core/SkPathView.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) {
|
||||
fMoveToPtr = fPts = path.fPathRef->points();
|
||||
fVerbs = path.fPathRef->verbsBegin();
|
||||
@ -712,55 +696,3 @@ SkPathEdgeIter::SkPathEdgeIter(const SkPath& path) {
|
||||
fNextIsNewContour = 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();
|
||||
}
|
||||
|
||||
SkScan::FillPath(path.view(), clip, &builder);
|
||||
SkScan::FillPath(path, clip, &builder);
|
||||
builder.done();
|
||||
|
||||
int count = builder.computeRunCount();
|
||||
|
@ -11,13 +11,12 @@
|
||||
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/private/SkFixed.h"
|
||||
#include "src/core/SkPathView.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
class SkRasterClip;
|
||||
class SkRegion;
|
||||
class SkBlitter;
|
||||
class SkPath;
|
||||
|
||||
/** Defines a fixed-point rectangle, identical to the integer SkIRect, but its
|
||||
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 (*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
|
||||
@ -50,8 +49,8 @@ public:
|
||||
static void FillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiFillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiFillXRect(const SkXRect&, const SkRasterClip&, SkBlitter*);
|
||||
static void FillPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiFillPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
||||
static void FillPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiFillPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||
static void FrameRect(const SkRect&, const SkPoint& strokeSize,
|
||||
const SkRasterClip&, SkBlitter*);
|
||||
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 HairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiHairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
|
||||
static void HairPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiHairPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
||||
static void HairSquarePath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiHairSquarePath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
||||
static void HairRoundPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiHairRoundPath(const SkPathView&, const SkRasterClip&, SkBlitter*);
|
||||
static void HairPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiHairPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||
static void HairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiHairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||
static void HairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||
static void AntiHairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*);
|
||||
|
||||
// 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:
|
||||
friend class SkAAClip;
|
||||
@ -80,16 +79,16 @@ private:
|
||||
static void FillRect(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 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 AntiFrameRect(const SkRect&, const SkPoint& strokeSize,
|
||||
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 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);
|
||||
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);
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,7 @@ private:
|
||||
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,
|
||||
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.
|
||||
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;
|
||||
if (!path.isRect(&rect)) {
|
||||
return false; // not rect
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <utility>
|
||||
|
||||
#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");
|
||||
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(
|
||||
const SkPathView& path,
|
||||
const SkPath& path,
|
||||
const SkIRect& clipRect,
|
||||
AdditiveBlitter* blitter,
|
||||
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.
|
||||
// Otherwise, the edge drift may access an invalid address inside the mask.
|
||||
SkIRect ir;
|
||||
path.fBounds.roundOut(&ir);
|
||||
path.getBounds().roundOut(&ir);
|
||||
leftBound = std::max(leftBound, SkIntToFixed(ir.fLeft));
|
||||
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
|
||||
// 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,
|
||||
&tailEdge,
|
||||
path.fFillType,
|
||||
path.getFillType(),
|
||||
blitter,
|
||||
start_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,
|
||||
const SkIRect& ir,
|
||||
const SkIRect& clipBounds,
|
||||
|
@ -602,18 +602,18 @@ constexpr int kSampleSize = 8;
|
||||
constexpr SkScalar kComplexityThreshold = 0.25;
|
||||
#endif
|
||||
|
||||
static void compute_complexity(const SkPathView& path, SkScalar& avgLength, SkScalar& complexity) {
|
||||
int n = path.fPoints.count();
|
||||
if (n < kSampleSize || path.fBounds.isEmpty()) {
|
||||
static void compute_complexity(const SkPath& path, SkScalar& avgLength, SkScalar& complexity) {
|
||||
int n = path.countPoints();
|
||||
if (n < kSampleSize || path.getBounds().isEmpty()) {
|
||||
// set to invalid value to indicate that we failed to compute
|
||||
avgLength = complexity = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
SkScalar sumLength = 0;
|
||||
SkPoint lastPoint = path.fPoints[0];
|
||||
SkPoint lastPoint = path.getPoint(0);
|
||||
for(int i = 1; i < kSampleSize; ++i) {
|
||||
SkPoint point = path.fPoints[i];
|
||||
SkPoint point = path.getPoint(i);
|
||||
sumLength += SkPoint::Distance(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; };
|
||||
|
||||
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
|
||||
// proportional to this.
|
||||
SkScalar intersections = sk_ieee_float_divide(sqr(n) * sqr(avgLength), diagonalSqr);
|
||||
|
||||
// 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.
|
||||
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)
|
||||
return false;
|
||||
#else
|
||||
@ -650,16 +650,16 @@ static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar co
|
||||
}
|
||||
|
||||
#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
|
||||
// bounds/resolution, it indicates that the path is not quite smooth in
|
||||
// the current resolution: the expected number of turning points in
|
||||
// every pixel row/column is significantly greater than zero. Hence
|
||||
// Aanlytic AA is not likely to produce visible quality improvements,
|
||||
// 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
|
||||
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
|
||||
// intersections because AAA will have too many scan lines. See
|
||||
// skbug.com/8272
|
||||
@ -671,7 +671,7 @@ static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar co
|
||||
#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) {
|
||||
bool containedInClip = clipBounds.contains(ir);
|
||||
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 (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) {
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
void SkScan::AntiFillPath(const SkPathView& path, const SkRegion& origClip,
|
||||
void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
|
||||
SkBlitter* blitter, bool forceRLE) {
|
||||
if (origClip.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isInverse = path.isInverseFillType();
|
||||
SkIRect ir = safeRoundOut(path.fBounds);
|
||||
SkIRect ir = safeRoundOut(path.getBounds());
|
||||
if (ir.isEmpty()) {
|
||||
if (isInverse) {
|
||||
blitter->blitRegion(origClip);
|
||||
@ -802,7 +802,7 @@ void SkScan::AntiFillPath(const SkPathView& path, const SkRegion& origClip,
|
||||
|
||||
#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()) {
|
||||
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()) {
|
||||
return;
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ void extend_pts(SkPath::Verb prevVerb, SkPath::Verb nextVerb, SkPoint* pts, int
|
||||
}
|
||||
|
||||
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) {
|
||||
if (path.isEmpty()) {
|
||||
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 SkIRect ibounds = path.fBounds.roundOut().makeOutset(capOut, capOut);
|
||||
const SkIRect ibounds = path.getBounds().roundOut().makeOutset(capOut, capOut);
|
||||
if (rclip.quickReject(ibounds)) {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -391,10 +391,8 @@ static SkEdge* sort_edges(SkEdge* list[], int count, SkEdge** last) {
|
||||
return list[0];
|
||||
}
|
||||
|
||||
#include "src/core/SkPathView.h"
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
walk_simple_edges(&headEdge, blitter, start_y, stop_y);
|
||||
} 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()) {
|
||||
return;
|
||||
}
|
||||
@ -632,7 +632,7 @@ void SkScan::FillPath(const SkPathView& path, const SkRegion& origClip, SkBlitte
|
||||
// don't reference "origClip" any more, just use clipPtr
|
||||
|
||||
|
||||
SkRect bounds = path.fBounds;
|
||||
SkRect bounds = path.getBounds();
|
||||
bool irPreClipped = false;
|
||||
if (!SkRectPriv::MakeLargeS32().contains(bounds)) {
|
||||
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) {
|
||||
SkRegion rgn(ir);
|
||||
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);
|
||||
}
|
||||
|
||||
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()) {
|
||||
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.
|
||||
const SkScalar limit = SK_MaxS16 >> 1;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ DEF_TEST(FillPathInverse, reporter) {
|
||||
SkIntToScalar(width), 0.0f)
|
||||
.close()
|
||||
.setFillType(SkPathFillType::kInverseWinding);
|
||||
SkScan::FillPath(path.view(), clip, &blitter);
|
||||
SkScan::FillPath(path, clip, &blitter);
|
||||
|
||||
REPORTER_ASSERT(reporter, blitter.m_blitCount == expected_lines);
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "src/core/SkAutoMalloc.h"
|
||||
#include "src/core/SkGeometry.h"
|
||||
#include "src/core/SkPathPriv.h"
|
||||
#include "src/core/SkPathView.h"
|
||||
#include "src/core/SkReadBuffer.h"
|
||||
#include "src/core/SkWriteBuffer.h"
|
||||
#include "tests/Test.h"
|
||||
@ -5658,18 +5657,12 @@ static void test_edger(skiatest::Reporter* r,
|
||||
}
|
||||
|
||||
SkPathEdgeIter iter(path);
|
||||
SkPathEdgeIter iter2(path.view());
|
||||
for (auto v : expected) {
|
||||
auto e = iter.next();
|
||||
REPORTER_ASSERT(r, e);
|
||||
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, !iter2.next());
|
||||
}
|
||||
|
||||
DEF_TEST(pathedger, r) {
|
||||
|
Loading…
Reference in New Issue
Block a user