56 lines
3.0 KiB
Swift
56 lines
3.0 KiB
Swift
import AppKit
|
|
|
|
// Render the launcher's SF Symbol directly at every macOS icon resolution.
|
|
precondition(CommandLine.arguments.count == 2, "Usage: swift Scripts/icon.swift <output.iconset>")
|
|
let directory = URL(fileURLWithPath: CommandLine.arguments[1], isDirectory: true)
|
|
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
|
let accent = NSColor(srgbRed: 0.95, green: 0.58, blue: 0.23, alpha: 1)
|
|
guard let symbol = NSImage(systemSymbolName: "sparkles", accessibilityDescription: nil)?
|
|
.withSymbolConfiguration(NSImage.SymbolConfiguration(paletteColors: [accent])) else {
|
|
fatalError("The sparkles SF Symbol is unavailable.")
|
|
}
|
|
let gradient = NSGradient(starting: NSColor(srgbRed: 0.27, green: 0.19, blue: 0.13, alpha: 1),
|
|
ending: NSColor(srgbRed: 0.12, green: 0.09, blue: 0.08, alpha: 1))!
|
|
|
|
for size in [16, 32, 128, 256, 512] {
|
|
for scale in [1, 2] {
|
|
let pixels = size * scale
|
|
let bitmap = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: pixels, pixelsHigh: pixels,
|
|
bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true,
|
|
isPlanar: false, colorSpaceName: .deviceRGB,
|
|
bytesPerRow: 0, bitsPerPixel: 0)!
|
|
NSGraphicsContext.saveGraphicsState()
|
|
NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: bitmap)
|
|
let context = NSGraphicsContext.current!.cgContext
|
|
context.scaleBy(x: CGFloat(pixels) / 1024, y: CGFloat(pixels) / 1024)
|
|
let tile = NSBezierPath(roundedRect: NSRect(x: 100, y: 100, width: 824, height: 824),
|
|
xRadius: 184, yRadius: 184)
|
|
NSGraphicsContext.saveGraphicsState()
|
|
let shadow = NSShadow()
|
|
shadow.shadowColor = NSColor.black.withAlphaComponent(0.28)
|
|
shadow.shadowBlurRadius = 24
|
|
shadow.shadowOffset = NSSize(width: 0, height: -12)
|
|
shadow.set()
|
|
NSColor(srgbRed: 0.12, green: 0.09, blue: 0.08, alpha: 1).setFill()
|
|
tile.fill()
|
|
NSGraphicsContext.restoreGraphicsState()
|
|
gradient.draw(in: tile, angle: -90)
|
|
NSColor.white.withAlphaComponent(0.10).setStroke()
|
|
tile.lineWidth = 2
|
|
tile.stroke()
|
|
|
|
let glyphHeight: CGFloat = 540
|
|
let glyphWidth = glyphHeight * symbol.size.width / symbol.size.height
|
|
symbol.draw(in: NSRect(x: (1024 - glyphWidth) / 2, y: (1024 - glyphHeight) / 2,
|
|
width: glyphWidth, height: glyphHeight),
|
|
from: .zero, operation: .sourceOver, fraction: 1)
|
|
NSGraphicsContext.restoreGraphicsState()
|
|
let suffix = scale == 2 ? "@2x" : ""
|
|
let output = directory.appendingPathComponent("icon_\(size)x\(size)\(suffix).png")
|
|
guard let png = bitmap.representation(using: .png, properties: [:]) else {
|
|
fatalError("Could not encode \(output.lastPathComponent).")
|
|
}
|
|
try png.write(to: output)
|
|
}
|
|
}
|