From 8b2d3f8701cf0417c705a6411afe41795fda2b6b Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 26 Nov 2025 10:37:12 +1000 Subject: [PATCH] Fix ligature caret offset determination --- .../GlyphDefinitionTable.cs | 4 +-- .../AdvancedTypographic/LigatureCaretList.cs | 10 +++--- .../AdvancedTypographic/LigatureGlyph.cs | 4 +-- .../ReferenceOutput/Test_Issue_474-.png | 3 ++ ...viceNow-Sans-Text-Bold-unmastered-1.1.woff | Bin 0 -> 13696 bytes .../Issues/Issues_474.cs | 30 ++++++++++++++++++ tests/SixLabors.Fonts.Tests/TestFonts.cs | 2 ++ 7 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 tests/Images/ReferenceOutput/Test_Issue_474-.png create mode 100644 tests/SixLabors.Fonts.Tests/Fonts/ServiceNow-Sans-Text-Bold-unmastered-1.1.woff create mode 100644 tests/SixLabors.Fonts.Tests/Issues/Issues_474.cs diff --git a/src/SixLabors.Fonts/Tables/AdvancedTypographic/GlyphDefinitionTable.cs b/src/SixLabors.Fonts/Tables/AdvancedTypographic/GlyphDefinitionTable.cs index 2fd85c1a2..1cffb088a 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 4d064947f..c69fd5017 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 6d7ffae2f..d8f00b663 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 000000000..847eda019 --- /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 0000000000000000000000000000000000000000..ae3eef6d3f773234f8b7eefd442c3fc1bf0d1e6c GIT binary patch literal 13696 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 IpR+0d57eT 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);