in Cyborg/DrawingCommand.swift [43:159]
func apply(to path: CGMutablePath, using prior: PriorContext, in size: CGSize) -> PriorContext {
switch self {
case .move(let point):
let next = point.times(size).add(prior.point)
path.move(to: next)
return next.asPriorContext
case .moveAbsolute(let point):
let next = point.times(size)
path.move(to: next)
return next.asPriorContext
case .curve(let control1, let control2, let end):
let intoAbsolute = prior.point
let control1 = control1.times(size).add(intoAbsolute)
let control2 = control2.times(size).add(intoAbsolute)
let end = end.times(size).add(intoAbsolute)
path.addCurve(to: end, control1: control1, control2: control2)
return .lastAndControlPoint(end, control2.reflected(across: end))
case .curveAbsolute(let control1, let control2, let end):
let control1 = control1.times(size)
let control2 = control2.times(size)
let end = end.times(size)
path.addCurve(to: end, control1: control1, control2: control2)
return .lastAndControlPoint(end, control2.reflected(across: end))
case .line(let point):
let point = point.times(size).add(prior.point)
path.addLine(to: point)
return point.asPriorContext
case .lineAbsolute(let point):
let point = point.times(size)
path.addLine(to: point)
return point.asPriorContext
case .horizontal(let magnitude):
let last = prior.point
let next = CGPoint(x: magnitude * size.width + last.x, y: last.y)
path.addLine(to: next)
return next.asPriorContext
case .horizontalAbsolute(let magnitude):
let last = prior.point
let next = CGPoint(x: magnitude * size.width, y: last.y)
path.addLine(to: next)
return next.asPriorContext
case .vertical(let magnitude):
let last = prior.point
let next = CGPoint(x: last.x, y: magnitude * size.height + last.y)
path.addLine(to: next)
return next.asPriorContext
case .verticalAbsolute(let magnitude):
let last = prior.point
let next = CGPoint(x: last.x, y: magnitude * size.height)
path.addLine(to: next)
return next.asPriorContext
case .smoothCurve(let control2, let end):
let (last, control1) = prior.pointAndControlPoint
let end = end.times(size).add(last)
let control2 = control2.times(size).add(last)
path.addCurve(to: end, control1: control1, control2: control2)
return .lastAndControlPoint(end,
control2.reflected(across: end))
case .smoothCurveAbsolute(let control2, let end):
let (_, control1) = prior.pointAndControlPoint
let end = end.times(size)
let control2 = control2.times(size)
path.addCurve(to: end, control1: control1, control2: control2)
return .lastAndControlPoint(end,
control2.reflected(across: end))
case .quadratic(let control1, let end):
let last = prior.point
let end = end.times(size).add(last)
let control1 = control1.times(size).add(last)
path.addQuadCurve(to: end, control: control1)
return .lastAndControlPoint(end,
control1.reflected(across: end))
case .quadraticAbsolute(let control1, let end):
let end = end.times(size)
let control1 = control1.times(size)
path.addQuadCurve(to: end, control: control1)
return .lastAndControlPoint(end,
control1.reflected(across: end))
case .arc(let radius, let rotation, let largeArcFlag, let sweepFlag, let endPoint):
return applyArc(to: path,
in: size,
radius: radius,
rotation: rotation,
largeArcFlag: largeArcFlag,
sweepFlag: sweepFlag,
endPoint: endPoint,
prior: prior,
isRelative: true)
case .arcAbsolute(let radius, let rotation, let largeArcFlag, let sweepFlag, let endPoint):
return applyArc(to: path,
in: size,
radius: radius,
rotation: rotation,
largeArcFlag: largeArcFlag,
sweepFlag: sweepFlag,
endPoint: endPoint,
prior: prior,
isRelative: false)
case .smoothQuadratic(let end):
let (last, control) = prior.pointAndControlPoint
let end = end.times(size).add(last)
path.addQuadCurve(to: end,
control: control)
return .lastAndControlPoint(end,
control.reflected(across: end))
case .smoothQuadraticAbsolute(let end):
let (_, control) = prior.pointAndControlPoint
let end = end.times(size)
path.addQuadCurve(to: end,
control: control)
return .lastAndControlPoint(end,
control.reflected(across: end))
case .closePath, .closePathAbsolute:
path.closeSubpath()
return path.currentPoint.asPriorContext
}
}