public record class TextRunOne 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 FontThe face it was shaped with.
public ShapedText ShapedThe glyphs, in design units.
public float SizeThe font size in pixels — what an em on this element measures.
public float Trackingletter-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 LeadingThe 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 StartWhere 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 LevelIts 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 WordSpacingword-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 IsRightToLeftWhether the run is drawn right to left.
public bool IsTabWhether this run is one tab, whose width its line decides rather than its font.
public float ScaleWhat multiplies a design unit to give a pixel.
public int ClustersHow many typographic characters the line has, for tracking to be added between.
public int SeparatorsHow many of this run's clusters are word-separator characters.
public float WidthHow wide the line is.
public float HeightHow tall one line of it is.
public float BaselineHow 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