// // KMGuideTargetView.swift // PDF Reader Pro // // Created by tangchao on 2024/6/25. // import Cocoa @objc enum KMGuideTargetStyle: UInt { case none = 0 case ellipse case round } @objcMembers class KMGuideTargetView: NSView { var lineWidth: CGFloat = 2 { didSet { self.needsDisplay = true } } var strokeColor: NSColor = .black { didSet { self.needsDisplay = true } } var insets: NSEdgeInsets = .init(top: 0, left: 0, bottom: 0, right: 0) { didSet { self.needsDisplay = true } } var style: KMGuideTargetStyle = .ellipse { didSet { self.needsDisplay = true } } var xRadius: CGFloat = 0 { didSet { self.needsDisplay = true } } var yRadius: CGFloat = 0 { didSet { self.needsDisplay = true } } override func draw(_ dirtyRect: NSRect) { super.draw(dirtyRect) let rect = self.bounds let left = self.insets.left let top = self.insets.top let drawW = max(NSWidth(rect)-left-self.insets.right, 0) let drawH = max(NSHeight(rect)-top-self.insets.bottom, 0) let drawRect = NSMakeRect(left, top, drawW, drawH) let context = NSGraphicsContext.current?.cgContext context?.saveGState() context?.setLineWidth(self.lineWidth) context?.setStrokeColor(self.strokeColor.cgColor) let dxy = self.lineWidth * 0.5 let outRect = drawRect.insetBy(dx: dxy, dy: dxy) if style == .ellipse { context?.addEllipse(in: outRect) } else if style == .round { let path = CGPath(roundedRect: outRect, cornerWidth: xRadius, cornerHeight: yRadius, transform: nil) context?.addPath(path) } let offset: CGFloat = 4 let inRect = outRect.insetBy(dx: dxy+offset, dy: dxy+offset) if style == .ellipse { context?.addEllipse(in: inRect) } else if style == .round { let path = CGPath(roundedRect: inRect, cornerWidth: xRadius-offset, cornerHeight: yRadius-offset, transform: nil) context?.addPath(path) } context?.strokePath() context?.restoreGState() } // func _bezierPathToCGPath(_ bezierPath: NSBezierPath) -> CGPath? { // let mutablePath = CGMutablePath() // let numElements = bezierPath.elementCount // let points = UnsafeMutablePointer.allocate(capacity: 3) // // for i in 0 ..< numElements { // switch bezierPath.element(at: i, associatedPoints: points) { // case .moveTo: // KMPathMoveToPoint(mutablePath, nil, points[0].x, points[0].y) // case .lineTo: // KMPathAddLineToPoint(mutablePath, nil, points[0].x, points[0].y) // case .curveTo: // KMPathAddCurveToPoint(mutablePath, nil, points[0].x, points[0].y,points[1].x, points[1].y, points[2].x, points[2].y) // case .closePath: // KMPathCloseSubpath(mutablePath) // default: // break // } // } // // return KMPathCreateCopy(mutablePath) // } }