import AppKit import Foundation struct IconRenderer { let size: CGFloat func render(to url: URL) throws { guard let bitmap = NSBitmapImageRep( bitmapDataPlanes: nil, pixelsWide: Int(size), pixelsHigh: Int(size), bitsPerSample: 8, samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: .deviceRGB, bytesPerRow: 0, bitsPerPixel: 0 ), let graphics = NSGraphicsContext(bitmapImageRep: bitmap) else { return } NSGraphicsContext.saveGraphicsState() NSGraphicsContext.current = graphics defer { NSGraphicsContext.restoreGraphicsState() } let context = graphics.cgContext context.setShouldAntialias(true) context.setAllowsAntialiasing(true) let rect = CGRect(x: 0, y: 0, width: size, height: size) let scale = size / 1024 let radius = 226 * scale let base = CGPath( roundedRect: rect.insetBy(dx: 44 * scale, dy: 44 * scale), cornerWidth: radius, cornerHeight: radius, transform: nil ) context.addPath(base) context.clip() let background = CGGradient( colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: [ NSColor(calibratedRed: 0.04, green: 0.12, blue: 0.24, alpha: 1).cgColor, NSColor(calibratedRed: 0.12, green: 0.20, blue: 0.42, alpha: 1).cgColor, NSColor(calibratedRed: 0.58, green: 0.16, blue: 0.88, alpha: 1).cgColor ] as CFArray, locations: [0, 0.52, 1] )! context.drawLinearGradient( background, start: CGPoint(x: rect.minX, y: rect.maxY), end: CGPoint(x: rect.maxX, y: rect.minY), options: [] ) drawGlow(context, color: NSColor.systemBlue, center: CGPoint(x: 260 * scale, y: 760 * scale), radius: 330 * scale) drawGlow(context, color: NSColor.systemPurple, center: CGPoint(x: 785 * scale, y: 285 * scale), radius: 430 * scale) drawGlassHighlight(context, rect: rect, scale: scale) drawBars(context, scale: scale) drawLens(context, scale: scale) context.resetClip() context.addPath(base) context.setStrokeColor(NSColor.white.withAlphaComponent(0.22).cgColor) context.setLineWidth(12 * scale) context.strokePath() guard let png = bitmap.representation(using: .png, properties: [:]) else { return } try png.write(to: url) } private func drawGlow(_ context: CGContext, color: NSColor, center: CGPoint, radius: CGFloat) { let gradient = CGGradient( colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: [ color.withAlphaComponent(0.55).cgColor, color.withAlphaComponent(0.0).cgColor ] as CFArray, locations: [0, 1] )! context.drawRadialGradient( gradient, startCenter: center, startRadius: 0, endCenter: center, endRadius: radius, options: [] ) } private func drawGlassHighlight(_ context: CGContext, rect: CGRect, scale: CGFloat) { let highlight = CGGradient( colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: [ NSColor.white.withAlphaComponent(0.32).cgColor, NSColor.white.withAlphaComponent(0.06).cgColor, NSColor.white.withAlphaComponent(0.0).cgColor ] as CFArray, locations: [0, 0.36, 1] )! let path = CGPath( roundedRect: CGRect(x: 120 * scale, y: 610 * scale, width: 790 * scale, height: 268 * scale), cornerWidth: 130 * scale, cornerHeight: 130 * scale, transform: nil ) context.saveGState() context.addPath(path) context.clip() context.drawLinearGradient( highlight, start: CGPoint(x: rect.minX, y: rect.maxY), end: CGPoint(x: rect.maxX, y: rect.minY), options: [] ) context.restoreGState() } private func drawBars(_ context: CGContext, scale: CGFloat) { let bars = [ CGRect(x: 288, y: 286, width: 86, height: 300), CGRect(x: 430, y: 212, width: 86, height: 448), CGRect(x: 572, y: 330, width: 86, height: 252) ].map { CGRect(x: $0.minX * scale, y: $0.minY * scale, width: $0.width * scale, height: $0.height * scale) } for (index, bar) in bars.enumerated() { let color: NSColor = index == 1 ? .white : NSColor(calibratedWhite: 1, alpha: 0.88) let path = CGPath( roundedRect: bar, cornerWidth: 44 * scale, cornerHeight: 44 * scale, transform: nil ) context.addPath(path) context.setFillColor(color.cgColor) context.fillPath() } } private func drawLens(_ context: CGContext, scale: CGFloat) { let ring = CGRect(x: 682 * scale, y: 228 * scale, width: 170 * scale, height: 170 * scale) context.setStrokeColor(NSColor.white.withAlphaComponent(0.92).cgColor) context.setLineWidth(34 * scale) context.strokeEllipse(in: ring) context.setLineCap(.round) context.move(to: CGPoint(x: 805 * scale, y: 275 * scale)) context.addLine(to: CGPoint(x: 892 * scale, y: 188 * scale)) context.strokePath() } } let outputRoot = URL(fileURLWithPath: CommandLine.arguments.dropFirst().first ?? "NativeTokenLens/Assets/AppIcon.iconset") try FileManager.default.createDirectory(at: outputRoot, withIntermediateDirectories: true) let specs: [(String, CGFloat)] = [ ("icon_16x16.png", 16), ("icon_16x16@2x.png", 32), ("icon_32x32.png", 32), ("icon_32x32@2x.png", 64), ("icon_128x128.png", 128), ("icon_128x128@2x.png", 256), ("icon_256x256.png", 256), ("icon_256x256@2x.png", 512), ("icon_512x512.png", 512), ("icon_512x512@2x.png", 1024) ] for spec in specs { try IconRenderer(size: spec.1).render(to: outputRoot.appendingPathComponent(spec.0)) }