#!/usr/bin/env swift // Generiert ein 1024×1024-AppIcon-PNG als Platzhalter. // forest-green Hintergrund + großes weißes "C" mit Karten-Stack-Andeutung. // // Aufruf: // swift scripts/make-appicon.swift // // Schreibt nach: Sources/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png // // Dies ist ein Platzhalter — vor App-Store-Submission durch ein // professionelles Icon ersetzen (siehe docs/RELEASE_CHECKLIST.md). import AppKit import CoreGraphics let size = 1024 let scale: CGFloat = 1.0 let cs = CGColorSpaceCreateDeviceRGB() guard let ctx = CGContext( data: nil, width: size, height: size, bitsPerComponent: 8, bytesPerRow: 0, space: cs, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue ) else { print("CGContext creation failed") exit(1) } // HSL(142, 76%, 28%) — forest primary light. Hand-konvertiert zu sRGB. let background = CGColor(red: 0.043, green: 0.494, blue: 0.227, alpha: 1) ctx.setFillColor(background) ctx.fill(CGRect(x: 0, y: 0, width: size, height: size)) // Subtile Karten-Stack-Schatten hinter dem C let shadow1 = CGColor(red: 1, green: 1, blue: 1, alpha: 0.08) let shadow2 = CGColor(red: 1, green: 1, blue: 1, alpha: 0.05) let cardW = CGFloat(size) * 0.62 let cardH = CGFloat(size) * 0.82 let cardX = (CGFloat(size) - cardW) / 2 let cardY = (CGFloat(size) - cardH) / 2 ctx.setFillColor(shadow2) ctx.beginPath() ctx.addPath(CGPath(roundedRect: CGRect(x: cardX + 30, y: cardY - 30, width: cardW, height: cardH), cornerWidth: 48, cornerHeight: 48, transform: nil)) ctx.fillPath() ctx.setFillColor(shadow1) ctx.beginPath() ctx.addPath(CGPath(roundedRect: CGRect(x: cardX + 15, y: cardY - 15, width: cardW, height: cardH), cornerWidth: 48, cornerHeight: 48, transform: nil)) ctx.fillPath() // Großer weißer "C"-Buchstabe — Helvetica-Neue-Bold let attrs: [NSAttributedString.Key: Any] = [ .font: NSFont(name: "HelveticaNeue-Bold", size: 720) ?? NSFont.boldSystemFont(ofSize: 720), .foregroundColor: NSColor.white, ] let str = NSAttributedString(string: "C", attributes: attrs) let line = CTLineCreateWithAttributedString(str) let bounds = CTLineGetImageBounds(line, ctx) let tx = (CGFloat(size) - bounds.width) / 2 - bounds.origin.x let ty = (CGFloat(size) - bounds.height) / 2 - bounds.origin.y ctx.textPosition = CGPoint(x: tx, y: ty) CTLineDraw(line, ctx) // PNG schreiben guard let cgImage = ctx.makeImage() else { print("makeImage failed") exit(1) } let bitmap = NSBitmapImageRep(cgImage: cgImage) guard let data = bitmap.representation(using: .png, properties: [:]) else { print("PNG encoding failed") exit(1) } let target = URL(fileURLWithPath: "Sources/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png") try data.write(to: target) print("Wrote \(target.path) (\(data.count) bytes)") _ = scale // suppress unused warning