2 // StrokeTextFieldCell.swift
5 // Created by Hori,Masaki on 2017/01/01.
6 // Copyright © 2017年 Hori,Masaki. All rights reserved.
11 final class StrokeTextFieldCell: NSTextFieldCell {
13 private static let boarderWidth: CGFloat = 2.0
15 private let layoutManager = NSLayoutManager()
16 private let textContainer = NSTextContainer()
18 required init(coder: NSCoder) {
20 super.init(coder: coder)
22 layoutManager.addTextContainer(textContainer)
25 override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
27 let attributedString = attributedStringValue
29 if attributedString.string.hasSuffix("/") {
31 super.drawInterior(withFrame: cellFrame, in: controlView)
36 let attribute = attributedString.attributes(at: 0, effectiveRange: nil)
38 guard let forgroundColor = attribute[.foregroundColor] as? NSColor else {
43 if forgroundColor == .controlTextColor {
45 super.drawInterior(withFrame: cellFrame, in: controlView)
50 guard let font = attribute[.font] as? NSFont else {
55 let textStorage = NSTextStorage(string: attributedString.string, attributes: attribute)
56 textStorage.addLayoutManager(layoutManager)
57 let range = layoutManager.glyphRange(for: textContainer)
58 let glyph = UnsafeMutablePointer<CGGlyph>.allocate(capacity: range.length)
59 let glyphLength = layoutManager.getGlyphs(in: range,
62 characterIndexes: nil,
64 var point = NSPoint(x: StrokeTextFieldCell.boarderWidth, y: 0)
65 point.y -= font.descender
67 if controlView.isFlipped {
69 point.y -= controlView.frame.height
72 let nsGlyph = UnsafeMutablePointer<NSGlyph>.allocate(capacity: range.length)
74 (0..<range.length).forEach { nsGlyph[$0] = NSGlyph(glyph[$0]) }
76 let path = NSBezierPath()
78 path.appendGlyphs(nsGlyph, count: glyphLength, in: font)
79 path.lineWidth = StrokeTextFieldCell.boarderWidth
80 path.lineJoinStyle = .roundLineJoinStyle
82 if controlView.isFlipped {
84 var affineTransform = AffineTransform()
85 affineTransform.scale(x: 1, y: -1)
86 path.transform(using: affineTransform)
94 textStorage.removeLayoutManager(layoutManager)