// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Collections.Generic;
using System.Linq;
namespace SixLabors.Fonts {
///
/// Represents a shaped and line-broken block of text.
///
internal sealed class TextBox
{
private readonly TextDirection textDirection;
private float? scaledMaxAdvance;
private float? minY;
private int glyphLayoutCount;
private bool hasGlyphLayoutCounts;
///
/// Initializes a new instance of the class.
///
/// The shaped, line-broken lines that make up this text box.
/// The block-level text direction.
public TextBox(IReadOnlyList textLines, TextDirection textDirection)
{
this.TextLines = textLines;
this.textDirection = textDirection;
}
///
/// Gets the shaped and line-broken lines that make up the text.
///
public IReadOnlyList TextLines { get; }
///
/// Returns the widest scaled line advance across all lines. The result is memoized.
///
/// The widest scaled line advance.
public float ScaledMaxAdvance()
=> this.scaledMaxAdvance ??= this.TextLines.Max(x => x.ScaledLineAdvance);
///
/// Returns the smallest (most negative) scaled Y position encountered across all lines.
/// Used to detect ink that extends above the typographic ascender (stacked marks in Tibetan etc.).
/// The result is memoized.
///
/// The smallest scaled Y position in the text box.
public float ScaledMinY()
=> this.minY ??= this.TextLines.Min(x => x.ScaledMinY);
///
/// Counts all glyph entries emitted from this text box. The result is memoized.
///
/// The number of glyph entries that layout will emit.
public int CountGlyphLayouts()
=> this.hasGlyphLayoutCounts ? this.glyphLayoutCount : this.CountGlyphLayoutsCore();
///
/// Computes the glyph-layout count in one pass.
///
/// The number of glyph entries that layout will emit.
private int CountGlyphLayoutsCore()
{
int count = 0;
for (int i = 0; i < this.TextLines.Count; i++)
{
count += this.TextLines[i].CountGlyphLayouts();
}
this.glyphLayoutCount = count;
this.hasGlyphLayoutCounts = true;
return count;
}
///
/// Returns the block-level text direction used for alignment calculations.
///
/// The block-level text direction.
public TextDirection TextDirection() => this.textDirection;
}
}