emitSegment method

void emitSegment(
  1. PathSegmentData segment,
  2. PathProxy path
)

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;
}