oficina / meet Public

CallGlyph: tuned optical table; tuner picks the middle of the stable range

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev f77d525904015ab57d6f86c3f118a67528eb1f74 parent 6e3b5a6
2 files changed, +43 −26
  • native/apple/Sources/CallsKit/CallGlyph.swift +13 −13
  • native/apple/Tests/CallsKitTests/CallGlyphTests.swift +30 −13
diff --git a/native/apple/Sources/CallsKit/CallGlyph.swift b/native/apple/Sources/CallsKit/CallGlyph.swift
index 375414a..680f3c5 100644
--- a/native/apple/Sources/CallsKit/CallGlyph.swift
+++ b/native/apple/Sources/CallsKit/CallGlyph.swift
@@ -52,22 +52,22 @@ public struct CallGlyph: View {
/// prints a fresh table when a symbol drifts past tolerance. A symbol
/// not listed is drawn where SF Symbols puts it.
public static let opticalOffsets: [String: CGFloat] = [
- "mic.fill": -0.015,
- "mic.slash.fill": -0.015,
- "video.fill": 0.000,
- "video.slash.fill": 0.000,
- "rectangle.on.rectangle": 0.017,
- "rectangle.on.rectangle.slash": 0.000,
+ "mic.fill": -0.016,
+ "mic.slash.fill": -0.016,
+ "video.fill": -0.008,
+ "video.slash.fill": -0.008,
+ "rectangle.on.rectangle": 0.016,
+ "rectangle.on.rectangle.slash": 0.014,
"slider.horizontal.3": 0.000,
- "rectangle.bottomthird.inset.filled": -0.067,
- "square.grid.2x2": 0.000,
- "square.and.arrow.up": -0.103,
+ "rectangle.bottomthird.inset.filled": -0.070,
+ "square.grid.2x2": -0.008,
+ "square.and.arrow.up": -0.110,
"bubble.left.and.bubble.right.fill": 0.074,
- "phone.down.fill": 0.000,
+ "phone.down.fill": 0.014,
"ellipsis": 0.000,
- "arrow.triangle.2.circlepath.camera": -0.034,
- "waveform": 0.000,
- "arrow.down.right.and.arrow.up.left": 0.000,
+ "arrow.triangle.2.circlepath.camera": -0.042,
+ "waveform": -0.008,
+ "arrow.down.right.and.arrow.up.left": -0.008,
]
public static func opticalOffset(_ symbol: String) -> CGFloat {
diff --git a/native/apple/Tests/CallsKitTests/CallGlyphTests.swift b/native/apple/Tests/CallsKitTests/CallGlyphTests.swift
index 8cba621..95190bb 100644
--- a/native/apple/Tests/CallsKitTests/CallGlyphTests.swift
+++ b/native/apple/Tests/CallsKitTests/CallGlyphTests.swift
@@ -96,29 +96,46 @@ import XCTest
return lines.joined(separator: "\n")
}
- /// With CALLS_GLYPH_TUNE=1, the table that does best: for each symbol
- /// the correction, in thousandths of an em, whose worst size is
- /// nearest the centre line — the pixel grid makes that a search rather
- /// than a sum.
+ /// With CALLS_GLYPH_TUNE=1, the table to use. The pixel grid makes
+ /// each symbol's worst offset a step function of its correction, so
+ /// the smallest correction that wins can sit on the edge of a step,
+ /// where a thousandth of an em flips it. This takes the middle of the
+ /// widest run of corrections (in 2/1000 em steps) whose worst size is
+ /// within 0.3 pt of the centre line, or, failing that, within 0.15 pt
+ /// of the best any correction does.
func testTuneTheTable() throws {
try XCTSkipUnless(ProcessInfo.processInfo.environment["CALLS_GLYPH_TUNE"] == "1")
var lines = ["tuned offsets (ems, negative up):"]
for symbol in CallGlyph.opticalOffsets.keys.sorted() {
- var best: (em: CGFloat, worst: CGFloat) = (0, .infinity)
- for step in -150...100 {
- let em = CGFloat(step) / 1000
+ let steps = Array(stride(from: -140, through: 100, by: 2))
+ let worsts: [CGFloat] = steps.map { step in
var worst: CGFloat = 0
for (_, metrics) in Self.sizes {
var glyph = CallGlyph(symbol)
- glyph.trial = em
- guard let ink = Ink.measure(glyph.environment(\.callGlyphMetrics, metrics)) else { continue }
- worst = max(worst, abs(ink.centroidOffset))
+ glyph.trial = CGFloat(step) / 1000
+ if let ink = Ink.measure(glyph.environment(\.callGlyphMetrics, metrics)) {
+ worst = max(worst, abs(ink.centroidOffset))
+ } else {
+ worst = .infinity
+ }
}
- if worst < best.worst - 0.01 || (abs(worst - best.worst) <= 0.01 && abs(em) < abs(best.em)) {
- best = (em, worst)
+ return worst
+ }
+ let threshold = max(0.3, (worsts.min() ?? 0) + 0.15)
+ var bestRun = (start: 0, length: 0), start = -1
+ for (i, worst) in worsts.enumerated() {
+ if worst <= threshold {
+ if start < 0 { start = i }
+ if i - start + 1 > bestRun.length { bestRun = (start, i - start + 1) }
+ } else {
+ start = -1
}
}
- lines.append(String(format: " \"%@\": %.3f, // worst %.2f pt", symbol, best.em, best.worst))
+ let middle = bestRun.start + bestRun.length / 2
+ lines.append(String(
+ format: " \"%@\": %.3f, // worst %.2f pt; %.3f to %.3f all within %.2f", symbol,
+ CGFloat(steps[middle]) / 1000, worsts[middle], CGFloat(steps[bestRun.start]) / 1000,
+ CGFloat(steps[bestRun.start + bestRun.length - 1]) / 1000, threshold))
}
print(lines.joined(separator: "\n"))
}