Redraw toolbar icons: full-canvas copper ohm glyph, add generator

The previous 24 px icons were a copper square with a tiny knocked-out
ohm that was unreadable in the toolbar. tools/gen_icons.py renders the
glyph supersampled from DejaVu Sans Bold in theme-specific copper
shades (plus the 64 px PCM listing icon).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
janik
2026-07-15 14:55:09 +07:00
parent 33489c7851
commit 99a06d533b
3 changed files with 56 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
"""Generate the plugin icons: a bold copper Ω filling the canvas.
python tools/gen_icons.py
Writes icons/fill_res_24_light.png (dark copper, for light toolbars),
icons/fill_res_24_dark.png (bright copper, for dark toolbars) and
resources/icon.png (64 px, for the PCM package listing). Rendered
supersampled with matplotlib's bundled DejaVu Sans Bold, then
downsampled for crisp antialiasing.
"""
from pathlib import Path
import matplotlib
from PIL import Image, ImageDraw, ImageFont
SS = 20 # supersampling factor
MARGIN = 1 # px kept clear per 24 px
COLORS = {
"light": (158, 88, 28), # dark copper on light toolbar
"dark": (232, 162, 94), # bright copper on dark toolbar
}
def render(color: tuple[int, int, int], size: int) -> Image.Image:
canvas = size * SS
img = Image.new("RGBA", (canvas, canvas), (0, 0, 0, 0))
draw = ImageDraw.Draw(img)
font_path = (Path(matplotlib.get_data_path())
/ "fonts" / "ttf" / "DejaVuSans-Bold.ttf")
# size the glyph so its ink box fills the canvas minus the margin
target = canvas - 2 * MARGIN * SS * size // 24
font = ImageFont.truetype(str(font_path), target)
x0, y0, x1, y1 = font.getbbox("Ω")
scale = min(target / (x1 - x0), target / (y1 - y0))
font = ImageFont.truetype(str(font_path), int(target * scale))
x0, y0, x1, y1 = font.getbbox("Ω")
pos = ((canvas - (x1 - x0)) // 2 - x0, (canvas - (y1 - y0)) // 2 - y0)
draw.text(pos, "Ω", font=font, fill=color + (255,))
return img.resize((size, size), Image.LANCZOS)
def main() -> None:
root = Path(__file__).resolve().parent.parent
for theme, color in COLORS.items():
p = root / "icons" / f"fill_res_24_{theme}.png"
render(color, 24).save(p)
print(f"wrote {p}")
p = root / "resources" / "icon.png"
p.parent.mkdir(exist_ok=True)
render(COLORS["light"], 64).save(p)
print(f"wrote {p}")
if __name__ == "__main__":
main()