applyTo method
dynamic
applyTo(
- Path path
)
Implementation
applyTo(Path path) {
// initial point of a sub-path, absolute position, updated on MoveTo
double ix = 0;
double iy = 0;
// current point, absolute position
double x = 0;
double y = 0;
// control point for bezier curve, absolute position
double? cx;
double? cy;
_CSSPathCommandType? preType;
for (var command in _commands) {
final params = command.params;
final type = command.type;
if (preType != null && preType.category != type.category) {
// reset control point for bezier curve when category is changed
cx = null;
cy = null;
}
switch (type) {
case _CSSPathCommandType.M:
if (command.isSubSequent) {
// sub sequent command treated as line to
path.lineTo(x = params[0], y = params[1]);
} else {
path.moveTo(ix = x = params[0], iy = y = params[1]);
}
break;
case _CSSPathCommandType.m:
if (command.isSubSequent) {
path.relativeLineTo(params[0], params[1]);
x += params[0];
y += params[1];
} else {
path.relativeMoveTo(params[0], params[1]);
ix = x += params[0];
iy = y += params[1];
}
break;
case _CSSPathCommandType.L:
path.lineTo(x = params[0], y = params[1]);
break;
case _CSSPathCommandType.l:
path.relativeLineTo(params[0], params[1]);
x += params[0];
y += params[1];
break;
case _CSSPathCommandType.H:
path.lineTo(x = params[0], y);
break;
case _CSSPathCommandType.h:
x += params[0];
path.relativeLineTo(params[0], 0);
break;
case _CSSPathCommandType.V:
path.lineTo(x, y = params[0]);
break;
case _CSSPathCommandType.v:
y += params[0];
path.relativeLineTo(0, params[0]);
break;
case _CSSPathCommandType.A:
path.arcToPoint(
Offset(x = params[5], y = params[6]),
radius: Radius.elliptical(params[0], params[1]),
rotation: params[2],
largeArc: params[3] == 1,
clockwise: params[4] == 1,
);
break;
case _CSSPathCommandType.a:
x += params[5];
y += params[6];
path.relativeArcToPoint(Offset(params[5], params[6]),
radius: Radius.elliptical(params[0], params[1]),
rotation: params[2],
largeArc: params[3] == 1,
clockwise: params[4] == 1);
break;
case _CSSPathCommandType.C:
path.cubicTo(params[0], params[1], cx = params[2], cy = params[3], x = params[4], y = params[5]);
break;
case _CSSPathCommandType.c:
path.relativeCubicTo(params[0], params[1], params[2], params[3], params[4], params[5]);
cx = x + params[2];
cy = y + params[3];
x += params[4];
y += params[5];
break;
case _CSSPathCommandType.S:
path.cubicTo(cx ?? x, cy ?? y, cx = params[0], cy = params[1], x = params[2], y = params[3]);
break;
case _CSSPathCommandType.s:
path.relativeCubicTo(cx != null ? cx - x : 0, cy != null ? cy - y : 0, params[0], params[1], params[2], params[3]);
cx = x + params[0];
cy = y + params[1];
x += params[2];
y += params[3];
break;
case _CSSPathCommandType.Q:
path.quadraticBezierTo(cx = params[0], cy = params[1], x = params[2], y = params[3]);
break;
case _CSSPathCommandType.q:
path.relativeQuadraticBezierTo(params[0], params[1], params[2], params[3]);
cx = x + params[0];
cy = y + params[1];
x += params[2];
y += params[3];
break;
case _CSSPathCommandType.T:
cx ??= x;
cy ??= y;
path.quadraticBezierTo(cx, cy, x = params[0], y = params[1]);
break;
case _CSSPathCommandType.t:
path.relativeQuadraticBezierTo(cx != null ? cx - x : 0, cy != null ? cy - y : 0, params[0], params[1]);
x += params[0];
y += params[1];
cx ??= x;
cy ??= y;
break;
case _CSSPathCommandType.Z:
case _CSSPathCommandType.z:
path.close();
x = ix;
y = iy;
break;
}
if (type.isBezierCurve) {
// reflect control point based on the end point
assert(cx != null);
assert(cy != null);
cx = x + (x - cx!);
cy = y + (y - cy!);
}
preType = type;
}
}