Rope
The document: a flat table of TextBlock leaves with Fenwick indexes over chars, codepoints, paragraph separators, heights and widths. Every position query — char↔codepoint, char↔paragraph, Y↔block, X↔block — is O(log blocks); an edit costs O(edited block) plus O(log blocks), or O(blocks) when it changes the block count. Blocks lent to workers through Lease are immutable for the lease's lifetime: an edit clones a shared block instead of mutating it.
Remarks
public ScanProfile Profile{ get; set }The scan profile blocks are classified with; changing it re-summarizes every block.
public static Rope FromChars()Builds a document from UTF-16 text, cutting blocks at paragraph boundaries where possible.
public TextBlockFlags BlockFlags()public EditShape Insert()public EditShape Delete()public EditShape InsertAtCodepoint()public EditShape DeleteAtCodepoint()public EditShape SetText()Replaces the whole content; the returned shape excludes the common prefix and suffix.
public EditShape Replace()The one mutation: removes removeCount chars at start and inserts text there. Boundaries may not split a surrogate pair.
Records a block's measured extent; it stays until the block is edited or the layout is reset. A measurement taken with the block's paragraph cut at a window edge is exact =: it replaces the estimate but leaves the block for the convergence sweep, and it never overwrites an exact measurement.
public BlockLease Lease()Pins blocks [first, first+count) for a worker: their content stays immutable until Dispose (main thread). Reads through the lease are safe from any thread.
