提交 f1d3d84f 编写于 作者: C Chinmay Garde 提交者: GitHub

Expose SkPath::arcTo and SkPath::rArcTo to Dart. (#4222)

上级 faaf321b
......@@ -34,6 +34,12 @@ bool _offsetIsValid(Offset offset) {
return true;
}
bool _radiusIsValid(Radius radius) {
assert(radius != null, 'Radius argument was null.');
assert(!radius.x.isNaN && !radius.y.isNaN, 'Radius argument contained a NaN value.');
return true;
}
Color _scaleAlpha(Color a, double factor) {
return a.withAlpha((a.alpha * factor).round().clamp(0, 255));
}
......@@ -860,6 +866,64 @@ class Path extends NativeFieldWrapperClass2 {
void _arcTo(double left, double top, double right, double bottom,
double startAngle, double sweepAngle, bool forceMoveTo) native "Path_arcTo";
/// Appends up to four conic curves weighted to describe an oval of [radius]
/// and rotated by [rotation].
///
/// The first curve begins from the last point in the path and the last ends
/// at [arcEnd]. The curves follow a path in a direction determined by
/// [clockwise] and [largeArc] in such a way that the sweep angle
/// is always less than 360 degrees.
///
/// A simple line is appended if either either radii are zero or the last
/// point in the path is [arcEnd]. The radii are scaled to fit the last path
/// point if both are greater than zero but too small to describe an arc.
///
void arcToPoint(Offset arcEnd, {
Radius radius: Radius.zero,
double rotation: 0.0,
bool largeArc: false,
bool clockwise: true,
}) {
assert(_offsetIsValid(arcEnd));
assert(_radiusIsValid(radius));
_arcToPoint(arcEnd.dx, arcEnd.dy, radius.x, radius.y, rotation,
largeArc, clockwise);
}
void _arcToPoint(double arcEndX, double arcEndY, double radiusX,
double radiusY, double rotation, bool largeArc,
bool clockwise) native "Path_arcToPoint";
/// Appends up to four conic curves weighted to describe an oval of [radius]
/// and rotated by [rotation].
///
/// The last path point is described by (px, py).
///
/// The first curve begins from the last point in the path and the last ends
/// at [arcEndDelta].dx + px and [arcEndDelta].dy + py. The curves follow a
/// path in a direction determined by [clockwise] and [largeArc]
/// in such a way that the sweep angle is always less than 360 degrees.
///
/// A simple line is appended if either either radii are zero, or, both
/// [arcEndDelta].dx and [arcEndDelta].dy are zero. The radii are scaled to
/// fit the last path point if both are greater than zero but too small to
/// describe an arc.
void relativeArcToPoint(Offset arcEndDelta, {
Radius radius: Radius.zero,
double rotation: 0.0,
bool largeArc: false,
bool clockwise: true,
}) {
assert(_offsetIsValid(arcEndDelta));
assert(_radiusIsValid(radius));
_relativeArcToPoint(arcEndDelta.dx, arcEndDelta.dy, radius.x, radius.y,
rotation, largeArc, clockwise);
}
void _relativeArcToPoint(double arcEndX, double arcEndY, double radiusX,
double radiusY, double rotation,
bool largeArc, bool clockwise)
native "Path_relativeArcToPoint";
/// Adds a new subpath that consists of four lines that outline the
/// given rectangle.
void addRect(Rect rect) {
......
......@@ -25,29 +25,31 @@ static void Path_constructor(Dart_NativeArguments args) {
IMPLEMENT_WRAPPERTYPEINFO(ui, Path);
#define FOR_EACH_BINDING(V) \
V(Path, getFillType) \
V(Path, setFillType) \
V(Path, moveTo) \
V(Path, relativeMoveTo) \
V(Path, lineTo) \
V(Path, relativeLineTo) \
V(Path, quadraticBezierTo) \
V(Path, relativeQuadraticBezierTo) \
V(Path, cubicTo) \
V(Path, relativeCubicTo) \
V(Path, conicTo) \
V(Path, relativeConicTo) \
V(Path, arcTo) \
V(Path, addRect) \
V(Path, addOval) \
V(Path, addArc) \
V(Path, addOval) \
V(Path, addPath) \
V(Path, addPolygon) \
V(Path, addRect) \
V(Path, addRRect) \
V(Path, addPath) \
V(Path, extendWithPath) \
V(Path, arcTo) \
V(Path, arcToPoint) \
V(Path, close) \
V(Path, reset) \
V(Path, conicTo) \
V(Path, contains) \
V(Path, cubicTo) \
V(Path, extendWithPath) \
V(Path, getFillType) \
V(Path, lineTo) \
V(Path, moveTo) \
V(Path, quadraticBezierTo) \
V(Path, relativeArcToPoint) \
V(Path, relativeConicTo) \
V(Path, relativeCubicTo) \
V(Path, relativeLineTo) \
V(Path, relativeMoveTo) \
V(Path, relativeQuadraticBezierTo) \
V(Path, reset) \
V(Path, setFillType) \
V(Path, shift) \
V(Path, transform)
......@@ -139,6 +141,39 @@ void CanvasPath::arcTo(float left,
forceMoveTo);
}
void CanvasPath::arcToPoint(float arcEndX,
float arcEndY,
float radiusX,
float radiusY,
float xAxisRotation,
bool isLargeArc,
bool isClockwiseDirection) {
const auto arcSize = isLargeArc ? SkPath::ArcSize::kLarge_ArcSize
: SkPath::ArcSize::kSmall_ArcSize;
const auto direction = isClockwiseDirection
? SkPath::Direction::kCW_Direction
: SkPath::Direction::kCCW_Direction;
path_.arcTo(radiusX, radiusY, xAxisRotation, arcSize, direction, arcEndX,
arcEndY);
}
void CanvasPath::relativeArcToPoint(float arcEndDeltaX,
float arcEndDeltaY,
float radiusX,
float radiusY,
float xAxisRotation,
bool isLargeArc,
bool isClockwiseDirection) {
const auto arcSize = isLargeArc ? SkPath::ArcSize::kLarge_ArcSize
: SkPath::ArcSize::kSmall_ArcSize;
const auto direction = isClockwiseDirection
? SkPath::Direction::kCW_Direction
: SkPath::Direction::kCCW_Direction;
path_.rArcTo(radiusX, radiusY, xAxisRotation, arcSize, direction,
arcEndDeltaX, arcEndDeltaY);
}
void CanvasPath::addRect(float left, float top, float right, float bottom) {
path_.addRect(SkRect::MakeLTRB(left, top, right, bottom));
}
......
......@@ -53,6 +53,20 @@ class CanvasPath : public fxl::RefCountedThreadSafe<CanvasPath>,
float startAngle,
float sweepAngle,
bool forceMoveTo);
void arcToPoint(float arcEndX,
float arcEndY,
float radiusX,
float radiusY,
float xAxisRotation,
bool isLargeArc,
bool isClockwiseDirection);
void relativeArcToPoint(float arcEndDeltaX,
float arcEndDeltaY,
float radiusX,
float radiusY,
float xAxisRotation,
bool isLargeArc,
bool isClockwiseDirection);
void addRect(float left, float top, float right, float bottom);
void addOval(float left, float top, float right, float bottom);
void addArc(float left,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册