Skip to content

Commit 660e253

Browse files
Fix for broken script and update tests
1 parent 65cea84 commit 660e253

15 files changed

+132
-17
lines changed

src/SixLabors.Fonts/TextLayout.cs

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -628,14 +628,16 @@ private static List<GlyphLayout> LayoutLineVertical(
628628

629629
for (int k = i; k < textLine.Count; k++)
630630
{
631-
if (textLine[k].IsTransformed)
631+
TextLine.GlyphLayoutData g = textLine[k];
632+
633+
if (g.GraphemeIndex != graphemeIndex)
632634
{
633-
currentGraphemeIsTransformed = true;
634635
break;
635636
}
636637

637-
if (textLine[k].IsLastInGrapheme)
638+
if (g.IsTransformed)
638639
{
640+
currentGraphemeIsTransformed = true;
639641
break;
640642
}
641643
}
@@ -654,10 +656,15 @@ private static List<GlyphLayout> LayoutLineVertical(
654656
float minX = float.PositiveInfinity;
655657
float maxX = float.NegativeInfinity;
656658

657-
for (int k = i; k < textLine.Count && textLine[k].GraphemeIndex == graphemeIndex; k++)
659+
for (int k = i; k < textLine.Count; k++)
658660
{
659661
TextLine.GlyphLayoutData g = textLine[k];
660662

663+
if (g.GraphemeIndex != graphemeIndex)
664+
{
665+
break;
666+
}
667+
661668
foreach (GlyphMetrics m in g.Metrics)
662669
{
663670
Vector2 s = new Vector2(g.PointSize) / m.ScaleFactor;
@@ -675,11 +682,6 @@ private static List<GlyphLayout> LayoutLineVertical(
675682
maxX = glyphMaxX;
676683
}
677684
}
678-
679-
if (g.IsLastInGrapheme)
680-
{
681-
break;
682-
}
683685
}
684686

685687
float inkWidth = maxX - minX;
@@ -715,13 +717,22 @@ private static List<GlyphLayout> LayoutLineVertical(
715717
// Offset our in both directions to account for horizontal ink centering and vertical baseline centering.
716718
Vector2 offset = new(alignX, (metric.Bounds.Max.Y + metric.TopSideBearing) * scale.Y);
717719

718-
// For transformed glyphs we advance horizontally using the horizontal advance not the line height.
720+
float advanceW = advanceX;
721+
722+
if (currentGraphemeIsTransformed && !isFirstInGrapheme)
723+
{
724+
// For transformed glyphs after the first in the grapheme we advance
725+
// horizontally using the horizontal advance not the line height.
726+
// This gives us the correct total advance across the grapheme.
727+
advanceW = scale.X * metric.AdvanceWidth;
728+
}
729+
719730
glyphs.Add(new GlyphLayout(
720731
new Glyph(metric, data.PointSize),
721732
boxLocation,
722733
penLocation + new Vector2((scaledMaxLineHeight - data.ScaledLineHeight) * .5F, 0),
723734
offset,
724-
currentGraphemeIsTransformed ? scale.X * metric.AdvanceWidth : advanceX,
735+
advanceW,
725736
data.ScaledAdvance + yExtraAdvance,
726737
GlyphLayoutMode.Vertical,
727738
i == 0 && j == 0,
@@ -1024,7 +1035,7 @@ private static bool DoFontRun(
10241035
charIndex += charsConsumed;
10251036

10261037
// Get the glyph id for the codepoint and add to the collection.
1027-
font.FontMetrics.TryGetGlyphId(current, next, out ushort glyphId, out skipNextCodePoint);
1038+
_ = font.FontMetrics.TryGetGlyphId(current, next, out ushort glyphId, out skipNextCodePoint);
10281039
substitutions.AddGlyph(glyphId, current, (TextDirection)bidiRuns[bidiRunIndex].Direction, textRuns[textRunIndex], codePointIndex);
10291040

10301041
codePointIndex++;
@@ -1156,8 +1167,7 @@ private static TextBox BreakLines(
11561167
//
11571168
// Note: Not all glyphs in a font will have a codepoint associated with them. e.g. most compositions, ligatures, etc.
11581169
CodePoint codePoint = codePointEnumerator.Current;
1159-
if (isSubstituted &&
1160-
metrics.Count == 1)
1170+
if (isSubstituted && metrics.Count == 1)
11611171
{
11621172
codePoint = glyph.CodePoint;
11631173
}
@@ -1302,11 +1312,14 @@ VerticalOrientationType.Rotate or
13021312
}
13031313
}
13041314

1305-
bool isLastInGrapheme = graphemeCodePointIndex == CodePoint.GetCodePointCount(grapheme) - 1;
1315+
int graphemeCodePointMax = CodePoint.GetCodePointCount(grapheme) - 1;
13061316

13071317
// For non-decomposed glyphs the length is always 1.
13081318
for (int i = 0; i < decomposedAdvances.Length; i++)
13091319
{
1320+
// Determine if this is the last codepoint in the grapheme.
1321+
bool isLastInGrapheme = graphemeCodePointIndex == graphemeCodePointMax && i == decomposedAdvances.Length - 1;
1322+
13101323
float decomposedAdvance = decomposedAdvances[i];
13111324

13121325
// Work out the scaled metrics for the glyph.
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
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)