feat: write ink drawings and handwriting through the page model

A page::Ink object in the model is written the way OneNote 2010 stores a
mouse drawing: an ink container (jcid 0x60014) the page lists as a child or
a paragraph holds as content, its data node (0x2003b) listing stroke objects
(0x20047) whose coordinates are ISF multi-byte first differences in HIMETRIC
with index, language, identity, time and half-inch origin, and one
drawing-attribute object (0x120048) per distinct pen carrying the dimension
table OneNote wrote for its own ink. Points are rounded to the HIMETRIC grid
(page::ink::snap gives callers the same rounding), so a written stroke reads
back equal. Editing rewrites the stroke list: stored strokes keep their paths
and pens, removed ones leave the list, new ones are created; removing the
object goes through the tree editor, which now accepts ink as a page child.

corpus/ink-edit holds cold reads of a Rust square-and-diagonal drawing on
the page and inside an outline paragraph, with screenshots of OneNote 2010
rendering both; tools/test_ink_edit.py checks them without a VM.

Assisted-by: claude-fable-5.1
237d4668adclover caruso committed on 9/26/2026, 3:26:20 AMparent7f30bf3
42 files changedLine totals unavailable