From 5564db4f5af6a0db1ad5eabc7f39e9a39d7c2fc2 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 5 Jul 2026 23:17:34 +0200 Subject: [PATCH] fix: t6 font crash (#881) * fix: make sure t6 always has at least one kerning pair * chore: ignore nonesense kerning pairs when dumping --- src/ObjLoading/Font/FontLoader.cpp.template | 15 ++++++++++---- src/ObjWriting/Font/FontDumper.cpp.template | 23 ++++++++++++++++++--- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/ObjLoading/Font/FontLoader.cpp.template b/src/ObjLoading/Font/FontLoader.cpp.template index 979420d8..02543156 100644 --- a/src/ObjLoading/Font/FontLoader.cpp.template +++ b/src/ObjLoading/Font/FontLoader.cpp.template @@ -306,14 +306,21 @@ namespace } SortKerningPairs(font); + + if (!EnsureFontContainsGlyphsOfKerningPairs(font)) + return false; } else { - font.kerningPairs = nullptr; + // The game is bugged here and accesses the kerning pairs even when kerningPairsCount is set to 0. + // It always checks the first entry so we add a nonsense entry here that never matches + // to ensure that no kerning is applied on randomly matching bytes. + font.kerningPairsCount = 1; + font.kerningPairs = m_memory.Alloc(1); + font.kerningPairs[0].wFirst = 0; + font.kerningPairs[0].wSecond = 0; + font.kerningPairs[0].iKernAmount = 0; } - - if (!EnsureFontContainsGlyphsOfKerningPairs(font)) - return false; #endif return true; diff --git a/src/ObjWriting/Font/FontDumper.cpp.template b/src/ObjWriting/Font/FontDumper.cpp.template index be9572db..4dc6720f 100644 --- a/src/ObjWriting/Font/FontDumper.cpp.template +++ b/src/ObjWriting/Font/FontDumper.cpp.template @@ -61,6 +61,20 @@ namespace } #ifdef FEATURE_T6 + bool HasActualKerningPairs(const Font_s& font) + { + if (font.kerningPairs == nullptr) + return false; + if (font.kerningPairsCount > 1) + return true; + if (font.kerningPairsCount == 0) + return false; + + const auto& firstKerningPair = font.kerningPairs[0]; + + return firstKerningPair.wFirst != 0 || firstKerningPair.wSecond != 0 || firstKerningPair.iKernAmount != 0; + } + void CreateJsonKerningPair(JsonKerningPair& jKerningPair, const KerningPairs& kerningPair) { jKerningPair.firstLetter = kerningPair.wFirst; @@ -91,9 +105,12 @@ namespace CreateJsonGlyph(jFont.glyphs[i], font.glyphs[i]); #ifdef FEATURE_T6 - jFont.kerningPairs.resize(font.kerningPairsCount); - for (auto i = 0; i < font.kerningPairsCount; i++) - CreateJsonKerningPair(jFont.kerningPairs[i], font.kerningPairs[i]); + if (HasActualKerningPairs(font)) + { + jFont.kerningPairs.resize(font.kerningPairsCount); + for (auto i = 0; i < font.kerningPairsCount; i++) + CreateJsonKerningPair(jFont.kerningPairs[i], font.kerningPairs[i]); + } #endif }