#!/usr/bin/env python3
"""
Turn Font Awesome glyphs into Android vector drawables.
The web board draws its rows with Font Awesome -- a bus for a bus, a
broadcast tower for a realtime time, a clock for a scheduled one. Rather
than pick lookalikes by hand, this reads the same metadata the web uses
(vendored at clients/lilygo4.7/fontawesome-free-6.2.0-desktop) and emits
the same paths as drawables, so a route on the phone and a route on a
panel are the same shape.
Regenerate with:
python3 tools/fa_to_vector.py
Font Awesome Free icons are CC BY 4.0; see the vendored LICENSE.txt.
"""
import json
import pathlib
import sys
HERE = pathlib.Path(__file__).resolve().parent
FA = HERE.parent.parent / "lilygo4.7" / "fontawesome-free-6.2.0-desktop" / "metadata" / "icons.json"
OUT = HERE.parent / "app" / "src" / "main" / "res" / "drawable"
# Every glyph the board can draw. Names are Font Awesome 6's own, and match
# what RoomSanctumWeb.IconHelpers and live_preview.ex ask for.
ICONS = [
# Transit modes, as live_preview.ex maps them.
"bus", "bus-simple", "train", "train-subway", "train-tram",
"ferry", "cable-car", "mountain",
# A time that came from the feed, and one that came from the timetable.
"tower-broadcast", "clock",
# Bikeshare.
"bicycle", "bolt-lightning", "square-parking", "battery-half",
# Which way to walk to it, on a Plani's cards.
"location-arrow",
# A train the source's fleet marks call out -- the MBTA's new ones.
"star",
# What the sky is doing. A detailed weather card says "Clouds" in words
# and the word is the smallest part of the answer; these are the picture.
"cloud", "cloud-sun", "cloud-rain", "cloud-showers-heavy", "cloud-bolt",
"snowflake", "smog", "tornado",
# A GBFS feed is not always bicycles: Getaround publishes cars, and other
# operators mopeds. Only where the free set has a truthful glyph -- there
# is no kick scooter in it, so those stay on the bicycle.
"car", "motorcycle",
# Alerts: the web uses a pin when the alert names the stop.
"location-dot", "triangle-exclamation",
# Tides: the web marks a high and a low with arrows to a line.
"arrows-up-to-line", "arrows-down-to-line",
# Sun and moon.
"sun", "moon",
# Weather's own measures.
"temperature-half", "droplet", "wind", "gauge-high",
# The rest of the source types, for card headers and rows.
"cloud-sun", "water", "lungs", "house", "calendar-day",
"seedling", "sun-plant-wilt", "code-branch", "envelopes-bulk",
"circle-check", "circle-xmark", "circle-info", "list",
# Brands, for the one source that is a company.
"github",
]
# Font Awesome Free has some glyphs only as brands. Named here rather than
# guessed, so a solid glyph silently becoming a brand one is a diff.
BRANDS = {"github"}
TEMPLATE = """<!-- Generated by tools/fa_to_vector.py from Font Awesome Free 6.2.0 ({name}).
Font Awesome Free icons are CC BY 4.0. Do not edit by hand. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="{vw}"
android:viewportHeight="{vh}"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="{path}" />
</vector>
"""
def resource_name(icon: str) -> str:
return "fa_" + icon.replace("-", "_")
def main() -> int:
if not FA.exists():
print(f"font awesome metadata not found at {FA}", file=sys.stderr)
return 1
icons = json.loads(FA.read_text())
OUT.mkdir(parents=True, exist_ok=True)
for name in ICONS:
icon = icons.get(name)
style = "brands" if name in BRANDS else "solid"
if icon is None or style not in icon.get("svg", {}):
print(f"no free {style} glyph for {name}", file=sys.stderr)
return 1
svg = icon["svg"][style]
_, _, vw, vh = svg["viewBox"]
path = svg["path"]
# Android's path parser is stricter than a browser's about quotes; the
# data itself is plain path commands, so only the attribute needs care.
assert '"' not in path, name
target = OUT / f"{resource_name(name)}.xml"
target.write_text(TEMPLATE.format(name=name, vw=vw, vh=vh, path=path))
print(f"wrote {target.relative_to(HERE.parent)}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
neiam
/apollos_crib
It's Apollo's Crib
public · Issues · Pulls 1 · Labels · Forks · Compare · Actions failure · Badges · Packages
⭐
Log in to mark this repository.
4.4 KiB · text
History
4eee00d