Files
jyvikoandClaude Opus 5.5 30812250d3 demo video: caption each stage with the MCP tool it calls
A band under the window names the tool behind each stage (open, mesh,
batch, check_model, solve, show_results). caption.py draws the bars in the
standard library from the interface's Inter SemiBold (OFL): a minimal
TrueType glyf reader, a non-zero scanline rasteriser and a zlib PNG
writer, unit-tested with python3 -m unittest. ffmpeg pads each picture
and composites the bar with its overlay filter.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
2026-10-14 00:40:45 -04:00

353 lines
13 KiB
Python

"""Caption pictures for the demo video, drawn in the Python standard library.
A minimal TrueType reader (the `cmap` format 4, `loca`, `glyf` simple and composite outlines and
`hmtx` advances of the TrueType specification), a scanline rasteriser (non-zero winding,
sub-scanlines with exact horizontal coverage) and a PNG writer (`zlib`, `struct`). It draws the
caption bar under the app window with the interface's own font, `crates/ui-egui/fonts/Inter-SemiBold.ttf` (SIL OFL
1.1, ATTRIBUTION.md), and ffmpeg composites it with its `overlay` filter.
No hinting, kerning or shaping: captions are short ASCII-and-punctuation labels.
"""
import math
import struct
import zlib
# Points per quadratic segment when flattening an outline.
CURVE_STEPS = 8
# Sub-scanlines per pixel row (vertical anti-aliasing; horizontal coverage is exact).
SUBSAMPLES = 5
# Nesting of composite glyphs a font may use before we refuse it.
MAX_COMPOSITE_DEPTH = 8
class FontError(ValueError):
pass
class Font:
"""The outlines and advances of a TrueType (`glyf`) font."""
def __init__(self, data):
self.data = data
if len(data) < 12:
raise FontError("not a font file")
(num_tables,) = struct.unpack_from(">H", data, 4)
self.tables = {}
for i in range(num_tables):
tag, _checksum, offset, length = struct.unpack_from(">4sIII", data, 12 + 16 * i)
if offset + length > len(data):
raise FontError(f"table {tag!r} runs past the end of the file")
self.tables[tag.decode("latin-1")] = (offset, length)
for tag in ("head", "hhea", "hmtx", "maxp", "cmap", "loca", "glyf"):
if tag not in self.tables:
raise FontError(f"no {tag} table (only TrueType outlines are supported)")
head = self.tables["head"][0]
(self.units_per_em,) = struct.unpack_from(">H", data, head + 18)
(loc_format,) = struct.unpack_from(">h", data, head + 50)
(self.num_glyphs,) = struct.unpack_from(">H", data, self.tables["maxp"][0] + 4)
hhea = self.tables["hhea"][0]
(self.num_h_metrics,) = struct.unpack_from(">H", data, hhea + 34)
loca = self.tables["loca"][0]
if loc_format == 0:
self.loca = [2 * v for v in struct.unpack_from(f">{self.num_glyphs + 1}H", data, loca)]
else:
self.loca = list(struct.unpack_from(f">{self.num_glyphs + 1}I", data, loca))
self.cmap = self._read_cmap()
@classmethod
def load(cls, path):
with open(path, "rb") as f:
return cls(f.read())
def _read_cmap(self):
"""The Unicode BMP subtable (format 4) as a code point -> glyph map."""
data = self.data
base = self.tables["cmap"][0]
(count,) = struct.unpack_from(">H", data, base + 2)
for i in range(count):
platform, encoding, offset = struct.unpack_from(">HHI", data, base + 4 + 8 * i)
sub = base + offset
if (platform, encoding) in ((3, 1), (0, 3)) and struct.unpack_from(">H", data, sub)[0] == 4:
return self._read_cmap4(sub)
raise FontError("no Unicode BMP (format 4) cmap subtable")
def _read_cmap4(self, sub):
data = self.data
(seg_x2,) = struct.unpack_from(">H", data, sub + 6)
segs = seg_x2 // 2
ends = struct.unpack_from(f">{segs}H", data, sub + 14)
starts = struct.unpack_from(f">{segs}H", data, sub + 16 + seg_x2)
deltas = struct.unpack_from(f">{segs}h", data, sub + 16 + 2 * seg_x2)
range_at = sub + 16 + 3 * seg_x2
ranges = struct.unpack_from(f">{segs}H", data, range_at)
table = {}
for i in range(segs):
for code in range(starts[i], ends[i] + 1):
if code == 0xFFFF:
continue
if ranges[i] == 0:
glyph = (code + deltas[i]) & 0xFFFF
else:
at = range_at + 2 * i + ranges[i] + 2 * (code - starts[i])
(glyph,) = struct.unpack_from(">H", data, at)
if glyph:
glyph = (glyph + deltas[i]) & 0xFFFF
if glyph:
table[code] = glyph
return table
def glyph(self, char):
"""The glyph index of a character (0, the missing glyph, when the font has none)."""
return self.cmap.get(ord(char), 0)
def advance(self, glyph):
hmtx = self.tables["hmtx"][0]
index = min(glyph, self.num_h_metrics - 1)
return struct.unpack_from(">H", self.data, hmtx + 4 * index)[0]
def contours(self, glyph, depth=0):
"""The glyph's outline as closed polylines in font units (y up)."""
if depth > MAX_COMPOSITE_DEPTH:
raise FontError("composite glyphs nested too deeply")
if not 0 <= glyph < self.num_glyphs:
raise FontError(f"glyph {glyph} out of range")
start, end = self.loca[glyph], self.loca[glyph + 1]
if start == end:
return [] # no outline (a space)
at = self.tables["glyf"][0] + start
(n,) = struct.unpack_from(">h", self.data, at)
if n >= 0:
return self._simple(at, n)
return self._composite(at + 10, depth)
def _simple(self, at, n):
data = self.data
ends = struct.unpack_from(f">{n}H", data, at + 10)
points = ends[-1] + 1 if n else 0
at += 10 + 2 * n
(instructions,) = struct.unpack_from(">H", data, at)
at += 2 + instructions
flags = []
while len(flags) < points:
flag = data[at]
at += 1
repeat = 1
if flag & 8:
repeat += data[at]
at += 1
flags.extend([flag] * repeat)
flags = flags[:points]
def coords(short_bit, same_bit):
nonlocal at
values, value = [], 0
for flag in flags:
if flag & short_bit:
delta = data[at]
at += 1
value += delta if flag & same_bit else -delta
elif not flag & same_bit:
value += struct.unpack_from(">h", data, at)[0]
at += 2
values.append(value)
return values
xs = coords(2, 16)
ys = coords(4, 32)
contours, first = [], 0
for last in ends:
pts = [(xs[i], ys[i], bool(flags[i] & 1)) for i in range(first, last + 1)]
first = last + 1
if pts:
contours.append(_flatten(pts))
return contours
def _composite(self, at, depth):
data = self.data
contours = []
while True:
flags, glyph = struct.unpack_from(">HH", data, at)
at += 4
if flags & 1:
arg1, arg2 = struct.unpack_from(">hh", data, at)
at += 4
else:
arg1, arg2 = struct.unpack_from(">bb", data, at)
at += 2
if not flags & 2:
raise FontError("composite glyphs placed by point matching are not supported")
a, b, c, d = 1.0, 0.0, 0.0, 1.0
if flags & 8:
a = d = _f2dot14(data, at)
at += 2
elif flags & 0x40:
a, d = _f2dot14(data, at), _f2dot14(data, at + 2)
at += 4
elif flags & 0x80:
a, b, c, d = (_f2dot14(data, at + 2 * k) for k in range(4))
at += 8
for contour in self.contours(glyph, depth + 1):
contours.append([(a * x + c * y + arg1, b * x + d * y + arg2) for x, y in contour])
if not flags & 0x20:
return contours
def _f2dot14(data, at):
return struct.unpack_from(">h", data, at)[0] / 16384.0
def _flatten(pts):
"""A closed quadratic B-spline contour (on- and off-curve points) as a polyline."""
# Start on an on-curve point; with none, at the midpoint of the first two off-curve ones.
start = next((i for i, p in enumerate(pts) if p[2]), None)
if start is None:
(x0, y0, _), (x1, y1, _) = pts[0], pts[1 % len(pts)]
pts = [((x0 + x1) / 2, (y0 + y1) / 2, True)] + pts
start = 0
pts = pts[start:] + pts[:start]
out = [(pts[0][0], pts[0][1])]
control = None
for x, y, on in pts[1:] + pts[:1]:
if on:
if control is None:
out.append((x, y))
else:
out.extend(_quad(out[-1], control, (x, y)))
control = None
else:
if control is not None:
mid = ((control[0] + x) / 2, (control[1] + y) / 2)
out.extend(_quad(out[-1], control, mid))
control = (x, y)
return out
def _quad(p0, p1, p2):
pts = []
for k in range(1, CURVE_STEPS + 1):
t = k / CURVE_STEPS
u = 1 - t
pts.append((u * u * p0[0] + 2 * u * t * p1[0] + t * t * p2[0], u * u * p0[1] + 2 * u * t * p1[1] + t * t * p2[1]))
return pts
def fill(polygons, width, height):
"""Coverage (0..1, row-major) of closed polygons in pixel coordinates (y down), non-zero rule."""
cover = [0.0] * (width * height)
edges = []
for poly in polygons:
for (x0, y0), (x1, y1) in zip(poly, poly[1:] + poly[:1]):
if y0 != y1:
edges.append((x0, y0, x1, y1, 1 if y1 > y0 else -1))
if not edges:
return cover
top = max(0, int(math.floor(min(min(e[1], e[3]) for e in edges))))
bottom = min(height, int(math.ceil(max(max(e[1], e[3]) for e in edges))))
weight = 1.0 / SUBSAMPLES
for row in range(top, bottom):
base = row * width
for s in range(SUBSAMPLES):
y = row + (s + 0.5) / SUBSAMPLES
crossings = []
for x0, y0, x1, y1, wind in edges:
if (y0 <= y < y1) or (y1 <= y < y0):
crossings.append((x0 + (y - y0) * (x1 - x0) / (y1 - y0), wind))
crossings.sort()
winding = 0
for (xa, wind), (xb, _) in zip(crossings, crossings[1:]):
winding += wind
if winding:
_span(cover, base, width, xa, xb, weight)
return cover
def _span(cover, base, width, xa, xb, weight):
"""Add `weight` times the covered fraction of each pixel in [xa, xb) of one row."""
xa, xb = max(xa, 0.0), min(xb, float(width))
if xb <= xa:
return
first, last = int(xa), min(int(math.ceil(xb)) - 1, width - 1)
if first == last:
cover[base + first] += weight * (xb - xa)
return
cover[base + first] += weight * (first + 1 - xa)
for px in range(first + 1, last):
cover[base + px] += weight
cover[base + last] += weight * (xb - last)
def text_width(font, text, size):
return sum(font.advance(font.glyph(ch)) for ch in text) * size / font.units_per_em
def text_polygons(font, text, size, x, baseline):
"""The outlines of a line of text at `size` pixels per em, its baseline at `baseline`."""
scale = size / font.units_per_em
polygons = []
for ch in text:
glyph = font.glyph(ch)
for contour in font.contours(glyph):
polygons.append([(x + px * scale, baseline - py * scale) for px, py in contour])
x += font.advance(glyph) * scale
return polygons, x
class Canvas:
"""An opaque RGB picture that shapes are painted over, anti-aliased by their coverage."""
def __init__(self, width, height, background):
self.width, self.height = width, height
self.rgb = [list(background) for _ in range(width * height)]
def paint(self, polygons, color):
"""Paint polygons in an sRGB colour (r, g, b bytes)."""
cover = fill(polygons, self.width, self.height)
for i, c in enumerate(cover):
if c > 0.0:
c = min(c, 1.0)
self.rgb[i] = [d + (s - d) * c for d, s in zip(self.rgb[i], color)]
def png(self):
rows = []
for y in range(self.height):
row = bytearray(b"\0") # filter: none
for px in self.rgb[y * self.width:(y + 1) * self.width]:
row.extend(min(255, int(round(v))) for v in px)
rows.append(bytes(row))
return png(self.width, self.height, b"".join(rows))
def png(width, height, scanlines):
"""An 8-bit RGB PNG from filtered scanlines (each row prefixed by its filter byte)."""
def chunk(tag, body):
return struct.pack(">I", len(body)) + tag + body + struct.pack(">I", zlib.crc32(tag + body) & 0xFFFFFFFF)
header = struct.pack(">IIBBBBB", width, height, 8, 2, 0, 0, 0)
return b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", header) + chunk(b"IDAT", zlib.compress(scanlines, 9)) + chunk(b"IEND", b"")
# The caption bar's look: the app's dark panel colour, the tool name in its accent blue.
BAR = (22, 26, 34)
TOOL = (110, 168, 255)
TEXT = (236, 239, 244)
SEPARATOR = " \u00b7 "
def caption_bar(font, size, tool, detail, font_size=22):
"""A caption bar of `size` (width, height) pixels: the MCP tool's name, then what it does,
centred."""
width, height = size
rest = SEPARATOR + detail if detail else ""
text_w = text_width(font, tool + rest, font_size)
canvas = Canvas(width, height, BAR)
# The baseline centres the font's cap height (about 0.73 em for Inter) in the bar.
baseline = height / 2 + 0.73 * font_size / 2
polygons, x = text_polygons(font, tool, font_size, (width - text_w) / 2, baseline)
canvas.paint(polygons, TOOL)
if rest:
polygons, _ = text_polygons(font, rest, font_size, x, baseline)
canvas.paint(polygons, TEXT)
return canvas.png()