在 Cocoa 中保存来自 CGContext 的路径
Save Path from CGContext in Cocoa
我正在尝试使用 Cocoa 在 Swift 中为 macOS 编写一个小型绘图应用程序。问题是当再次绘制 NSView
时,最后绘制的线条消失了。有没有办法保留绘制的线条?我可以将这些点保存在一个数组中,但这会大大降低性能。不幸的是,CGContextSaveGState
函数不保存路径。
这是我的 class 我正在画的NSView
(用鼠标或手写笔):
import Cocoa
class DrawingView: NSView {
// Variables
var lastPoint = CGPoint.zero
var currentPoint = CGPoint.zero
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var alpha: CGFloat = 1.0
var brushSize: CGFloat = 2.0
var dragged = false
// Draw function
override func drawRect(rect: NSRect) {
super.drawRect(rect)
let context = NSGraphicsContext.currentContext()?.CGContext
CGContextMoveToPoint(context, lastPoint.x, lastPoint.y)
if !dragged {
CGContextAddLineToPoint(context, lastPoint.x, lastPoint.y)
} else {
CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y)
lastPoint = currentPoint
}
CGContextSetLineCap(context, .Round)
CGContextSetLineWidth(context, brushSize)
CGContextSetRGBStrokeColor(context, red, green, blue, alpha)
CGContextSetBlendMode(context, .Normal)
CGContextDrawPath(context, .Stroke)
}
// Mouse event functions
override func mouseDown(event: NSEvent) {
dragged = false
lastPoint = event.locationInWindow
self.setNeedsDisplayInRect(self.frame)
}
override func mouseDragged(event: NSEvent) {
dragged = true
currentPoint = event.locationInWindow
self.setNeedsDisplayInRect(self.frame)
}
override func mouseUp(event: NSEvent) {
self.setNeedsDisplayInRect(self.frame)
}
}
对于这种情况,我将退出 CoreGraphics 并使用 NSBezierPath
。您可以将其保存在 属性 中。然后你可以调用 lineToPoint
随着更多的点进来,然后调用 stroke
来绘制它。例如:
let strokeColor = NSColor(red: red, green: green, blue: blue, alpha: 1.0)
let path = NSBezierPath()
path.lineWidth = brushSize
path.lineCapStyle = .RoundLineCapStyle
path.lineJoinStyle = .RoundLineJoinStyle
path.moveToPoint(lastPoint)
path.lineToPoint(currentPoint)
...
strokeColor.setStroke()
path.stroke()
您正在寻找 CGContextCopyPath。它给你一个 CGPath 伪对象。保存它的最简单方法是将其作为 path
填充到 NSBezierPath 中,因为 NSBezierPath 是一个 真实的 对象,ARC 将为您进行内存管理。
我正在尝试使用 Cocoa 在 Swift 中为 macOS 编写一个小型绘图应用程序。问题是当再次绘制 NSView
时,最后绘制的线条消失了。有没有办法保留绘制的线条?我可以将这些点保存在一个数组中,但这会大大降低性能。不幸的是,CGContextSaveGState
函数不保存路径。
这是我的 class 我正在画的NSView
(用鼠标或手写笔):
import Cocoa
class DrawingView: NSView {
// Variables
var lastPoint = CGPoint.zero
var currentPoint = CGPoint.zero
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var alpha: CGFloat = 1.0
var brushSize: CGFloat = 2.0
var dragged = false
// Draw function
override func drawRect(rect: NSRect) {
super.drawRect(rect)
let context = NSGraphicsContext.currentContext()?.CGContext
CGContextMoveToPoint(context, lastPoint.x, lastPoint.y)
if !dragged {
CGContextAddLineToPoint(context, lastPoint.x, lastPoint.y)
} else {
CGContextAddLineToPoint(context, currentPoint.x, currentPoint.y)
lastPoint = currentPoint
}
CGContextSetLineCap(context, .Round)
CGContextSetLineWidth(context, brushSize)
CGContextSetRGBStrokeColor(context, red, green, blue, alpha)
CGContextSetBlendMode(context, .Normal)
CGContextDrawPath(context, .Stroke)
}
// Mouse event functions
override func mouseDown(event: NSEvent) {
dragged = false
lastPoint = event.locationInWindow
self.setNeedsDisplayInRect(self.frame)
}
override func mouseDragged(event: NSEvent) {
dragged = true
currentPoint = event.locationInWindow
self.setNeedsDisplayInRect(self.frame)
}
override func mouseUp(event: NSEvent) {
self.setNeedsDisplayInRect(self.frame)
}
}
对于这种情况,我将退出 CoreGraphics 并使用 NSBezierPath
。您可以将其保存在 属性 中。然后你可以调用 lineToPoint
随着更多的点进来,然后调用 stroke
来绘制它。例如:
let strokeColor = NSColor(red: red, green: green, blue: blue, alpha: 1.0)
let path = NSBezierPath()
path.lineWidth = brushSize
path.lineCapStyle = .RoundLineCapStyle
path.lineJoinStyle = .RoundLineJoinStyle
path.moveToPoint(lastPoint)
path.lineToPoint(currentPoint)
...
strokeColor.setStroke()
path.stroke()
您正在寻找 CGContextCopyPath。它给你一个 CGPath 伪对象。保存它的最简单方法是将其作为 path
填充到 NSBezierPath 中,因为 NSBezierPath 是一个 真实的 对象,ARC 将为您进行内存管理。