The capture also draws the two wordmarks of the splash
scripts/screenshots.py draws logo.71.ans and logo.53.ans, through the splash's own loader and the emulator's Terminus raster, in the Campbell colours, into docs/screenshots/splash/logo.<width>.png at one image pixel per font pixel. The website takes its splash from there, so it always shows the art that the app shows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
68280533a7
commit
f8a9ce1cb8
4 files changed
+73
-5
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
+8
-3
@@ -6,7 +6,7 @@ These are tools for the repository. None of them is in the wheel.
|
||||
|---|---|
|
||||
| `basemap-doctor.py` | Finds why a user's map has no basemap: certificates, DNS, proxy, or colour depth |
|
||||
| `cardputer-zero/` | `build-deb.sh` builds the Debian package for M5Stack's app store. Run it on the Cardputer Zero or on another arm64 Debian 13 system. `store/` holds the listing for the store (`app-builder.json`, which `czdev publish` reads), its icon, and its screenshots. `screenshot.py` saves the display of a Cardputer as a 320×170 PNG over SSH, as the store wants a screenshot. `store-publish.py` sends a package to the store with M5Stack's `czdev`, with two corrections. The release workflow runs it after each release. `launcher-entry.sh` puts a source checkout in the Cardputer Zero's app launcher. `remove` takes it out. `meshterm.png` is the package's icon: the website's logo, at the launcher's 100×100 size. `meshterm-dev.png` is its negative, for the checkout's entry, so that the two entries look different. `type-text.py` types a pasted string (an API key, a Wi-Fi password) on the Cardputer's keyboard from another computer, over SSH |
|
||||
| `screenshots.py` | Makes the screenshots of the website from the demo mesh (`--demo`): the main menu, the chat, the paths of a message, and the map, for the terminal, the Cardputer Zero, and the PicoCalc. They are the same at each run. The result goes to `docs/screenshots/<set>/` |
|
||||
| `screenshots.py` | Makes the screenshots of the website from the demo mesh (`--demo`): the main menu, the chat, the paths of a message, and the map, for the terminal, the Cardputer Zero, and the PicoCalc. They are the same at each run. The result goes to `docs/screenshots/<set>/`. It also draws the two wordmarks of the splash into `docs/screenshots/splash/`, which the website uses as its splash |
|
||||
| `picocalc-lyra/` | Setup of the Calculinux device: console font, palette, Wi-Fi. `xiao-radio/` is the kit for the XIAO radio (firmware build, flashing, UART setup) |
|
||||
| `uconsole/` | The uConsole's always-on SPI bridge service. MeshTerm can also control that radio directly, with no script (refer to `docs/devices/uconsole.md`) |
|
||||
|
||||
@@ -67,5 +67,10 @@ Emoji, which Windows has. On another system, change `TEXT_FONTS` and `EMOJI_FONT
|
||||
top of the script. The first run downloads the tiles of the map. The later runs use the
|
||||
tile cache in the temporary directory.
|
||||
|
||||
After a change to a screen, run the script again, then rebuild the website (refer to the
|
||||
README of the `meshterm.net` repository).
|
||||
The script also draws each wordmark of the startup splash (`meshterm/assets/splash/*.ans`)
|
||||
as `docs/screenshots/splash/logo.<width>.png`, one image pixel for each pixel of the font,
|
||||
in the Campbell colours. The website takes its splash from there: the wide mark on a wide
|
||||
screen, and the narrow mark on a phone. `--only splash` draws only these two images.
|
||||
|
||||
After a change to a screen or to the art, run the script again, then rebuild the website
|
||||
(refer to the README of the `meshterm.net` repository).
|
||||
+65
-2
@@ -9,6 +9,10 @@ an 80×24 terminal), ``cardputer-zero``, and ``picocalc-lyra``. Each run uses ``
|
||||
the paths of a message, and the map, and it saves each screen as a PNG. The result is
|
||||
``DIR/<set>/<screen>.png`` (``DIR`` is ``docs/screenshots`` by default).
|
||||
|
||||
The script also draws each wordmark of the startup splash (``meshterm/assets/splash``) as
|
||||
``DIR/splash/logo.<width>.png``, one image pixel for each pixel of the font: the website
|
||||
shows them as its splash, the wide mark on a wide screen and the narrow mark on a phone.
|
||||
|
||||
The screens are the same at each run, for four reasons:
|
||||
|
||||
* The demo writes the same history at each start.
|
||||
@@ -53,6 +57,18 @@ ROOT = Path(__file__).resolve().parent.parent
|
||||
#: The sets, in the order on the website. The terminal set is the default there.
|
||||
SETS = ("terminal", "cardputer-zero", "picocalc-lyra")
|
||||
|
||||
#: The name of the wordmarks in ``--only``. They need no run of MeshTerm.
|
||||
SPLASH = "splash"
|
||||
|
||||
#: The 16 colours of the wordmarks: the Campbell scheme of Windows Terminal, which the
|
||||
#: art was drawn in and the website uses.
|
||||
CAMPBELL = (
|
||||
(12, 12, 12), (197, 15, 31), (19, 161, 14), (193, 156, 0),
|
||||
(0, 55, 218), (136, 23, 152), (58, 150, 221), (204, 204, 204),
|
||||
(118, 118, 118), (231, 72, 86), (22, 198, 12), (249, 241, 165),
|
||||
(59, 120, 255), (180, 0, 158), (97, 214, 214), (242, 242, 242),
|
||||
) # fmt: skip
|
||||
|
||||
#: The grid of the terminal set: a standard terminal.
|
||||
TERMINAL_GRID = (80, 24)
|
||||
|
||||
@@ -74,7 +90,7 @@ def main(argv: list[str]) -> int:
|
||||
"""Run one child process for each set, then report what each one wrote."""
|
||||
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
parser.add_argument("--out", type=Path, default=ROOT / "docs" / "screenshots")
|
||||
parser.add_argument("--only", nargs="*", choices=SETS, default=list(SETS))
|
||||
parser.add_argument("--only", nargs="*", choices=(*SETS, SPLASH), default=[*SETS, SPLASH])
|
||||
parser.add_argument("--child", choices=SETS, help=argparse.SUPPRESS)
|
||||
args = parser.parse_args(argv)
|
||||
if args.child:
|
||||
@@ -85,7 +101,10 @@ def main(argv: list[str]) -> int:
|
||||
# directory of its own, so it gets the font directory of this machine by name.
|
||||
fonts = os.environ.get("MESHTERM_EMULATOR_FONTS") or str(font_dir())
|
||||
status = 0
|
||||
for name in args.only:
|
||||
if SPLASH in args.only:
|
||||
for path in _draw_splash(args.out / SPLASH):
|
||||
print(f"{SPLASH}: {path}", flush=True)
|
||||
for name in (name for name in args.only if name in SETS):
|
||||
home = Path(tempfile.gettempdir()) / "meshterm-screenshots" / name
|
||||
env = {
|
||||
**os.environ,
|
||||
@@ -270,6 +289,50 @@ def _tour(capture: Capture, type_text: Callable[[str], None], save: Callable[[st
|
||||
# --------------------------------------------------------------------------- drawing
|
||||
|
||||
|
||||
def _draw_splash(target: Path) -> list[Path]:
|
||||
"""Draw each wordmark of the splash in the emulator's font, one image pixel per pixel.
|
||||
|
||||
The marks are the ANSI art that the startup splash shows, read through the same loader
|
||||
(:func:`meshterm.ui.logo.load_logo`, widest first). The emulator's raster draws them
|
||||
in Terminus 6×12, the font of the handhelds. Its cell has the shape of the VGA cell
|
||||
that the art was drawn in, so the art keeps its proportions.
|
||||
|
||||
Returns:
|
||||
The paths of the images, widest mark first.
|
||||
"""
|
||||
from PIL import Image
|
||||
|
||||
from meshterm.emulator.font import CELL_H, CELL_W, find_font
|
||||
from meshterm.emulator.raster import Raster
|
||||
from meshterm.emulator.vt import Terminal
|
||||
from meshterm.ui.logo import load_logo, logo_width
|
||||
|
||||
target.mkdir(parents=True, exist_ok=True)
|
||||
font = find_font()
|
||||
written: list[Path] = []
|
||||
limit: int | None = None
|
||||
while rows := load_logo(limit):
|
||||
width = logo_width(rows)
|
||||
terminal = Terminal(width, len(rows), palette=CAMPBELL)
|
||||
terminal.feed("\r\n".join(f"{row}\x1b[0m" for row in rows))
|
||||
raster = Raster(
|
||||
terminal,
|
||||
font,
|
||||
default_fg=CAMPBELL[7],
|
||||
default_bg=CAMPBELL[0],
|
||||
width=width * CELL_W,
|
||||
height=len(rows) * CELL_H,
|
||||
top_left=True,
|
||||
)
|
||||
raster.redraw()
|
||||
size = (raster.width, raster.height)
|
||||
path = target / f"logo.{width}.png"
|
||||
Image.frombytes("RGB", size, bytes(raster.pixels)).save(path, optimize=True)
|
||||
written.append(path)
|
||||
limit = width - 1
|
||||
return written
|
||||
|
||||
|
||||
def _draw(name: str, grid, palette): # noqa: ANN001, ANN202 - cells, colours, an Image
|
||||
"""The image of one screen, in the look of its set."""
|
||||
from meshterm.emulator.devices import DEVICES
|
||||
|
||||
Reference in new issue
Block a user