CommandPathSource.fromJson constructor

CommandPathSource.fromJson(
  1. Map<String, Object?> json
)

Implementation

factory CommandPathSource.fromJson(Map<String, Object?> json) {
  _requireKeys(json, const {'kind', 'commands'}, 'source');
  if (json['kind'] != 'commands' || json['commands'] is! List) {
    throw const FormatException('Expected a commands path source.');
  }
  final values = json['commands'] as List;
  final commands = <PathCmd>[];
  for (var index = 0; index < values.length; index++) {
    final path = 'commands[$index]';
    final value = _object(values[index], path);
    final verb = switch (value['verb']) {
      'moveTo' => PathVerb.moveTo,
      'lineTo' => PathVerb.lineTo,
      'quadTo' => PathVerb.quadTo,
      'cubicTo' => PathVerb.cubicTo,
      'close' => PathVerb.close,
      _ => throw FormatException('$path has an unsupported verb.'),
    };
    final pointNames = switch (verb) {
      PathVerb.moveTo || PathVerb.lineTo => const ['p'],
      PathVerb.quadTo => const ['c1', 'p'],
      PathVerb.cubicTo => const ['c1', 'c2', 'p'],
      PathVerb.close => const <String>[],
    };
    _requireKeys(value, {'verb', ...pointNames}, path);
    Vec2 point(String name) => _point(value[name], '$path.$name');
    commands.add(switch (verb) {
      PathVerb.moveTo => PathCmd.moveTo(point('p')),
      PathVerb.lineTo => PathCmd.lineTo(point('p')),
      PathVerb.quadTo => PathCmd.quadTo(point('c1'), point('p')),
      PathVerb.cubicTo => PathCmd.cubicTo(
        point('c1'),
        point('c2'),
        point('p'),
      ),
      PathVerb.close => PathCmd.close(),
    });
  }
  try {
    return CommandPathSource(commands);
  } on ArgumentError catch (error) {
    throw FormatException(error.message?.toString() ?? 'Invalid commands.');
  }
}