105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Generate the Furtka brand files from the winning logo (Mark M) everywhere
|
||
|
|
it ships: website, live installer, on-box UI, ISO boot splash, repo docs.
|
||
|
|
|
||
|
|
python3 website/tools/brand-assets.py
|
||
|
|
|
||
|
|
Reuses the geometry and rasteriser of logo-assets.py (the poll showcase), so
|
||
|
|
the mark is drawn from one source. Needs the same build-only deps: cairosvg,
|
||
|
|
Pillow, fontTools. Output files are committed; re-run after a geometry change.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import importlib.util
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
|
||
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
|
|
REPO = os.path.abspath(os.path.join(HERE, "..", ".."))
|
||
|
|
|
||
|
|
_spec = importlib.util.spec_from_file_location("logo_assets", os.path.join(HERE, "logo-assets.py"))
|
||
|
|
la = importlib.util.module_from_spec(_spec)
|
||
|
|
_spec.loader.exec_module(la)
|
||
|
|
|
||
|
|
K = "m"
|
||
|
|
COLOR = la.MARKS[K]["color"] # light-theme accent
|
||
|
|
COLOR_DARK = "#ff6b56" # dark-theme accent used by the site and the box UI
|
||
|
|
INK = la.MARKS[K]["ink"]
|
||
|
|
|
||
|
|
|
||
|
|
def out(*parts):
|
||
|
|
path = os.path.join(REPO, *parts)
|
||
|
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||
|
|
return path
|
||
|
|
|
||
|
|
|
||
|
|
def favicon_svg():
|
||
|
|
"""Small-size tier, accent colour, lighter accent on dark browser chrome."""
|
||
|
|
inner = la.body(K, "min", "currentColor")
|
||
|
|
x, y, w, h = la.MARKS[K]["vb"]
|
||
|
|
return (
|
||
|
|
f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="{x} {y} {w} {h}">'
|
||
|
|
f"<style>svg{{color:{COLOR}}}"
|
||
|
|
f"@media (prefers-color-scheme:dark){{svg{{color:{COLOR_DARK}}}}}</style>"
|
||
|
|
f"{inner}</svg>\n"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def mark_svg(tier, color):
|
||
|
|
return (
|
||
|
|
la.svg(K, tier, color, standalone=True)
|
||
|
|
.replace(' class="pm"', "")
|
||
|
|
.replace(' aria-hidden="true" focusable="false"', "")
|
||
|
|
+ "\n"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def lockup_svg(color):
|
||
|
|
s = la.lockup(K).replace("currentColor", color)
|
||
|
|
return (
|
||
|
|
s.replace('<svg class="pm"', f"<svg {la.XMLNS}").replace(
|
||
|
|
' aria-hidden="true" focusable="false"', ' role="img" aria-label="Furtka"'
|
||
|
|
)
|
||
|
|
+ "\n"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def write(path, text):
|
||
|
|
with open(path, "w") as f:
|
||
|
|
f.write(text)
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
fav = favicon_svg()
|
||
|
|
for p in (
|
||
|
|
("website", "static", "favicon.svg"),
|
||
|
|
("webinstaller", "static", "favicon.svg"),
|
||
|
|
("assets", "www", "favicon.svg"),
|
||
|
|
):
|
||
|
|
write(out(*p), fav)
|
||
|
|
|
||
|
|
la.tile(K, 180, pad=0.2).convert("RGB").save(
|
||
|
|
out("website", "static", "apple-touch-icon.png"), optimize=True
|
||
|
|
)
|
||
|
|
# Default share card for pages without their own og:image.
|
||
|
|
la.lockup_png(K, 1200, 630, False, 230).convert("RGB").save(
|
||
|
|
out("website", "static", "img", "brand", "social.png"), optimize=True
|
||
|
|
)
|
||
|
|
# syslinux (BIOS boot menu) wants a 640x480 PNG and draws its menu over
|
||
|
|
# the middle of it, so the lockup sits small in the top band — same
|
||
|
|
# layout as releng's Arch splash, which build.sh replaces with this.
|
||
|
|
splash_band = la.lockup_png(K, 640, 120, False, 44)
|
||
|
|
splash = la.Image.new("RGBA", (640, 480), INK)
|
||
|
|
splash.alpha_composite(splash_band, (0, 8))
|
||
|
|
splash.convert("RGB").save(out("iso", "overlay", "splash.png"), optimize=True)
|
||
|
|
|
||
|
|
write(out("docs", "brand", "furtka-mark.svg"), mark_svg("flat", COLOR))
|
||
|
|
write(out("docs", "brand", "furtka-mark-small.svg"), mark_svg("min", COLOR))
|
||
|
|
write(out("docs", "brand", "furtka-lockup.svg"), lockup_svg(COLOR))
|
||
|
|
write(out("docs", "brand", "furtka-lockup-white.svg"), lockup_svg("#ffffff"))
|
||
|
|
write(out("docs", "brand", "console-banner.txt"), la.banner(K, cols=20) + "\n")
|
||
|
|
print("brand assets ok")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
sys.exit(main())
|