scripts/make-icon.swift
41 lines · 2371 bytes
1 symbol in this file
1// Draws Orgstar's app icon and writes an iconset: an outline's heading star over three
2// indented lines, on a deep blue-to-violet square. Usage: swift scripts/make-icon.swift <dir.iconset>
3import AppKit
4
5let folder = URL(fileURLWithPath: CommandLine.arguments[1])
6try FileManager.default.createDirectory(at: folder, withIntermediateDirectories: true)
7
8func draw(_ size: CGFloat) -> NSBitmapImageRep {
9 let rep = NSBitmapImageRep(bitmapDataPlanes: nil, pixelsWide: Int(size), pixelsHigh: Int(size), bitsPerSample: 8,
10 samplesPerPixel: 4, hasAlpha: true, isPlanar: false, colorSpaceName: .deviceRGB, bytesPerRow: 0, bitsPerPixel: 0)!
11 NSGraphicsContext.saveGraphicsState()
12 NSGraphicsContext.current = NSGraphicsContext(bitmapImageRep: rep)
13 let s = size / 1024
14 // The macOS icon grid: an 824-point rounded square in a 1024 canvas.
15 let square = NSRect(x: 100 * s, y: 100 * s, width: 824 * s, height: 824 * s)
16 let shape = NSBezierPath(roundedRect: square, xRadius: 185 * s, yRadius: 185 * s)
17 NSGradient(colors: [NSColor(srgbRed: 0.13, green: 0.20, blue: 0.55, alpha: 1), NSColor(srgbRed: 0.40, green: 0.22, blue: 0.70, alpha: 1)])!
18 .draw(in: shape, angle: -60)
19 // The heading star.
20 let star = NSAttributedString(string: "✱", attributes: [
21 .font: NSFont.systemFont(ofSize: 330 * s, weight: .heavy), .foregroundColor: NSColor(srgbRed: 1, green: 0.78, blue: 0.30, alpha: 1),
22 ])
23 star.draw(at: NSPoint(x: 190 * s, y: 520 * s))
24 // Three outline lines, indented like a heading's children.
25 NSColor(white: 1, alpha: 0.92).setFill()
26 for (i, (x, width)) in [(470.0, 330.0), (300.0, 500.0), (380.0, 420.0)].enumerated() {
27 let y = (650 - Double(i) * 150) * s
28 let line = i == 0 ? NSRect(x: x * s, y: y, width: width * s, height: 70 * s) : NSRect(x: x * s, y: y, width: width * s, height: 56 * s)
29 NSBezierPath(roundedRect: line, xRadius: 28 * s, yRadius: 28 * s).fill()
30 }
31 NSGraphicsContext.restoreGraphicsState()
32 return rep
33}
34
35for base in [16, 32, 128, 256, 512] {
36 for scale in [1, 2] {
37 let name = scale == 1 ? "icon_\(base)x\(base).png" : "icon_\(base)x\(base)@2x.png"
38 let data = draw(CGFloat(base * scale)).representation(using: .png, properties: [:])!
39 try data.write(to: folder.appendingPathComponent(name))
40 }
41}