Files
antarchy-mirror/tools/rasterize_pixelarticons.py
T
craisinlord c77d1da53b new icons
royal guardian first pass
2026-09-16 23:12:47 -05:00

126 lines
3.6 KiB
Python

import re
from pathlib import Path
from PIL import Image
SOURCE_DIR = (
Path(__file__).resolve().parents[1]
/ "common-1.21.1/src/main/resources/assets/antarchy/textures/gui/antpaint"
)
ICON_NAMES = ("undo", "redo", "pencil", "eraser", "trash")
TOKEN = re.compile(r"[MmLlHhVvZz]|-?(?:\d+(?:\.\d*)?|\.\d+)")
def polygons_from_path(data):
tokens = TOKEN.findall(data)
polygons = []
points = []
x = y = start_x = start_y = 0.0
command = None
i = 0
while i < len(tokens):
if tokens[i].isalpha():
command = tokens[i]
i += 1
if command in "Zz":
if len(points) > 2:
polygons.append(points)
points = []
x, y = start_x, start_y
command = None
continue
if command is None:
raise ValueError(f"Unexpected SVG path data near token {i}: {data}")
relative = command.islower()
op = command.upper()
if op in ("M", "L"):
px = float(tokens[i])
py = float(tokens[i + 1])
i += 2
if relative:
px += x
py += y
x, y = px, py
if op == "M":
if len(points) > 2:
polygons.append(points)
points = [(x, y)]
start_x, start_y = x, y
command = "l" if relative else "L"
else:
points.append((x, y))
elif op == "H":
px = float(tokens[i])
i += 1
x = x + px if relative else px
points.append((x, y))
elif op == "V":
py = float(tokens[i])
i += 1
y = y + py if relative else py
points.append((x, y))
else:
raise ValueError(f"Unsupported SVG command {command!r}: {data}")
if len(points) > 2:
polygons.append(points)
return polygons
def contains_point(polygon, px, py):
inside = False
previous = polygon[-1]
for current in polygon:
x1, y1 = previous
x2, y2 = current
if (y1 > py) != (y2 > py):
crossing_x = (x2 - x1) * (py - y1) / (y2 - y1) + x1
if px < crossing_x:
inside = not inside
previous = current
return inside
def main():
for icon_name in ICON_NAMES:
source = (SOURCE_DIR / f"{icon_name}.svg").read_text(encoding="utf-8")
paths = re.findall(r'<path\b[^>]*\bd="([^"]+)"', source)
if not paths:
raise ValueError(f"No SVG path found in {icon_name}.svg")
polygons = [polygon for path in paths for polygon in polygons_from_path(path)]
mask = [
[
any(contains_point(poly, x + 0.5, y + 0.5) for poly in polygons)
for x in range(24)
]
for y in range(24)
]
image = Image.new("RGBA", (24, 24), (0, 0, 0, 0))
pixels = image.load()
for y in range(24):
for x in range(24):
if mask[y][x]:
pixels[x, y] = (101, 255, 101, 255)
continue
outlined = any(
0 <= nx < 24 and 0 <= ny < 24 and mask[ny][nx]
for nx, ny in (
(x - 1, y),
(x + 1, y),
(x, y - 1),
(x, y + 1),
)
)
if outlined:
pixels[x, y] = (3, 6, 3, 255)
image.save(SOURCE_DIR / f"{icon_name}.png")
if __name__ == "__main__":
main()