emitSegment method
Implementation
void emitSegment(PathSegmentData segment, PathProxy path) {
final PathSegmentData normSeg = segment;
assert(_currentPoint != null); // ignore: unnecessary_null_comparison
// Convert relative points to absolute points.
switch (segment.command) {
case SvgPathSegType.quadToRel:
normSeg.point1 += _currentPoint;
normSeg.targetPoint += _currentPoint;
break;
case SvgPathSegType.cubicToRel:
normSeg.point1 += _currentPoint;
continue smooth_rel;
smooth_rel:
case SvgPathSegType.smoothCubicToRel:
normSeg.point2 += _currentPoint;
continue arc_rel;
case SvgPathSegType.moveToRel:
case SvgPathSegType.lineToRel:
case SvgPathSegType.lineToHorizontalRel:
case SvgPathSegType.lineToVerticalRel:
case SvgPathSegType.smoothQuadToRel:
arc_rel:
case SvgPathSegType.arcToRel:
normSeg.targetPoint += _currentPoint;
break;
case SvgPathSegType.lineToHorizontalAbs:
normSeg.targetPoint =
_PathOffset(normSeg.targetPoint.dx, _currentPoint.dy);
break;
case SvgPathSegType.lineToVerticalAbs:
normSeg.targetPoint =
_PathOffset(_currentPoint.dx, normSeg.targetPoint.dy);
break;
case SvgPathSegType.close:
// Reset m_currentPoint for the next path.
normSeg.targetPoint = _subPathPoint;
break;
default:
break;
}
// Update command verb, handle smooth segments and convert quadratic curve
// segments to cubics.
switch (segment.command) {
case SvgPathSegType.moveToRel:
case SvgPathSegType.moveToAbs:
_subPathPoint = normSeg.targetPoint;
// normSeg.command = SvgPathSegType.moveToAbs;
path.moveTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy);
break;
case SvgPathSegType.lineToRel:
case SvgPathSegType.lineToAbs:
case SvgPathSegType.lineToHorizontalRel:
case SvgPathSegType.lineToHorizontalAbs:
case SvgPathSegType.lineToVerticalRel:
case SvgPathSegType.lineToVerticalAbs:
// normSeg.command = SvgPathSegType.lineToAbs;
path.lineTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy);
break;
case SvgPathSegType.close:
// normSeg.command = SvgPathSegType.close;
path.close();
break;
case SvgPathSegType.smoothCubicToRel:
case SvgPathSegType.smoothCubicToAbs:
if (!isCubicCommand(_lastCommand)) {
normSeg.point1 = _currentPoint;
} else {
normSeg.point1 = OffsetHelper.reflectedPoint(
_currentPoint,
_controlPoint,
);
}
continue cubic_abs2;
case SvgPathSegType.cubicToRel:
cubic_abs2:
case SvgPathSegType.cubicToAbs:
_controlPoint = normSeg.point2;
// normSeg.command = SvgPathSegType.cubicToAbs;
path.cubicTo(
normSeg.point1.dx,
normSeg.point1.dy,
normSeg.point2.dx,
normSeg.point2.dy,
normSeg.targetPoint.dx,
normSeg.targetPoint.dy,
);
break;
case SvgPathSegType.smoothQuadToRel:
case SvgPathSegType.smoothQuadToAbs:
if (!isQuadraticCommand(_lastCommand)) {
normSeg.point1 = _currentPoint;
} else {
normSeg.point1 = OffsetHelper.reflectedPoint(
_currentPoint,
_controlPoint,
);
}
continue quad_abs2;
case SvgPathSegType.quadToRel:
quad_abs2:
case SvgPathSegType.quadToAbs:
// Save the unmodified control point.
_controlPoint = normSeg.point1;
normSeg.point1 = OffsetHelper.blendPoints(_currentPoint, _controlPoint);
normSeg.point2 = OffsetHelper.blendPoints(
normSeg.targetPoint,
_controlPoint,
);
// normSeg.command = SvgPathSegType.cubicToAbs;
path.cubicTo(
normSeg.point1.dx,
normSeg.point1.dy,
normSeg.point2.dx,
normSeg.point2.dy,
normSeg.targetPoint.dx,
normSeg.targetPoint.dy,
);
break;
case SvgPathSegType.arcToRel:
case SvgPathSegType.arcToAbs:
if (!_decomposeArcToCubic(_currentPoint, normSeg, path)) {
// On failure, emit a line segment to the target point.
// normSeg.command = SvgPathSegType.lineToAbs;
path.lineTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy);
// } else {
// // decomposeArcToCubic() has already emitted the normalized
// // segments, so set command to PathSegArcAbs, to skip any further
// // emit.
// // normSeg.command = SvgPathSegType.arcToAbs;
}
break;
default:
throw StateError('Invalid command type in path');
}
_currentPoint = normSeg.targetPoint;
if (!isCubicCommand(segment.command) &&
!isQuadraticCommand(segment.command)) {
_controlPoint = _currentPoint;
}
_lastCommand = segment.command;
}