Config->Nikhahit is built by kbts_CodepointToGlyph(Font, 0xE4D, 0, 0) with no config and no codepoint index, and the sara am case in the Thai/Lao block copies it in whole with kbts__InsertGlyphBefore, so the inserted nikhahit reports UserIdOrCodepointIndex 0 for every sara am in the run. The sara aa half keeps the sara am's index through kbts__SetGlyphPreserveLinksAndUserId, and its config is restored explicitly, so the two halves of one character disagree about which character they came from.
Reproduce via shape A น ้ ำ B (0x41 0xE19 0xE49 0xE33 0x42) and read the indices: 0 1 0 2 3 4, the nikhahit at index 0 between characters 1 and 2.
Our fix (I realize these line numbers match our copy, not the upstream, but hopefully the context is unique enough to still apply):
--- a/kb_text_shape.h
+++ b/kb_text_shape.h
@@ -20920,6 +20920,10 @@
kbts_glyph *NewGlyph = kbts__InsertGlyphBefore(Storage, AboveBaseGlyph, &Config->Nikhahit);
if(!NewGlyph)
{
goto OutOfMemory;
}
+ NewGlyph->UserIdOrCodepointIndex = Glyph->UserIdOrCodepointIndex;
+ NewGlyph->Config = Glyph->Config;
+
kbts_glyph_config *GlyphConfig = Glyph->Config;
kbts__SetGlyphPreserveLinksAndUserId(Glyph, &Config->SaraAa);
I'm not sure whether the nikhahit should inherit its information from the current glyph or from the above-base glyph. I'm doing as you suggest in https://github.com/JimmyLefevre/kb/commit/826ec09239897183a7dab2a364f72486f099509d .