82 lines
2.9 KiB
Swift
82 lines
2.9 KiB
Swift
// Regenerates the app icon PNGs from the same geometry as Branding/logo.svg.
|
|
//
|
|
// cd apps/ios
|
|
// swift Branding/make-icons.swift Koins/Assets.xcassets/AppIcon.appiconset
|
|
//
|
|
// iOS cannot use SVG for app icons, so the SVG is the source artwork and this
|
|
// script produces the raster the asset catalog needs. It also writes
|
|
// Branding/logo-light.png (white ground, black mark).
|
|
import AppKit
|
|
import CoreGraphics
|
|
import Foundation
|
|
|
|
// Draws the same geometry as Branding/logo.svg with CoreGraphics, because iOS
|
|
// app icons must be raster images.
|
|
func drawIcon(size: CGFloat, inverted: Bool = false) -> CGImage? {
|
|
let scale = size / 1024.0
|
|
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
|
guard let context = CGContext(data: nil,
|
|
width: Int(size),
|
|
height: Int(size),
|
|
bitsPerComponent: 8,
|
|
bytesPerRow: 0,
|
|
space: colorSpace,
|
|
bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue) else { return nil }
|
|
|
|
let background = inverted ? NSColor.white : NSColor.black
|
|
let foreground = inverted ? NSColor.black : NSColor.white
|
|
context.setFillColor(background.cgColor)
|
|
context.fill(CGRect(x: 0, y: 0, width: size, height: size))
|
|
|
|
context.setStrokeColor(foreground.cgColor)
|
|
context.setLineWidth(118 * scale)
|
|
context.setLineCap(.butt)
|
|
context.setLineJoin(.miter)
|
|
|
|
func point(_ x: CGFloat, _ y: CGFloat) -> CGPoint {
|
|
// SVG y grows downwards, CoreGraphics grows upwards.
|
|
CGPoint(x: x * scale, y: size - y * scale)
|
|
}
|
|
|
|
// Left leg continuing into the central V (one path, so the top corner is a
|
|
// clean miter rather than two overlapping strokes).
|
|
context.beginPath()
|
|
context.move(to: point(279, 758))
|
|
context.addLine(to: point(279, 280))
|
|
context.addLine(to: point(512, 640))
|
|
context.strokePath()
|
|
|
|
// Right leg, mirrored.
|
|
context.beginPath()
|
|
context.move(to: point(745, 758))
|
|
context.addLine(to: point(745, 280))
|
|
context.addLine(to: point(512, 640))
|
|
context.strokePath()
|
|
|
|
// Full-width bar across the base.
|
|
context.beginPath()
|
|
context.move(to: point(220, 699))
|
|
context.addLine(to: point(804, 699))
|
|
context.strokePath()
|
|
|
|
return context.makeImage()
|
|
}
|
|
|
|
func write(_ image: CGImage, to path: String) {
|
|
let rep = NSBitmapImageRep(cgImage: image)
|
|
guard let data = rep.representation(using: .png, properties: [:]) else { return }
|
|
try? data.write(to: URL(fileURLWithPath: path))
|
|
print("wrote \(path)")
|
|
}
|
|
|
|
let outputDir = CommandLine.arguments.count > 1 ? CommandLine.arguments[1] : "/tmp"
|
|
try? FileManager.default.createDirectory(atPath: outputDir, withIntermediateDirectories: true)
|
|
|
|
if let icon = drawIcon(size: 1024) {
|
|
write(icon, to: "\(outputDir)/AppIcon-1024.png")
|
|
}
|
|
// A light variant, handy for other surfaces (white background, black mark).
|
|
if let light = drawIcon(size: 1024, inverted: true) {
|
|
write(light, to: "\(outputDir)/AppIcon-light-1024.png")
|
|
}
|