2019-03-10 11:50:24 +03:00
|
|
|
|
/**
|
|
|
|
|
* Tae Won Ha - http://taewon.de - @hataewon
|
|
|
|
|
* See LICENSE
|
|
|
|
|
*/
|
2018-08-27 19:44:42 +03:00
|
|
|
|
|
|
|
|
|
import Cocoa
|
|
|
|
|
|
|
|
|
|
// let cells = ["👨👨👧👧", "", "a"]
|
|
|
|
|
// let cells = ["👶🏽", "", "a"]
|
|
|
|
|
// let cells = ["ü", "a͆", "a̪"]
|
|
|
|
|
// let cells = ["a", "b" , "c"]
|
|
|
|
|
// let cells = ["<", "-", "-", "\u{1F600}", "", " ", "b", "c"]
|
|
|
|
|
|
|
|
|
|
class MyView: NSView {
|
|
|
|
|
|
|
|
|
|
required init?(coder decoder: NSCoder) {
|
|
|
|
|
super.init(coder: decoder)
|
|
|
|
|
self.setupUgrid()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func draw(_ dirtyRect: NSRect) {
|
|
|
|
|
guard let context = NSGraphicsContext.current?.cgContext else { return }
|
|
|
|
|
|
2019-04-16 23:14:58 +03:00
|
|
|
|
let cellSize = FontUtils.cellSize(of: fira, linespacing: 1, characterspacing: 1)
|
2018-08-27 19:44:42 +03:00
|
|
|
|
|
2018-08-30 18:48:49 +03:00
|
|
|
|
/*
|
|
|
|
|
let string = "a\u{034B}"
|
|
|
|
|
let attrStr = NSAttributedString(string: string, attributes: [.font: fira])
|
|
|
|
|
let ctLine = CTLineCreateWithAttributedString(attrStr)
|
|
|
|
|
let ctRun = (CTLineGetGlyphRuns(ctLine) as! Array<CTRun>)[0]
|
|
|
|
|
let glyphCount = CTRunGetGlyphCount(ctRun)
|
|
|
|
|
var glyphs = Array(repeating: CGGlyph(), count: glyphCount)
|
|
|
|
|
var positions = Array(repeating: CGPoint(), count: glyphCount)
|
|
|
|
|
var advances = Array(repeating: CGSize(), count: glyphCount)
|
|
|
|
|
CTRunGetGlyphs(ctRun, .zero, &glyphs)
|
|
|
|
|
CTRunGetPositions(ctRun, .zero, &positions)
|
|
|
|
|
CTRunGetAdvances(ctRun, .zero, &advances)
|
|
|
|
|
|
|
|
|
|
let attrs = CTRunGetAttributes(ctRun) as! [NSAttributedStringKey: Any]
|
|
|
|
|
let font = attrs[NSAttributedStringKey.font] as! NSFont
|
|
|
|
|
|
|
|
|
|
for i in (0..<positions.count) {
|
|
|
|
|
positions[i].x += 20
|
|
|
|
|
positions[i].y += 10
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print(glyphs)
|
|
|
|
|
print(positions)
|
|
|
|
|
print(advances)
|
|
|
|
|
|
|
|
|
|
CTFontDrawGlyphs(font, glyphs, positions, glyphCount, context)
|
|
|
|
|
*/
|
|
|
|
|
|
2018-08-27 19:44:42 +03:00
|
|
|
|
/*
|
|
|
|
|
// let glyphs: [CGGlyph] = [1614, 1494, 1104, 133]
|
|
|
|
|
let glyphs: [CGGlyph] = [1614, 1614, 1063]
|
|
|
|
|
let positions = (0..<3).compactMap {
|
|
|
|
|
CGPoint(x: CGFloat($0) * cellSize.width, y: 10)
|
|
|
|
|
}
|
|
|
|
|
CTFontDrawGlyphs(
|
|
|
|
|
fira,
|
|
|
|
|
glyphs,
|
|
|
|
|
positions,
|
|
|
|
|
3,
|
|
|
|
|
context
|
|
|
|
|
)
|
|
|
|
|
*/
|
|
|
|
|
|
2019-03-11 10:08:59 +03:00
|
|
|
|
let runs = (0..<5).map { row in
|
2018-08-29 09:40:01 +03:00
|
|
|
|
AttributesRun(
|
2018-08-27 19:44:42 +03:00
|
|
|
|
location: CGPoint(x: 0, y: CGFloat(row) * cellSize.height),
|
|
|
|
|
cells: self.ugrid.cells[row][0..<10],
|
|
|
|
|
attrs: CellAttributes(
|
|
|
|
|
fontTrait: [],
|
|
|
|
|
foreground: 0,
|
|
|
|
|
background: 0xFFFFFF,
|
|
|
|
|
special: 0xFF0000,
|
|
|
|
|
reverse: false
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
}
|
2018-09-03 13:59:48 +03:00
|
|
|
|
|
2018-08-29 09:40:01 +03:00
|
|
|
|
let defaultAttrs = CellAttributes(
|
|
|
|
|
fontTrait: [],
|
|
|
|
|
foreground: 0,
|
|
|
|
|
background: 0xFFFFFF,
|
|
|
|
|
special: 0xFF0000,
|
|
|
|
|
reverse: false
|
|
|
|
|
)
|
2018-09-03 13:59:48 +03:00
|
|
|
|
|
2019-03-11 10:08:59 +03:00
|
|
|
|
self.runDrawer.usesLigatures = true
|
2018-08-29 09:40:01 +03:00
|
|
|
|
runs.forEach { run in
|
2018-09-03 13:59:48 +03:00
|
|
|
|
self.runDrawer.draw(
|
|
|
|
|
runs,
|
|
|
|
|
defaultAttributes: defaultAttrs,
|
|
|
|
|
offset: .zero,
|
|
|
|
|
in: context
|
|
|
|
|
)
|
2018-08-30 18:48:49 +03:00
|
|
|
|
}
|
2018-08-27 19:44:42 +03:00
|
|
|
|
|
|
|
|
|
self.draw(cellGridIn: context, cellSize: cellSize)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private let ugrid = UGrid()
|
2018-08-29 09:40:01 +03:00
|
|
|
|
private let runDrawer = AttributesRunDrawer(
|
2019-04-16 23:14:58 +03:00
|
|
|
|
baseFont: fira, linespacing: 1, characterspacing: 1, usesLigatures: true
|
2018-08-27 19:44:42 +03:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
private func draw(cellGridIn context: CGContext, cellSize: CGSize) {
|
|
|
|
|
context.saveGState()
|
|
|
|
|
defer { context.restoreGState() }
|
|
|
|
|
|
|
|
|
|
let color = NSColor.magenta.cgColor
|
|
|
|
|
context.setFillColor(color)
|
|
|
|
|
|
|
|
|
|
var lines = [
|
|
|
|
|
CGRect(x: 0, y: 0, width: 1, height: self.bounds.height),
|
|
|
|
|
CGRect(x: self.bounds.width - 1, y: 0,
|
|
|
|
|
width: 1, height: self.bounds.height),
|
|
|
|
|
CGRect(x: 0, y: 0, width: self.bounds.width, height: 1),
|
|
|
|
|
CGRect(x: 0, y: self.bounds.height - 1,
|
|
|
|
|
width: self.bounds.width, height: 1),
|
|
|
|
|
]
|
|
|
|
|
let rowCount = Int(ceil(self.bounds.height / cellSize.height))
|
|
|
|
|
let columnCount = Int(ceil(self.bounds.width / cellSize.width))
|
|
|
|
|
|
|
|
|
|
for row in 0..<rowCount {
|
|
|
|
|
for col in 0..<columnCount {
|
|
|
|
|
lines.append(contentsOf: [
|
|
|
|
|
CGRect(x: CGFloat(col) * cellSize.width,
|
|
|
|
|
y: CGFloat(row) * cellSize.height,
|
|
|
|
|
width: 1,
|
|
|
|
|
height: self.bounds.height),
|
|
|
|
|
CGRect(x: CGFloat(col) * cellSize.width,
|
|
|
|
|
y: CGFloat(row) * cellSize.height,
|
|
|
|
|
width: self.bounds.width,
|
|
|
|
|
height: 1),
|
|
|
|
|
])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lines.forEach { $0.fill() }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private func setupUgrid() {
|
|
|
|
|
self.ugrid.resize(Size(width: 10, height: 10))
|
|
|
|
|
self.ugrid.update(
|
|
|
|
|
row: 0,
|
|
|
|
|
startCol: 0,
|
|
|
|
|
endCol: 10,
|
|
|
|
|
clearCol: 10,
|
|
|
|
|
clearAttr: 0,
|
|
|
|
|
chunk: [
|
|
|
|
|
"하", "", "태", "", "원", "", " ", "a\u{1DC1}", "a\u{032A}", "a\u{034B}"
|
|
|
|
|
],
|
|
|
|
|
attrIds: Array(repeating: 0, count: 10)
|
|
|
|
|
)
|
|
|
|
|
self.ugrid.update(
|
2018-08-30 18:48:49 +03:00
|
|
|
|
row: 2,
|
2018-08-27 19:44:42 +03:00
|
|
|
|
startCol: 0,
|
|
|
|
|
endCol: 10,
|
|
|
|
|
clearCol: 10,
|
|
|
|
|
clearAttr: 0,
|
|
|
|
|
chunk: [">", "=", " ", "-", "-", ">", " ", "<", "=", ">"],
|
|
|
|
|
attrIds: Array(repeating: 0, count: 10)
|
|
|
|
|
)
|
2018-08-27 20:44:21 +03:00
|
|
|
|
self.ugrid.update(
|
|
|
|
|
row: 1,
|
|
|
|
|
startCol: 0,
|
|
|
|
|
endCol: 10,
|
|
|
|
|
clearCol: 10,
|
|
|
|
|
clearAttr: 0,
|
|
|
|
|
chunk: [ "ἐ", "τ" ,"έ", "ἔ", "-", ">", " ", "<", "=", ">"],
|
|
|
|
|
attrIds: Array(repeating: 0, count: 10)
|
|
|
|
|
)
|
2018-08-27 19:44:42 +03:00
|
|
|
|
self.ugrid.update(
|
2018-08-30 18:48:49 +03:00
|
|
|
|
row: 3,
|
2018-08-27 19:44:42 +03:00
|
|
|
|
startCol: 0,
|
|
|
|
|
endCol: 10,
|
|
|
|
|
clearCol: 10,
|
|
|
|
|
clearAttr: 0,
|
|
|
|
|
chunk: (0..<10).compactMap { String($0) },
|
|
|
|
|
attrIds: Array(repeating: 0, count: 10)
|
|
|
|
|
)
|
2019-03-11 00:40:53 +03:00
|
|
|
|
self.ugrid.update(
|
|
|
|
|
row: 4,
|
|
|
|
|
startCol: 0,
|
2019-03-11 10:22:06 +03:00
|
|
|
|
endCol: 8,
|
|
|
|
|
clearCol: 8,
|
2019-03-11 00:40:53 +03:00
|
|
|
|
clearAttr: 0,
|
2019-03-11 10:22:06 +03:00
|
|
|
|
chunk: ["क", "ख", "ग", "घ", "ड़", "-", ">", "ड़"],
|
|
|
|
|
attrIds: Array(repeating: 0, count: 8)
|
2019-03-11 00:40:53 +03:00
|
|
|
|
)
|
2018-08-27 19:44:42 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private let fira = NSFont(name: "FiraCode-Regular", size: 36)!
|