private static bool Match <T>( int increment, T[] sequence, SkippingGlyphIterator iterator, Func <T, GlyphShapingData, bool> condition, Span <int> matches) { ushort position = iterator.Index; ushort offset = iterator.Increment(increment); IGlyphShapingCollection collection = iterator.Collection; int i = 0; while (i < sequence.Length && i < MaxContextLength && offset < collection.Count) { if (!condition(sequence[i], collection.GetGlyphShapingData(offset))) { break; } if (matches.Length == MaxContextLength) { matches[i] = iterator.Index; } i++; offset = iterator.Next(); } iterator.Index = position; return(i == sequence.Length); }
/// <inheritdoc/> public override void AssignFeatures(IGlyphShapingCollection collection, int index, int count) { this.AddFeature(collection, index, count, CcmpTag); this.AddFeature(collection, index, count, LoclTag); this.AddFeature(collection, index, count, IsolTag, false); this.AddFeature(collection, index, count, FinaTag, false); this.AddFeature(collection, index, count, Fin2Tag, false); this.AddFeature(collection, index, count, Fin3Tag, false); this.AddFeature(collection, index, count, MediTag, false); this.AddFeature(collection, index, count, Med2Tag, false); this.AddFeature(collection, index, count, InitTag, false); this.AddFeature(collection, index, count, MsetTag); base.AssignFeatures(collection, index, count); int prev = -1; int state = 0; byte[] actions = new byte[count]; // Apply the state machine to map glyphs to features. for (int i = 0; i < count; i++) { GlyphShapingData data = collection.GetGlyphShapingData(i + index); JoiningClass joiningClass = CodePoint.GetJoiningClass(data.CodePoint); JoiningType joiningType = joiningClass.JoiningType; if (joiningType == JoiningType.Transparent) { actions[i] = None; continue; } int shapingClassIndex = GetShapingClassIndex(joiningType); byte[] actionsWithState = StateTable[state, shapingClassIndex]; byte prevAction = actionsWithState[0]; byte curAction = actionsWithState[1]; state = actionsWithState[2]; if (prevAction != None && prev != -1) { actions[prev] = prevAction; } actions[i] = curAction; prev = i; } // Apply the chosen features to their respective glyphs. for (int i = 0; i < actions.Length; i++) { switch (actions[i]) { case Fina: collection.EnableShapingFeature(i + index, FinaTag); break; case Fin2: collection.EnableShapingFeature(i + index, Fin2Tag); break; case Fin3: collection.EnableShapingFeature(i + index, Fin3Tag); break; case Isol: collection.EnableShapingFeature(i + index, IsolTag); break; case Init: collection.EnableShapingFeature(i + index, InitTag); break; case Medi: collection.EnableShapingFeature(i + index, MediTag); break; case Med2: collection.EnableShapingFeature(i + index, Med2Tag); break; } } }