#!/usr/bin/env python3
"""Render static/logo.svg into the home-screen icons.
python3 tools/make_icons.py
Writes static/icon-180.png (what iOS uses on the home screen) and
static/icon-512.png (Android / the web manifest): the white mark on a
transparent background, which iOS lays over black on the home screen.
The PNGs are committed, so this only needs running if the logo changes.
It rasterises with headless Chromium, which is a heavy thing to install
for one job -- if you have librsvg to hand, this does the same:
rsvg-convert -w 512 -h 512 static/logo.svg -o static/icon-512.png
Otherwise: pip install playwright && playwright install chromium
"""
import sys
from pathlib import Path
STATIC = Path(__file__).resolve().parent.parent / "static"
LOGO = STATIC / "logo.svg"
SIZES = (180, 512)
MARGIN = 0.14 # breathing room, so iOS's rounded mask never clips it
PAGE = """
"""
def main():
try:
from playwright.sync_api import sync_playwright
except ImportError:
sys.exit("needs playwright: pip install playwright && playwright install chromium")
if not LOGO.exists():
sys.exit(f"no logo at {LOGO}")
scratch = STATIC / "_icon.html"
try:
with sync_playwright() as p:
browser = p.chromium.launch(args=["--no-sandbox"])
for size in SIZES:
inner = round(size * (1 - 2 * MARGIN))
scratch.write_text(PAGE.format(size=size, inner=inner))
page = browser.new_page(viewport={"width": size, "height": size})
page.goto(scratch.as_uri())
page.wait_for_timeout(120) # let the SVG paint
target = STATIC / f"icon-{size}.png"
page.screenshot(path=target, omit_background=True)
page.close()
print(f"wrote {target} ({target.stat().st_size} bytes)")
browser.close()
finally:
scratch.unlink(missing_ok=True)
if __name__ == "__main__":
main()