Vixen
dd8b0a81
csharp
public record class TextRun

One stretch of an element's text: one face, shaped and measured at one size.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

A run is one face, and a line is a list of them. See TextLine: a string whose characters are not all in one font becomes several runs, and so would a rich text span carrying its own size. Everything on this type is about the one face, so a consumer that reaches for Font or Scale is asking a question only a run can answer — the line is where a mixed-font width or caret lives, because those can only be composed in pixels.

⚠ One line. Nothing here breaks a paragraph across lines, so a string wider than its element overflows it rather than wrapping — the measure function ignores the width it is offered. Vixen.Ui.Text already has the UAX#14 line breaker this needs and wrapping is the next piece of text work rather than a missing consideration; said here so that a long label overflowing reads as a known edge rather than as a layout bug.

The size is carried alongside the shaping rather than baked into it, because the shaping is shared: the cache returns the same ShapedText for the same string in the same font whatever size it is drawn at, and this is the per-element view of it.

Fields and properties (16)

  • public FontFace Font

    The face it was shaped with.

  • public ShapedText Shaped

    The glyphs, in design units.

  • public float Size

    The font size in pixels — what an em on this element measures.

  • public float Tracking

    letter-spacing in pixels, added after every typographic character. Zero for the overwhelming majority of text, and the code below is written so that zero costs nothing.

  • public float Leading

    The computed line-height in pixels, or NaN for the font's own recommendation. NaN rather than zero, because zero is a line height somebody might mean.

  • public int Start

    Where this run's text begins in the text it was shaped from, as a UTF-16 index. Zero for a line that is one run, and what lets a caret index reach the run it belongs to. ⚠ The shaped text and the element's own text are the same string unless a text-transform expanded something — straße uppercases to STRASSE, seven characters where the author wrote six. TextLine carries the map between the two and does the translation, so a caller reaching past it into a run is the one place the distinction has to be held in mind.

  • public int Level

    Its bidi embedding level — even runs left to right, odd runs right to left. Zero for text that is entirely left-to-right, which is what a caller that has not thought about it gets. ⚠ This is what lets a line be drawn in an order its runs are not stored in. A run is cut where the face changes and also where the level changes, and it has to be both: TextLine reorders whole runs by L2, and reversing a stretch of runs is sound only if each run has one level throughout. A run split by coverage alone and given the level of its first character reorders its neighbours correctly and strands its own neutrals — a line whose words are in the right order and whose spaces are not.

  • public float WordSpacing

    word-spacing in pixels, added to the advance of every word-separator character. Zero for almost all text, and the same shape as so that zero costs nothing. ⚠ It is not tracking on the space, and the difference is which characters count. CSS Text 3 § 8.2 defines a closed list of word-separator characters — the ordinary space and the no-break space are the two any interface meets — and applies this to those and to nothing else. A tab is not one; nor is a zero-width space, which is a break opportunity rather than a separator. IsWordSeparator is that list, written out rather than approximated by char.IsWhiteSpace, which would space a tab and a line separator as well.

  • public bool IsRightToLeft

    Whether the run is drawn right to left.

  • public bool IsTab

    Whether this run is one tab, whose width its line decides rather than its font.

  • public float Scale

    What multiplies a design unit to give a pixel.

  • public int Clusters

    How many typographic characters the line has, for tracking to be added between.

  • public int Separators

    How many of this run's clusters are word-separator characters.

  • public float Width

    How wide the line is.

  • public float Height

    How tall one line of it is.

  • public float Baseline

    How far below the top of the line the baseline sits.

Methods (9)

  • public TextRun(FontFace Font, ShapedText Shaped, float Size, float Tracking = 0, float Leading = NaN, int Start = 0, int Level = 0, float WordSpacing = 0)

    One stretch of an element's text: one face, shaped and measured at one size.

  • public float CaretOffset(int index)

    How far along the run a caret index sits, in pixels.

  • public float CaretOffset(int index, CaretAffinity affinity)

    How far along the run a caret sits, given which side of the index it is on.

  • public int CaretIndexAt(float x)

    Which caret index a distance from the run's start lands on.

  • public (int Index, CaretAffinity Affinity) CaretPositionAt(float x)

    Which caret a distance from the run's start lands on, and which side of it.

  • public void Place(List<PositionedGlyph> into, float penX = 0)

    Places every glyph relative to the start of the line.

  • public DecorationBar Bar(TextDecorationLine line, TextDecoration decoration)

    Where one decoration line sits on this run, relative to its baseline.

  • public IEnumerable<DecorationBar> Bars(TextDecoration decoration, bool under)

    The bars a decoration asks for on one side of the glyphs.

  • public static bool Under(TextDecorationLine line)

    Whether a line is painted beneath the glyphs rather than over them.

Used by (16)

  • BidiFallbackTestsVixen.Ui.Tests
  • BidiMirroringTestsVixen.Ui.Tests
  • CaretAffinityTestsVixen.Ui.Controls.Tests
  • CaretAffinityTestsVixen.Ui.Tests
  • DrawListBuilderVixen.Ui
  • DrawnLayerTextTestsVixen.Ui.Tests
  • FontFallbackTestsVixen.Ui.Tests
  • FontRegistryTestsVixen.Ui.Tests
  • HyphensTestsVixen.Ui.Tests
  • LanguageTestsVixen.Ui.Tests
  • LineClampTestsVixen.Ui.Tests
  • SelectionRangeTestsVixen.Ui.Controls.Tests
  • TextLineVixen.Ui
  • TextTestsVixen.Ui.Tests
  • TextTransformTestsVixen.Ui.Tests
  • UiElementVixen.Ui