Skip to content

Commit eadc8db

Browse files
Merge pull request #455 from SixLabors/js/fix-451
Do not over-apply sub-tables during contextual substitution list apply
2 parents 95e5d75 + 76b3e23 commit eadc8db

File tree

13 files changed

+83
-20
lines changed

13 files changed

+83
-20
lines changed

src/SixLabors.Fonts/GlyphShapingData.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ public GlyphShapingData(GlyphShapingData data, bool clearFeatures = false)
6161
this.Features.AddRange(data.Features);
6262
}
6363

64-
this.AppliedFeatures.AddRange(data.AppliedFeatures);
64+
foreach (Tag feature in data.AppliedFeatures)
65+
{
66+
this.AppliedFeatures.Add(feature);
67+
}
6568

6669
this.Bounds = data.Bounds;
6770
}
@@ -124,7 +127,7 @@ public GlyphShapingData(GlyphShapingData data, bool clearFeatures = false)
124127
/// <summary>
125128
/// Gets or sets the collection of applied features.
126129
/// </summary>
127-
public List<Tag> AppliedFeatures { get; set; } = new();
130+
public HashSet<Tag> AppliedFeatures { get; set; } = new();
128131

129132
/// <summary>
130133
/// Gets or sets the shaping bounds.

src/SixLabors.Fonts/Tables/AdvancedTypographic/AdvancedTypographicUtils.cs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ public static bool ApplyLookupList(
5151
int index,
5252
int count)
5353
{
54-
bool hasChanged = false;
5554
SkippingGlyphIterator iterator = new(fontMetrics, collection, index, lookupFlags);
5655
int currentCount = collection.Count;
5756

@@ -62,7 +61,7 @@ public static bool ApplyLookupList(
6261
iterator.Index = index;
6362
iterator.Increment(sequenceIndex);
6463
GSub.LookupTable lookup = table.LookupList.LookupTables[lookupIndex];
65-
hasChanged |= lookup.TrySubstitution(fontMetrics, table, collection, feature, iterator.Index, count - (iterator.Index - index));
64+
_ = lookup.TrySubstitution(fontMetrics, table, collection, feature, iterator.Index, count - (iterator.Index - index));
6665

6766
// Account for substitutions changing the length of the collection.
6867
if (collection.Count != currentCount)
@@ -72,7 +71,7 @@ public static bool ApplyLookupList(
7271
}
7372
}
7473

75-
return hasChanged;
74+
return true;
7675
}
7776

