static void copyClosingSubpathsApplierFunction(void* info, const CGPathElement* element) { CGMutablePathRef path = static_cast<CGMutablePathRef>(info); CGPoint* points = element->points; switch (element->type) { case kCGPathElementMoveToPoint: if (!CGPathIsEmpty(path)) // to silence a warning when trying to close an empty path CGPathCloseSubpath(path); // This is the only change from CGPathCreateMutableCopy CGPathMoveToPoint(path, 0, points[0].x, points[0].y); break; case kCGPathElementAddLineToPoint: CGPathAddLineToPoint(path, 0, points[0].x, points[0].y); break; case kCGPathElementAddQuadCurveToPoint: CGPathAddQuadCurveToPoint(path, 0, points[0].x, points[0].y, points[1].x, points[1].y); break; case kCGPathElementAddCurveToPoint: CGPathAddCurveToPoint(path, 0, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y); break; case kCGPathElementCloseSubpath: CGPathCloseSubpath(path); break; } }
Point PathBuilderCG::CurrentPoint() const { Point ret; if (!CGPathIsEmpty(mCGPath)) { CGPoint pt = CGPathGetCurrentPoint(mCGPath); ret.MoveTo(pt.x, pt.y); } return ret; }
void PathBuilderCG::LineTo(const Point &aPoint) { if (!aPoint.IsFinite()) { return; } if (CGPathIsEmpty(mCGPath)) MoveTo(aPoint); else CGPathAddLineToPoint(mCGPath, nullptr, aPoint.x, aPoint.y); }
void PathBuilderCG::QuadraticBezierTo(const Point &aCP1, const Point &aCP2) { if (!aCP1.IsFinite() || !aCP2.IsFinite()) { return; } if (CGPathIsEmpty(mCGPath)) MoveTo(aCP1); CGPathAddQuadCurveToPoint(mCGPath, nullptr, aCP1.x, aCP1.y, aCP2.x, aCP2.y); }
bool Path::isEmpty() const { return CGPathIsEmpty(m_path); }
void PathBuilderCG::Close() { if (!CGPathIsEmpty(mCGPath)) CGPathCloseSubpath(mCGPath); }
void Path::closeSubpath() { if (!CGPathIsEmpty(m_path)) // to silence a warning when trying to close an empty path CGPathCloseSubpath(m_path); }
bool Path::isEmpty() const { return isNull() || CGPathIsEmpty(m_path); }