Rope
The document: a flat table of TextBlock leaves with indexes over chars, codepoints, paragraph separators, heights and line 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 until the layout is reset. An edit of the block returns its height to an estimate and leaves its widths at this measurement until the block is measured again. A measurement taken with the block's paragraph cut at a window edge is exact =: it replaces an estimate or an earlier inexact measurement, never an exact one.
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.
