Files
byre/mac/Sources/Byre/FontAndSVG.swift
T

114 lines
4.3 KiB
Swift
Raw Normal View History

import AppKit
import CoreText
2026-10-16 22:46:54 -07:00
import OpenAPIRuntime
import SwiftUI
func runFonts(_ font: CTFont, _ text: String) -> String {
let line = CTLineCreateWithAttributedString(NSAttributedString(string: text, attributes: [.font: font as NSFont]))
return (CTLineGetGlyphRuns(line) as! [CTRun]).map { run in
let f = (CTRunGetAttributes(run) as NSDictionary)[kCTFontAttributeName] as! CTFont
let file = (CTFontCopyAttribute(f, kCTFontURLAttribute) as? URL)?.lastPathComponent ?? "system"
let r = CTRunGetStringRange(run)
let part = (text as NSString).substring(with: NSRange(location: r.location, length: r.length))
return "\(part) → \(CTFontCopyPostScriptName(f)) (\(file))"
}.joined(separator: "\n")
}
struct FontSpike: View {
private let sample = "The quick brown fox jumps — 0O 1lI {}[] őŁżę → │"
var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 12) {
ForEach(Array([(400.0, false), (700.0, false), (400.0, true), (700.0, true)].enumerated()), id: \.offset) { _, style in
let (w, italic) = style
VStack(alignment: .leading) {
Text("weight \(Int(w))\(italic ? " italic" : "")")
.foregroundStyle(.secondary)
Text(sample)
.font(Fonts.font(16, weight: w, italic: italic))
Text(runFonts(Fonts.ct(16, weight: w, italic: italic), sample))
.foregroundStyle(.secondary)
}
}
VStack(alignment: .leading) {
Text("Fonts.font(16) with SwiftUI .bold() and .italic()")
.foregroundStyle(.secondary)
Text(sample)
.font(Fonts.font(16))
.bold()
.italic()
}
VStack(alignment: .leading) {
Text("System font, for comparison")
.foregroundStyle(.secondary)
Text(sample)
.font(.system(size: 16))
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(8)
}
}
}
struct SVGSpike: View {
2026-10-16 22:46:54 -07:00
@Environment(Store.self) private var store
@ViewState private var path = "web/favicon.svg"
@ViewState private var image: NSImage?
@ViewState private var failure = ""
var body: some View {
VStack(alignment: .leading) {
HStack {
TextField("Worktree path", text: $path)
.frame(width: 320)
Button("Load") {
Task {
await load()
}
}
}
if let image {
Text(verbatim: "NSImage size \(Int(image.size.width))×\(Int(image.size.height)), reps \(image.representations.map { String(describing: type(of: $0)) })")
.foregroundStyle(.secondary)
HStack(alignment: .top, spacing: 16) {
Image(nsImage: image)
Image(nsImage: image)
.resizable()
.scaledToFit()
.frame(width: 256, height: 256)
}
}
if !failure.isEmpty {
Text(failure)
}
Spacer()
}
.task {
await load()
}
}
private func load() async {
image = nil
failure = ""
2026-10-16 22:46:54 -07:00
guard let taskId = store.selectedTaskId else {
return
}
do {
2026-10-16 22:46:54 -07:00
let body = switch try await store.api.client.getTaskImage(path: .init(taskId: taskId), query: .init(path: path)).ok.body {
case .png(let b), .jpeg(let b), .imageGif(let b), .imageWebp(let b), .imageSvgXml(let b): b
}
let data = try await Data(collecting: body, upTo: 32 << 20)
guard let img = NSImage(data: data) else {
failure = "image not available: \(path)"
return
}
image = img
} catch {
2026-10-16 22:46:54 -07:00
failure = "image not available: \(path) (\(errorText(error)))"
}
}
}