Skip to content

Instantly share code, notes, and snippets.

@juliensagot
Last active September 26, 2023 23:11
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save juliensagot/9749c3a1df28c38fb9f9 to your computer and use it in GitHub Desktop.
Save juliensagot/9749c3a1df28c38fb9f9 to your computer and use it in GitHub Desktop.
Convert NSBezierPath to CGPath (Swift 5.1, Xcode 11.3 (11C29))
extension NSBezierPath {
/// A `CGPath` object representing the current `NSBezierPath`.
var cgPath: CGPath {
let path = CGMutablePath()
let points = UnsafeMutablePointer<NSPoint>.allocate(capacity: 3)
if elementCount > 0 {
var didClosePath = true
for index in 0..<elementCount {
let pathType = element(at: index, associatedPoints: points)
switch pathType {
case .moveTo:
path.move(to: points[0])
case .lineTo:
path.addLine(to: points[0])
didClosePath = false
case .curveTo:
path.addCurve(to: points[2], control1: points[0], control2: points[1])
didClosePath = false
case .closePath:
path.closeSubpath()
didClosePath = true
@unknown default:
break
}
}
if !didClosePath { path.closeSubpath() }
}
points.deallocate()
return path
}
}
@keefo
Copy link

keefo commented Apr 11, 2021

Hi @juliensagot

@keefo Do you have an example of a non-working path so I can check?

I use this original code to draw a circle in my project.
it gives me weird results. So, I checked the Apple doc and updated line 24. It works now in my project.

https://github.com/keefo/NeewerLite/blob/main/NeewerLite/NeewerLite/Common/ColorWheel.swift#L112
https://github.com/keefo/NeewerLite/blob/main/NeewerLite/NeewerLite/Common/NSBezierPathExtensions.swift#L28

@juliensagot
Copy link
Author

@keefo @dceddia Thank you guys! I've updated the gist 🙏

@pkclsoft
Copy link

Why do you call closeSubPath() at line 31? If you want a path that is not closed, then this causes issues.

@iSapozhnik
Copy link

If you are targeting macOS 14 then cgPath is already part of the NSBezierPath API - https://developer.apple.com/videos/play/wwdc2023/10054/?time=676

@pkclsoft
Copy link

If you are targeting macOS 14 then cgPath is already part of the NSBezierPath API - https://developer.apple.com/videos/play/wwdc2023/10054/?time=676

LOL, do you mean "finally"? It is great that it's been added, but this would have been a logical thing to have had for a long time now. Thanks for pointing that out though, as there are new elements in the case that are not handled by this gist that the new built-in probably does.

@iSapozhnik
Copy link

If you are targeting macOS 14 then cgPath is already part of the NSBezierPath API - https://developer.apple.com/videos/play/wwdc2023/10054/?time=676

LOL, do you mean "finally"? It is great that it's been added, but this would have been a logical thing to have had for a long time now. Thanks for pointing that out though, as there are new elements in the case that are not handled by this gist that the new built-in probably does.

Even though I did not mean "finally" but I share your view. It's sad to see how appkit is still years behind uikit but on the other hand I'm happy that there is at least some work is going on improving appkit API.

@juliensagot
Copy link
Author

If you are targeting macOS 14 then cgPath is already part of the NSBezierPath API - https://developer.apple.com/videos/play/wwdc2023/10054/?time=676

Nice catch! What a time to be alive 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment