return this from maker calls, so we can chain the calls
Bug: skia: Change-Id: Id62eda9dab9399ce1183a959438db7dde59889d8 Reviewed-on: https://skia-review.googlesource.com/147113 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
parent
31a0944bb3
commit
b631742f0b
@ -14,10 +14,10 @@ namespace {
|
||||
void test_concave(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
canvas->translate(0, 0);
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(30), SkIntToScalar(30));
|
||||
path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(80), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(30), SkIntToScalar(30))
|
||||
.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
canvas->drawPath(path, paint);
|
||||
}
|
||||
|
||||
@ -26,10 +26,10 @@ void test_reverse_concave(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
canvas->save();
|
||||
canvas->translate(100, 0);
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
path.lineTo(SkIntToScalar(30), SkIntToScalar(30));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(20), SkIntToScalar(80))
|
||||
.lineTo(SkIntToScalar(30), SkIntToScalar(30))
|
||||
.lineTo(SkIntToScalar(80), SkIntToScalar(20));
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->restore();
|
||||
}
|
||||
@ -39,10 +39,10 @@ void test_bowtie(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
canvas->save();
|
||||
canvas->translate(200, 0);
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(80), SkIntToScalar(80))
|
||||
.lineTo(SkIntToScalar(80), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->restore();
|
||||
}
|
||||
@ -52,12 +52,12 @@ void test_fake_bowtie(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
canvas->save();
|
||||
canvas->translate(300, 0);
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(50), SkIntToScalar(40));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
|
||||
path.lineTo(SkIntToScalar(50), SkIntToScalar(60));
|
||||
path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(50), SkIntToScalar(40))
|
||||
.lineTo(SkIntToScalar(80), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(80), SkIntToScalar(80))
|
||||
.lineTo(SkIntToScalar(50), SkIntToScalar(60))
|
||||
.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->restore();
|
||||
}
|
||||
@ -69,12 +69,12 @@ void test_intruding_vertex(SkCanvas* canvas, const SkPaint& paint) {
|
||||
canvas->save();
|
||||
canvas->translate(400, 0);
|
||||
path.setIsVolatile(true);
|
||||
path.moveTo(20, 20);
|
||||
path.lineTo(50, 50);
|
||||
path.lineTo(68, 20);
|
||||
path.lineTo(68, 80);
|
||||
path.lineTo(50, 50);
|
||||
path.lineTo(20, 80);
|
||||
path.moveTo(20, 20)
|
||||
.lineTo(50, 50)
|
||||
.lineTo(68, 20)
|
||||
.lineTo(68, 80)
|
||||
.lineTo(50, 50)
|
||||
.lineTo(20, 80);
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->restore();
|
||||
}
|
||||
@ -86,12 +86,12 @@ void test_inversion_repeat_vertex(SkCanvas* canvas, const SkPaint& paint) {
|
||||
canvas->save();
|
||||
canvas->translate(400, 100);
|
||||
path.setIsVolatile(true);
|
||||
path.moveTo(80, 50);
|
||||
path.lineTo(40, 80);
|
||||
path.lineTo(60, 20);
|
||||
path.lineTo(20, 20);
|
||||
path.lineTo(39.99f, 80);
|
||||
path.lineTo(80, 50);
|
||||
path.moveTo(80, 50)
|
||||
.lineTo(40, 80)
|
||||
.lineTo(60, 20)
|
||||
.lineTo(20, 20)
|
||||
.lineTo(39.99f, 80)
|
||||
.lineTo(80, 50);
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->restore();
|
||||
}
|
||||
@ -101,12 +101,12 @@ void test_fish(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
canvas->save();
|
||||
canvas->translate(0, 100);
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
|
||||
path.lineTo(SkIntToScalar(70), SkIntToScalar(50));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
path.lineTo(SkIntToScalar(0), SkIntToScalar(50));
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(80), SkIntToScalar(80))
|
||||
.lineTo(SkIntToScalar(70), SkIntToScalar(50))
|
||||
.lineTo(SkIntToScalar(80), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(20), SkIntToScalar(80))
|
||||
.lineTo(SkIntToScalar(0), SkIntToScalar(50));
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->restore();
|
||||
}
|
||||
@ -117,12 +117,12 @@ void test_fast_forward(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
canvas->save();
|
||||
canvas->translate(100, 100);
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(60), SkIntToScalar(50));
|
||||
path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
path.moveTo(SkIntToScalar(40), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(40), SkIntToScalar(80));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(50));
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(60), SkIntToScalar(50))
|
||||
.lineTo(SkIntToScalar(20), SkIntToScalar(80))
|
||||
.moveTo(SkIntToScalar(40), SkIntToScalar(20))
|
||||
.lineTo(SkIntToScalar(40), SkIntToScalar(80))
|
||||
.lineTo(SkIntToScalar(80), SkIntToScalar(50));
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->restore();
|
||||
}
|
||||
@ -132,30 +132,18 @@ void test_hole(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
canvas->save();
|
||||
canvas->translate(200, 100);
|
||||
path.moveTo(SkIntToScalar(20), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(20));
|
||||
path.lineTo(SkIntToScalar(80), SkIntToScalar(80));
|
||||
path.lineTo(SkIntToScalar(20), SkIntToScalar(80));
|
||||
path.moveTo(SkIntToScalar(30), SkIntToScalar(30));
|
||||
path.lineTo(SkIntToScalar(30), SkIntToScalar(70));
|
||||
path.lineTo(SkIntToScalar(70), SkIntToScalar(70));
|
||||
path.lineTo(SkIntToScalar(70), SkIntToScalar(30));
|
||||
path.addPoly({{20,20}, {80,20}, {80,80}, {20,80}}, false)
|
||||
.addPoly({{30,30}, {30,70}, {70,70}, {70,30}}, false);
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
// Star test (self-intersecting)
|
||||
void test_star(SkCanvas* canvas, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
canvas->save();
|
||||
canvas->translate(300, 100);
|
||||
path.moveTo(30, 20);
|
||||
path.lineTo(50, 80);
|
||||
path.lineTo(70, 20);
|
||||
path.lineTo(20, 57);
|
||||
path.lineTo(80, 57);
|
||||
path.close();
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->drawPath(SkPath().addPoly({{30,20}, {50,80}, {70,20}, {20,57}, {80,57}}, false),
|
||||
paint);
|
||||
canvas->restore();
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "SkMatrix.h"
|
||||
#include "../private/SkPathRef.h"
|
||||
#include "../private/SkTo.h"
|
||||
#include <initializer_list>
|
||||
|
||||
class SkAutoPathBoundsUpdate;
|
||||
class SkData;
|
||||
@ -301,7 +302,7 @@ public:
|
||||
Removes verb array, SkPoint array, and weights, and sets FillType to kWinding_FillType.
|
||||
Internal storage associated with SkPath is released.
|
||||
*/
|
||||
void reset();
|
||||
SkPath& reset();
|
||||
|
||||
/** Sets SkPath to its initial state, preserving internal storage.
|
||||
Removes verb array, SkPoint array, and weights, and sets FillType to kWinding_FillType.
|
||||
@ -310,7 +311,7 @@ public:
|
||||
Use rewind() instead of reset() if SkPath storage will be reused and performance
|
||||
is critical.
|
||||
*/
|
||||
void rewind();
|
||||
SkPath& rewind();
|
||||
|
||||
/** Returns if SkPath is empty.
|
||||
Empty SkPath may have FillType but has no SkPoint, SkPath::Verb, or conic weight.
|
||||
@ -548,15 +549,16 @@ public:
|
||||
|
||||
@param x x-axis value of contour start
|
||||
@param y y-axis value of contour start
|
||||
@return this path
|
||||
*/
|
||||
void moveTo(SkScalar x, SkScalar y);
|
||||
SkPath& moveTo(SkScalar x, SkScalar y);
|
||||
|
||||
/** Adds beginning of contour at SkPoint p.
|
||||
|
||||
@param p contour start
|
||||
*/
|
||||
void moveTo(const SkPoint& p) {
|
||||
this->moveTo(p.fX, p.fY);
|
||||
SkPath& moveTo(const SkPoint& p) {
|
||||
return this->moveTo(p.fX, p.fY);
|
||||
}
|
||||
|
||||
/** Adds beginning of contour relative to last point.
|
||||
@ -567,7 +569,7 @@ public:
|
||||
@param dx offset from last point to contour start on x-axis
|
||||
@param dy offset from last point to contour start on y-axis
|
||||
*/
|
||||
void rMoveTo(SkScalar dx, SkScalar dy);
|
||||
SkPath& rMoveTo(SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Adds line from last point to (x, y). If SkPath is empty, or last SkPath::Verb is
|
||||
kClose_Verb, last point is set to (0, 0) before adding line.
|
||||
@ -578,7 +580,7 @@ public:
|
||||
@param x end of added line in x
|
||||
@param y end of added line in y
|
||||
*/
|
||||
void lineTo(SkScalar x, SkScalar y);
|
||||
SkPath& lineTo(SkScalar x, SkScalar y);
|
||||
|
||||
/** Adds line from last point to SkPoint p. If SkPath is empty, or last SkPath::Verb is
|
||||
kClose_Verb, last point is set to (0, 0) before adding line.
|
||||
@ -588,8 +590,8 @@ public:
|
||||
|
||||
@param p end SkPoint of added line
|
||||
*/
|
||||
void lineTo(const SkPoint& p) {
|
||||
this->lineTo(p.fX, p.fY);
|
||||
SkPath& lineTo(const SkPoint& p) {
|
||||
return this->lineTo(p.fX, p.fY);
|
||||
}
|
||||
|
||||
/** Adds line from last point to vector (dx, dy). If SkPath is empty, or last SkPath::Verb is
|
||||
@ -603,7 +605,7 @@ public:
|
||||
@param dx offset from last point to line end on x-axis
|
||||
@param dy offset from last point to line end on y-axis
|
||||
*/
|
||||
void rLineTo(SkScalar dx, SkScalar dy);
|
||||
SkPath& rLineTo(SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Adds quad from last point towards (x1, y1), to (x2, y2).
|
||||
If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to (0, 0)
|
||||
@ -618,7 +620,7 @@ public:
|
||||
@param x2 end SkPoint of quad in x
|
||||
@param y2 end SkPoint of quad in y
|
||||
*/
|
||||
void quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
|
||||
SkPath& quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
|
||||
|
||||
/** Adds quad from last point towards SkPoint p1, to SkPoint p2.
|
||||
If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to (0, 0)
|
||||
@ -631,8 +633,8 @@ public:
|
||||
@param p1 control SkPoint of added quad
|
||||
@param p2 end SkPoint of added quad
|
||||
*/
|
||||
void quadTo(const SkPoint& p1, const SkPoint& p2) {
|
||||
this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
|
||||
SkPath& quadTo(const SkPoint& p1, const SkPoint& p2) {
|
||||
return this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
|
||||
}
|
||||
|
||||
/** Adds quad from last point towards vector (dx1, dy1), to vector (dx2, dy2).
|
||||
@ -651,7 +653,7 @@ public:
|
||||
@param dx2 offset from last point to quad end on x-axis
|
||||
@param dy2 offset from last point to quad end on y-axis
|
||||
*/
|
||||
void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
|
||||
SkPath& rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
|
||||
|
||||
/** Adds conic from last point towards (x1, y1), to (x2, y2), weighted by w.
|
||||
If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to (0, 0)
|
||||
@ -674,8 +676,8 @@ public:
|
||||
@param y2 end SkPoint of conic in y
|
||||
@param w weight of added conic
|
||||
*/
|
||||
void conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar w);
|
||||
SkPath& conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar w);
|
||||
|
||||
/** Adds conic from last point towards SkPoint p1, to SkPoint p2, weighted by w.
|
||||
If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to (0, 0)
|
||||
@ -696,8 +698,8 @@ public:
|
||||
@param p2 end SkPoint of added conic
|
||||
@param w weight of added conic
|
||||
*/
|
||||
void conicTo(const SkPoint& p1, const SkPoint& p2, SkScalar w) {
|
||||
this->conicTo(p1.fX, p1.fY, p2.fX, p2.fY, w);
|
||||
SkPath& conicTo(const SkPoint& p1, const SkPoint& p2, SkScalar w) {
|
||||
return this->conicTo(p1.fX, p1.fY, p2.fX, p2.fY, w);
|
||||
}
|
||||
|
||||
/** Adds conic from last point towards vector (dx1, dy1), to vector (dx2, dy2),
|
||||
@ -724,8 +726,8 @@ public:
|
||||
@param dy2 offset from last point to conic end on y-axis
|
||||
@param w weight of added conic
|
||||
*/
|
||||
void rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
|
||||
SkScalar w);
|
||||
SkPath& rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
|
||||
SkScalar w);
|
||||
|
||||
/** Adds cubic from last point towards (x1, y1), then towards (x2, y2), ending at
|
||||
(x3, y3). If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to
|
||||
@ -742,8 +744,8 @@ public:
|
||||
@param x3 end SkPoint of cubic in x
|
||||
@param y3 end SkPoint of cubic in y
|
||||
*/
|
||||
void cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3);
|
||||
SkPath& cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3);
|
||||
|
||||
/** Adds cubic from last point towards SkPoint p1, then towards SkPoint p2, ending at
|
||||
SkPoint p3. If SkPath is empty, or last SkPath::Verb is kClose_Verb, last point is set to
|
||||
@ -757,8 +759,8 @@ public:
|
||||
@param p2 second control SkPoint of cubic
|
||||
@param p3 end SkPoint of cubic
|
||||
*/
|
||||
void cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) {
|
||||
this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
|
||||
SkPath& cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) {
|
||||
return this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
|
||||
}
|
||||
|
||||
/** Adds cubic from last point towards vector (dx1, dy1), then towards
|
||||
@ -780,8 +782,8 @@ public:
|
||||
@param x3 offset from last point to cubic end on x-axis
|
||||
@param y3 offset from last point to cubic end on y-axis
|
||||
*/
|
||||
void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3);
|
||||
SkPath& rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3);
|
||||
|
||||
/** Appends arc to SkPath. Arc added is part of ellipse
|
||||
bounded by oval, from startAngle through sweepAngle. Both startAngle and
|
||||
@ -797,7 +799,7 @@ public:
|
||||
@param sweepAngle sweep, in degrees. Positive is clockwise; treated modulo 360
|
||||
@param forceMoveTo true to start a new contour with arc
|
||||
*/
|
||||
void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo);
|
||||
SkPath& arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo);
|
||||
|
||||
/** Appends arc to SkPath, after appending line if needed. Arc is implemented by conic
|
||||
weighted to describe part of circle. Arc is contained by tangent from
|
||||
@ -810,7 +812,7 @@ public:
|
||||
@param y2 y-axis value end of second tangent
|
||||
@param radius distance from arc to circle center
|
||||
*/
|
||||
void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius);
|
||||
SkPath& arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius);
|
||||
|
||||
/** Appends arc to SkPath, after appending line if needed. Arc is implemented by conic
|
||||
weighted to describe part of circle. Arc is contained by tangent from
|
||||
@ -830,8 +832,8 @@ public:
|
||||
@param p2 end of second tangent
|
||||
@param radius distance from arc to circle center
|
||||
*/
|
||||
void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) {
|
||||
this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius);
|
||||
SkPath& arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) {
|
||||
return this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius);
|
||||
}
|
||||
|
||||
/** \enum SkPath::ArcSize
|
||||
@ -866,8 +868,8 @@ public:
|
||||
@param x end of arc
|
||||
@param y end of arc
|
||||
*/
|
||||
void arcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
|
||||
Direction sweep, SkScalar x, SkScalar y);
|
||||
SkPath& arcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
|
||||
Direction sweep, SkScalar x, SkScalar y);
|
||||
|
||||
/** Appends arc to SkPath. Arc is implemented by one or more conic weighted to describe part of oval
|
||||
with radii (r.fX, r.fY) rotated by xAxisRotate degrees. Arc curves from last SkPath SkPoint to
|
||||
@ -889,9 +891,9 @@ public:
|
||||
@param sweep chooses clockwise or counterclockwise arc
|
||||
@param xy end of arc
|
||||
*/
|
||||
void arcTo(const SkPoint r, SkScalar xAxisRotate, ArcSize largeArc, Direction sweep,
|
||||
SkPath& arcTo(const SkPoint r, SkScalar xAxisRotate, ArcSize largeArc, Direction sweep,
|
||||
const SkPoint xy) {
|
||||
this->arcTo(r.fX, r.fY, xAxisRotate, largeArc, sweep, xy.fX, xy.fY);
|
||||
return this->arcTo(r.fX, r.fY, xAxisRotate, largeArc, sweep, xy.fX, xy.fY);
|
||||
}
|
||||
|
||||
/** Appends arc to SkPath, relative to last SkPath SkPoint. Arc is implemented by one or
|
||||
@ -919,8 +921,8 @@ public:
|
||||
@param dx x-axis offset end of arc from last SkPath SkPoint
|
||||
@param dy y-axis offset end of arc from last SkPath SkPoint
|
||||
*/
|
||||
void rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
|
||||
Direction sweep, SkScalar dx, SkScalar dy);
|
||||
SkPath& rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
|
||||
Direction sweep, SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Appends kClose_Verb to SkPath. A closed contour connects the first and last SkPoint
|
||||
with line, forming a continuous loop. Open and closed contour draw the same
|
||||
@ -930,7 +932,7 @@ public:
|
||||
|
||||
close() has no effect if SkPath is empty or last SkPath SkPath::Verb is kClose_Verb.
|
||||
*/
|
||||
void close();
|
||||
SkPath& close();
|
||||
|
||||
/** Returns true if fill is inverted and SkPath with fill represents area outside
|
||||
of its geometric bounds.
|
||||
@ -1025,7 +1027,7 @@ public:
|
||||
@param rect SkRect to add as a closed contour
|
||||
@param dir SkPath::Direction to wind added contour
|
||||
*/
|
||||
void addRect(const SkRect& rect, Direction dir = kCW_Direction);
|
||||
SkPath& addRect(const SkRect& rect, Direction dir = kCW_Direction);
|
||||
|
||||
/** Adds SkRect to SkPath, appending kMove_Verb, three kLine_Verb, and kClose_Verb.
|
||||
If dir is kCW_Direction, SkRect corners are added clockwise; if dir is
|
||||
@ -1036,7 +1038,7 @@ public:
|
||||
@param dir SkPath::Direction to wind added contour
|
||||
@param start initial corner of SkRect to add
|
||||
*/
|
||||
void addRect(const SkRect& rect, Direction dir, unsigned start);
|
||||
SkPath& addRect(const SkRect& rect, Direction dir, unsigned start);
|
||||
|
||||
/** Adds SkRect (left, top, right, bottom) to SkPath,
|
||||
appending kMove_Verb, three kLine_Verb, and kClose_Verb,
|
||||
@ -1050,8 +1052,8 @@ public:
|
||||
@param bottom larger y-axis value of SkRect
|
||||
@param dir SkPath::Direction to wind added contour
|
||||
*/
|
||||
void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
|
||||
Direction dir = kCW_Direction);
|
||||
SkPath& addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/** Adds oval to path, appending kMove_Verb, four kConic_Verb, and kClose_Verb.
|
||||
Oval is upright ellipse bounded by SkRect oval with radii equal to half oval width
|
||||
@ -1061,7 +1063,7 @@ public:
|
||||
@param oval bounds of ellipse added
|
||||
@param dir SkPath::Direction to wind ellipse
|
||||
*/
|
||||
void addOval(const SkRect& oval, Direction dir = kCW_Direction);
|
||||
SkPath& addOval(const SkRect& oval, Direction dir = kCW_Direction);
|
||||
|
||||
/** Adds oval to SkPath, appending kMove_Verb, four kConic_Verb, and kClose_Verb.
|
||||
Oval is upright ellipse bounded by SkRect oval with radii equal to half oval width
|
||||
@ -1072,7 +1074,7 @@ public:
|
||||
@param dir SkPath::Direction to wind ellipse
|
||||
@param start index of initial point of ellipse
|
||||
*/
|
||||
void addOval(const SkRect& oval, Direction dir, unsigned start);
|
||||
SkPath& addOval(const SkRect& oval, Direction dir, unsigned start);
|
||||
|
||||
/** Adds circle centered at (x, y) of size radius to SkPath, appending kMove_Verb,
|
||||
four kConic_Verb, and kClose_Verb. Circle begins at: (x + radius, y), continuing
|
||||
@ -1085,8 +1087,8 @@ public:
|
||||
@param radius distance from center to edge
|
||||
@param dir SkPath::Direction to wind circle
|
||||
*/
|
||||
void addCircle(SkScalar x, SkScalar y, SkScalar radius,
|
||||
Direction dir = kCW_Direction);
|
||||
SkPath& addCircle(SkScalar x, SkScalar y, SkScalar radius,
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/** Appends arc to SkPath, as the start of new contour. Arc added is part of ellipse
|
||||
bounded by oval, from startAngle through sweepAngle. Both startAngle and
|
||||
@ -1101,7 +1103,7 @@ public:
|
||||
@param startAngle starting angle of arc in degrees
|
||||
@param sweepAngle sweep, in degrees. Positive is clockwise; treated modulo 360
|
||||
*/
|
||||
void addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
|
||||
SkPath& addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
|
||||
|
||||
/** Appends SkRRect to SkPath, creating a new closed contour. SkRRect has bounds
|
||||
equal to rect; each corner is 90 degrees of an ellipse with radii (rx, ry). If
|
||||
@ -1120,8 +1122,8 @@ public:
|
||||
@param ry y-axis radius of rounded corners on the SkRRect
|
||||
@param dir SkPath::Direction to wind SkRRect
|
||||
*/
|
||||
void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
|
||||
Direction dir = kCW_Direction);
|
||||
SkPath& addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/** Appends SkRRect to SkPath, creating a new closed contour. SkRRect has bounds
|
||||
equal to rect; each corner is 90 degrees of an ellipse with radii from the
|
||||
@ -1131,8 +1133,8 @@ public:
|
||||
@param radii array of 8 SkScalar values, a radius pair for each corner
|
||||
@param dir SkPath::Direction to wind SkRRect
|
||||
*/
|
||||
void addRoundRect(const SkRect& rect, const SkScalar radii[],
|
||||
Direction dir = kCW_Direction);
|
||||
SkPath& addRoundRect(const SkRect& rect, const SkScalar radii[],
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/** Adds rrect to SkPath, creating a new closed contour. If
|
||||
dir is kCW_Direction, rrect starts at top-left of the lower-left corner and
|
||||
@ -1144,7 +1146,7 @@ public:
|
||||
@param rrect bounds and radii of rounded rectangle
|
||||
@param dir SkPath::Direction to wind SkRRect
|
||||
*/
|
||||
void addRRect(const SkRRect& rrect, Direction dir = kCW_Direction);
|
||||
SkPath& addRRect(const SkRRect& rrect, Direction dir = kCW_Direction);
|
||||
|
||||
/** Adds rrect to SkPath, creating a new closed contour. If dir is kCW_Direction, rrect
|
||||
winds clockwise; if dir is kCCW_Direction, rrect winds counterclockwise.
|
||||
@ -1154,7 +1156,7 @@ public:
|
||||
@param dir SkPath::Direction to wind SkRRect
|
||||
@param start index of initial point of SkRRect
|
||||
*/
|
||||
void addRRect(const SkRRect& rrect, Direction dir, unsigned start);
|
||||
SkPath& addRRect(const SkRRect& rrect, Direction dir, unsigned start);
|
||||
|
||||
/** Adds contour created from line array, adding (count - 1) line segments.
|
||||
Contour added starts at pts[0], then adds a line for every additional SkPoint
|
||||
@ -1168,7 +1170,11 @@ public:
|
||||
@param count length of SkPoint array
|
||||
@param close true to add line connecting contour end and start
|
||||
*/
|
||||
void addPoly(const SkPoint pts[], int count, bool close);
|
||||
SkPath& addPoly(const SkPoint pts[], int count, bool close);
|
||||
|
||||
SkPath& addPoly(const std::initializer_list<SkPoint>& list, bool close) {
|
||||
return this->addPoly(list.begin(), SkToInt(list.size()), close);
|
||||
}
|
||||
|
||||
/** \enum SkPath::AddPathMode
|
||||
AddPathMode chooses how addPath() appends. Adding one SkPath to another can extend
|
||||
@ -1190,8 +1196,8 @@ public:
|
||||
@param dy offset added to src SkPoint array y-axis coordinates
|
||||
@param mode kAppend_AddPathMode or kExtend_AddPathMode
|
||||
*/
|
||||
void addPath(const SkPath& src, SkScalar dx, SkScalar dy,
|
||||
AddPathMode mode = kAppend_AddPathMode);
|
||||
SkPath& addPath(const SkPath& src, SkScalar dx, SkScalar dy,
|
||||
AddPathMode mode = kAppend_AddPathMode);
|
||||
|
||||
/** Appends src to SkPath.
|
||||
|
||||
@ -1202,10 +1208,10 @@ public:
|
||||
@param src SkPath verbs, SkPoint, and conic weights to add
|
||||
@param mode kAppend_AddPathMode or kExtend_AddPathMode
|
||||
*/
|
||||
void addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) {
|
||||
SkPath& addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) {
|
||||
SkMatrix m;
|
||||
m.reset();
|
||||
this->addPath(src, m, mode);
|
||||
return this->addPath(src, m, mode);
|
||||
}
|
||||
|
||||
/** Appends src to SkPath, transformed by matrix. Transformed curves may have different
|
||||
@ -1219,14 +1225,15 @@ public:
|
||||
@param matrix transform applied to src
|
||||
@param mode kAppend_AddPathMode or kExtend_AddPathMode
|
||||
*/
|
||||
void addPath(const SkPath& src, const SkMatrix& matrix, AddPathMode mode = kAppend_AddPathMode);
|
||||
SkPath& addPath(const SkPath& src, const SkMatrix& matrix,
|
||||
AddPathMode mode = kAppend_AddPathMode);
|
||||
|
||||
/** Appends src to SkPath, from back to front.
|
||||
Reversed src always appends a new contour to SkPath.
|
||||
|
||||
@param src SkPath verbs, SkPoint, and conic weights to add
|
||||
*/
|
||||
void reverseAddPath(const SkPath& src);
|
||||
SkPath& reverseAddPath(const SkPath& src);
|
||||
|
||||
/** Offsets SkPoint array by (dx, dy). Offset SkPath replaces dst.
|
||||
If dst is nullptr, SkPath is replaced by offset data.
|
||||
@ -1642,7 +1649,7 @@ private:
|
||||
last point. If no moveTo() call has been made for this contour, the
|
||||
first point is automatically set to (0,0).
|
||||
*/
|
||||
void reversePathTo(const SkPath&);
|
||||
SkPath& reversePathTo(const SkPath&);
|
||||
|
||||
// called before we add points for lineTo, quadTo, cubicTo, checking to see
|
||||
// if we need to inject a leading moveTo first
|
||||
|
@ -364,18 +364,20 @@ uint32_t SkPath::getGenerationID() const {
|
||||
return genID;
|
||||
}
|
||||
|
||||
void SkPath::reset() {
|
||||
SkPath& SkPath::reset() {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
fPathRef.reset(SkPathRef::CreateEmpty());
|
||||
this->resetFields();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::rewind() {
|
||||
SkPath& SkPath::rewind() {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
SkPathRef::Rewind(&fPathRef);
|
||||
this->resetFields();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool SkPath::isLastContourClosed() const {
|
||||
@ -746,7 +748,7 @@ void SkPath::incReserve(U16CPU inc) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
}
|
||||
|
||||
void SkPath::moveTo(SkScalar x, SkScalar y) {
|
||||
SkPath& SkPath::moveTo(SkScalar x, SkScalar y) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
SkPathRef::Editor ed(&fPathRef);
|
||||
@ -757,12 +759,13 @@ void SkPath::moveTo(SkScalar x, SkScalar y) {
|
||||
ed.growForVerb(kMove_Verb)->set(x, y);
|
||||
|
||||
DIRTY_AFTER_EDIT;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::rMoveTo(SkScalar x, SkScalar y) {
|
||||
SkPath& SkPath::rMoveTo(SkScalar x, SkScalar y) {
|
||||
SkPoint pt;
|
||||
this->getLastPt(&pt);
|
||||
this->moveTo(pt.fX + x, pt.fY + y);
|
||||
return this->moveTo(pt.fX + x, pt.fY + y);
|
||||
}
|
||||
|
||||
void SkPath::injectMoveToIfNeeded() {
|
||||
@ -779,7 +782,7 @@ void SkPath::injectMoveToIfNeeded() {
|
||||
}
|
||||
}
|
||||
|
||||
void SkPath::lineTo(SkScalar x, SkScalar y) {
|
||||
SkPath& SkPath::lineTo(SkScalar x, SkScalar y) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
this->injectMoveToIfNeeded();
|
||||
@ -788,16 +791,17 @@ void SkPath::lineTo(SkScalar x, SkScalar y) {
|
||||
ed.growForVerb(kLine_Verb)->set(x, y);
|
||||
|
||||
DIRTY_AFTER_EDIT;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::rLineTo(SkScalar x, SkScalar y) {
|
||||
SkPath& SkPath::rLineTo(SkScalar x, SkScalar y) {
|
||||
this->injectMoveToIfNeeded(); // This can change the result of this->getLastPt().
|
||||
SkPoint pt;
|
||||
this->getLastPt(&pt);
|
||||
this->lineTo(pt.fX + x, pt.fY + y);
|
||||
return this->lineTo(pt.fX + x, pt.fY + y);
|
||||
}
|
||||
|
||||
void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
|
||||
SkPath& SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
this->injectMoveToIfNeeded();
|
||||
@ -808,17 +812,18 @@ void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
|
||||
pts[1].set(x2, y2);
|
||||
|
||||
DIRTY_AFTER_EDIT;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
|
||||
SkPath& SkPath::rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
|
||||
this->injectMoveToIfNeeded(); // This can change the result of this->getLastPt().
|
||||
SkPoint pt;
|
||||
this->getLastPt(&pt);
|
||||
this->quadTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2);
|
||||
return this->quadTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2);
|
||||
}
|
||||
|
||||
void SkPath::conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar w) {
|
||||
SkPath& SkPath::conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar w) {
|
||||
// check for <= 0 or NaN with this test
|
||||
if (!(w > 0)) {
|
||||
this->lineTo(x2, y2);
|
||||
@ -839,18 +844,19 @@ void SkPath::conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
|
||||
DIRTY_AFTER_EDIT;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
|
||||
SkScalar w) {
|
||||
SkPath& SkPath::rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
|
||||
SkScalar w) {
|
||||
this->injectMoveToIfNeeded(); // This can change the result of this->getLastPt().
|
||||
SkPoint pt;
|
||||
this->getLastPt(&pt);
|
||||
this->conicTo(pt.fX + dx1, pt.fY + dy1, pt.fX + dx2, pt.fY + dy2, w);
|
||||
return this->conicTo(pt.fX + dx1, pt.fY + dy1, pt.fX + dx2, pt.fY + dy2, w);
|
||||
}
|
||||
|
||||
void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3) {
|
||||
SkPath& SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
this->injectMoveToIfNeeded();
|
||||
@ -862,18 +868,19 @@ void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
pts[2].set(x3, y3);
|
||||
|
||||
DIRTY_AFTER_EDIT;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3) {
|
||||
SkPath& SkPath::rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3) {
|
||||
this->injectMoveToIfNeeded(); // This can change the result of this->getLastPt().
|
||||
SkPoint pt;
|
||||
this->getLastPt(&pt);
|
||||
this->cubicTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2,
|
||||
pt.fX + x3, pt.fY + y3);
|
||||
return this->cubicTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2,
|
||||
pt.fX + x3, pt.fY + y3);
|
||||
}
|
||||
|
||||
void SkPath::close() {
|
||||
SkPath& SkPath::close() {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
|
||||
int count = fPathRef->countVerbs();
|
||||
@ -905,6 +912,7 @@ void SkPath::close() {
|
||||
#else
|
||||
fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToIndex) - 1);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -991,16 +999,16 @@ static void assert_known_direction(int dir) {
|
||||
SkASSERT(SkPath::kCW_Direction == dir || SkPath::kCCW_Direction == dir);
|
||||
}
|
||||
|
||||
void SkPath::addRect(const SkRect& rect, Direction dir) {
|
||||
this->addRect(rect, dir, 0);
|
||||
SkPath& SkPath::addRect(const SkRect& rect, Direction dir) {
|
||||
return this->addRect(rect, dir, 0);
|
||||
}
|
||||
|
||||
void SkPath::addRect(SkScalar left, SkScalar top, SkScalar right,
|
||||
SkPath& SkPath::addRect(SkScalar left, SkScalar top, SkScalar right,
|
||||
SkScalar bottom, Direction dir) {
|
||||
this->addRect(SkRect::MakeLTRB(left, top, right, bottom), dir, 0);
|
||||
return this->addRect(SkRect::MakeLTRB(left, top, right, bottom), dir, 0);
|
||||
}
|
||||
|
||||
void SkPath::addRect(const SkRect &rect, Direction dir, unsigned startIndex) {
|
||||
SkPath& SkPath::addRect(const SkRect &rect, Direction dir, unsigned startIndex) {
|
||||
assert_known_direction(dir);
|
||||
fFirstDirection = this->hasOnlyMoveTos() ?
|
||||
(SkPathPriv::FirstDirection)dir : SkPathPriv::kUnknown_FirstDirection;
|
||||
@ -1021,12 +1029,13 @@ void SkPath::addRect(const SkRect &rect, Direction dir, unsigned startIndex) {
|
||||
this->close();
|
||||
|
||||
SkASSERT(this->countVerbs() == initialVerbCount + kVerbs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::addPoly(const SkPoint pts[], int count, bool close) {
|
||||
SkPath& SkPath::addPoly(const SkPoint pts[], int count, bool close) {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
if (count <= 0) {
|
||||
return;
|
||||
return *this;
|
||||
}
|
||||
|
||||
fLastMoveToIndex = fPathRef->countPoints();
|
||||
@ -1047,6 +1056,7 @@ void SkPath::addPoly(const SkPoint pts[], int count, bool close) {
|
||||
|
||||
DIRTY_AFTER_EDIT;
|
||||
SkDEBUGCODE(this->validate();)
|
||||
return *this;
|
||||
}
|
||||
|
||||
#include "SkGeometry.h"
|
||||
@ -1122,76 +1132,77 @@ static int build_arc_conics(const SkRect& oval, const SkVector& start, const SkV
|
||||
return count;
|
||||
}
|
||||
|
||||
void SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[],
|
||||
SkPath& SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[],
|
||||
Direction dir) {
|
||||
SkRRect rrect;
|
||||
rrect.setRectRadii(rect, (const SkVector*) radii);
|
||||
this->addRRect(rrect, dir);
|
||||
return this->addRRect(rrect, dir);
|
||||
}
|
||||
|
||||
void SkPath::addRRect(const SkRRect& rrect, Direction dir) {
|
||||
SkPath& SkPath::addRRect(const SkRRect& rrect, Direction dir) {
|
||||
// legacy start indices: 6 (CW) and 7(CCW)
|
||||
this->addRRect(rrect, dir, dir == kCW_Direction ? 6 : 7);
|
||||
return this->addRRect(rrect, dir, dir == kCW_Direction ? 6 : 7);
|
||||
}
|
||||
|
||||
void SkPath::addRRect(const SkRRect &rrect, Direction dir, unsigned startIndex) {
|
||||
assert_known_direction(dir);
|
||||
SkPath& SkPath::addRRect(const SkRRect &rrect, Direction dir, unsigned startIndex) {
|
||||
assert_known_direction(dir);
|
||||
|
||||
bool isRRect = hasOnlyMoveTos();
|
||||
const SkRect& bounds = rrect.getBounds();
|
||||
bool isRRect = hasOnlyMoveTos();
|
||||
const SkRect& bounds = rrect.getBounds();
|
||||
|
||||
if (rrect.isRect() || rrect.isEmpty()) {
|
||||
// degenerate(rect) => radii points are collapsing
|
||||
this->addRect(bounds, dir, (startIndex + 1) / 2);
|
||||
} else if (rrect.isOval()) {
|
||||
// degenerate(oval) => line points are collapsing
|
||||
this->addOval(bounds, dir, startIndex / 2);
|
||||
} else {
|
||||
fFirstDirection = this->hasOnlyMoveTos() ?
|
||||
(SkPathPriv::FirstDirection)dir : SkPathPriv::kUnknown_FirstDirection;
|
||||
if (rrect.isRect() || rrect.isEmpty()) {
|
||||
// degenerate(rect) => radii points are collapsing
|
||||
this->addRect(bounds, dir, (startIndex + 1) / 2);
|
||||
} else if (rrect.isOval()) {
|
||||
// degenerate(oval) => line points are collapsing
|
||||
this->addOval(bounds, dir, startIndex / 2);
|
||||
} else {
|
||||
fFirstDirection = this->hasOnlyMoveTos() ?
|
||||
(SkPathPriv::FirstDirection)dir : SkPathPriv::kUnknown_FirstDirection;
|
||||
|
||||
SkAutoPathBoundsUpdate apbu(this, bounds);
|
||||
SkAutoDisableDirectionCheck addc(this);
|
||||
SkAutoPathBoundsUpdate apbu(this, bounds);
|
||||
SkAutoDisableDirectionCheck addc(this);
|
||||
|
||||
// we start with a conic on odd indices when moving CW vs. even indices when moving CCW
|
||||
const bool startsWithConic = ((startIndex & 1) == (dir == kCW_Direction));
|
||||
const SkScalar weight = SK_ScalarRoot2Over2;
|
||||
// we start with a conic on odd indices when moving CW vs. even indices when moving CCW
|
||||
const bool startsWithConic = ((startIndex & 1) == (dir == kCW_Direction));
|
||||
const SkScalar weight = SK_ScalarRoot2Over2;
|
||||
|
||||
SkDEBUGCODE(int initialVerbCount = this->countVerbs());
|
||||
const int kVerbs = startsWithConic
|
||||
? 9 // moveTo + 4x conicTo + 3x lineTo + close
|
||||
: 10; // moveTo + 4x lineTo + 4x conicTo + close
|
||||
this->incReserve(kVerbs);
|
||||
SkDEBUGCODE(int initialVerbCount = this->countVerbs());
|
||||
const int kVerbs = startsWithConic
|
||||
? 9 // moveTo + 4x conicTo + 3x lineTo + close
|
||||
: 10; // moveTo + 4x lineTo + 4x conicTo + close
|
||||
this->incReserve(kVerbs);
|
||||
|
||||
RRectPointIterator rrectIter(rrect, dir, startIndex);
|
||||
// Corner iterator indices follow the collapsed radii model,
|
||||
// adjusted such that the start pt is "behind" the radii start pt.
|
||||
const unsigned rectStartIndex = startIndex / 2 + (dir == kCW_Direction ? 0 : 1);
|
||||
RectPointIterator rectIter(bounds, dir, rectStartIndex);
|
||||
RRectPointIterator rrectIter(rrect, dir, startIndex);
|
||||
// Corner iterator indices follow the collapsed radii model,
|
||||
// adjusted such that the start pt is "behind" the radii start pt.
|
||||
const unsigned rectStartIndex = startIndex / 2 + (dir == kCW_Direction ? 0 : 1);
|
||||
RectPointIterator rectIter(bounds, dir, rectStartIndex);
|
||||
|
||||
this->moveTo(rrectIter.current());
|
||||
if (startsWithConic) {
|
||||
for (unsigned i = 0; i < 3; ++i) {
|
||||
this->conicTo(rectIter.next(), rrectIter.next(), weight);
|
||||
this->lineTo(rrectIter.next());
|
||||
}
|
||||
this->moveTo(rrectIter.current());
|
||||
if (startsWithConic) {
|
||||
for (unsigned i = 0; i < 3; ++i) {
|
||||
this->conicTo(rectIter.next(), rrectIter.next(), weight);
|
||||
this->lineTo(rrectIter.next());
|
||||
}
|
||||
this->conicTo(rectIter.next(), rrectIter.next(), weight);
|
||||
// final lineTo handled by close().
|
||||
} else {
|
||||
for (unsigned i = 0; i < 4; ++i) {
|
||||
this->lineTo(rrectIter.next());
|
||||
this->conicTo(rectIter.next(), rrectIter.next(), weight);
|
||||
// final lineTo handled by close().
|
||||
} else {
|
||||
for (unsigned i = 0; i < 4; ++i) {
|
||||
this->lineTo(rrectIter.next());
|
||||
this->conicTo(rectIter.next(), rrectIter.next(), weight);
|
||||
}
|
||||
}
|
||||
this->close();
|
||||
|
||||
SkPathRef::Editor ed(&fPathRef);
|
||||
ed.setIsRRect(isRRect, dir, startIndex % 8);
|
||||
|
||||
SkASSERT(this->countVerbs() == initialVerbCount + kVerbs);
|
||||
}
|
||||
this->close();
|
||||
|
||||
SkDEBUGCODE(fPathRef->validate();)
|
||||
SkPathRef::Editor ed(&fPathRef);
|
||||
ed.setIsRRect(isRRect, dir, startIndex % 8);
|
||||
|
||||
SkASSERT(this->countVerbs() == initialVerbCount + kVerbs);
|
||||
}
|
||||
|
||||
SkDEBUGCODE(fPathRef->validate();)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool SkPath::hasOnlyMoveTos() const {
|
||||
@ -1224,25 +1235,25 @@ bool SkPath::isZeroLengthSincePoint(int startPtIndex) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkPath::addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
|
||||
Direction dir) {
|
||||
SkPath& SkPath::addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
|
||||
Direction dir) {
|
||||
assert_known_direction(dir);
|
||||
|
||||
if (rx < 0 || ry < 0) {
|
||||
return;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SkRRect rrect;
|
||||
rrect.setRectXY(rect, rx, ry);
|
||||
this->addRRect(rrect, dir);
|
||||
return this->addRRect(rrect, dir);
|
||||
}
|
||||
|
||||
void SkPath::addOval(const SkRect& oval, Direction dir) {
|
||||
SkPath& SkPath::addOval(const SkRect& oval, Direction dir) {
|
||||
// legacy start index: 1
|
||||
this->addOval(oval, dir, 1);
|
||||
return this->addOval(oval, dir, 1);
|
||||
}
|
||||
|
||||
void SkPath::addOval(const SkRect &oval, Direction dir, unsigned startPointIndex) {
|
||||
SkPath& SkPath::addOval(const SkRect &oval, Direction dir, unsigned startPointIndex) {
|
||||
assert_known_direction(dir);
|
||||
|
||||
/* If addOval() is called after previous moveTo(),
|
||||
@ -1281,18 +1292,20 @@ void SkPath::addOval(const SkRect &oval, Direction dir, unsigned startPointIndex
|
||||
SkPathRef::Editor ed(&fPathRef);
|
||||
|
||||
ed.setIsOval(isOval, kCCW_Direction == dir, startPointIndex % 4);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) {
|
||||
SkPath& SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) {
|
||||
if (r > 0) {
|
||||
this->addOval(SkRect::MakeLTRB(x - r, y - r, x + r, y + r), dir);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
bool forceMoveTo) {
|
||||
SkPath& SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
bool forceMoveTo) {
|
||||
if (oval.width() < 0 || oval.height() < 0) {
|
||||
return;
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (fPathRef->countVerbs() == 0) {
|
||||
@ -1301,8 +1314,7 @@ void SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
|
||||
SkPoint lonePt;
|
||||
if (arc_is_lone_point(oval, startAngle, sweepAngle, &lonePt)) {
|
||||
forceMoveTo ? this->moveTo(lonePt) : this->lineTo(lonePt);
|
||||
return;
|
||||
return forceMoveTo ? this->moveTo(lonePt) : this->lineTo(lonePt);
|
||||
}
|
||||
|
||||
SkVector startV, stopV;
|
||||
@ -1340,7 +1352,7 @@ void SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
singlePt.set(oval.centerX() + radiusX * sk_float_cos(endAngle),
|
||||
oval.centerY() + radiusY * sk_float_sin(endAngle));
|
||||
addPt(singlePt);
|
||||
return;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SkConic conics[SkConic::kMaxConicsForArc];
|
||||
@ -1355,6 +1367,7 @@ void SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
} else {
|
||||
addPt(singlePt);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// This converts the SVG arc to conics.
|
||||
@ -1363,8 +1376,8 @@ void SkPath::arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
// See also SVG implementation notes:
|
||||
// http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
|
||||
// Note that arcSweep bool value is flipped from the original implementation.
|
||||
void SkPath::arcTo(SkScalar rx, SkScalar ry, SkScalar angle, SkPath::ArcSize arcLarge,
|
||||
SkPath::Direction arcSweep, SkScalar x, SkScalar y) {
|
||||
SkPath& SkPath::arcTo(SkScalar rx, SkScalar ry, SkScalar angle, SkPath::ArcSize arcLarge,
|
||||
SkPath::Direction arcSweep, SkScalar x, SkScalar y) {
|
||||
this->injectMoveToIfNeeded();
|
||||
SkPoint srcPts[2];
|
||||
this->getLastPt(&srcPts[0]);
|
||||
@ -1372,15 +1385,13 @@ void SkPath::arcTo(SkScalar rx, SkScalar ry, SkScalar angle, SkPath::ArcSize arc
|
||||
// joining the endpoints.
|
||||
// http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters
|
||||
if (!rx || !ry) {
|
||||
this->lineTo(x, y);
|
||||
return;
|
||||
return this->lineTo(x, y);
|
||||
}
|
||||
// If the current point and target point for the arc are identical, it should be treated as a
|
||||
// zero length path. This ensures continuity in animations.
|
||||
srcPts[1].set(x, y);
|
||||
if (srcPts[0] == srcPts[1]) {
|
||||
this->lineTo(x, y);
|
||||
return;
|
||||
return this->lineTo(x, y);
|
||||
}
|
||||
rx = SkScalarAbs(rx);
|
||||
ry = SkScalarAbs(ry);
|
||||
@ -1446,7 +1457,7 @@ void SkPath::arcTo(SkScalar rx, SkScalar ry, SkScalar angle, SkPath::ArcSize arc
|
||||
SkScalar thetaWidth = thetaArc / segments;
|
||||
SkScalar t = SkScalarTan(0.5f * thetaWidth);
|
||||
if (!SkScalarIsFinite(t)) {
|
||||
return;
|
||||
return *this;
|
||||
}
|
||||
SkScalar startTheta = theta1;
|
||||
SkScalar w = SkScalarSqrt(SK_ScalarHalf + SkScalarCos(thetaWidth) * SK_ScalarHalf);
|
||||
@ -1484,18 +1495,20 @@ void SkPath::arcTo(SkScalar rx, SkScalar ry, SkScalar angle, SkPath::ArcSize arc
|
||||
this->conicTo(mapped[0], mapped[1], w);
|
||||
startTheta = endTheta;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, SkPath::ArcSize largeArc,
|
||||
SkPath::Direction sweep, SkScalar dx, SkScalar dy) {
|
||||
SkPath& SkPath::rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, SkPath::ArcSize largeArc,
|
||||
SkPath::Direction sweep, SkScalar dx, SkScalar dy) {
|
||||
SkPoint currentPoint;
|
||||
this->getLastPt(¤tPoint);
|
||||
this->arcTo(rx, ry, xAxisRotate, largeArc, sweep, currentPoint.fX + dx, currentPoint.fY + dy);
|
||||
return this->arcTo(rx, ry, xAxisRotate, largeArc, sweep,
|
||||
currentPoint.fX + dx, currentPoint.fY + dy);
|
||||
}
|
||||
|
||||
void SkPath::addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle) {
|
||||
SkPath& SkPath::addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle) {
|
||||
if (oval.isEmpty() || 0 == sweepAngle) {
|
||||
return;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const SkScalar kFullCircleAngle = SkIntToScalar(360);
|
||||
@ -1510,22 +1523,20 @@ void SkPath::addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle
|
||||
// Index 1 is at startAngle == 0.
|
||||
SkScalar startIndex = std::fmod(startOver90I + 1.f, 4.f);
|
||||
startIndex = startIndex < 0 ? startIndex + 4.f : startIndex;
|
||||
this->addOval(oval, sweepAngle > 0 ? kCW_Direction : kCCW_Direction,
|
||||
(unsigned) startIndex);
|
||||
return;
|
||||
return this->addOval(oval, sweepAngle > 0 ? kCW_Direction : kCCW_Direction,
|
||||
(unsigned) startIndex);
|
||||
}
|
||||
}
|
||||
this->arcTo(oval, startAngle, sweepAngle, true);
|
||||
return this->arcTo(oval, startAngle, sweepAngle, true);
|
||||
}
|
||||
|
||||
/*
|
||||
Need to handle the case when the angle is sharp, and our computed end-points
|
||||
for the arc go behind pt1 and/or p2...
|
||||
*/
|
||||
void SkPath::arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius) {
|
||||
SkPath& SkPath::arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius) {
|
||||
if (radius == 0) {
|
||||
this->lineTo(x1, y1);
|
||||
return;
|
||||
return this->lineTo(x1, y1);
|
||||
}
|
||||
|
||||
SkVector before, after;
|
||||
@ -1544,8 +1555,7 @@ void SkPath::arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar
|
||||
SkScalar sinh = SkPoint::CrossProduct(before, after);
|
||||
|
||||
if (SkScalarNearlyZero(sinh)) { // angle is too tight
|
||||
this->lineTo(x1, y1);
|
||||
return;
|
||||
return this->lineTo(x1, y1);
|
||||
}
|
||||
|
||||
SkScalar dist = SkScalarAbs(radius * (1 - cosh) / sinh);
|
||||
@ -1555,19 +1565,19 @@ void SkPath::arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar
|
||||
after.setLength(dist);
|
||||
this->lineTo(xx, yy);
|
||||
SkScalar weight = SkScalarSqrt(SK_ScalarHalf + cosh * SK_ScalarHalf);
|
||||
this->conicTo(x1, y1, x1 + after.fX, y1 + after.fY, weight);
|
||||
return this->conicTo(x1, y1, x1 + after.fX, y1 + after.fY, weight);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkPath::addPath(const SkPath& path, SkScalar dx, SkScalar dy, AddPathMode mode) {
|
||||
SkPath& SkPath::addPath(const SkPath& path, SkScalar dx, SkScalar dy, AddPathMode mode) {
|
||||
SkMatrix matrix;
|
||||
|
||||
matrix.setTranslate(dx, dy);
|
||||
this->addPath(path, matrix, mode);
|
||||
return this->addPath(path, matrix, mode);
|
||||
}
|
||||
|
||||
void SkPath::addPath(const SkPath& path, const SkMatrix& matrix, AddPathMode mode) {
|
||||
SkPath& SkPath::addPath(const SkPath& path, const SkMatrix& matrix, AddPathMode mode) {
|
||||
SkPathRef::Editor(&fPathRef, path.countVerbs(), path.countPoints());
|
||||
|
||||
RawIter iter(path);
|
||||
@ -1611,6 +1621,7 @@ void SkPath::addPath(const SkPath& path, const SkMatrix& matrix, AddPathMode mod
|
||||
}
|
||||
firstVerb = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -1631,10 +1642,10 @@ static int pts_in_verb(unsigned verb) {
|
||||
}
|
||||
|
||||
// ignore the last point of the 1st contour
|
||||
void SkPath::reversePathTo(const SkPath& path) {
|
||||
SkPath& SkPath::reversePathTo(const SkPath& path) {
|
||||
const uint8_t* verbs = path.fPathRef->verbsMemBegin(); // points at the last verb
|
||||
if (!verbs) { // empty path returns nullptr
|
||||
return;
|
||||
return *this;
|
||||
}
|
||||
const uint8_t* verbsEnd = path.fPathRef->verbs() - 1; // points just past the first verb
|
||||
SkASSERT(verbsEnd[0] == kMove_Verb);
|
||||
@ -1647,7 +1658,7 @@ void SkPath::reversePathTo(const SkPath& path) {
|
||||
switch (v) {
|
||||
case kMove_Verb:
|
||||
// if the path has multiple contours, stop after reversing the last
|
||||
return;
|
||||
return *this;
|
||||
case kLine_Verb:
|
||||
this->lineTo(pts[0]);
|
||||
break;
|
||||
@ -1668,9 +1679,10 @@ void SkPath::reversePathTo(const SkPath& path) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkPath::reverseAddPath(const SkPath& src) {
|
||||
SkPath& SkPath::reverseAddPath(const SkPath& src) {
|
||||
SkPathRef::Editor ed(&fPathRef, src.fPathRef->countPoints(), src.fPathRef->countVerbs());
|
||||
|
||||
const SkPoint* pts = src.fPathRef->pointsEnd();
|
||||
@ -1719,6 +1731,7 @@ void SkPath::reverseAddPath(const SkPath& src) {
|
||||
SkDEBUGFAIL("unexpected verb");
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -121,12 +121,9 @@ static void test_crbug_140803() {
|
||||
bm.allocN32Pixels(2700, 30*1024);
|
||||
SkCanvas canvas(bm);
|
||||
|
||||
SkPath path;
|
||||
path.moveTo(2762, 20);
|
||||
path.quadTo(11, 21702, 10, 21706);
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
canvas.drawPath(path, paint);
|
||||
canvas.drawPath(SkPath().moveTo(2762, 20).quadTo(11, 21702, 10, 21706), paint);
|
||||
}
|
||||
|
||||
// Need to exercise drawing an inverse-path whose bounds intersect the clip,
|
||||
|
@ -106,11 +106,11 @@ static void iter_paint(skiatest::Reporter* reporter, const SkPath& path, bool sh
|
||||
|
||||
static void make_empty(SkPath*) {}
|
||||
static void make_M(SkPath* path) { path->moveTo(CX, CY); }
|
||||
static void make_MM(SkPath* path) { path->moveTo(CX, CY); path->moveTo(CX, CY); }
|
||||
static void make_MZM(SkPath* path) { path->moveTo(CX, CY); path->close(); path->moveTo(CX, CY); }
|
||||
static void make_L(SkPath* path) { path->moveTo(CX, CY); path->lineTo(CX, CY); }
|
||||
static void make_Q(SkPath* path) { path->moveTo(CX, CY); path->quadTo(CX, CY, CX, CY); }
|
||||
static void make_C(SkPath* path) { path->moveTo(CX, CY); path->cubicTo(CX, CY, CX, CY, CX, CY); }
|
||||
static void make_MM(SkPath* path) { path->moveTo(CX, CY).moveTo(CX, CY); }
|
||||
static void make_MZM(SkPath* path) { path->moveTo(CX, CY).close().moveTo(CX, CY); }
|
||||
static void make_L(SkPath* path) { path->moveTo(CX, CY).lineTo(CX, CY); }
|
||||
static void make_Q(SkPath* path) { path->moveTo(CX, CY).quadTo(CX, CY, CX, CY); }
|
||||
static void make_C(SkPath* path) { path->moveTo(CX, CY).cubicTo(CX, CY, CX, CY, CX, CY); }
|
||||
|
||||
/* Two invariants are tested: How does an empty/degenerate path draw?
|
||||
* - if the path is drawn inverse, it should draw everywhere
|
||||
|
@ -37,11 +37,11 @@ DEF_TEST(FillPathInverse, reporter) {
|
||||
int width = 200;
|
||||
int expected_lines = 5;
|
||||
clip.set(0, height - expected_lines, width, height);
|
||||
path.moveTo(0.0f, 0.0f);
|
||||
path.quadTo(SkIntToScalar(width/2), SkIntToScalar(height),
|
||||
SkIntToScalar(width), 0.0f);
|
||||
path.close();
|
||||
path.setFillType(SkPath::kInverseWinding_FillType);
|
||||
path.moveTo(0.0f, 0.0f)
|
||||
.quadTo(SkIntToScalar(width/2), SkIntToScalar(height),
|
||||
SkIntToScalar(width), 0.0f)
|
||||
.close()
|
||||
.setFillType(SkPath::kInverseWinding_FillType);
|
||||
SkScan::FillPath(path, clip, &blitter);
|
||||
|
||||
REPORTER_ASSERT(reporter, blitter.m_blitCount == expected_lines);
|
||||
|
Loading…
Reference in New Issue
Block a user