From bbd7ab362c61887315849d283f924f87843a7a64 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Martineau Date: Wed, 26 Aug 2026 00:13:40 -0400 Subject: [PATCH] Updated splash screen (ANSI art, CP437) --- meshterm/assets/logo.ans | Bin 2377 -> 3976 bytes meshterm/assets/logo_53.ans | Bin 2026 -> 3210 bytes tests/test_theme16.py | 50 ++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/meshterm/assets/logo.ans b/meshterm/assets/logo.ans index 74a03cb160ee9df9b9a84cced28a133715fd8f38..65d5b292c41db85e09568b2885a4540910648bcd 100644 GIT binary patch literal 3976 zcmbVOJ!>3S6qVBi0wJlRX5=ahmW$br7;Z_kyTG5!6ZbT{BIs=SWt+68zw-liqSTW!>&FBl+Y31EO zN!vxEEL{Lvs%59FVRiO95D1abn`x?RfSwRF^ln@@+Q?=B@!@_M~Z98;bQP z29`k?puTbPe)SiCz0^__p^zCbjwN>r;)nQ~v9`(sPESBine;w;iI3+7tERUk%NO1b z&|1fugu;yGQ3bE*yiFh1=6J6eQD|glam;72X~8fRCFC5^NMQ*@s`79o zPe$XR;(A)TtSgwZUQwD4<%o87@ygY*gn02v^C&C?>&5g9ke5L^^Eg={Vq{eO{b>U+ z_1M~6O-_=O+={|w7n*k$fJ*(JPU~HsrFKDVsvHg5G@*Gn5SC0lOH0P5r%Vp**a^D| z0mgQeZ#14B5BDP1-YVP^6dHPY<^1&U1Sx$+u8l}i;aytckXX|xuNTmAHRQCJ-&a>?)>vV D#s(x# delta 242 zcmeB>KPki_9c_?1S&(0LVh!g+lah%^5)*59Co3`vGj5z1tOjIH+$b{Hn~`&3l-$G` z4tW#P+}k*SbhL@V#7KD^>1bm^YoNMKH~~sA+y6vqN1o4m{ zxl0@EeKZXb$&96KJs%$-`mQDB_o1 zy?ToAN*yIjB#gl;v;7&6uymY3t19EGhHV+)xP#AYc>;xrr$( zrD!IJfUqsa)X~lj=gHN*%s)4)n%00-6xOw3*r9XR43nWunbekjzzn9MODvpUu_Sc& zQsvOH5vV?s&|MMb*33;fu81s~LB)6_Wdd+MIxiV(Nu7Gw9y=qDPXe28xQ24T#TBHI zSO-}6YQ8$Ml8hsvsLWESt1_r7Wr-qn7e}E7OpAhoIWaYe?kKlx;l^>|HvkaX_FNK( zsfedUwO*=RGC)EqrwRiqrwUk|1Z8Q6P8eQDN(>IL<&s@RYf|%-8$8r*vBf=O@CakX zgfKDieXK|Xl5yHg=68t>KY&5a9&3-GcAY|ql8l{S{I~muC3F|TA zYvRMR!I!fIF1h2zzq&*1S-sWEPSzbbB$1oH@Z${y>iY+bFij@eIz0L^-T%CIoIKxp zv7WB?lkLgw!OQpilj(Gl?CegD_YWq!C#(PwO5v&a)mCcx1?#g9n;*B{q-o delta 315 zcmeB@e8oSZXQDs<#01`nYq>c$!oWlaS!L;HW5e7#($R+2CWg5iu!4yWGW9TJCZ@T! zaRBLP69bS*#^$-aTnfklq}dv%a}!Pg(q#?Q&dY^eYjiHm&6qSoFS4Bq3P5qw+&ee` mNE6UDkiRGAvx`nHU>5;mj>+2W;+t==b+IyKvQJLqQ2_uEg^rg1 diff --git a/tests/test_theme16.py b/tests/test_theme16.py index 44c1e46..1c8054c 100644 --- a/tests/test_theme16.py +++ b/tests/test_theme16.py @@ -375,6 +375,56 @@ 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_every_wordmark_draws_one_cell_per_cell() -> None: + """No mark holds a byte the terminal won't draw as a glyph. + + An art editor writes straight to video memory, where codepage 437's first 32 bytes are + pictures (►, ◄, ‼) rather than commands. Nothing downstream reads them that way: the + codecs decode them as the control characters they nominally are, Rich measures each as + no cells at all — so every one swallows a column and slides the rest of its row, the + same wound NUL cells leave (see :mod:`meshterm.ui.logo`) — and one of them, ``0x13``, + is XOFF on a real console. So this asks the question that catches all of it at once: + does every character the mark draws occupy exactly the one cell it was drawn in? + """ + from rich.text import Text + + from meshterm.ui.logo import _VARIANTS, _rows + + for name in _VARIANTS: + rows = _rows(name) + assert rows, f"{name} should be readable" + for i, row in enumerate(rows): + plain = Text.from_ansi(row).plain + odd = [ch for ch in plain if cell_len(ch) != 1 and ch != ""] + assert not odd, ( + f"{name} row {i} holds {[hex(ord(c)) for c in odd]}, which the terminal " + "draws in something other than the one cell it was drawn in" + ) + + +def test_the_mark_the_console_picks_stays_inside_its_font() -> None: + """The wordmark obeys the glyph contract every other screen does. + + The PicoCalc's console font is a 512-glyph inventory, and a character outside it is a + test failure rather than a tofu box found on-device. The mark is art rather than + chrome, so it never passed through the gallery's sweep — and it is the very first thing + the device draws. + """ + from rich.text import Text + + from meshterm.ui.logo import load_logo + + set_platform(PICOCALC) + rows = load_logo(53) + assert rows, "the 53-column mark should fit a 53-column console" + for i, row in enumerate(rows): + for ch in Text.from_ansi(row).plain: + assert ord(ch) in FONT_CODEPOINTS, ( + f"mark row {i} draws {ch!r} (U+{ord(ch):04X}), which the console font " + "has no glyph for" + ) + + def test_narrow_wordmark_keeps_its_dim_rows_off_the_bright_bank() -> None: """Every dim-bank span of the wordmark states its own intensity.