mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-25 14:52:19 +03:00
GH-221 Draw word-wise to take ligatures into account
This commit is contained in:
parent
2bfa872648
commit
75f922d4e7
@ -83,7 +83,7 @@ struct Region: CustomStringConvertible {
|
||||
|
||||
/// Almost a verbatim copy of ugrid.c of NeoVim
|
||||
class Grid: CustomStringConvertible {
|
||||
|
||||
|
||||
private(set) var region = Region.zero
|
||||
private(set) var size = Size.zero
|
||||
private(set) var putPosition = Position.zero
|
||||
@ -201,6 +201,32 @@ class Grid: CustomStringConvertible {
|
||||
return position.row * self.size.width + position.column
|
||||
}
|
||||
|
||||
func regionOfCurrentWord(position: Position) -> Region {
|
||||
let row = position.row
|
||||
let column = position.column
|
||||
|
||||
// NSLog("current char: '\(self.cells[row][column])'")
|
||||
|
||||
var left = 0
|
||||
for (idx, cell) in self.cells[row][0...column].enumerate().reverse() {
|
||||
if cell.string == " " || cell.string == "" {
|
||||
left = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var right = self.region.right
|
||||
for idx in column..<self.size.width {
|
||||
let cell = self.cells[row][idx]
|
||||
if cell.string == " " || cell.string == "" {
|
||||
right = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return Region(top: row, bottom: row, left: left, right: right)
|
||||
}
|
||||
|
||||
func positionFromSingleIndex(idx: Int) -> Position {
|
||||
let row = Int(floor(Double(idx) / Double(self.size.width)))
|
||||
let column = idx - row * self.size.width
|
||||
|
@ -63,8 +63,9 @@ public class NeoVimView: NSView {
|
||||
private var pinchTargetScale = CGFloat(1)
|
||||
private var pinchImage = NSImage()
|
||||
|
||||
public var useLigatures = false {
|
||||
public var usesLigatures = false {
|
||||
didSet {
|
||||
self.drawer.usesLigatures = self.usesLigatures
|
||||
self.needsDisplay = true
|
||||
}
|
||||
}
|
||||
@ -180,6 +181,7 @@ public class NeoVimView: NSView {
|
||||
CGContextSetTextDrawingMode(context, .Fill);
|
||||
|
||||
let dirtyRects = self.rectsBeingDrawn()
|
||||
// NSLog("\(dirtyRects)")
|
||||
|
||||
self.rowRunIntersecting(rects: dirtyRects).forEach { rowFrag in
|
||||
// For background drawing we don't filter out the put(0, 0)s: in some cases only the put(0, 0)-cells should be
|
||||
@ -292,8 +294,8 @@ public class NeoVimView: NSView {
|
||||
|
||||
private func pointInViewFor(row row: Int, column: Int) -> CGPoint {
|
||||
return CGPoint(
|
||||
x: CGFloat(column) * self.cellSize.width + self.xOffset,
|
||||
y: self.frame.size.height - CGFloat(row) * self.cellSize.height - self.cellSize.height - self.yOffset
|
||||
x: self.xOffset + CGFloat(column) * self.cellSize.width,
|
||||
y: self.frame.size.height - self.yOffset - CGFloat(row) * self.cellSize.height - self.cellSize.height
|
||||
)
|
||||
}
|
||||
|
||||
@ -310,11 +312,14 @@ public class NeoVimView: NSView {
|
||||
let width = right - left + 1
|
||||
let height = bottom - top + 1
|
||||
|
||||
let cellWidth = self.cellSize.width
|
||||
let cellHeight = self.cellSize.height
|
||||
|
||||
return CGRect(
|
||||
x: left * self.cellSize.width + self.xOffset,
|
||||
y: (CGFloat(self.grid.size.height) - bottom) * self.cellSize.height - self.yOffset,
|
||||
width: width * self.cellSize.width,
|
||||
height: height * self.cellSize.height
|
||||
x: self.xOffset + left * cellWidth,
|
||||
y: self.bounds.size.height - self.yOffset - top * cellHeight - height * cellHeight,
|
||||
width: width * cellWidth,
|
||||
height: height * cellHeight
|
||||
)
|
||||
}
|
||||
|
||||
@ -849,10 +854,19 @@ extension NeoVimView: NeoVimUiBridgeProtocol {
|
||||
let curPos = self.grid.putPosition
|
||||
// NSLog("\(#function): \(curPos) -> \(string)")
|
||||
self.grid.put(string)
|
||||
self.setNeedsDisplay(cellPosition: curPos)
|
||||
|
||||
if self.usesLigatures {
|
||||
if string == " " {
|
||||
self.setNeedsDisplay(cellPosition: curPos)
|
||||
} else {
|
||||
self.setNeedsDisplay(region: self.grid.regionOfCurrentWord(curPos))
|
||||
}
|
||||
} else {
|
||||
self.setNeedsDisplay(cellPosition: curPos)
|
||||
}
|
||||
|
||||
// When the cursor is in the command line, then we need this...
|
||||
self.setNeedsDisplay(cellPosition: self.grid.nextCellPosition(curPos))
|
||||
|
||||
self.setNeedsDisplay(screenCursor: self.grid.screenCursor)
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
@interface TextDrawer : NSObject
|
||||
|
||||
@property (nonatomic, nonnull, retain) NSFont *font;
|
||||
@property (nonatomic) bool useLigatures;
|
||||
@property (nonatomic) bool usesLigatures;
|
||||
@property (nonatomic, readonly) CGFloat leading;
|
||||
@property (nonatomic, readonly) CGFloat descent;
|
||||
@property (nonatomic, readonly) CGSize cellSize;
|
||||
|
@ -57,7 +57,7 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
_useLigatures = useLigatures;
|
||||
_usesLigatures = useLigatures;
|
||||
_layoutManager = [[NSLayoutManager alloc] init];
|
||||
_fontLookupCache = [[NSMutableArray alloc] init];
|
||||
_fontTraitCache = [[NSMutableDictionary alloc] init];
|
||||
@ -135,7 +135,7 @@
|
||||
CTFontRef fontWithTraits = [self fontWithTrait:fontTrait];
|
||||
|
||||
CGContextSetRGBFillColor(context, RED(foreground), GREEN(foreground), BLUE(foreground), 1.0);
|
||||
recurseDraw(unichars, glyphs, positions, unilength, context, fontWithTraits, _fontLookupCache, _useLigatures);
|
||||
recurseDraw(unichars, glyphs, positions, unilength, context, fontWithTraits, _fontLookupCache, _usesLigatures);
|
||||
|
||||
CFRelease(fontWithTraits);
|
||||
free(glyphs);
|
||||
|
@ -35,6 +35,7 @@ class AppearancePrefPane: NSView, NSComboBoxDelegate, NSControlTextEditingDelega
|
||||
private var font: NSFont
|
||||
private var fontSize = CGFloat(13)
|
||||
private var fontName = "Menlo"
|
||||
private var usesLigatures = false
|
||||
|
||||
// Return true to place this to the upper left corner when the scroll view is bigger than this view.
|
||||
override var flipped: Bool {
|
||||
@ -47,6 +48,7 @@ class AppearancePrefPane: NSView, NSComboBoxDelegate, NSControlTextEditingDelega
|
||||
self.font = initialData.editorFont
|
||||
self.fontSize = initialData.editorFont.pointSize
|
||||
self.fontName = initialData.editorFont.fontName
|
||||
self.usesLigatures = initialData.editorUsesLigatures
|
||||
|
||||
super.init(frame: CGRect.zero)
|
||||
self.translatesAutoresizingMaskIntoConstraints = false
|
||||
@ -164,6 +166,7 @@ class AppearancePrefPane: NSView, NSComboBoxDelegate, NSControlTextEditingDelega
|
||||
private func updateViews() {
|
||||
self.fontPopup.selectItemWithTitle(self.fontName)
|
||||
self.sizeCombo.stringValue = String(Int(self.fontSize))
|
||||
self.ligatureCheckbox.state = self.usesLigatures ? NSOnState : NSOffState
|
||||
self.previewArea.font = self.font
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ class MainWindowComponent: NSObject, NSWindowDelegate, NeoVimViewDelegate, Compo
|
||||
private let window: NSWindow
|
||||
|
||||
private var defaultEditorFont: NSFont
|
||||
private var usesLigatures: Bool
|
||||
|
||||
var uuid: String {
|
||||
return self.neoVimView.uuid
|
||||
@ -36,6 +37,7 @@ class MainWindowComponent: NSObject, NSWindowDelegate, NeoVimViewDelegate, Compo
|
||||
self.mainWindowManager = manager
|
||||
self.window = self.windowController.window!
|
||||
self.defaultEditorFont = initialData.appearance.editorFont
|
||||
self.usesLigatures = initialData.appearance.editorUsesLigatures
|
||||
|
||||
super.init()
|
||||
|
||||
@ -66,9 +68,10 @@ class MainWindowComponent: NSObject, NSWindowDelegate, NeoVimViewDelegate, Compo
|
||||
private func addReactions() {
|
||||
self.source
|
||||
.filter { $0 is PrefData }
|
||||
.map { ($0 as! PrefData).appearance.editorFont }
|
||||
.subscribeNext { [unowned self] font in
|
||||
self.neoVimView.font = font
|
||||
.map { ($0 as! PrefData).appearance }
|
||||
.subscribeNext { [unowned self] appearance in
|
||||
self.neoVimView.usesLigatures = appearance.editorUsesLigatures
|
||||
self.neoVimView.font = appearance.editorFont
|
||||
}
|
||||
.addDisposableTo(self.disposeBag)
|
||||
}
|
||||
@ -105,6 +108,7 @@ extension MainWindowComponent {
|
||||
|
||||
func neoVimReady() {
|
||||
self.neoVimView.font = self.defaultEditorFont
|
||||
self.neoVimView.usesLigatures = self.usesLigatures
|
||||
}
|
||||
|
||||
func neoVimStopped() {
|
||||
|
@ -79,8 +79,9 @@ class PrefStore: Store {
|
||||
private func prefsDict(prefData: PrefData) -> [String: AnyObject] {
|
||||
let appearanceData = prefData.appearance
|
||||
let prefs: [String: AnyObject] = [
|
||||
PrefKeys.editorFontName: appearanceData.editorFont.fontName,
|
||||
PrefKeys.editorFontSize: appearanceData.editorFont.pointSize
|
||||
PrefKeys.editorFontName: appearanceData.editorFont.fontName,
|
||||
PrefKeys.editorFontSize: appearanceData.editorFont.pointSize,
|
||||
PrefKeys.editorUsesLigatures: appearanceData.editorUsesLigatures
|
||||
]
|
||||
return prefs
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user