Docsv3.31.0
Back to API Reference
Class

Rope

sealed
Inherits:ITextDocument
Implements:IDisposable

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

Main-thread only, except for reads through a BlockLease. Block boundaries never split a surrogate pair or a CRLF pair; edits may not split a surrogate pair (they throw), matching ITextDocument consumers' expectations.
public ScanProfile Profile{ get; set }

The scan profile blocks are classified with; changing it re-summarizes every block.

public int CodepointCount{ get }
public int CharCount{ get }
public int Length{ get }

Logical length in UTF-16 units; the same value as CharCount.

public int Version{ get }
public int ParagraphCount{ get }

Paragraphs, counting the (possibly empty) one after the last separator; never zero.

public int BlockCount{ get }
public bool IsEmpty{ get }
public int MeasuredBlockCount{ get }

Blocks whose extent is an exact measurement rather than an estimate.

public double TotalHeight{ get }
public float ContentWidth{ get }

Gets the widest line from the current block measurements and estimates.

[ctor]public Rope(ScanProfile profile = null)

Creates an empty document.

public static Rope FromChars(ReadOnlySpan<char> text, ScanProfile profile = null)

Builds a document from UTF-16 text, cutting blocks at paragraph boundaries where possible.

public void Dispose()

Releases every block reference this document holds and the loaded source, if any.

[ctor]public Rope(int capacity)

Creates an empty document; capacity is accepted for call-site compatibility and has no effect on block sizing.

public int BlockAtChar(int charIndex, out int offsetInBlock)

Block containing logical char charIndex; an index at the end maps to the last block's end.

public int BlockAtCodepoint(int cpIndex, out int offsetInBlock)
public int BlockCharStart(int block)
public int BlockCodepointStart(int block)
public int BlockCharCount(int block)
public int BlockCodepointCount(int block)
public int BlockSeparatorCount(int block)
public TextBlockFlags BlockFlags(int block)
public bool BlockStartsParagraph(int block)

True when the block begins a paragraph: it is the first block or its predecessor ends with a separator.

public bool BlockEndsParagraph(int block)

True when a paragraph ends at the block's end: it is the last block or it ends with a separator.

public int BlockFirstParagraph(int block)

Index of the first paragraph that starts inside or continues into the block.

public int CharToParagraph(int charIndex)

Zero-based paragraph containing logical char charIndex.

public int ParagraphStartChar(int paragraph)

Logical char index where paragraph paragraph starts.

public int CharToCodepointIndex(int charIndex)
public int CodepointToCharIndex(int cpIndex)
public int CopyChars(int start, int count, Span<char> destination)

Copies logical chars [start, start+count); returns the number copied (clamped to the document and the destination).

public int CopyCodepointRange(int startCodepoint, int codepointCount, Span<char> destination)
public int CopyTo(Span<char> destination)

Copies the whole content; returns the number of chars written.

public int CopyTo(int start, int count, Span<char> destination)

Copies logical chars [start, start+count); returns the number written.

public string GetCodepointRange(int codepointIndex, int codepointCount)

The text of a codepoint range as a new string.

public int SnapToPairBoundary(int charPosition)

Clamps to [0, Length] and snaps an interior surrogate boundary backward.

public int CountCodepoints(int charStart, int charCount)

Codepoints in a logical char range.

public int GetCodepointAt(int codepointIndex)
public bool ContentEquals(ReadOnlySpan<char> other)

True when the content equals other unit for unit; compares block by block without allocating.

public override string ToString()

The document as a string; allocates the whole text.

public EditShape Insert(int charIndex, ReadOnlySpan<char> text)
public EditShape Delete(int charIndex, int charCount)
public EditShape InsertAtCodepoint(int cpIndex, ReadOnlySpan<char> text)
public EditShape DeleteAtCodepoint(int cpIndex, int cpCount)
public EditShape SetText(ReadOnlySpan<char> text)

Replaces the whole content; the returned shape excludes the common prefix and suffix.

public void Clear()
public EditShape Replace(int start, int removeCount, ReadOnlySpan<char> text)

The one mutation: removes removeCount chars at start and inserts text there. Boundaries may not split a surrogate pair.

public void ResetLayout(in LayoutEstimate newEstimate)

Resets every block's extent to an estimate under new layout parameters.

public void RefineEstimate(in LayoutEstimate newEstimate)

Updates the estimation parameters without discarding measured blocks; estimated blocks are re-estimated, and edited blocks re-estimate their height.

public void SetBlockMeasured(int block, float height, float width, bool exact = true)

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 = false: it replaces an estimate or an earlier inexact measurement, never an exact one.

public bool IsBlockExact(int block)

True when the block's extent was measured with its paragraph intact.

public double BlockTop(int block)
public double BlockHeight(int block)
public double BlockWidth(int block)
public double BlockLeftInParagraph(int block)

Horizontal offset of the block from the start of its paragraph — meaningful when the paragraph spans several blocks.

public int BlockAtY(double y)

Block whose vertical span contains y (document space, top-down), clamped to the table.

public BlockLease Lease(int first, int count)

Pins blocks [first, first+count) for a worker: their content stays immutable until BlockLease.Dispose (main thread). Reads through the lease are safe from any thread.