// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using SixLabors.Fonts.Unicode; using System.Collections.Generic; namespace SixLabors.Fonts.Tables.AdvancedTypographic.Shapers { /// /// Abstract base class for all script shapers. Defines the shaping pipeline /// consisting of preprocessing, feature planning, postprocessing, and feature assignment stages. /// internal abstract class BaseShaper { /// /// Gets or sets the script classification for this shaper. /// public ScriptClass ScriptClass { get; protected set; } /// /// Gets or sets the mark zeroing mode that determines when mark advances are zeroed. /// public MarkZeroingMode MarkZeroingMode { get; protected set; } /// /// Assigns the features to each glyph within the collection. /// /// The glyph shaping collection. /// The zero-based index of the elements to assign. /// The number of elements to assign. public void Plan(IGlyphShapingCollection collection, int index, int count) { int collectionCount = collection.Count; this.PlanPreprocessingFeatures(collection, index, count); RecalculateCount(collection, ref collectionCount, ref count); this.PlanFeatures(collection, index, count); RecalculateCount(collection, ref collectionCount, ref count); this.PlanPostprocessingFeatures(collection, index, count); RecalculateCount(collection, ref collectionCount, ref count); this.AssignFeatures(collection, index, count); } /// /// Assigns the features to each glyph within the collection. /// /// The glyph shaping collection. /// The zero-based index of the elements to assign. /// The number of elements to assign. protected abstract void PlanFeatures(IGlyphShapingCollection collection, int index, int count); /// /// Assigns the preprocessing features to each glyph within the collection. /// /// The glyph shaping collection. /// The zero-based index of the elements to assign. /// The number of elements to assign. protected abstract void PlanPreprocessingFeatures(IGlyphShapingCollection collection, int index, int count); /// /// Assigns the postprocessing features to each glyph within the collection. /// /// The glyph shaping collection. /// The zero-based index of the elements to assign. /// The number of elements to assign. protected abstract void PlanPostprocessingFeatures(IGlyphShapingCollection collection, int index, int count); /// /// Assigns the shaper specific substitution features to each glyph within the collection. /// /// The glyph shaping collection. /// The zero-based index of the elements to assign. /// The number of elements to assign. protected abstract void AssignFeatures(IGlyphShapingCollection collection, int index, int count); /// /// Gets the ordered collection of shaping stages for this shaper. /// /// The shaping stages. public abstract IEnumerable GetShapingStages(); /// /// Recalculates the count when the collection size changes during shaping. /// /// The glyph shaping collection. /// The previous collection count, updated to the current count. /// The element count, adjusted by the size delta. private static void RecalculateCount(IGlyphShapingCollection collection, ref int oldCount, ref int count) { // If the collection has changed size we need to recalculate the count. int delta = collection.Count - oldCount; count += delta; oldCount += delta; } } }