7877
public static bool ApplyLookupList(
@@ -85,7 +84,6 @@ public static bool ApplyLookupList(
8584
int index,
8685
int count)
8786
{
88-
bool hasChanged = false;
8987
SkippingGlyphIterator iterator = new(fontMetrics, collection, index, lookupFlags);
9088
foreach (SequenceLookupRecord lookupRecord in records)
9189
{
@@ -94,10 +92,10 @@ public static bool ApplyLookupList(
9492
iterator.Index = index;
9593
iterator.Increment(sequenceIndex);
9694
LookupTable lookup = table.LookupList.LookupTables[lookupIndex];
97-
hasChanged |= lookup.TryUpdatePosition(fontMetrics, table, collection, feature, iterator.Index, count - (iterator.Index - index));
95+
_ = lookup.TryUpdatePosition(fontMetrics, table, collection, feature, iterator.Index, count - (iterator.Index - index));
9896
}
9997

100-
return hasChanged;
98+
return true;
10199
}
102100

103101
public static bool MatchInputSequence(SkippingGlyphIterator iterator, Tag feature, ushort increment, ushort[] sequence, Span<int> matches)
@@ -222,7 +220,7 @@ public static bool CheckAllCoverages(
222220
CoverageTable[] lookahead)
223221
{
224222
// Check that there are enough context glyphs.
225-
if (index - backtrack.Length < 0 || input.Length + lookahead.Length > count)
223+
if (index < backtrack.Length || input.Length + lookahead.Length > count)
226224
{
227225
return false;
228226
}
@@ -253,7 +251,8 @@ public static void ApplyAnchor(
253251
int index,
254252
AnchorTable baseAnchor,
255253
MarkRecord markRecord,
256-
int baseGlyphIndex)
254+
int baseGlyphIndex,
255+
Tag feature)
257256
{
258257
GlyphShapingData baseData = collection[baseGlyphIndex];
259258
AnchorXY baseXY = baseAnchor.GetAnchor(fontMetrics, baseData, collection);
@@ -264,18 +263,21 @@ public static void ApplyAnchor(
264263
markData.Bounds.X = baseXY.XCoordinate - markXY.XCoordinate;
265264
markData.Bounds.Y = baseXY.YCoordinate - markXY.YCoordinate;
266265
markData.MarkAttachment = baseGlyphIndex;
266+
markData.AppliedFeatures.Add(feature);
267267
}
268268

269269
public static void ApplyPosition(
270270
GlyphPositioningCollection collection,
271271
int index,
272-
ValueRecord record)
272+
ValueRecord record,
273+
Tag feature)
273274
{
274275
GlyphShapingData current = collection[index];
275276
current.Bounds.Width += record.XAdvance;
276277
current.Bounds.Height += record.YAdvance;
277278
current.Bounds.X += record.XPlacement;
278279
current.Bounds.Y += record.YPlacement;
280+
current.AppliedFeatures.Add(feature);
279281
}
280282

281283
public static bool IsMarkGlyph(FontMetrics fontMetrics, ushort glyphId, GlyphShapingData shapingData)

src/SixLabors.Fonts/Tables/AdvancedTypographic/GPos/LookupType1SubTable.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public override bool TryUpdatePosition(
8181
if (coverage > -1)
8282
{
8383
ValueRecord record = this.valueRecord;
84-
AdvancedTypographicUtils.ApplyPosition(collection, index, record);
84+
AdvancedTypographicUtils.ApplyPosition(collection, index, record, feature);
8585

8686
return true;
8787
}
@@ -152,7 +152,7 @@ public override bool TryUpdatePosition(
152152
if (coverage > -1)
153153
{
154154
ValueRecord record = this.valueRecords[coverage];
155-
AdvancedTypographicUtils.ApplyPosition(collection, index, record);
155+
AdvancedTypographicUtils.ApplyPosition(collection, index, record, feature);
156156

157157
return true;
158158
}

src/SixLabors.Fonts/Tables/AdvancedTypographic/GPos/LookupType2SubTable.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ public override bool TryUpdatePosition(
117117
if (pairSet.TryGetPairValueRecord(glyphId2, out PairValueRecord pairValueRecord))
118118
{
119119
ValueRecord record1 = pairValueRecord.ValueRecord1;
120-
AdvancedTypographicUtils.ApplyPosition(collection, index, record1);
120+
AdvancedTypographicUtils.ApplyPosition(collection, index, record1, feature);
121121

122122
ValueRecord record2 = pairValueRecord.ValueRecord2;
123-
AdvancedTypographicUtils.ApplyPosition(collection, index + 1, record2);
123+
AdvancedTypographicUtils.ApplyPosition(collection, index + 1, record2, feature);
124124

125125
return true;
126126
}
@@ -285,10 +285,10 @@ public override bool TryUpdatePosition(
285285
Class2Record class2Record = class1Record.Class2Records[classDef2];
286286

287287
ValueRecord record1 = class2Record.ValueRecord1;
288-
AdvancedTypographicUtils.ApplyPosition(collection, index, record1);
288+
AdvancedTypographicUtils.ApplyPosition(collection, index, record1, feature);
289289

290290
ValueRecord record2 = class2Record.ValueRecord2;
291-
AdvancedTypographicUtils.ApplyPosition(collection, index + 1, record2);
291+
AdvancedTypographicUtils.ApplyPosition(collection, index + 1, record2, feature);
292292

293293
return true;
294294
}

src/SixLabors.Fonts/Tables/AdvancedTypographic/GPos/LookupType4SubTable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public override bool TryUpdatePosition(
126126

127127
MarkRecord markRecord = this.markArrayTable.MarkRecords[markIndex];
128128
AnchorTable baseAnchor = this.baseArrayTable.BaseRecords[baseIndex].BaseAnchorTables[markRecord.MarkClass];
129-
AdvancedTypographicUtils.ApplyAnchor(fontMetrics, collection, index, baseAnchor, markRecord, baseGlyphIndex);
129+
AdvancedTypographicUtils.ApplyAnchor(fontMetrics, collection, index, baseAnchor, markRecord, baseGlyphIndex, feature);
130130

131131
return true;
132132
}

src/SixLabors.Fonts/Tables/AdvancedTypographic/GPos/LookupType5SubTable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public override bool TryUpdatePosition(
140140

141141
MarkRecord markRecord = this.markArrayTable.MarkRecords[markIndex];
142142
AnchorTable baseAnchor = ligatureAttach.ComponentRecords[compIndex].LigatureAnchorTables[markRecord.MarkClass];
143-
AdvancedTypographicUtils.ApplyAnchor(fontMetrics, collection, index, baseAnchor, markRecord, baseGlyphIndex);
143+
AdvancedTypographicUtils.ApplyAnchor(fontMetrics, collection, index, baseAnchor, markRecord, baseGlyphIndex, feature);
144144

145145
return true;
146146
}

src/SixLabors.Fonts/Tables/AdvancedTypographic/GPos/LookupType6SubTable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public override bool TryUpdatePosition(
158158

159159
MarkRecord markRecord = this.mark1ArrayTable.MarkRecords[mark1Index];
160160
AnchorTable baseAnchor = this.mark2ArrayTable.Mark2Records[mark2Index].MarkAnchorTable[markRecord.MarkClass];
161-
AdvancedTypographicUtils.ApplyAnchor(fontMetrics, collection, index, baseAnchor, markRecord, prevIdx);
161+
AdvancedTypographicUtils.ApplyAnchor(fontMetrics, collection, index, baseAnchor, markRecord, prevIdx, feature);
162162

163163
return true;
164164
}
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)