mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-25 06:43:24 +03:00
GH-666 Optimize rendering
Too slow: When we parallelize the CTLine computation, it's quite fast, but then, the CPU usage is very very high. Still, parallelizing.
This commit is contained in:
parent
9b8e0b6d42
commit
d531835e4c
@ -40,9 +40,36 @@ extension NvimView {
|
||||
).set()
|
||||
dirtyRects.fill()
|
||||
|
||||
self.runs(intersecting: dirtyRects).forEach { row in
|
||||
self.draw(row, in: context)
|
||||
let attrsRuns = self.runs(intersecting: dirtyRects)
|
||||
let runs = attrsRuns.parallelMap {
|
||||
// let runs = attrsRuns.map {
|
||||
run -> (attrsRun: AttributesRun, fontGlyphRuns: [FontGlyphRun]) in
|
||||
|
||||
let font = FontUtils.font(adding: run.attrs.fontTrait, to: self.font)
|
||||
|
||||
let fontGlyphRuns = self.typesetter.fontGlyphRunsWithLigatures(
|
||||
nvimUtf16Cells: run.cells.map { Array($0.string.utf16) },
|
||||
startColumn: run.cells.startIndex,
|
||||
offset: CGPoint(
|
||||
x: self.xOffset, y: run.location.y + self.baselineOffset
|
||||
),
|
||||
font: font,
|
||||
cellWidth: self.cellSize.width
|
||||
)
|
||||
|
||||
return (attrsRun: run, fontGlyphRuns: fontGlyphRuns)
|
||||
}
|
||||
|
||||
let defaultAttrs = self.cellAttributesCollection.defaultAttributes
|
||||
runs.forEach { (attrsRun, fontGlyphRuns) in
|
||||
self.runDrawer.draw(
|
||||
attrsRun,
|
||||
fontGlyphRuns: fontGlyphRuns,
|
||||
defaultAttributes: defaultAttrs,
|
||||
in: context
|
||||
)
|
||||
}
|
||||
|
||||
// self.drawCursor(context: context)
|
||||
|
||||
#if DEBUG
|
||||
@ -191,8 +218,8 @@ extension NvimView {
|
||||
else {
|
||||
// GH-666: FIXME: correct error handling
|
||||
logger.error("row: \(row), range: \(range): " +
|
||||
"Could not get CellAttributes with ID " +
|
||||
"\(cells.first?.attrId)")
|
||||
"Could not get CellAttributes with ID " +
|
||||
"\(cells.first?.attrId)")
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -278,6 +305,7 @@ extension NvimView {
|
||||
of: newFont, linespacing: self.linespacing
|
||||
)
|
||||
|
||||
self.baselineOffset = self.cellSize.height - CTFontGetAscent(newFont)
|
||||
self.resizeNeoVimUi(to: self.bounds.size)
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import MessagePack
|
||||
|
||||
extension NvimView {
|
||||
|
||||
func resize(_ value: MessagePackValue) {
|
||||
final func resize(_ value: MessagePackValue) {
|
||||
guard let array = MessagePackUtils.array(from: value, ofSize: 2, conversion: { $0.intValue }) else {
|
||||
return
|
||||
}
|
||||
@ -22,16 +22,16 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func clear() {
|
||||
final func clear() {
|
||||
bridgeLogger.mark()
|
||||
|
||||
gui.async {
|
||||
self.grid.clear()
|
||||
// self.ugrid.clear()
|
||||
self.markForRenderWholeView()
|
||||
}
|
||||
}
|
||||
|
||||
func modeChange(_ value: MessagePackValue) {
|
||||
final func modeChange(_ value: MessagePackValue) {
|
||||
guard let mode = MessagePackUtils.value(from: value, conversion: { v -> CursorModeShape? in
|
||||
guard let rawValue = v.intValue else { return nil }
|
||||
return CursorModeShape(rawValue: UInt(rawValue))
|
||||
@ -43,7 +43,7 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func scroll(_ value: MessagePackValue) {
|
||||
final func scroll(_ value: MessagePackValue) {
|
||||
guard let array = MessagePackUtils.array(
|
||||
from: value, ofSize: 6, conversion: { $0.intValue }
|
||||
) else {
|
||||
@ -64,7 +64,7 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func unmark(_ value: MessagePackValue) {
|
||||
final func unmark(_ value: MessagePackValue) {
|
||||
// bridgeLogger.debug("\(row):\(column)")
|
||||
//
|
||||
// gui.async {
|
||||
@ -75,8 +75,9 @@ extension NvimView {
|
||||
// }
|
||||
}
|
||||
|
||||
func flush(_ renderData: [MessagePackValue]) {
|
||||
bridgeLogger.hr()
|
||||
final func flush(_ renderData: [MessagePackValue]) {
|
||||
// bridgeLogger.hr()
|
||||
bridgeLogger.debug(renderData.count)
|
||||
|
||||
gui.async {
|
||||
renderData.forEach { value in
|
||||
@ -109,14 +110,14 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func setTitle(with value: MessagePackValue) {
|
||||
final func setTitle(with value: MessagePackValue) {
|
||||
guard let title = value.stringValue else { return }
|
||||
|
||||
bridgeLogger.debug(title)
|
||||
self.eventsSubject.onNext(.setTitle(title))
|
||||
}
|
||||
|
||||
func stop() {
|
||||
final func stop() {
|
||||
bridgeLogger.hr()
|
||||
try? self.api
|
||||
.stop()
|
||||
@ -132,7 +133,7 @@ extension NvimView {
|
||||
.wait()
|
||||
}
|
||||
|
||||
func autoCommandEvent(_ value: MessagePackValue) {
|
||||
final func autoCommandEvent(_ value: MessagePackValue) {
|
||||
guard let array = MessagePackUtils.array(from: value, ofSize: 2, conversion: { $0.intValue }),
|
||||
let event = NvimAutoCommandEvent(rawValue: array[0]) else { return }
|
||||
let bufferHandle = array[1]
|
||||
@ -156,7 +157,7 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func ipcBecameInvalid(_ reason: String) {
|
||||
final func ipcBecameInvalid(_ reason: String) {
|
||||
bridgeLogger.debug(reason)
|
||||
|
||||
self.eventsSubject.onNext(.ipcBecameInvalid(reason))
|
||||
@ -191,11 +192,11 @@ extension NvimView {
|
||||
return
|
||||
}
|
||||
|
||||
bridgeLogger.trace(
|
||||
"row: \(row), startCol: \(startCol), endCol: \(endCol), " +
|
||||
"clearCol: \(clearCol), clearAttr: \(clearAttr), " +
|
||||
"chunk: \(chunk), attrIds: \(attrIds)"
|
||||
)
|
||||
// bridgeLogger.trace(
|
||||
// "row: \(row), startCol: \(startCol), endCol: \(endCol), " +
|
||||
// "clearCol: \(clearCol), clearAttr: \(clearAttr), " +
|
||||
// "chunk: \(chunk), attrIds: \(attrIds)"
|
||||
// )
|
||||
|
||||
let count = endCol - startCol
|
||||
guard chunk.count == count && attrIds.count == count else { return }
|
||||
@ -241,13 +242,13 @@ extension NvimView {
|
||||
// MARK: - Simple
|
||||
extension NvimView {
|
||||
|
||||
func bell() {
|
||||
final func bell() {
|
||||
bridgeLogger.mark()
|
||||
|
||||
NSSound.beep()
|
||||
}
|
||||
|
||||
func cwdChanged(_ value: MessagePackValue) {
|
||||
final func cwdChanged(_ value: MessagePackValue) {
|
||||
guard let cwd = value.stringValue else { return }
|
||||
|
||||
bridgeLogger.debug(cwd)
|
||||
@ -255,7 +256,7 @@ extension NvimView {
|
||||
self.eventsSubject.onNext(.cwdChanged)
|
||||
}
|
||||
|
||||
func colorSchemeChanged(_ value: MessagePackValue) {
|
||||
final func colorSchemeChanged(_ value: MessagePackValue) {
|
||||
guard let values = MessagePackUtils.array(from: value, ofSize: 5, conversion: { $0.intValue }) else { return }
|
||||
|
||||
let theme = Theme(values)
|
||||
@ -267,7 +268,7 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func defaultColorsChanged(_ value: MessagePackValue) {
|
||||
final func defaultColorsChanged(_ value: MessagePackValue) {
|
||||
guard let values = MessagePackUtils.array(
|
||||
from: value, ofSize: 3, conversion: { $0.intValue }
|
||||
) else {
|
||||
@ -294,14 +295,14 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func setDirty(with value: MessagePackValue) {
|
||||
final func setDirty(with value: MessagePackValue) {
|
||||
guard let dirty = value.boolValue else { return }
|
||||
|
||||
bridgeLogger.debug(dirty)
|
||||
self.eventsSubject.onNext(.setDirtyStatus(dirty))
|
||||
}
|
||||
|
||||
func setAttr(with value: MessagePackValue) {
|
||||
final func setAttr(with value: MessagePackValue) {
|
||||
guard let array = value.arrayValue else { return }
|
||||
guard array.count == 6 else { return }
|
||||
|
||||
@ -334,38 +335,38 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func updateMenu() {
|
||||
final func updateMenu() {
|
||||
bridgeLogger.mark()
|
||||
}
|
||||
|
||||
func busyStart() {
|
||||
final func busyStart() {
|
||||
bridgeLogger.mark()
|
||||
}
|
||||
|
||||
func busyStop() {
|
||||
final func busyStop() {
|
||||
bridgeLogger.mark()
|
||||
}
|
||||
|
||||
func mouseOn() {
|
||||
final func mouseOn() {
|
||||
bridgeLogger.mark()
|
||||
}
|
||||
|
||||
func mouseOff() {
|
||||
final func mouseOff() {
|
||||
bridgeLogger.mark()
|
||||
}
|
||||
|
||||
func visualBell() {
|
||||
final func visualBell() {
|
||||
bridgeLogger.mark()
|
||||
}
|
||||
|
||||
func suspend() {
|
||||
final func suspend() {
|
||||
bridgeLogger.mark()
|
||||
}
|
||||
}
|
||||
|
||||
extension NvimView {
|
||||
|
||||
func markForRender(cellPosition position: Position) {
|
||||
final func markForRender(cellPosition position: Position) {
|
||||
self.markForRender(position: position)
|
||||
|
||||
if self.grid.isCellEmpty(position) {
|
||||
@ -377,26 +378,26 @@ extension NvimView {
|
||||
}
|
||||
}
|
||||
|
||||
func markForRender(position: Position) {
|
||||
final func markForRender(position: Position) {
|
||||
self.markForRender(row: position.row, column: position.column)
|
||||
}
|
||||
|
||||
func markForRender(screenCursor position: Position) {
|
||||
final func markForRender(screenCursor position: Position) {
|
||||
self.markForRender(position: position)
|
||||
if self.grid.isNextCellEmpty(position) {
|
||||
self.markForRender(position: self.grid.nextCellPosition(position))
|
||||
}
|
||||
}
|
||||
|
||||
func markForRenderWholeView() {
|
||||
final func markForRenderWholeView() {
|
||||
self.needsDisplay = true
|
||||
}
|
||||
|
||||
func markForRender(region: Region) {
|
||||
final func markForRender(region: Region) {
|
||||
self.setNeedsDisplay(self.rect(for: region))
|
||||
}
|
||||
|
||||
func markForRender(row: Int, column: Int) {
|
||||
final func markForRender(row: Int, column: Int) {
|
||||
self.setNeedsDisplay(self.rect(forRow: row, column: column))
|
||||
}
|
||||
}
|
||||
|
@ -380,4 +380,6 @@ public class NvimView: NSView,
|
||||
|
||||
// MARK: - Private
|
||||
private var _linespacing = NvimView.defaultLinespacing
|
||||
let typesetter = Typesetter()
|
||||
var baselineOffset = CGFloat(0)
|
||||
}
|
||||
|
@ -5,11 +5,7 @@
|
||||
|
||||
import Cocoa
|
||||
|
||||
class AttributesRunDrawer {
|
||||
|
||||
private let logger = LogContext.stdoutLogger(
|
||||
as: String(reflecting: AttributesRunDrawer.self)
|
||||
)
|
||||
final class AttributesRunDrawer {
|
||||
|
||||
var baseFont: NSFont {
|
||||
didSet {
|
||||
@ -33,6 +29,38 @@ class AttributesRunDrawer {
|
||||
self.updateFontMetrics()
|
||||
}
|
||||
|
||||
func draw(
|
||||
_ run: AttributesRun,
|
||||
fontGlyphRuns: [FontGlyphRun],
|
||||
defaultAttributes: CellAttributes,
|
||||
`in` context: CGContext
|
||||
) {
|
||||
context.saveGState()
|
||||
defer { context.restoreGState() }
|
||||
|
||||
self.draw(
|
||||
backgroundFor: run,
|
||||
with: defaultAttributes,
|
||||
in: context
|
||||
)
|
||||
|
||||
context.setFillColor(
|
||||
ColorUtils.cgColorIgnoringAlpha(run.attrs.effectiveForeground)
|
||||
)
|
||||
|
||||
fontGlyphRuns.forEach { run in
|
||||
CTFontDrawGlyphs(
|
||||
run.font,
|
||||
run.glyphs,
|
||||
run.positions,
|
||||
run.glyphs.count,
|
||||
context
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: GH-666: Draw underline/curl
|
||||
}
|
||||
|
||||
func draw(
|
||||
_ run: AttributesRun,
|
||||
with defaultAttributes: CellAttributes,
|
||||
@ -58,7 +86,6 @@ class AttributesRunDrawer {
|
||||
nvimUtf16Cells: run.cells.map { Array($0.string.utf16) },
|
||||
startColumn: run.cells.startIndex,
|
||||
offset: CGPoint(x: xOffset, y: run.location.y + self.baselineOffset),
|
||||
foreground: run.attrs.effectiveForeground,
|
||||
font: font,
|
||||
cellWidth: self.cellSize.width
|
||||
)
|
||||
@ -68,7 +95,6 @@ class AttributesRunDrawer {
|
||||
nvimCells: run.cells.map { $0.string },
|
||||
startColumn: run.cells.startIndex,
|
||||
offset: CGPoint(x: xOffset, y: run.location.y + self.baselineOffset),
|
||||
foreground: run.attrs.effectiveForeground,
|
||||
font: font,
|
||||
cellWidth: self.cellSize.width
|
||||
)
|
||||
|
@ -13,6 +13,25 @@ extension Array where Element: Hashable {
|
||||
}
|
||||
}
|
||||
|
||||
extension Array {
|
||||
|
||||
/// Does not retain the order of elements.
|
||||
func parallelMap<T>(_ transform: @escaping (Element) -> T) -> [T] {
|
||||
var result = Array<T>()
|
||||
result.reserveCapacity(self.count)
|
||||
|
||||
var lock = OS_SPINLOCK_INIT
|
||||
DispatchQueue.concurrentPerform(iterations: self.count) { i in
|
||||
let mapped = transform(self[i])
|
||||
OSSpinLockLock(&lock)
|
||||
result.append(mapped)
|
||||
OSSpinLockUnlock(&lock)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
extension ArraySlice {
|
||||
|
||||
func groupedRanges<T: Equatable>(with marker: (Int, Element, ArraySlice<Element>) -> T) -> [CountableClosedRange<Int>] {
|
||||
|
@ -5,13 +5,12 @@
|
||||
|
||||
import Cocoa
|
||||
|
||||
class Typesetter {
|
||||
final class Typesetter {
|
||||
|
||||
final func fontGlyphRunsWithLigatures(
|
||||
func fontGlyphRunsWithLigatures(
|
||||
nvimUtf16Cells: [[Unicode.UTF16.CodeUnit]],
|
||||
startColumn: Int,
|
||||
offset: CGPoint,
|
||||
foreground: Int,
|
||||
font: NSFont,
|
||||
cellWidth: CGFloat
|
||||
) -> [FontGlyphRun] {
|
||||
@ -21,13 +20,9 @@ class Typesetter {
|
||||
from: nvimUtf16Cells,
|
||||
utf16CharsCount: utf16Chars.count
|
||||
)
|
||||
let ctRuns = self.ctRuns(
|
||||
from: utf16Chars, font: font, foreground: foreground
|
||||
)
|
||||
let ctRuns = self.ctRuns(from: utf16Chars, font: font)
|
||||
|
||||
var result = Array<FontGlyphRun>()
|
||||
result.reserveCapacity(ctRuns.count)
|
||||
for run in ctRuns {
|
||||
let result = ctRuns.map { run -> FontGlyphRun in
|
||||
let glyphCount = CTRunGetGlyphCount(run)
|
||||
|
||||
var glyphs = Array(repeating: CGGlyph(), count: glyphCount)
|
||||
@ -53,19 +48,16 @@ class Typesetter {
|
||||
positions[i].y += offset.y
|
||||
}
|
||||
|
||||
guard
|
||||
let attrs = CTRunGetAttributes(run) as? [NSAttributedStringKey: Any],
|
||||
let font = attrs[NSAttributedStringKey.font] as? NSFont
|
||||
else {
|
||||
// FIXME: GH-666: Return the default font
|
||||
preconditionFailure("Could not get font from CTRun!")
|
||||
}
|
||||
let attrs = CTRunGetAttributes(run)
|
||||
let font = Unmanaged<NSFont>.fromOpaque(
|
||||
CFDictionaryGetValue(
|
||||
attrs, Unmanaged.passUnretained(kCTFontAttributeName).toOpaque()
|
||||
)
|
||||
).takeUnretainedValue()
|
||||
|
||||
let fontGlyphRun = FontGlyphRun(
|
||||
return FontGlyphRun(
|
||||
font: font, glyphs: glyphs, positions: positions
|
||||
)
|
||||
|
||||
result.append(fontGlyphRun)
|
||||
}
|
||||
|
||||
return result
|
||||
@ -80,36 +72,45 @@ class Typesetter {
|
||||
var i = 0
|
||||
repeat {
|
||||
if nvimUtf16Cells[cellIndex].isEmpty {
|
||||
cellIndex += 1
|
||||
cellIndex = cellIndex &+ 1
|
||||
continue
|
||||
}
|
||||
|
||||
for _ in (0..<nvimUtf16Cells[cellIndex].count) {
|
||||
cellIndices[i] = cellIndex
|
||||
i += 1
|
||||
i = i &+ 1
|
||||
}
|
||||
cellIndex += 1
|
||||
cellIndex = cellIndex &+ 1
|
||||
} while cellIndex < nvimUtf16Cells.count
|
||||
|
||||
return cellIndices
|
||||
}
|
||||
|
||||
private func utf16Chars(from nvimUtf16Cells: [[Unicode.UTF16.CodeUnit]]) -> Array<UInt16> {
|
||||
var utf16Chars = Array<Unicode.UTF16.CodeUnit>()
|
||||
utf16Chars.reserveCapacity(Int(Double(nvimUtf16Cells.count) * 1.5))
|
||||
|
||||
private func utf16Chars(
|
||||
from nvimUtf16Cells: [[Unicode.UTF16.CodeUnit]]
|
||||
) -> Array<UInt16> {
|
||||
// Using reduce seems to be slower than the following:
|
||||
var count = 0
|
||||
for i in 0..<nvimUtf16Cells.count {
|
||||
utf16Chars.append(contentsOf: nvimUtf16Cells[i])
|
||||
count = count &+ nvimUtf16Cells[i].count
|
||||
}
|
||||
|
||||
return utf16Chars
|
||||
// Using append(contentsOf:) seems to be slower than the following:
|
||||
var result = Array(repeating: Unicode.UTF16.CodeUnit(), count: count)
|
||||
for i in 0..<nvimUtf16Cells.count {
|
||||
let cell = nvimUtf16Cells[i]
|
||||
for j in 0..<cell.count {
|
||||
result[i + j] = cell[j]
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
final func fontGlyphRunsWithoutLigatures(
|
||||
func fontGlyphRunsWithoutLigatures(
|
||||
nvimCells: [String],
|
||||
startColumn: Int,
|
||||
offset: CGPoint,
|
||||
foreground: Int,
|
||||
font: NSFont,
|
||||
cellWidth: CGFloat
|
||||
) -> [FontGlyphRun] {
|
||||
@ -124,7 +125,6 @@ class Typesetter {
|
||||
nvimUtf16Cells: run.nvimUtf16Cells,
|
||||
startColumn: startColumn + run.startColumn,
|
||||
offset: offset,
|
||||
foreground: foreground,
|
||||
font: font,
|
||||
cellWidth: cellWidth
|
||||
)
|
||||
@ -133,9 +133,11 @@ class Typesetter {
|
||||
let unichars = self.utf16Chars(from: run.nvimUtf16Cells)
|
||||
var glyphs = Array<CGGlyph>(repeating: CGGlyph(), count: unichars.count)
|
||||
|
||||
let gotAllGlyphs = CTFontGetGlyphsForCharacters(
|
||||
font, unichars, &glyphs, unichars.count
|
||||
)
|
||||
let gotAllGlyphs = unichars.withUnsafeBufferPointer { pointer in
|
||||
CTFontGetGlyphsForCharacters(
|
||||
font, pointer.baseAddress!, &glyphs, unichars.count
|
||||
)
|
||||
}
|
||||
if gotAllGlyphs {
|
||||
let startColumnForPositions = startColumn + run.startColumn
|
||||
let endColumn = startColumnForPositions + glyphs.count
|
||||
@ -160,7 +162,6 @@ class Typesetter {
|
||||
nvimUtf16Cells: nvimUtf16Cells,
|
||||
startColumn: startColumn + range.lowerBound,
|
||||
offset: offset,
|
||||
foreground: foreground,
|
||||
font: font,
|
||||
cellWidth: cellWidth
|
||||
)
|
||||
@ -187,21 +188,22 @@ class Typesetter {
|
||||
}
|
||||
|
||||
private func ctRuns(
|
||||
from utf16Chars: [Unicode.UTF16.CodeUnit],
|
||||
font: NSFont,
|
||||
foreground: Int
|
||||
from utf16Chars: Array<Unicode.UTF16.CodeUnit>,
|
||||
font: NSFont
|
||||
) -> [CTRun] {
|
||||
let attrStr = NSAttributedString(
|
||||
string: String(utf16CodeUnits: utf16Chars, count: utf16Chars.count),
|
||||
attributes: [
|
||||
.font: font,
|
||||
.foregroundColor: ColorUtils.cgColorIgnoringAlpha(foreground),
|
||||
.ligature: 1,
|
||||
.ligature: 1
|
||||
]
|
||||
)
|
||||
let ctLine = CTLineCreateWithAttributedString(attrStr)
|
||||
|
||||
guard let ctRuns = CTLineGetGlyphRuns(ctLine) as? [CTRun] else { return [] }
|
||||
let ctLine = CTLineCreateWithAttributedString(attrStr)
|
||||
guard let ctRuns = CTLineGetGlyphRuns(ctLine) as? [CTRun] else {
|
||||
return []
|
||||
}
|
||||
|
||||
return ctRuns
|
||||
}
|
||||
|
||||
@ -220,7 +222,7 @@ class Typesetter {
|
||||
}
|
||||
|
||||
let nvimUtf16Cells = nvimCells.map { Array($0.utf16) }
|
||||
let utf16Chars = nvimUtf16Cells.flatMap { $0 }
|
||||
let utf16Chars = self.utf16Chars(from: nvimUtf16Cells)
|
||||
|
||||
let hasMoreThanTwoCells = nvimUtf16Cells.count >= 2
|
||||
let firstCharHasSingleUnichar = nvimUtf16Cells[0].count == 1
|
||||
|
@ -11,7 +11,7 @@ struct UCell {
|
||||
var attrId: Int
|
||||
}
|
||||
|
||||
class UGrid {
|
||||
final class UGrid {
|
||||
|
||||
private(set) var size = Size.zero
|
||||
private(set) var posision = Position.zero
|
||||
@ -102,6 +102,10 @@ class UGrid {
|
||||
))
|
||||
}
|
||||
|
||||
func clear() {
|
||||
// self.clear(region: self.region)
|
||||
}
|
||||
|
||||
func clear(region: Region) {
|
||||
// FIXME: sometimes clearRegion gets called without first resizing the Grid.
|
||||
// Should we handle this?
|
||||
|
@ -16,7 +16,6 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
|
||||
nvimCells: emojiMarked(["a", "b", "c"]),
|
||||
startColumn: 10,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -40,7 +39,6 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
|
||||
nvimCells: emojiMarked(["ü", "î", "ñ"]),
|
||||
startColumn: 20,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -66,7 +64,6 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
|
||||
),
|
||||
startColumn: 10,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -127,7 +124,6 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
|
||||
nvimCells: asciiMarked(["a", "b", "\u{1F600}", "", "\u{1F377}", ""]),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -161,7 +157,6 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
|
||||
nvimCells: asciiMarked(["a", "\u{1F476}", "", "\u{1F3FD}", ""]),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -193,7 +188,6 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
|
||||
nvimCells: asciiMarked(["a", "b", "하", "", "태", "", "원", ""]),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -227,7 +221,6 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
|
||||
nvimCells: asciiMarked(["a", "b", "河", "", "泰", "", "元", ""]),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -261,7 +254,6 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
|
||||
nvimCells: emojiMarked(["a", "\u{10437}", "\u{1F14}"]),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -301,7 +293,6 @@ class TypesetterWithoutLigaturesTest: XCTestCase {
|
||||
nvimCells: emojiMarked(["a", "-", "-", ">", "a"]),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: fira,
|
||||
cellWidth: firaWidth
|
||||
)
|
||||
@ -340,7 +331,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
)),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -364,7 +354,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
nvimUtf16Cells: utf16Chars(emojiMarked(["ü", "î", "ñ"])),
|
||||
startColumn: 10,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -392,7 +381,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -437,7 +425,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
),
|
||||
startColumn: 0,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -465,7 +452,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
),
|
||||
startColumn: 0,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -493,7 +479,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
)),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -518,7 +503,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -544,7 +528,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
),
|
||||
startColumn: 1,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -570,7 +553,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
),
|
||||
startColumn: 0,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: defaultFont,
|
||||
cellWidth: defaultWidth
|
||||
)
|
||||
@ -602,7 +584,6 @@ class TypesetterWithLigaturesTest: XCTestCase {
|
||||
),
|
||||
startColumn: 0,
|
||||
offset: offset,
|
||||
foreground: 0,
|
||||
font: fira,
|
||||
cellWidth: firaWidth
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user