53 lines
2.1 KiB
Swift
53 lines
2.1 KiB
Swift
import CoreText
|
|
import SwiftUI
|
|
|
|
enum Fonts {
|
|
nonisolated(unsafe) private static let descriptors: [String: CTFontDescriptor] = {
|
|
let dir = Bundle.main.resourceURL!.appendingPathComponent("fonts")
|
|
var out: [String: CTFontDescriptor] = [:]
|
|
for name in try! FileManager.default.contentsOfDirectory(atPath: dir.path) where name.hasSuffix(".woff2") {
|
|
let url = dir.appendingPathComponent(name)
|
|
let found = CTFontManagerCreateFontDescriptorsFromURL(url as CFURL) as! [CTFontDescriptor]
|
|
out[name] = found[0]
|
|
}
|
|
return out
|
|
}()
|
|
|
|
private static func file(_ subset: String, _ italic: Bool, _ weight: CGFloat) -> CTFontDescriptor {
|
|
let d = descriptors["atkinson-hyperlegible-mono-\(subset)-wght-\(italic ? "italic" : "normal").woff2"]!
|
|
return CTFontDescriptorCreateCopyWithVariation(d, 0x7767_6874 as CFNumber, weight)
|
|
}
|
|
|
|
static func ct(_ size: CGFloat, weight: CGFloat = 400, italic: Bool = false) -> CTFont {
|
|
let ext = file("latin-ext", italic, weight)
|
|
let d = CTFontDescriptorCreateCopyWithAttributes(file("latin", italic, weight), [kCTFontCascadeListAttribute: [ext]] as CFDictionary)
|
|
return CTFontCreateWithFontDescriptor(d, size, nil)
|
|
}
|
|
|
|
nonisolated(unsafe) private static var fonts: [String: (font: Font, ns: NSFont)] = [:]
|
|
private static let lock = NSLock()
|
|
|
|
private static func cached(_ size: CGFloat, _ weight: CGFloat, _ italic: Bool) -> (font: Font, ns: NSFont) {
|
|
let key = "\(size) \(weight) \(italic)"
|
|
lock.lock()
|
|
defer {
|
|
lock.unlock()
|
|
}
|
|
if let f = fonts[key] {
|
|
return f
|
|
}
|
|
let c = ct(size, weight: weight, italic: italic)
|
|
let f = (Font(c), c as NSFont)
|
|
fonts[key] = f
|
|
return f
|
|
}
|
|
|
|
static func font(_ size: CGFloat, weight: CGFloat = 400, italic: Bool = false) -> Font {
|
|
cached(size, weight, italic).font
|
|
}
|
|
|
|
static func ns(_ size: CGFloat, weight: CGFloat = 400, italic: Bool = false) -> NSFont {
|
|
cached(size, weight, italic).ns
|
|
}
|
|
}
|