Class LineFlow
Lays a paragraph out one line at a time, each at its own width, so text can flow across columns and pages or around images; Layout(float) is built on it. Not thread-safe; make one per flow.
public sealed class LineFlow
- Inheritance
-
LineFlow
- Inherited Members
Examples
// One line at a time, each at its own width: two columns of four lines, the second wrapping around an image.
LineFlow flow = paragraph.CreateFlow();
List<TextLine> first = [], second = [];
while (first.Count < 4 && flow.NextLine(150) is TextLine line)
{
first.Add(line);
}
while (flow.NextLine(second.Count < 2 ? 90 : 150) is TextLine line)
{
second.Add(line); // narrower beside the image
}
Properties
IsComplete
Gets whether every line has been laid out. An empty paragraph has no lines, and a final hard break adds none, as CSS lays text out.
public bool IsComplete { get; }
Property Value
Paragraph
Gets the paragraph being laid out.
public Paragraph Paragraph { get; }
Property Value
Position
Gets the UTF-16 index the next line starts at.
public int Position { get; }
Property Value
Methods
NextLine(float)
Lays out the next line in the available width.
public TextLine? NextLine(float availableWidth)
Parameters
availableWidthfloatThe line's width in canvas units; PositiveInfinity for no wrapping.
Returns
- TextLine
The line, its top at 0, or null when the paragraph is done.
Exceptions
- ArgumentOutOfRangeException
availableWidthis negative or not a number.
Reset()
Starts again from the paragraph's first line.
public void Reset()
Rewind(int)
Takes back the lines from position on, so the next NextLine(float) lays out from there
again: a line that did not fit at the foot of a column goes back to start the next one (Start).
public void Rewind(int position)
Parameters
Examples
// One article flowed down two columns of a page: LineFlow hands out one line at a time at the width asked for, so the
// first column can be narrowed beside a picture and the rest carries on in the second. On Egap's PDF canvas the same
// calls write searchable text.
ParagraphStyle style = new() { DefaultStyle = new TextStyle { FontFamilies = [family], Size = 10 }, Align = TextAlign.Justify };
LineFlow flow = Paragraph.Create(article, style).CreateFlow();
(float X, float Top, float Bottom)[] columns = [(40, 60, 300), (310, 60, 300)];
foreach ((float x, float top, float bottom) in columns)
{
float y = top;
while (!flow.IsComplete)
{
float width = x == 40 && y < 160 ? 150 : 245; // beside a picture at the top of column one
TextLine line = flow.NextLine(width)!;
if (y + line.Height > bottom)
{
flow.Rewind(line.Start); // that line goes to the next column
break;
}
foreach (LayoutRun run in line.Runs)
{
if (run.Glyphs is { Count: > 0 } glyphs)
{
page.DrawGlyphRun(glyphs, new System.Numerics.Vector2(x, y), new SolidPaint(Rgba8.Black));
}
}
y += line.Height;
}
}
Exceptions
- ArgumentOutOfRangeException
positionis negative or past Position.