OSDN Git Service

swiftlint 'line_length'の警告を修正
[kcd/KCD.git] / KCD / StrokeTextFieldCell.swift
1 //
2 //  StrokeTextFieldCell.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/01.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 class StrokeTextFieldCell: NSTextFieldCell {
12     private static let boarderWidth: CGFloat = 2.0
13     
14     private let layoutManager: NSLayoutManager
15     private let textContainer: NSTextContainer
16     
17     required init(coder: NSCoder) {
18         layoutManager = NSLayoutManager()
19         textContainer = NSTextContainer()
20         super.init(coder: coder)
21         layoutManager.addTextContainer(textContainer)
22     }
23     
24     override func drawInterior(withFrame cellFrame: NSRect, in controlView: NSView) {
25         let attributedString = attributedStringValue
26         if attributedString.string.hasSuffix("/") {
27             super.drawInterior(withFrame: cellFrame, in: controlView)
28             return
29         }
30         let attribute = attributedString.attributes(at: 0, effectiveRange: nil)
31         guard let forgroundColor = attribute[NSForegroundColorAttributeName] as? NSColor else { return }
32         if forgroundColor == NSColor.controlTextColor {
33             super.drawInterior(withFrame: cellFrame, in: controlView)
34             return
35         }
36         guard let font = attribute[NSFontAttributeName] as? NSFont else { return }
37         
38         let textStorage = NSTextStorage(string: attributedString.string, attributes: attribute)
39         textStorage.addLayoutManager(layoutManager)
40         let range = layoutManager.glyphRange(for: textContainer)
41         let glyph = UnsafeMutablePointer<CGGlyph>.allocate(capacity: range.length)
42         let glyphLength = layoutManager.getGlyphs(in: range,
43                                                   glyphs: glyph,
44                                                   properties: nil,
45                                                   characterIndexes: nil,
46                                                   bidiLevels: nil)
47         var point = NSPoint(x: StrokeTextFieldCell.boarderWidth, y: 0)
48         point.y -= font.descender
49         if controlView.isFlipped {
50             point.y -= controlView.frame.height
51         }
52         let nsGlyph = UnsafeMutablePointer<NSGlyph>.allocate(capacity: range.length)
53         for i in 0...range.length {
54             nsGlyph[i] = NSGlyph(glyph[i])
55         }
56         
57         let path = NSBezierPath()
58         path.move(to: point)
59         path.appendGlyphs(nsGlyph, count: glyphLength, in: font)
60         path.lineWidth = StrokeTextFieldCell.boarderWidth
61         path.lineJoinStyle = .roundLineJoinStyle
62         if controlView.isFlipped {
63             var affineTransform = AffineTransform()
64             affineTransform.scale(x: 1, y: -1)
65             path.transform(using: affineTransform)
66         }
67         
68         NSColor.black.set()
69         path.stroke()
70         forgroundColor.set()
71         path.fill()
72         
73         textStorage.removeLayoutManager(layoutManager)
74     }
75 }