// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; using System.Collections.Generic; using System.Diagnostics; using SixLabors.Fonts.Unicode; namespace SixLabors.Fonts { /// /// Per-codepoint shaping data stored inside a . /// Each entry corresponds to a single codepoint — complex scripts may map one grapheme to /// multiple entries (tracked via ). /// [DebuggerDisplay("{DebuggerDisplay,nq}")] internal struct GlyphLayoutData { internal const int NoHyphenationMarker = -1; /// /// Initializes a new instance of the struct. /// /// The shaped glyph metrics for this codepoint. /// The font used to shape and render this entry. /// The point size at which the glyph is rendered. /// The scaled advance of this entry. /// The scaled line height contributed by this entry. /// The scaled typographic ascender. /// The scaled typographic descender. /// The symmetric metrics delta applied during line-box construction. /// The minimum scaled Y (topmost ink) across . /// The resolved bidi run this entry belongs to. /// The grapheme index in the source text. /// Whether this is the last codepoint in its grapheme cluster. /// The codepoint index in the source text. /// The index of this codepoint within its grapheme cluster. /// Whether the entry participates in a transformed vertical layout. /// Whether the entry was produced by Unicode decomposition. /// The UTF-16 character index in the source string. /// The marker index to use if this entry becomes a selected soft-hyphen break. public GlyphLayoutData( IReadOnlyList metrics, Font font, float pointSize, float scaledAdvance, float scaledLineHeight, float scaledAscender, float scaledDescender, float scaledDelta, float scaledMinY, BidiRun bidiRun, int graphemeIndex, bool isLastInGrapheme, int codePointIndex, int graphemeCodePointIndex, bool isTransformed, bool isDecomposed, int stringIndex, int hyphenationMarkerIndex = NoHyphenationMarker) { this.Metrics = metrics; this.Font = font; this.PointSize = pointSize; this.ScaledAdvance = scaledAdvance; this.ScaledLineHeight = scaledLineHeight; this.ScaledAscender = scaledAscender; this.ScaledDescender = scaledDescender; this.ScaledDelta = scaledDelta; this.ScaledMinY = scaledMinY; this.BidiRun = bidiRun; this.GraphemeIndex = graphemeIndex; this.IsLastInGrapheme = isLastInGrapheme; this.CodePointIndex = codePointIndex; this.GraphemeCodePointIndex = graphemeCodePointIndex; this.IsTransformed = isTransformed; this.IsDecomposed = isDecomposed; this.StringIndex = stringIndex; this.HyphenationMarkerIndex = hyphenationMarkerIndex; } /// Gets the source codepoint for this entry. public readonly CodePoint CodePoint => this.Metrics[0].CodePoint; /// Gets the shaped glyph metrics produced for this codepoint (one codepoint may map to several glyphs). public IReadOnlyList Metrics { get; } /// Gets the font used to shape and render this entry. public Font Font { get; } /// Gets the point size at which this entry is rendered. public float PointSize { get; } /// Gets or sets the scaled advance of this entry (mutated by justification). public float ScaledAdvance { get; set; } /// Gets the scaled line height contributed by this entry, before line-spacing is applied. public float ScaledLineHeight { get; } /// Gets the scaled typographic ascender. public float ScaledAscender { get; } /// Gets the scaled typographic descender. public float ScaledDescender { get; } /// Gets the symmetric ascender/descender delta applied during line-box construction. public float ScaledDelta { get; } /// Gets the smallest (most negative) scaled Y across . public float ScaledMinY { get; } /// Gets the resolved bidi run this entry belongs to. public BidiRun BidiRun { get; } /// Gets the text direction derived from . public readonly TextDirection TextDirection => (TextDirection)this.BidiRun.Direction; /// Gets the zero-based grapheme index in the original text. public int GraphemeIndex { get; } /// Gets or sets a value indicating whether this is the last entry in its grapheme cluster. public bool IsLastInGrapheme { get; set; } /// Gets the index of this codepoint within its grapheme cluster (0-based). public int GraphemeCodePointIndex { get; } /// Gets the codepoint index in the source text. public int CodePointIndex { get; } /// Gets a value indicating whether the entry participates in a transformed vertical layout. public bool IsTransformed { get; } /// Gets a value indicating whether the entry was produced by Unicode decomposition. public bool IsDecomposed { get; } /// Gets the zero-based UTF-16 code unit index in the original text. public int StringIndex { get; } /// Gets the marker index to use if this entry becomes a selected soft-hyphen break. public int HyphenationMarkerIndex { get; } /// Gets a value indicating whether the codepoint is a line-break character. public readonly bool IsNewLine => CodePoint.IsNewLine(this.CodePoint); private readonly string DebuggerDisplay => FormattableString .Invariant($"{this.CodePoint.ToDebuggerDisplay()} : {this.TextDirection} : {this.CodePointIndex}, level: {this.BidiRun.Level}"); } }