Back to API Reference
Class

TextProcessor

sealed
Implements:IDisposable

Processes Unicode text through script analysis, BiDi reordering, shaping, and layout.

Remarks

TextProcessor is the main entry point for the text processing pipeline. It orchestrates multiple Unicode algorithms to produce correctly shaped and positioned glyphs. Processing pipeline: Parsing — converts UTF-16 to codepoints Script analysis (UAX #24) — identifies script per codepoint BiDi algorithm (UAX #9) — determines text direction and reordering Itemization — splits text into runs by script, direction, and font Shaping — converts codepoints to positioned glyphs via HarfBuzz Line breaking (UAX #14) — determines line break opportunities Layout — positions glyphs according to alignment settings Performance: The processor caches intermediate results. Use invalidation methods only when necessary to avoid redundant processing.

Example

csharp
public OrderedEvent Parsed{ get }

Runs after parsing and before shaping, in ascending subscriber order.

public OrderedEvent Analyzed{ get }

Runs once bidi levels, scripts, break opportunities, grapheme breaks and word boundaries are final, and before itemization reads them. The phase for work that needs analysis results yet must still reach shaping — hiding clusters from it, above all.

public OrderedEvent Shaped{ get }

Runs after shaping and before shaped advances are consumed.

public OrderedEvent LinesBroken{ get }

Runs after lines are broken or remeasured and before positioning, including forced rewraps.

public OrderedEvent<TextProcessSettings> ConfigureSettings{ get }

Mutates paragraph-level settings before each processing stage consumes them.

public OrderedEvent<LineStyleContext> OnResolveLineStyle{ get }

Resolves paragraph-scoped alignment for each line.

public OrderedEvent<LineHeightModeContext> OnResolveLineHeight{ get }

Resolves line-height mode and scale before each line's base height is computed.

public OrderedEvent LayoutComplete{ get }

Runs after final glyph positions have been calculated.

public OrderedEvent<LineHeightContext> OnCalculateLineHeight{ get }

Mutates the vertical advance calculated for each line.

public bool HasValidFirstPassData{ get }

Gets a value indicating whether valid first pass data (parsing, BiDi, shaping) is available.

public bool HasValidPositionedGlyphs{ get }

Gets a value indicating whether valid positioned glyphs are available.

public float ResultWidth{ get }

Gets the actual width of the laid out text.

public float ResultHeight{ get }

Gets the actual height of the laid out text.

public ReadOnlySpan<PositionedGlyph> PositionedGlyphs{ get }

Gets the positioned glyphs ready for rendering.

[ctor]public TextProcessor(UniTextBuffers uniTextBuffers)

Initializes a new instance of the TextProcessor class.

public void SetFontProvider(UniTextFontProvider provider)

Sets the font provider used for font lookup and glyph metrics. Must be called with a non-null provider before EnsureFirstPass.

public void Dispose()

Releases pooled processing state and ordered callback storage.

public void InvalidateFirstPassData()

Invalidates all cached processing data, forcing a complete reprocess on next call.

public void InvalidateLayoutData()

Invalidates cached layout data while preserving shaping results.

public void InvalidatePositionedGlyphs()

Invalidates cached glyph positions while preserving line break data.

public void EnsureFirstPass(ReadOnlySpan<char> text, TextProcessSettings settings)

Ensures the first pass processing (parsing, BiDi, shaping) is complete.

public bool CanReuseLines(float width, float fontSize, bool wordWrap)

Determines whether cached line data can be reused for the specified parameters.

public void EnsureLines(float width, float fontSize, bool wordWrap)

Ensures line breaking is complete for the specified parameters.

public bool CanReusePositions(float maxHeight, HorizontalAlignment hAlign, VerticalAlignment vAlign, TextJustify textJustify, LastLineAlignment lastLineAlignment)

Determines whether cached glyph positions can be reused for the specified parameters.

public void EnsurePositions(TextProcessSettings settings)

Ensures final glyph positioning is complete for the specified settings.

public void ForceRelayout(ReadOnlySpan<float> cpWidths)

Forces a complete relayout using custom codepoint widths.

public void ForceReposition()

Forces recalculation of glyph positions while preserving line breaks.

public float GetUnwrappedWidth()

Gets the total width of all text runs without line wrapping.

public float GetPreferredWidth(float fontSize)

Gets the preferred width for the text at the specified font size.

public float GetPreferredHeight(float fontSize, float lineSpacing)

Gets the preferred height for the text at the specified font size.

public float GetMaxLineWidth()

Gets the maximum width among all lines, considering explicit line breaks.

public float FindOptimalFontSize(float minSize, float maxSize, float targetWidth, float targetHeight, TextProcessSettings baseSettings)

The largest font size in minSize–maxSize whose text fits the target box, or minSize when none does. Layout state is restored around the search.

public void ReserveLineSpace()

Reserves extra leading on one side of a specific line for boundary decorations (over/under ruby, etc.): over above the line, under below it. Added to that line's outer gap, or to the block edge for the first/last line. Largest request per side wins. Called from a modifier's line-height callback.

public void ReserveLineWidth()

Reserves width shaping units beside every line for something the text holds room for rather than wraps — a label a frontier keeps a place for, and its like. Added to the width the text reports, so a host sizing to that width leaves the room instead of handing back exactly the text and forcing whoever reserves to take it out of the content. Largest request wins, and requests last until the next parse re-declares them. Called from a modifier's shaped-phase callback, over widths no allocated width can move — a reserve answering to the width it helps decide would chase itself.

public void AddLineGap()

Adds a signed amount to the gap between lineIndex and the following line — negative pulls them together, down to full overlap; the gap never inverts. Requests sum, unlike the largest-wins ReserveLineSpace, so a caller composing several of its own values resolves them before calling. Out-of-range indices are ignored, which is what keeps block edges untouched. Called from a modifier's line-height callback.

public readonly UniTextBuffers buf

The buffer container holding all intermediate and final processing results.

See Also