toCharStringCommands method

List<CharStringCommand> toCharStringCommands(
  1. CharStringOptimizer optimizer
)

Implementation

List<CharStringCommand> toCharStringCommands(CharStringOptimizer optimizer) {
  for (final outline in outlines) {
    if (outline.hasQuadCurves) {
      // NOTE: what about doing it implicitly?
      throw UnsupportedError('CharString outlines must contain cubic curves');
    }

    if (outline.fillRule == FillRule.evenodd) {
      logger.logOnce(Level.warning,
          'Some of the outlines are using even-odd fill rule. Make sure using a non-zero winding number fill rule for OpenType outlines.');
    }
  }

  final commandList = <CharStringCommand>[];

  final isOnCurveList = _getIsOnCurveList();
  final endPoints = _getEndPoints();
  final pointList = _getPointList();

  final relX =
      absToRelCoordinates(pointList.map((e) => e.x.toInt()).toList());
  final relY =
      absToRelCoordinates(pointList.map((e) => e.y.toInt()).toList());

  var isContourStart = true;

  for (var i = 0; i < relX.length; i++) {
    if (isContourStart) {
      commandList.add(CharStringCommand.moveto(relX[i], relY[i]));
      isContourStart = false;
      continue;
    }

    if (!isOnCurveList[i] && !isOnCurveList[i + 1]) {
      final points = [
        for (var p = 0; p < 3; p++) ...[relX[i + p], relY[i + p]]
      ];

      commandList.add(CharStringCommand.curveto(points));
      i += 2;
    } else {
      commandList.add(CharStringCommand.lineto(relX[i], relY[i]));
    }

    if (endPoints.isNotEmpty && endPoints.first == i) {
      endPoints.removeAt(0);
      isContourStart = true;
    }
  }

  return optimizer.optimize(commandList);
}