// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. namespace SixLabors.Fonts { /// /// Walks a one laid-out line at a time. /// /// /// Each produced line is positioned independently, without cumulative offsets from earlier or later lines. /// public sealed class LineLayoutEnumerator { private readonly TextBlock textBlock; private readonly TextLineBreakEnumerator lineEnumerator; private readonly TextDirection textDirection; private readonly bool suppressLayout; private LineLayout? current; /// /// Initializes a new instance of the class. /// /// The prepared text block to enumerate. internal LineLayoutEnumerator(TextBlock textBlock) { this.textBlock = textBlock; this.lineEnumerator = new(textBlock.LogicalLine, textBlock.Options); this.textDirection = TextLayout.GetTextDirection(textBlock.LogicalLine, textBlock.Options); this.suppressLayout = textBlock.Options.MaxLines == 0; } /// /// Gets the current line layout. /// public LineLayout Current => this.current!; /// /// Advances to the next line using the supplied wrapping length. /// /// /// The wrapping length applies only to the line being produced by this call. /// /// The wrapping length in pixels. Use -1 to disable wrapping. /// when a line was produced. public bool MoveNext(float wrappingLength) { if (this.suppressLayout) { return false; } if (!this.lineEnumerator.MoveNext(wrappingLength)) { return false; } // The walker lays out each produced line independently so callers can // place variable-width lines into custom columns, shapes, or virtualized // surfaces without inheriting block-level line offsets. this.current = this.textBlock.GetLineLayout( this.lineEnumerator.Current, wrappingLength, this.textDirection); return true; } } }