diff --git a/src/SixLabors.Fonts/Tables/AdvancedTypographic/GlyphDefinitionTable.cs b/src/SixLabors.Fonts/Tables/AdvancedTypographic/GlyphDefinitionTable.cs index 2fd85c1a..1cffb088 100644 --- a/src/SixLabors.Fonts/Tables/AdvancedTypographic/GlyphDefinitionTable.cs +++ b/src/SixLabors.Fonts/Tables/AdvancedTypographic/GlyphDefinitionTable.cs @@ -125,8 +125,8 @@ public static GlyphDefinitionTable Load(BigEndianBinaryReader reader) ushort glyphClassDefOffset = reader.ReadUInt16(); ushort attachListOffset = reader.ReadUInt16(); - ushort ligatureCaretListOffset = reader.ReadUInt16(); - ushort markAttachClassDefOffset = reader.ReadUInt16(); + ushort ligatureCaretListOffset = reader.ReadOffset16(); + ushort markAttachClassDefOffset = reader.ReadOffset16(); ushort markGlyphSetsDefOffset = 0; uint itemVarStoreOffset = 0; diff --git a/src/SixLabors.Fonts/Tables/AdvancedTypographic/LigatureCaretList.cs b/src/SixLabors.Fonts/Tables/AdvancedTypographic/LigatureCaretList.cs index 4d064947..c69fd501 100644 --- a/src/SixLabors.Fonts/Tables/AdvancedTypographic/LigatureCaretList.cs +++ b/src/SixLabors.Fonts/Tables/AdvancedTypographic/LigatureCaretList.cs @@ -22,22 +22,22 @@ public static LigatureCaretList Load(BigEndianBinaryReader reader, long offset) // ----------|--------------------------------|-------------------------------------------------------------------------------------------------------- reader.Seek(offset, SeekOrigin.Begin); - ushort coverageOffset = reader.ReadUInt16(); + ushort coverageOffset = reader.ReadOffset16(); ushort ligGlyphCount = reader.ReadUInt16(); using Buffer ligGlyphOffsetsBuffer = new(ligGlyphCount); Span ligGlyphOffsets = ligGlyphOffsetsBuffer.GetSpan(); reader.ReadUInt16Array(ligGlyphOffsets); - var ligatureCaretList = new LigatureCaretList() + LigatureCaretList ligatureCaretList = new() { - CoverageTable = CoverageTable.Load(reader, offset + coverageOffset) + CoverageTable = CoverageTable.Load(reader, offset + coverageOffset), + LigatureGlyphs = new LigatureGlyph[ligGlyphCount] }; - ligatureCaretList.LigatureGlyphs = new LigatureGlyph[ligGlyphCount]; for (int i = 0; i < ligatureCaretList.LigatureGlyphs.Length; i++) { - ligatureCaretList.LigatureGlyphs[i] = LigatureGlyph.Load(reader, ligGlyphOffsets[i]); + ligatureCaretList.LigatureGlyphs[i] = LigatureGlyph.Load(reader, offset + ligGlyphOffsets[i]); } return ligatureCaretList; diff --git a/src/SixLabors.Fonts/Tables/AdvancedTypographic/LigatureGlyph.cs b/src/SixLabors.Fonts/Tables/AdvancedTypographic/LigatureGlyph.cs index 6d7ffae2..d8f00b66 100644 --- a/src/SixLabors.Fonts/Tables/AdvancedTypographic/LigatureGlyph.cs +++ b/src/SixLabors.Fonts/Tables/AdvancedTypographic/LigatureGlyph.cs @@ -12,11 +12,9 @@ public static LigatureGlyph Load(BigEndianBinaryReader reader, long offset) reader.Seek(offset, SeekOrigin.Begin); ushort caretCount = reader.ReadUInt16(); - var ligatureGlyph = new LigatureGlyph() + return new LigatureGlyph() { CaretValueOffsets = reader.ReadUInt16Array(caretCount) }; - - return ligatureGlyph; } } diff --git a/tests/Images/ReferenceOutput/Test_Issue_474-.png b/tests/Images/ReferenceOutput/Test_Issue_474-.png new file mode 100644 index 00000000..847eda01 --- /dev/null +++ b/tests/Images/ReferenceOutput/Test_Issue_474-.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7612d4f20b5fc1ebd68f34a0f9723a428b86dffec560fd4295312e5df072a91d +size 5226 diff --git a/tests/SixLabors.Fonts.Tests/Fonts/ServiceNow-Sans-Text-Bold-unmastered-1.1.woff b/tests/SixLabors.Fonts.Tests/Fonts/ServiceNow-Sans-Text-Bold-unmastered-1.1.woff new file mode 100644 index 00000000..ae3eef6d Binary files /dev/null and b/tests/SixLabors.Fonts.Tests/Fonts/ServiceNow-Sans-Text-Bold-unmastered-1.1.woff differ diff --git a/tests/SixLabors.Fonts.Tests/Issues/Issues_474.cs b/tests/SixLabors.Fonts.Tests/Issues/Issues_474.cs new file mode 100644 index 00000000..78359e5b --- /dev/null +++ b/tests/SixLabors.Fonts.Tests/Issues/Issues_474.cs @@ -0,0 +1,30 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Text; + +namespace SixLabors.Fonts.Tests.Issues; + +public class Issues_474 +{ + [Fact] + public void Test_Issue_474() + { + StringBuilder stringBuilder = new(); + stringBuilder.AppendLine("Latin: The quick brown fox jumps over the lazy dog."); + string text = stringBuilder.ToString(); + + FontCollection fontCollection = new(); + string serviceNow = fontCollection.Add(TestFonts.ServiceNowWoff2).Name; + + FontFamily mainFontFamily = fontCollection.Get(serviceNow); + Font mainFont = mainFontFamily.CreateFont(30, FontStyle.Regular); + + // There are too many metrics to validate here so we just ensure no exceptions are thrown + // and the rendering looks correct by inspecting the snapshot. + TextLayoutTestUtilities.TestLayout( + text, + new TextOptions(mainFont), + includeGeometry: false); + } +} diff --git a/tests/SixLabors.Fonts.Tests/TestFonts.cs b/tests/SixLabors.Fonts.Tests/TestFonts.cs index ac0e7714..a1e52136 100644 --- a/tests/SixLabors.Fonts.Tests/TestFonts.cs +++ b/tests/SixLabors.Fonts.Tests/TestFonts.cs @@ -291,6 +291,8 @@ public static class TestFonts public static string SofiaSansCondensedLight => GetFullPath("SofiaSansCondensed-ExtraLight-Regular.ttf"); + public static string ServiceNowWoff2 => GetFullPath("ServiceNow-Sans-Text-Bold-unmastered-1.1.woff"); + public static Stream TwemojiMozillaData() => OpenStream(TwemojiMozillaFile); public static Stream SegoeuiEmojiData() => OpenStream(SegoeuiEmojiFile);