"""Generate the PNG app icons (stdlib only, no dependencies). python tools/make_icons.py Draws three glowing neon rings on a dark background, matching icons/icon.svg. """ import math import os import struct import zlib BG = (5, 5, 11) # (cx, cy, r, colour) in a 0..1 unit square RINGS = [ (0.34, 0.40, 0.17, (255, 46, 99)), (0.66, 0.40, 0.17, (0, 229, 255)), (0.50, 0.68, 0.17, (255, 229, 0)), ] LINE = 0.032 # ring stroke width GLOW = 0.05 # glow falloff def render(size, scale=1.0): """scale < 1 shrinks the artwork towards the centre (maskable safe zone).""" rows = [] for py in range(size): row = bytearray([0]) # filter type 0 for px in range(size): x = ((px + 0.5) / size - 0.5) / scale + 0.5 y = ((py + 0.5) / size - 0.5) / scale + 0.5 r, g, b = (c / 255 for c in BG) for cx, cy, rr, col in RINGS: d = abs(math.hypot(x - cx, y - cy) - rr) aa = 1.0 / (size * scale) core = min(1.0, max(0.0, (LINE / 2 - d) / aa + 0.5)) glow = math.exp(-max(0.0, d - LINE / 2) / GLOW) * 0.55 k = max(core, glow) cr, cg, cb = (c / 255 for c in col) # additive, like the neon theme r, g, b = r + cr * k, g + cg * k, b + cb * k if core > 0: # white-hot centre line w = max(0.0, 1 - d / (LINE * 0.18)) * 0.7 r, g, b = r + w, g + w, b + w row += bytes(min(255, int(v * 255 + 0.5)) for v in (r, g, b)) rows.append(bytes(row)) return b"".join(rows) def write_png(path, size, raw): def chunk(tag, data): c = struct.pack(">I", len(data)) + tag + data return c + struct.pack(">I", zlib.crc32(tag + data) & 0xFFFFFFFF) ihdr = struct.pack(">IIBBBBB", size, size, 8, 2, 0, 0, 0) # 8-bit RGB png = b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", ihdr) + chunk(b"IDAT", zlib.compress(raw, 9)) + chunk(b"IEND", b"") with open(path, "wb") as f: f.write(png) print("wrote", path) def main(): out = os.path.join(os.path.dirname(__file__), "..", "icons") os.makedirs(out, exist_ok=True) write_png(os.path.join(out, "icon-192.png"), 192, render(192)) write_png(os.path.join(out, "icon-512.png"), 512, render(512)) write_png(os.path.join(out, "icon-maskable-512.png"), 512, render(512, scale=0.78)) write_png(os.path.join(out, "apple-touch-icon.png"), 180, render(180, scale=0.9)) if __name__ == "__main__": main()