21 return bounds.fTop >=
clip.fBottom || bounds.fBottom <=
clip.fTop;
42 if (src[0].fY > src[
count - 1].fY) {
43 for (
int i = 0; i <
count; i++) {
44 dst[i] = src[
count - i - 1];
58 const SkPoint pts[] = { p0, p1 };
60 for (
int i = 0; i < lineCount; i++) {
61 this->appendLine(lines[i], lines[i + 1]);
105 if (pts[0].fY <
clip.fTop) {
118 for (
int i = 0; i < 3; i++) {
119 if (pts[i].fY <
clip.fTop) {
127 if (pts[2].fY >
clip.fBottom) {
139 for (
int i = 0; i < 3; i++) {
140 if (pts[i].fY >
clip.fBottom) {
154 if (pts[2].fY <=
clip.fTop || pts[0].fY >=
clip.fBottom) {
161 if (pts[0].fX > pts[2].fX) {
163 swap(pts[0], pts[2]);
171 if (pts[2].fX <=
clip.fLeft) {
172 this->appendVLine(
clip.fLeft, pts[0].fY, pts[2].fY, reverse);
175 if (pts[0].fX >=
clip.fRight) {
177 this->appendVLine(
clip.fRight, pts[0].fY, pts[2].fY, reverse);
186 if (pts[0].fX <
clip.fLeft) {
189 this->appendVLine(
clip.fLeft, tmp[0].fY, tmp[2].fY, reverse);
199 this->appendVLine(
clip.fLeft, pts[0].fY, pts[2].fY, reverse);
205 if (pts[2].fX >
clip.fRight) {
212 this->appendQuad(tmp, reverse);
213 this->appendVLine(
clip.fRight, tmp[2].fY, tmp[4].fY, reverse);
217 pts[1].
fX = std::min(pts[1].fX,
clip.fRight);
218 pts[2].
fX = std::min(pts[2].fX,
clip.fRight);
219 this->appendQuad(pts, reverse);
222 this->appendQuad(pts, reverse);
227 fCurrPoint = fPoints;
231 bounds.setBounds(srcPts, 3);
236 for (
int y = 0;
y <= countY;
y++) {
239 for (
int x = 0;
x <= countX;
x++) {
240 this->clipMonoQuad(&monoX[
x * 2],
clip);
241 SkASSERT(fCurrVerb - fVerbs < kMaxVerbs);
242 SkASSERT(fCurrPoint - fPoints <= kMaxPoints);
248 fCurrPoint = fPoints;
261 SkScalar A = src[6] + 3*(src[2] - src[4]) -
D;
262 SkScalar B = 3*(src[4] - src[2] - src[2] +
D);
269 if (closest > dist) {
276 }
while (closest > 0.25f && lastT != t);
291 if (pts[0].fY <
clip.fTop) {
305 if (tmp[3].fY <
clip.fTop && tmp[4].
fY <
clip.fTop && tmp[5].
fY <
clip.fTop) {
307 memcpy(tmp2, &tmp[3].fX, 4 *
sizeof(
SkPoint));
322 if (pts[3].fY >
clip.fBottom) {
347 if (pts[3].fY <=
clip.fTop || pts[0].fY >=
clip.fBottom) {
354 if (pts[0].fX > pts[3].fX) {
356 swap(pts[0], pts[3]);
357 swap(pts[1], pts[2]);
363 if (pts[3].fX <=
clip.fLeft) {
364 this->appendVLine(
clip.fLeft, pts[0].fY, pts[3].fY, reverse);
367 if (pts[0].fX >=
clip.fRight) {
369 this->appendVLine(
clip.fRight, pts[0].fY, pts[3].fY, reverse);
375 if (pts[0].fX <
clip.fLeft) {
378 this->appendVLine(
clip.fLeft, tmp[0].fY, tmp[3].fY, reverse);
392 if (pts[3].fX >
clip.fRight) {
398 this->appendCubic(tmp, reverse);
399 this->appendVLine(
clip.fRight, tmp[3].fY, tmp[6].fY, reverse);
401 this->appendCubic(pts, reverse);
423 fCurrPoint = fPoints;
428 if (bounds.fBottom >
clip.fTop && bounds.fTop <
clip.fBottom) {
440 for (
int y = 0;
y <= countY;
y++) {
443 for (
int x = 0;
x <= countX;
x++) {
444 this->clipMonoCubic(&monoX[
x * 3],
clip);
445 SkASSERT(fCurrVerb - fVerbs < kMaxVerbs);
446 SkASSERT(fCurrPoint - fPoints <= kMaxPoints);
453 fCurrPoint = fPoints;
474 fCurrPoint[0].
set(
x, y0);
475 fCurrPoint[1].
set(
x, y1);
479void SkEdgeClipper::appendQuad(
const SkPoint pts[3],
bool reverse) {
483 fCurrPoint[0] = pts[2];
484 fCurrPoint[2] = pts[0];
486 fCurrPoint[0] = pts[0];
487 fCurrPoint[2] = pts[2];
489 fCurrPoint[1] = pts[1];
493void SkEdgeClipper::appendCubic(
const SkPoint pts[4],
bool reverse) {
497 for (
int i = 0; i < 4; i++) {
498 fCurrPoint[i] = pts[3 - i];
501 memcpy(fCurrPoint, pts, 4 *
sizeof(
SkPoint));
511 memcpy(pts, fCurrPoint, 2 *
sizeof(
SkPoint));
516 memcpy(pts, fCurrPoint, 3 *
sizeof(
SkPoint));
521 memcpy(pts, fCurrPoint, 4 *
sizeof(
SkPoint));
528 SkDEBUGFAIL(
"unexpected verb in quadclippper2 iter");
537static void assert_monotonic(
const SkScalar coord[],
int count) {
538 if (coord[0] > coord[(
count - 1) * 2]) {
539 for (
int i = 1; i <
count; i++) {
540 SkASSERT(coord[2 * (i - 1)] >= coord[i * 2]);
542 }
else if (coord[0] < coord[(
count - 1) * 2]) {
543 for (
int i = 1; i <
count; i++) {
544 SkASSERT(coord[2 * (i - 1)] <= coord[i * 2]);
547 for (
int i = 1; i <
count; i++) {
548 SkASSERT(coord[2 * (i - 1)] == coord[i * 2]);
555 assert_monotonic(&pts[0].fY,
count);
561 assert_monotonic(&pts[0].fX,
count);
567 void (*consume)(
SkEdgeClipper*,
bool newCtr,
void* ctx),
void* ctx) {
576 while (
auto e = iter.
next()) {
578 case SkPathEdgeIter::Edge::kLine:
580 consume(&clipper, e.fIsNewContour, ctx);
583 case SkPathEdgeIter::Edge::kQuad:
585 consume(&clipper, e.fIsNewContour, ctx);
588 case SkPathEdgeIter::Edge::kConic: {
590 for (
int i = 0; i < quadder.
countQuads(); ++i) {
592 consume(&clipper, e.fIsNewContour, ctx);
597 case SkPathEdgeIter::Edge::kCubic:
599 consume(&clipper, e.fIsNewContour, ctx);
static int step(int x, SkScalar min, SkScalar max)
#define SkDEBUGFAIL(message)
static void clamp_le(SkScalar &value, SkScalar max)
static bool chopMonoQuadAtY(SkPoint pts[3], SkScalar y, SkScalar *t)
static bool chopMonoQuadAt(SkScalar c0, SkScalar c1, SkScalar c2, SkScalar target, SkScalar *t)
static void chop_mono_cubic_at_x(SkPoint src[4], SkScalar x, SkPoint dst[7])
static bool too_big_for_reliable_float_math(const SkRect &r)
static void chop_mono_cubic_at_y(SkPoint src[4], SkScalar y, SkPoint dst[7])
static bool quick_reject(const SkRect &bounds, const SkRect &clip)
static void chop_quad_in_Y(SkPoint pts[3], const SkRect &clip)
static void chop_cubic_in_Y(SkPoint pts[4], const SkRect &clip)
static SkScalar mono_cubic_closestT(const SkScalar src[], SkScalar x)
static void clamp_ge(SkScalar &value, SkScalar min)
static bool sort_increasing_Y(SkPoint dst[], const SkPoint src[], int count)
static SkRect compute_cubic_bounds(const SkPoint pts[4])
static bool chopMonoQuadAtX(SkPoint pts[3], SkScalar x, SkScalar *t)
#define sk_assert_monotonic_y(pts, count)
#define sk_assert_monotonic_x(pts, count)
void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t)
int SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5])
int SkChopCubicAtYExtrema(const SkPoint src[4], SkPoint dst[10])
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t)
int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2])
bool SkChopMonoCubicAtY(const SkPoint src[4], SkScalar y, SkPoint dst[7])
int SkChopCubicAtXExtrema(const SkPoint src[4], SkPoint dst[10])
bool SkChopMonoCubicAtX(const SkPoint src[4], SkScalar x, SkPoint dst[7])
int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5])
#define SK_INIT_TO_AVOID_WARNING
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
void swap(sk_sp< T > &a, sk_sp< T > &b)
const SkPoint * computeQuads(const SkConic &conic, SkScalar tol)
bool canCullToTheRight() const
static void ClipPath(const SkPath &path, const SkRect &clip, bool canCullToTheRight, void(*consume)(SkEdgeClipper *, bool newCtr, void *ctx), void *ctx)
SkPath::Verb next(SkPoint pts[])
bool clipCubic(const SkPoint pts[4], const SkRect &clip)
bool clipLine(SkPoint p0, SkPoint p1, const SkRect &clip)
bool clipQuad(const SkPoint pts[3], const SkRect &clip)
static int ClipLine(const SkPoint pts[2], const SkRect &clip, SkPoint lines[kMaxPoints], bool canCullToTheRight)
SkScalar conicWeight() const
static float max(float r, float g, float b)
static float min(float r, float g, float b)
void set(float x, float y)
SkScalar fBottom
larger y-axis bounds
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
void setBounds(const SkPoint pts[], int count)
SkScalar fTop
smaller y-axis bounds