parseSegment method

PathSegmentData parseSegment()

Implementation

PathSegmentData parseSegment() {
  assert(hasMoreData);
  final PathSegmentData segment = PathSegmentData();
  final int lookahead = _string.codeUnitAt(_idx);
  SvgPathSegType command = AsciiConstants.mapLetterToSegmentType(lookahead);
  if (_previousCommand == SvgPathSegType.unknown) {
    // First command has to be a moveto.
    if (command != SvgPathSegType.moveToRel &&
        command != SvgPathSegType.moveToAbs) {
      throw StateError('Expected to find moveTo command');
    }
    // Consume command letter.
    _idx++;
  } else if (command == SvgPathSegType.unknown) {
    // Possibly an implicit command.
    assert(_previousCommand != SvgPathSegType.unknown);
    command = _maybeImplicitCommand(lookahead, command);
    if (command == SvgPathSegType.unknown) {
      throw StateError('Expected a path command');
    }
  } else {
    // Valid explicit command.
    _idx++;
  }

  segment.command = _previousCommand = command;

  switch (segment.command) {
    case SvgPathSegType.cubicToRel:
    case SvgPathSegType.cubicToAbs:
      segment.point1 = _PathOffset(_parseNumber(), _parseNumber());
      continue cubic_smooth;
    case SvgPathSegType.smoothCubicToRel:
    cubic_smooth:
    case SvgPathSegType.smoothCubicToAbs:
      segment.point2 = _PathOffset(_parseNumber(), _parseNumber());
      continue quad_smooth;
    case SvgPathSegType.moveToRel:
    case SvgPathSegType.moveToAbs:
    case SvgPathSegType.lineToRel:
    case SvgPathSegType.lineToAbs:
    case SvgPathSegType.smoothQuadToRel:
    quad_smooth:
    case SvgPathSegType.smoothQuadToAbs:
      segment.targetPoint = _PathOffset(_parseNumber(), _parseNumber());
      break;
    case SvgPathSegType.lineToHorizontalRel:
    case SvgPathSegType.lineToHorizontalAbs:
      segment.targetPoint =
          _PathOffset(_parseNumber(), segment.targetPoint.dy);
      break;
    case SvgPathSegType.lineToVerticalRel:
    case SvgPathSegType.lineToVerticalAbs:
      segment.targetPoint =
          _PathOffset(segment.targetPoint.dx, _parseNumber());
      break;
    case SvgPathSegType.close:
      _skipOptionalSvgSpaces();
      break;
    case SvgPathSegType.quadToRel:
    case SvgPathSegType.quadToAbs:
      segment.point1 = _PathOffset(_parseNumber(), _parseNumber());
      segment.targetPoint = _PathOffset(_parseNumber(), _parseNumber());
      break;
    case SvgPathSegType.arcToRel:
    case SvgPathSegType.arcToAbs:
      segment.point1 = _PathOffset(_parseNumber(), _parseNumber());
      segment.arcAngle = _parseNumber();
      segment.arcLarge = _parseArcFlag();
      segment.arcSweep = _parseArcFlag();
      segment.targetPoint = _PathOffset(_parseNumber(), _parseNumber());
      break;
    case SvgPathSegType.unknown:
      throw StateError('Unknown segment command');
  }

  return segment;
}