"""Analytical drawing of recorded experimental geometry, not an app screenshot.""" from pathlib import Path import hashlib import json from PIL import Image, ImageDraw, ImageFont root = Path(__file__).resolve().parent.parent run = root / '.local/native-qa/resize-falsifiers-a95-01' output = run / 'obstacle-comparison.png' assert not output.exists() record = json.loads((run / 'case-2.json').read_bytes()) font = lambda n: ImageFont.truetype('C:/Windows/Fonts/arial.ttf', n) canvas = Image.new('RGB', (1260, 760), '#ffffff') draw = ImageDraw.Draw(canvas) draw.text((30, 20), 'A capacity spill creates a blocked port exit', font=font(27), fill='#142a3b') draw.text((30, 60), 'Recorded core geometry; cropped owner and obstacle. Port stubs only, not desktop rendering.', font=font(17), fill='#374957') styles = [('Current', 'Current', 'Owner grows to 224 x 232'), ('SameSidesAdaptSpacing', 'Adaptive spacing', 'Requested owner: 224 x 160'), ('CapacityAware', 'Capacity-aware candidate', 'Requested owner: 224 x 160')] for index, (policy, title, caption) in enumerate(styles): path = run / 'case-2-geometry' / f'obstacle-{policy}.projection.json' raw = path.read_bytes() assert hashlib.sha256(raw).hexdigest() == record['geometry'][str(path)]['sha256'] view = json.loads(raw) left = 20 + index * 415 scale = 1.2 point = lambda x, y: (left + 70 + x * scale, 335 + y * scale) rect = lambda n, pad=0: (*point(n['position']['x'] - pad, n['position']['y'] - pad), *point(n['position']['x'] + n['size']['width'] + pad, n['position']['y'] + n['size']['height'] + pad)) draw.rounded_rectangle((left, 104, left + 402, 738), radius=9, outline='#c1cbd2', width=1) draw.text((left + 15, 116), title, font=font(20), fill='#142a3b') owner = next(n for n in view['nodes'] if n['id'].endswith('0028')) obstacle = next(n for n in view['nodes'] if n['id'].endswith('002a')) draw.rectangle(rect(obstacle, 12), fill='#fee7e7', outline='#d68a8a', width=1) draw.rectangle(rect(obstacle), fill='#dce3e9', outline='#4e6475', width=2) draw.text(point(17, -125), 'Unrelated obstacle', font=font(18), fill='#243c4e') draw.text(point(17, -99), 'Pink: 12-unit clearance', font=font(16), fill='#774040') draw.rectangle(rect(owner), fill='#eef7ff', outline='#205b86', width=2) draw.text(point(20, 30), 'Owner', font=font(19), fill='#205b86') bad = 0 for port in view['ports']: if port['owner'] != owner['id']: continue x, y = port['position']['x'], port['position']['y'] nx, ny = {'Left': (-1, 0), 'Right': (1, 0), 'Top': (0, -1), 'Bottom': (0, 1)}[port['side']] # This record's independently observed collision is retained in case-2. blocked = policy == 'CapacityAware' and port['element'].endswith('006a') bad += blocked color = '#bc212b' if blocked else '#205b86' draw.line([point(x, y), point(x + nx * 18, y + ny * 18)], fill=color, width=4 if blocked else 2) draw.rectangle((*point(x - 7, y - 7), *point(x + 7, y + 7)), fill='white', outline=color, width=2) if blocked: draw.text(point(129, -18), 'Blocked', font=font(17), fill=color) draw.text((left + 15, 650), caption, font=font(18), fill='#243c4e') draw.text((left + 15, 680), f'{bad} blocked stub' + ('' if bad == 1 else 's'), font=font(18), fill='#bc212b' if bad else '#205b86') draw.text((left + 15, 708), 'Distant connected peer is outside this crop.', font=font(14), fill='#4e6475') canvas.save(output) print(output)