#!/usr/bin/env python3 """ Gera o ícone do Tigre (app GUI SwiftUI) em 1024x1024 PNG. Desenho: fundo escuro arredondado (gradiente), um "T" em laranja com listras diagonais escuras (pele de tigre). A geração dos tamanhos menores e do .icns é feita pelo make-app.command via sips + iconutil. Uso: python3 admin/make_icon.py [caminho_de_saida.png] """ import struct import zlib import sys import os SIZE = 1024 def create_png(width, height, pixels): """Cria um PNG RGBA.""" def chunk(ctype, data): c = ctype + data crc = struct.pack('>I', zlib.crc32(c) & 0xFFFFFFFF) return struct.pack('>I', len(data)) + c + crc header = b'\x89PNG\r\n\x1a\n' ihdr = chunk(b'IHDR', struct.pack('>IIBBBBB', width, height, 8, 6, 0, 0, 0)) raw = b'' for y in range(height): raw += b'\x00' for x in range(width): i = (y * width + x) * 4 raw += bytes(pixels[i:i+4]) idat = chunk(b'IDAT', zlib.compress(raw, 9)) return header + ihdr + idat + chunk(b'IEND', b'') def lerp(a, b, t): return int(a + (b - a) * t) def draw_icon(size): px = [0] * (size * size * 4) def set_px(x, y, r, g, b, a=255): if 0 <= x < size and 0 <= y < size: i = (y * size + x) * 4 af = a / 255.0 px[i] = lerp(px[i], r, af) px[i+1] = lerp(px[i+1], g, af) px[i+2] = lerp(px[i+2], b, af) px[i+3] = max(px[i+3], a) def in_rrect(x, y, x0, y0, x1, y1, r): """Ponto dentro de retângulo arredondado (sem AA — ok, sips suaviza).""" if x < x0 or x > x1 or y < y0 or y > y1: return False cx = min(max(x, x0 + r), x1 - r) cy = min(max(y, y0 + r), y1 - r) return (x - cx) ** 2 + (y - cy) ** 2 <= r * r def fill_rrect(x0, y0, x1, y1, r, rg, g_, b_, a=255): for y in range(int(y0), int(y1)): for x in range(int(x0), int(x1)): if in_rrect(x, y, x0, y0, x1, y1, r): set_px(x, y, rg, g_, b_, a) # ── Fundo: gradiente vertical escuro + cantos arredondados (squircle liso) ── m = size * 0.03 corner = size * 0.22 for y in range(size): t = y / size br = lerp(0x2b, 0x12, t) bgc = lerp(0x2b, 0x12, t) bb = lerp(0x33, 0x16, t) for x in range(size): if in_rrect(x, y, m, m, size - m - 1, size - m - 1, corner): set_px(x, y, br, bgc, bb) # ── Letra "T" (barra + haste) em laranja com gradiente ── t_x0, t_x1 = size * 0.16, size * 0.84 bar_y0, bar_y1 = size * 0.28, size * 0.47 stem_x0, stem_x1 = size * 0.42, size * 0.58 stem_y0, stem_y1 = size * 0.47, size * 0.78 lr = size * 0.04 for y in range(size): t = y / size or_ = lerp(0xff, 0xee, t) og = lerp(0xa2, 0x5c, t) ob = lerp(0x38, 0x0d, t) # barra for x in range(size): if in_rrect(x, y, t_x0, bar_y0, t_x1, bar_y1, lr): set_px(x, y, or_, og, ob) # haste for x in range(size): if in_rrect(x, y, stem_x0, stem_y0, stem_x1, stem_y1, lr): if x < stem_x0 + lr or x > stem_x1 - lr or y > stem_y1 - lr: if in_rrect(x, y, stem_x0, stem_y0, stem_x1, stem_y1, lr): set_px(x, y, or_, og, ob) else: set_px(x, y, or_, og, ob) # ── Listras de tigre (faixas diagonais escuras) ── stripes = [ (0.20, 0.36, 0.58, 0.76), # haste (diagonal) (0.34, 0.50, 0.26, 0.42), (0.50, 0.66, 0.22, 0.40), (0.22, 0.40, 0.62, 0.82), ] # Converte faixa reta em diagonal: x' = x + (y - bar_y0) * slant slant = 0.35 for (x0f, x1f, y0f, y1f) in stripes: x0, x1 = size * x0f, size * x1f y0, y1 = size * y0f, size * y1f for y in range(int(y0), int(y1)): shift = (y - y0) * slant if shift < 0: continue sx0, sx1 = x0 + shift, x1 + shift for x in range(int(sx0), int(sx1)): if x < 0 or x >= size: continue i = (y * size + x) * 4 # cor escura translúcida (mistura manual p/ lerp com canal alpha) af = 0.78 px[i] = lerp(px[i], 0x0c, af) px[i+1] = lerp(px[i+1], 0x0a, af) px[i+2] = lerp(px[i+2], 0x06, af) px[i+3] = max(px[i+3], int(255 * 0.85)) return px def main(): out = sys.argv[1] if len(sys.argv) > 1 else "/tmp/tigre_icon_1024.png" px = draw_icon(SIZE) with open(out, "wb") as f: f.write(create_png(SIZE, SIZE, px)) print(f"OK: {out} ({SIZE}x{SIZE})") if __name__ == "__main__": main()