Skip to content

Commit 8422156

Browse files
Merge branch 'main' into js/fix-412
2 parents 4fc2016 + 00fa0f0 commit 8422156

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ namespace SixLabors.Fonts.Tables.AdvancedTypographic.GPos;
1111
[DebuggerDisplay("X: {XCoordinate}, Y: {YCoordinate}")]
1212
internal abstract class AnchorTable
1313
{
14+
private static readonly AnchorTable Empty = new EmptyAnchor();
15+
1416
/// <summary>
1517
/// Initializes a new instance of the <see cref="AnchorTable"/> class.
1618
/// </summary>
@@ -50,7 +52,10 @@ public static AnchorTable Load(BigEndianBinaryReader reader, long offset)
5052
1 => AnchorFormat1.Load(reader),
5153
2 => AnchorFormat2.Load(reader),
5254
3 => AnchorFormat3.Load(reader),
53-
_ => throw new InvalidFontFileException($"anchorFormat identifier {anchorFormat} is invalid. Should be '1', '2' or '3'.")
55+
56+
// Harfbuzz (Anchor.hh) and FontKit appear to treat this as a default anchor and do not throw.
57+
// NotoSans Regular can trigger this. See https://github.com/SixLabors/Fonts/issues/417
58+
_ => Empty,
5459
};
5560
}
5661

@@ -119,7 +124,6 @@ public override AnchorXY GetAnchor(FontMetrics fontMetrics, GlyphShapingData dat
119124
{
120125
foreach (GlyphMetrics metric in metrics)
121126
{
122-
// TODO: What does HarfBuzz do here?
123127
if (metric is not TrueTypeGlyphMetrics ttmetric)
124128
{
125129
break;
@@ -185,4 +189,18 @@ public static AnchorFormat3 Load(BigEndianBinaryReader reader)
185189
public override AnchorXY GetAnchor(FontMetrics fontMetrics, GlyphShapingData data, GlyphPositioningCollection collection)
186190
=> new(this.XCoordinate, this.YCoordinate);
187191
}
192+
193+
internal sealed class EmptyAnchor : AnchorTable
194+
{
195+
public EmptyAnchor()
196+
: base(0, 0)
197+
{
198+
}
199+
200+
public override AnchorXY GetAnchor(
201+
FontMetrics fontMetrics,
202+
GlyphShapingData data,
203+
GlyphPositioningCollection collection)
204+
=> new(0, 0);
205+
}
188206
}
569 KB
Binary file not shown.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
namespace SixLabors.Fonts.Tests.Issues;
5+
6+
public class Issues_417
7+
{
8+
[Fact]
9+
public void DoesNotThrow_InvalidAnchor()
10+
{
11+
FontFamily family = new FontCollection().Add(TestFonts.NotoSansRegular);
12+
family.TryGetMetrics(FontStyle.Regular, out FontMetrics metrics);
13+
14+
Font font = family.CreateFont(metrics?.UnitsPerEm ?? 1000);
15+
16+
TextOptions options = new(font);
17+
18+
// References values generated using.
19+
// https://www.corvelsoftware.co.uk/crowbar/
20+
TextMeasurer.TryMeasureCharacterAdvances("Text", options, out ReadOnlySpan<GlyphBounds> advances);
21+
22+
Assert.Equal(4, advances.Length);
23+
Assert.Equal(486, advances[0].Bounds.Width);
24+
Assert.Equal(544, advances[1].Bounds.Width);
25+
Assert.Equal(529, advances[2].Bounds.Width);
26+
Assert.Equal(361, advances[3].Bounds.Width);
27+
28+
GlyphRenderer renderer = new();
29+
TextRenderer.RenderTextTo(renderer, "Text", new TextOptions(font));
30+
31+
int[] expectedGlyphIndices = { 55, 72, 91, 87 };
32+
Assert.Equal(expectedGlyphIndices.Length, renderer.GlyphKeys.Count);
33+
for (int i = 0; i < expectedGlyphIndices.Length; i++)
34+
{
35+
Assert.Equal(expectedGlyphIndices[i], renderer.GlyphKeys[i].GlyphId);
36+
}
37+
}
38+
}

tests/SixLabors.Fonts.Tests/TestFonts.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ public static class TestFonts
257257

258258
public static string KellySlabFile => GetFullPath("KellySlab-Regular.ttf");
259259

260+
public static string NotoSansRegular => GetFullPath("NotoSans-Regular.ttf");
261+
260262
public static Stream TwemojiMozillaData() => OpenStream(TwemojiMozillaFile);
261263

262264
public static Stream SegoeuiEmojiData() => OpenStream(SegoeuiEmojiFile);

0 commit comments

Comments
 (0)