#!/usr/bin/env python3 """Generate placeholder sticker PNGs for the default packs.""" import math import os import struct import zlib ROOT = os.path.join(os.path.dirname(__file__), "..", "data", "stickers") SIZE = 96 def chunk(tag, data): crc = zlib.crc32(tag + data) & 0xFFFFFFFF return struct.pack(">I", len(data)) + tag + data + struct.pack(">I", crc) def encode_png(pixels): raw = b"" for y in range(SIZE): raw += b"\x00" for x in range(SIZE): raw += bytes(pixels[y][x]) return ( b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", SIZE, SIZE, 8, 6, 0, 0, 0)) + chunk(b"IDAT", zlib.compress(raw, 9)) + chunk(b"IEND", b"") ) def blank(fill=(0, 0, 0, 0)): return [[fill for _ in range(SIZE)] for _ in range(SIZE)] def setp(px, x, y, c): if 0 <= x < SIZE and 0 <= y < SIZE: px[y][x] = c def disk(px, cx, cy, r, color): r2 = r * r for y in range(int(cy - r), int(cy + r) + 1): for x in range(int(cx - r), int(cx + r) + 1): if (x - cx) ** 2 + (y - cy) ** 2 <= r2: setp(px, x, y, color) def ring(px, cx, cy, r, w, color): r2 = r * r inner = (r - w) ** 2 for y in range(int(cy - r), int(cy + r) + 1): for x in range(int(cx - r), int(cx + r) + 1): d = (x - cx) ** 2 + (y - cy) ** 2 if inner <= d <= r2: setp(px, x, y, color) def line(px, x0, y0, x1, y1, w, color): steps = max(abs(x1 - x0), abs(y1 - y0), 1) for i in range(steps + 1): t = i / steps x = x0 + (x1 - x0) * t y = y0 + (y1 - y0) * t disk(px, x, y, w, color) def save(pack, code, px): d = os.path.join(ROOT, str(pack)) os.makedirs(d, exist_ok=True) path = os.path.join(d, code + ".png") with open(path, "wb") as f: f.write(encode_png(px)) print("wrote", path) def face_base(color=(255, 214, 64, 255)): px = blank() disk(px, 48, 48, 40, color) return px def smile(): px = face_base() disk(px, 34, 40, 5, (60, 40, 20, 255)) disk(px, 62, 40, 5, (60, 40, 20, 255)) line(px, 32, 62, 48, 70, 3, (60, 40, 20, 255)) line(px, 48, 70, 64, 62, 3, (60, 40, 20, 255)) save(1, "smile", px) def laugh(): px = face_base() disk(px, 34, 38, 5, (60, 40, 20, 255)) disk(px, 62, 38, 5, (60, 40, 20, 255)) disk(px, 48, 64, 14, (60, 40, 20, 255)) disk(px, 48, 60, 12, (255, 214, 64, 255)) save(1, "laugh", px) def sad(): px = face_base((130, 180, 255, 255)) disk(px, 34, 42, 5, (40, 50, 90, 255)) disk(px, 62, 42, 5, (40, 50, 90, 255)) line(px, 32, 70, 48, 62, 3, (40, 50, 90, 255)) line(px, 48, 62, 64, 70, 3, (40, 50, 90, 255)) disk(px, 70, 58, 5, (80, 140, 255, 255)) save(1, "sad", px) def angry(): px = face_base((255, 120, 90, 255)) disk(px, 34, 44, 5, (80, 20, 20, 255)) disk(px, 62, 44, 5, (80, 20, 20, 255)) line(px, 24, 32, 42, 40, 3, (80, 20, 20, 255)) line(px, 72, 32, 54, 40, 3, (80, 20, 20, 255)) line(px, 34, 68, 62, 68, 3, (80, 20, 20, 255)) save(1, "angry", px) def cool(): px = face_base() disk(px, 34, 42, 10, (30, 30, 30, 255)) disk(px, 62, 42, 10, (30, 30, 30, 255)) line(px, 44, 42, 52, 42, 3, (30, 30, 30, 255)) line(px, 32, 66, 64, 66, 3, (60, 40, 20, 255)) save(1, "cool", px) def wow(): px = face_base((255, 230, 120, 255)) ring(px, 34, 40, 8, 3, (60, 40, 20, 255)) ring(px, 62, 40, 8, 3, (60, 40, 20, 255)) disk(px, 48, 66, 9, (60, 40, 20, 255)) save(1, "wow", px) def sleep(): px = face_base((200, 210, 255, 255)) line(px, 26, 42, 42, 42, 3, (60, 40, 80, 255)) line(px, 54, 42, 70, 42, 3, (60, 40, 80, 255)) line(px, 34, 66, 62, 66, 3, (60, 40, 80, 255)) disk(px, 74, 24, 6, (140, 120, 255, 255)) save(1, "sleep", px) def shy(): px = face_base((255, 200, 210, 255)) disk(px, 34, 42, 4, (80, 40, 50, 255)) disk(px, 62, 42, 4, (80, 40, 50, 255)) disk(px, 26, 56, 7, (255, 140, 150, 180)) disk(px, 70, 56, 7, (255, 140, 150, 180)) line(px, 38, 66, 58, 66, 2, (80, 40, 50, 255)) save(1, "shy", px) def like(): px = blank() disk(px, 48, 52, 28, (7, 193, 96, 255)) line(px, 40, 58, 40, 30, 6, (255, 255, 255, 255)) disk(px, 54, 36, 10, (255, 255, 255, 255)) save(2, "like", px) def ok(): px = blank() disk(px, 48, 48, 30, (64, 158, 255, 255)) ring(px, 48, 48, 14, 5, (255, 255, 255, 255)) save(2, "ok", px) def clap(): px = blank() disk(px, 36, 52, 18, (255, 180, 70, 255)) disk(px, 60, 44, 18, (255, 200, 90, 255)) save(2, "clap", px) def wave(): px = blank() disk(px, 48, 58, 22, (255, 210, 140, 255)) disk(px, 62, 30, 12, (255, 210, 140, 255)) save(2, "wave", px) if __name__ == "__main__": smile() laugh() sad() angry() cool() wow() sleep() shy() like() ok() clap() wave()