51 lines
2.4 KiB
Swift
51 lines
2.4 KiB
Swift
import AppKit
|
|
import Testing
|
|
@testable import Conjure
|
|
|
|
@Test @MainActor
|
|
func iconsScaleWithTypographyWithoutEnlargingSymbolsToApplicationSize() throws {
|
|
_ = NSApplication.shared
|
|
let artwork = NSImage(size: NSSize(width: 128, height: 128), flipped: false) { rect in
|
|
NSColor.white.setFill()
|
|
rect.fill()
|
|
return true
|
|
}
|
|
var rendered: [(application: CGFloat, symbol: CGFloat)] = []
|
|
for (textSize, expectedApplicationSize): (CGFloat, CGFloat) in [(14, 22), (28, 44)] {
|
|
let host = NSView(frame: NSRect(x: 0, y: 0, width: 100, height: 100))
|
|
let icon = IconView(font: .systemFont(ofSize: textSize, weight: .medium))
|
|
host.addSubview(icon)
|
|
NSLayoutConstraint.activate([
|
|
icon.centerXAnchor.constraint(equalTo: host.centerXAnchor),
|
|
icon.centerYAnchor.constraint(equalTo: host.centerYAnchor)
|
|
])
|
|
host.layoutSubtreeIfNeeded()
|
|
#expect(icon.frame.size == NSSize(width: expectedApplicationSize, height: expectedApplicationSize))
|
|
func artworkHeight() throws -> CGFloat {
|
|
let bitmap = try #require(icon.bitmapImageRepForCachingDisplay(in: icon.bounds))
|
|
icon.cacheDisplay(in: icon.bounds, to: bitmap)
|
|
var first = bitmap.pixelsHigh
|
|
var last = -1
|
|
for y in 0..<bitmap.pixelsHigh {
|
|
for x in 0..<bitmap.pixelsWide where (bitmap.colorAt(x: x, y: y)?.alphaComponent ?? 0) > 0.5 {
|
|
first = min(first, y)
|
|
last = max(last, y)
|
|
}
|
|
}
|
|
return CGFloat(last - first + 1) * icon.bounds.height / CGFloat(bitmap.pixelsHigh)
|
|
}
|
|
icon.image = artwork
|
|
let applicationHeight = try artworkHeight()
|
|
// Reuse the same slot, as launcher cells do when switching to command/calculator results.
|
|
icon.image = NSImage(systemSymbolName: "stop.circle", accessibilityDescription: nil)
|
|
let symbolHeight = try artworkHeight()
|
|
#expect(applicationHeight == expectedApplicationSize)
|
|
#expect(symbolHeight > textSize * 0.75 && symbolHeight <= textSize)
|
|
icon.image = artwork
|
|
#expect(try artworkHeight() == applicationHeight)
|
|
rendered.append((applicationHeight, symbolHeight))
|
|
}
|
|
#expect(rendered[1].application == rendered[0].application * 2)
|
|
#expect(abs(rendered[1].symbol - rendered[0].symbol * 2) <= 1)
|
|
}
|