¿Cómo puedo get el área y el perímetro del uibeizerPath como método fill () ha utilizado el área cerrada

Como UIBeizerPath admite para fill() llenar el área incluida. Mi requisito es cómo obtengo el área cerrada de UIBeizerPath() mismo que el método fill() está utilizando. Estaría muy agradecido si pudiera get ayuda para encontrar el área y el perímetro de la ruta beizer.

Supongamos que quiero get el área adjunta en la letra 'A', puedo get todos los beizerPath CGPoints pero no puedo definir subpaths como la regla evenOdd para get las properties de campo requeridas y finalmente get el área. Tengo mucha curiosidad por saber cómo fill() es capaz de get el área cerrada.

Conseguí beizerPath para la fuente como en esta solución y quiero get el área para cualquier fuente dibujada de esto.

¿Cómo podría lograr esto?

 extension CGPath{ func forEach( body: @convention(block) (CGPathElement) -> Void) { typealias Body = @convention(block) (CGPathElement) -> Void let callback: @convention(c) (UnsafeMutableRawPointer, UnsafePointer<CGPathElement>) -> Void = { (info, element) in let body = unsafeBitCast(info, to: Body.self) body(element.pointee) } print(MemoryLayout.size(ofValue: body)) let unsafeBody = unsafeBitCast(body, to: UnsafeMutableRawPointer.self) self.apply(info: unsafeBody, function: unsafeBitCast(callback, to: CGPathApplierFunction.self)) } } extension UIBezierPath{ var length: CGFloat{ var pathLength:CGFloat = 0.0 var current = CGPoint.zero var first = CGPoint.zero self.cgPath.forEach{ element in pathLength += element.distance(to: current, startPoint: first) if element.type == .moveToPoint{ first = element.point } if element.type != .closeSubpath{ current = element.point } } return pathLength } } extension CGPathElement{ var point: CGPoint{ switch type { case .moveToPoint, .addLineToPoint: return self.points[0] case .addQuadCurveToPoint: return self.points[1] case .addCurveToPoint: return self.points[2] case .closeSubpath: return CGRect.null.origin } } func distance(to point: CGPoint, startPoint: CGPoint ) -> CGFloat{ switch type { case .moveToPoint: return 0.0 case .closeSubpath: return point.distance(to:startPoint) case .addLineToPoint: return point.distance(to:self.points[0]) case .addCurveToPoint: return BezierCurveLength(p0: point, c1: self.points[0], c2: self.points[1], p1: self.points[2]) case .addQuadCurveToPoint: return BezierCurveLength(p0: point, c1: self.points[0], p1: self.points[1]) } } } extension CGPoint{ func distance(to:CGPoint) -> CGFloat{ let dx = pow(to.x - self.x,2) let dy = pow(to.y - self.y,2) return sqrt(dx+dy) } } // Helper Functions func CubicBezierCurveFactors(t:CGFloat) -> (CGFloat,CGFloat,CGFloat,CGFloat){ let t1 = pow(1.0-t, 3.0) let t2 = 3.0*pow(1.0-t,2.0)*t let t3 = 3.0*(1.0-t)*pow(t,2.0) let t4 = pow(t, 3.0) return (t1,t2,t3,t4) } func QuadBezierCurveFactors(t:CGFloat) -> (CGFloat,CGFloat,CGFloat){ let t1 = pow(1.0-t,2.0) let t2 = 2.0*(1-t)*t let t3 = pow(t, 2.0) return (t1,t2,t3) } // Quadratic Bezier Curve func BezierCurve(t:CGFloat,p0:CGFloat,c1:CGFloat,p1:CGFloat) -> CGFloat{ let factors = QuadBezierCurveFactors(t: t) return (factors.0*p0) + (factors.1*c1) + (factors.2*p1) } // Quadratic Bezier Curve func BezierCurve(t:CGFloat,p0:CGPoint,c1:CGPoint,p1:CGPoint) -> CGPoint{ let x = BezierCurve(t: t, p0: p0.x, c1: c1.x, p1: p1.x) let y = BezierCurve(t: t, p0: p0.y, c1: c1.y, p1: p1.y) return CGPoint(x: x, y: y) } // Cubic Bezier Curve func BezierCurve(t:CGFloat,p0:CGFloat, c1:CGFloat, c2:CGFloat, p1:CGFloat) -> CGFloat{ let factors = CubicBezierCurveFactors(t: t) return (factors.0*p0) + (factors.1*c1) + (factors.2*c2) + (factors.3*p1) } // Cubic Bezier Curve func BezierCurve(t: CGFloat, p0:CGPoint, c1:CGPoint, c2: CGPoint, p1: CGPoint) -> CGPoint{ let x = BezierCurve(t: t, p0: p0.x, c1: c1.x, c2: c2.x, p1: p1.x) let y = BezierCurve(t: t, p0: p0.y, c1: c1.y, c2: c2.y, p1: p1.y) return CGPoint(x: x, y: y) } // Cubic Bezier Curve Length func BezierCurveLength(p0:CGPoint,c1:CGPoint, c2:CGPoint, p1:CGPoint) -> CGFloat{ let steps = 12 var current = p0 var previous = p0 var length:CGFloat = 0.0 for i in 1...steps{ let t = CGFloat(i) / CGFloat(steps) current = BezierCurve(t: t, p0: p0, c1: c1, c2: c2, p1: p1) length += previous.distance(to: current) previous = current } return length } // Quadratic Bezier Curve Length func BezierCurveLength(p0:CGPoint,c1:CGPoint, p1:CGPoint) -> CGFloat{ let steps = 12 var current = p0 var previous = p0 var length:CGFloat = 0.0 for i in 1...steps{ let t = CGFloat(i) / CGFloat(steps) current = BezierCurve(t: t, p0: p0, c1: c1, p1: p1) length += previous.distance(to: current) previous = current } return length }