From 35527bc52e9590836a930e1a49444d16cf738daa Mon Sep 17 00:00:00 2001 From: Tae Won Ha Date: Wed, 27 Dec 2023 21:50:10 +0100 Subject: [PATCH] Do not include font check for CTRuns when typesetting. We have to clear the cache when changing the font (and other parameters which may affect the typesetting). --- Commons/Sources/Commons/FifoCache.swift | 5 +++++ .../Sources/NvimView/AttributesRunDrawer.swift | 6 +++++- NvimView/Sources/NvimView/Typesetter.swift | 16 +++++++--------- .../Support/MinimalNvimViewDemo/Document.swift | 2 +- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Commons/Sources/Commons/FifoCache.swift b/Commons/Sources/Commons/FifoCache.swift index 3cfa22ae..42fa9356 100644 --- a/Commons/Sources/Commons/FifoCache.swift +++ b/Commons/Sources/Commons/FifoCache.swift @@ -23,6 +23,11 @@ public final class FifoCache { } public func valueForKey(_ key: Key) -> Value? { self.storage[key] } + + public func clear() { + self.keys = Array(repeating: nil, count: count) + self.storage.removeAll(keepingCapacity: true) + } private let count: Int private var keys: [Key?] diff --git a/NvimView/Sources/NvimView/AttributesRunDrawer.swift b/NvimView/Sources/NvimView/AttributesRunDrawer.swift index 31b366f8..9ff0f22e 100644 --- a/NvimView/Sources/NvimView/AttributesRunDrawer.swift +++ b/NvimView/Sources/NvimView/AttributesRunDrawer.swift @@ -18,7 +18,9 @@ final class AttributesRunDrawer { didSet { self.updateFontMetrics() } } - var usesLigatures: Bool + var usesLigatures: Bool { + didSet { self.typesetter.clearCache() } + } private(set) var cellSize: CGSize = .zero private(set) var baselineOffset: CGFloat = 0 @@ -187,5 +189,7 @@ final class AttributesRunDrawer { self.descent = CTFontGetDescent(self.font) self.underlinePosition = CTFontGetUnderlinePosition(self.font) self.underlineThickness = CTFontGetUnderlineThickness(self.font) + + self.typesetter.clearCache() } } diff --git a/NvimView/Sources/NvimView/Typesetter.swift b/NvimView/Sources/NvimView/Typesetter.swift index 95abcbae..5a0e2526 100644 --- a/NvimView/Sources/NvimView/Typesetter.swift +++ b/NvimView/Sources/NvimView/Typesetter.swift @@ -8,6 +8,10 @@ import Commons import os final class Typesetter { + func clearCache() { + self.ctRunsCache.clear() + } + func fontGlyphRunsWithLigatures( nvimUtf16Cells: [[Unicode.UTF16.CodeUnit]], startColumn: Int, @@ -141,8 +145,7 @@ final class Typesetter { } private func ctRuns(from utf16Chars: [Unicode.UTF16.CodeUnit], font: NSFont) -> [CTRun] { - if let ctRunsAndFont = self.ctRunsCache.valueForKey(utf16Chars), - font == ctRunsAndFont.font { return ctRunsAndFont.ctRuns } + if let ctRunsAndFont = self.ctRunsCache.valueForKey(utf16Chars) { return ctRunsAndFont } let attrStr = NSAttributedString( string: String(utf16CodeUnits: utf16Chars, count: utf16Chars.count), @@ -152,7 +155,7 @@ final class Typesetter { let ctLine = CTLineCreateWithAttributedString(attrStr) guard let ctRuns = CTLineGetGlyphRuns(ctLine) as? [CTRun] else { return [] } - self.ctRunsCache.set(CtRunsAndFont(ctRuns: ctRuns, font: font), forKey: utf16Chars) + self.ctRunsCache.set(ctRuns, forKey: utf16Chars) return ctRuns } @@ -270,15 +273,10 @@ final class Typesetter { } } - private let ctRunsCache = FifoCache<[Unicode.UTF16.CodeUnit], CtRunsAndFont>(count: 5000) + private let ctRunsCache = FifoCache<[Unicode.UTF16.CodeUnit], [CTRun]>(count: 5000) private let log = OSLog(subsystem: Defs.loggerSubsystem, category: Defs.LoggerCategory.view) - private struct CtRunsAndFont { - var ctRuns: [CTRun] - var font: NSFont - } - private struct NvimUtf16CellsRun { var startColumn: Int var nvimUtf16Cells: [[Unicode.UTF16.CodeUnit]] diff --git a/NvimView/Support/MinimalNvimViewDemo/Document.swift b/NvimView/Support/MinimalNvimViewDemo/Document.swift index dc420f85..57efd1e3 100644 --- a/NvimView/Support/MinimalNvimViewDemo/Document.swift +++ b/NvimView/Support/MinimalNvimViewDemo/Document.swift @@ -16,7 +16,7 @@ class Document: NSDocument, NSWindowDelegate { override init() { super.init() - self.nvimView.font = NSFont(name: "Fira Code", size: 13) + self.nvimView.font = NSFont(name: "Iosevka", size: 13) ?? NSFont.userFixedPitchFont(ofSize: 13)! self.nvimView.usesLigatures = true self.nvimView.usesLiveResize = true