#!/usr/bin/env python3 # Produit les icônes PNG de l'application (web/icons/icon-192.png et # icon-512.png) à partir des formes de web/icons/icon.svg : un fond de bois # et deux pions. Icônes provisoires, en attendant l'identité définitive. # # Python seul, sans bibliothèque : chaque pixel est échantillonné 4 × 4 fois # pour adoucir les bords. À relancer seulement si les formes changent, dans # la chaîne C (Python 3) : # docker run --rm --user "$(id -u):$(id -g)" -v "$PWD:/src" -w /src \ # ustagammon/build-c:2 python3 scripts/make-icons.py # # Copyright (C) 2026 les auteurs d'Ustagammon. # Licence : GPLv3 ou ultérieure (voir LICENSE). import struct import zlib BACKGROUND = (0x6B, 0x44, 0x26) # Pions dessinés dans l'ordre : (centre x, centre y, rayon, remplissage, # bord), en unités d'une icône de 512 pixels ; bord de 10 unités. CHECKERS = [ (300, 300, 120, (0x2B, 0x22, 0x1C), (0x0D, 0x0A, 0x08)), (212, 212, 120, (0xFB, 0xF6, 0xEA), (0x7D, 0x6A, 0x52)), ] EDGE = 10 SAMPLES = 4 def color_at(x, y): """Couleur d'un point de l'icône, en unités de 512.""" color = BACKGROUND for cx, cy, r, fill, edge in CHECKERS: d2 = (x - cx) ** 2 + (y - cy) ** 2 if d2 <= (r + EDGE / 2) ** 2: color = fill if d2 <= (r - EDGE / 2) ** 2 else edge return color def render(size): scale = 512 / size rows = [] for py in range(size): row = bytearray([0]) # filtre PNG « aucun » for px in range(size): total = [0, 0, 0] for sy in range(SAMPLES): for sx in range(SAMPLES): x = (px + (sx + 0.5) / SAMPLES) * scale y = (py + (sy + 0.5) / SAMPLES) * scale for i, c in enumerate(color_at(x, y)): total[i] += c row += bytes(round(t / SAMPLES**2) for t in total) rows.append(bytes(row)) return b"".join(rows) def png(size, pixels): def chunk(kind, data): body = kind + data return struct.pack(">I", len(data)) + body + struct.pack(">I", zlib.crc32(body)) header = struct.pack(">IIBBBBB", size, size, 8, 2, 0, 0, 0) # RVB, 8 bits return ( b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", header) + chunk(b"IDAT", zlib.compress(pixels, 9)) + chunk(b"IEND", b"") ) for size in (192, 512): with open(f"web/icons/icon-{size}.png", "wb") as f: f.write(png(size, render(size)))