Updated splash screen (ANSI art, CP437)
This commit is contained in:
1 parent
eb8ecb46c8
commit
fae342c2bd
3 files changed
+64
-15
No files matched your search
Binary file not shown.
+44
-2
@@ -48,6 +48,15 @@ _VARIANTS: tuple[str, ...] = ("logo.ans", "logo_53.ans")
|
||||
#: a row only ever has to carry a *colour* across the seam — never a cursor move.
|
||||
_SGR = re.compile(r"\x1b\[[0-9;]*m")
|
||||
|
||||
#: A foreground on the dim bank, said without a word about intensity. Bold *is* brightness
|
||||
#: on the PicoCalc console, so a bare one inherits whatever the span before it left set and
|
||||
#: lands a bank too high — the theme's own styles state their intent for the same reason.
|
||||
_DIM_FG = re.compile(r"3[0-7]")
|
||||
|
||||
#: Parameters that settle the intensity question themselves, so a span carrying one needs
|
||||
#: no help: a reset, bold, faint, or an explicit return to normal.
|
||||
_SAYS_INTENSITY = frozenset({"", "0", "1", "2", "22"})
|
||||
|
||||
#: SAUCE rides on the end of an art file behind DOS's end-of-file mark: 128 bytes naming
|
||||
#: the author, the canvas and the font. None of it is meant to reach the screen.
|
||||
_EOF_MARK = b"\x1a"
|
||||
@@ -121,6 +130,39 @@ def _rewrap(line: str, width: int) -> list[str]:
|
||||
return rows
|
||||
|
||||
|
||||
def _state_intensity(row: str) -> str:
|
||||
"""Rewrite the row's colour changes so every one says whether it is bright.
|
||||
|
||||
An art editor spells brightness the DOS way — ``1m`` lifts the bank and each span after
|
||||
it inherits that — which reads correctly only while the escapes stay one unbroken
|
||||
stream. They don't here: a row is handed to Rich on its own, and the console draws bold
|
||||
*as* the bright bank, so a span that never mentions intensity is read against whatever
|
||||
happened to be set. Saying it outright changes no colour; it just stops one drifting.
|
||||
"""
|
||||
out: list[str] = []
|
||||
bright = False
|
||||
at = 0
|
||||
while at < len(row):
|
||||
found = _SGR.match(row, at)
|
||||
if not found:
|
||||
out.append(row[at])
|
||||
at += 1
|
||||
continue
|
||||
params = found.group()[2:-1]
|
||||
parts = params.split(";") if params else [""]
|
||||
for part in parts: # what this sequence leaves the intensity set to
|
||||
if part in ("", "0", "22"):
|
||||
bright = False
|
||||
elif part == "1":
|
||||
bright = True
|
||||
if any(_DIM_FG.fullmatch(p) for p in parts) and not any(p in _SAYS_INTENSITY for p in parts):
|
||||
out.append("\x1b[" + ";".join(["1" if bright else "22"] + parts) + "m")
|
||||
else:
|
||||
out.append(found.group())
|
||||
at = found.end()
|
||||
return "".join(out)
|
||||
|
||||
|
||||
def _rows(name: str) -> list[str]:
|
||||
"""The named mark's rows, or ``[]`` when it can't be read."""
|
||||
try:
|
||||
@@ -133,8 +175,8 @@ def _rows(name: str) -> list[str]:
|
||||
if lines and lines[-1] == "": # drop the trailing newline's empty row
|
||||
lines.pop()
|
||||
if width:
|
||||
return [row for line in lines for row in _rewrap(line, width)]
|
||||
return lines
|
||||
lines = [row for line in lines for row in _rewrap(line, width)]
|
||||
return [_state_intensity(row) for row in lines]
|
||||
|
||||
|
||||
def logo_width(rows: list[str]) -> int:
|
||||
|
||||
+20
-13
@@ -375,14 +375,16 @@ def test_specimen_renders_clean_on_picocalc() -> None:
|
||||
assert ord(ch) in FONT_CODEPOINTS, f"line {i} char {ch!r} outside the font"
|
||||
|
||||
|
||||
def test_narrow_wordmark_keeps_its_dim_row_off_the_bright_bank() -> None:
|
||||
"""Every span of the wordmark's dim-slot row states its intensity.
|
||||
def test_narrow_wordmark_keeps_its_dim_rows_off_the_bright_bank() -> None:
|
||||
"""Every dim-bank span of the wordmark states its own intensity.
|
||||
|
||||
The mark alternates letter blocks with slate bevels, so a row painted on the dim bank
|
||||
is a run of ``3N`` spans each following a ``90``. Bare, they inherit the console's
|
||||
intensity bit and half the row renders a bank too bright — the narrow mark's fourth
|
||||
row came out part red (slot 1), part light red (slot 9), split at every span that
|
||||
followed a bevel.
|
||||
An art editor spells brightness the DOS way — a ``1m`` lifts the bank and every span
|
||||
after it inherits that — which only reads correctly while the escapes stay one unbroken
|
||||
stream. A row reaches the console on its own, and bold *is* the bright bank there, so a
|
||||
span that never mentions intensity is read against whatever happened to be set: the
|
||||
narrow mark's letter row came out part red (slot 1), part light red (slot 9), splitting
|
||||
at every span that followed a bevel. The art is redrawn from time to time, so this
|
||||
pins the rule rather than the picture — no row index, no particular colour.
|
||||
"""
|
||||
from meshterm.ui.logo import load_logo
|
||||
from meshterm.ui.tui.frame import _banner_lines
|
||||
@@ -390,12 +392,17 @@ def test_narrow_wordmark_keeps_its_dim_row_off_the_bright_bank() -> None:
|
||||
set_platform(PICOCALC)
|
||||
rows = _banner_lines(load_logo(53), 53)
|
||||
assert rows, "the 53-column mark should fit a 53-column console"
|
||||
for i, row in enumerate(rows):
|
||||
for sgr in re.findall(r"\x1b\[([0-9;]*)m", row):
|
||||
assert not re.fullmatch(r"3[0-7]", sgr), f"bare dim-bank SGR on row {i}: {row!r}"
|
||||
# The fourth row is the mark's only dim-slot row, and it is one colour throughout.
|
||||
reds = set(re.findall(r"\x1b\[([0-9;]+)m(?=█)", rows[3]))
|
||||
assert reds == {"22;31"}, reds
|
||||
dim = [
|
||||
sgr
|
||||
for row in rows
|
||||
for sgr in re.findall(r"\x1b\[([0-9;]*)m", row)
|
||||
if any(re.fullmatch(r"3[0-7]", part) for part in sgr.split(";"))
|
||||
]
|
||||
# Without this the loop below would pass on a mark that never touches the dim bank.
|
||||
assert dim, "the mark paints on the dim bank somewhere, or this check says nothing"
|
||||
for sgr in dim:
|
||||
parts = sgr.split(";")
|
||||
assert any(p in {"0", "1", "2", "22"} for p in parts), f"unstated intensity: {sgr!r}"
|
||||
|
||||
|
||||
# -- relocated marks stay importable from their old homes -----------------------------
|
||||
|
||||
Reference in new issue
Block a user