#!/usr/bin/env python3 """ Emits the Android vector drawables for the chosen Route mark. This is a real conversion, not a copy: VectorDrawable understands a subset of SVG. Three things in the source SVG have no direct equivalent and are translated here. -> two arc commands, since only exists stroke-dasharray -> trimPathStart / trimPathEnd, which cut one segment out of a path; the dash offset becomes the trim start, expressed as a fraction of the circle's circumference opacity -> strokeAlpha / fillAlpha Run after gen_logos.py; writes straight into app/src/main/res/drawable/. """ import math import pathlib import gen_logos HERE = pathlib.Path(__file__).parent RES = HERE.parent / "app" / "src" / "main" / "res" / "drawable" CX = CY = 54.0 # The standalone logo draws its ring at r=43, which is outside the adaptive-icon safe # circle (r=33) — a launcher mask crops it clean off, taking the accent segment with # it. The launcher build therefore shrinks the whole mark to fit inside the safe zone. DESIGN_RING_R = 43.0 RING_R = 32.0 GLYPH_SIZE = 40.0 # Must match concept_route() in gen_logos.py. DASH_LEN = 34.0 DASH_OFFSET = 100.0 # Trim fractions describe an angular span, so they are derived from the design radius # and stay correct at any ring size. DESIGN_CIRCUMFERENCE = 2 * math.pi * DESIGN_RING_R # Starts at due east and sweeps clockwise, matching how a browser renders , # so the trim fractions below land the accent in the same place as the preview. RING_PATH = ( f"M{CX + RING_R},{CY} " f"A{RING_R},{RING_R} 0 1 1 {CX - RING_R},{CY} " f"A{RING_R},{RING_R} 0 1 1 {CX + RING_R},{CY}" ) LAUNCHER = """ """ # Status-bar icons are flattened to a single color with only alpha preserved, so the # ring and accent are dropped — at 24dp they would collapse into a grey smudge. MONO = """ """ # Themed ("monochrome") launcher icons keep the 108 canvas and are tinted by the # system, so this one keeps the ring for a fuller shape at launcher size. THEMED = """ """ def main(): glyph = gen_logos.glyph_path("route") launcher_scale = GLYPH_SIZE / gen_logos.GLYPH_BOX common = dict( ring=RING_PATH, glyph=glyph, dim=gen_logos.DIM, ink=gen_logos.INK, accent=gen_logos.ACCENT, tx=f"{CX - GLYPH_SIZE / 2:g}", ty=f"{CY + GLYPH_SIZE / 2:g}", scale=f"{launcher_scale:.6f}", trim_start=DASH_OFFSET / DESIGN_CIRCUMFERENCE, trim_end=(DASH_OFFSET + DASH_LEN) / DESIGN_CIRCUMFERENCE, ) RES.mkdir(parents=True, exist_ok=True) (RES / "ic_launcher_foreground.xml").write_text(LAUNCHER.format(**common)) (RES / "ic_launcher_monochrome.xml").write_text(THEMED.format(**common)) # The status-bar glyph fills a 24dp box edge to edge, minus a little padding. mono_size = 20.0 mono_scale = mono_size / gen_logos.GLYPH_BOX (RES / "ic_stat_rippr.xml").write_text( MONO.format( glyph=glyph, tx=f"{(24 - mono_size) / 2:g}", ty=f"{(24 + mono_size) / 2:g}", scale=f"{mono_scale:.6f}", ) ) for name in ("ic_launcher_foreground", "ic_launcher_monochrome", "ic_stat_rippr"): print(f"wrote {RES / (name + '.xml')}") if __name__ == "__main__": main()