[AAT] Use a ring buffer for ligature stack
I think Apple does very similarly, but probably with a stack size of 16.
We do it with a stack size that is currently set to 64.
Fixes https://github.com/harfbuzz/harfbuzz/issues/1531
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 6e7bb03..c2a75a8 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -461,14 +461,11 @@
DEBUG_MSG (APPLY, nullptr, "Ligature transition at %u", buffer->idx);
if (entry.flags & LigatureEntryT::SetComponent)
{
- if (unlikely (match_length >= ARRAY_LENGTH (match_positions)))
- match_length = 0; /* TODO Use a ring buffer instead. */
-
/* Never mark same index twice, in case DontAdvance was used... */
- if (match_length && match_positions[match_length - 1] == buffer->out_len)
+ if (match_length && match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] == buffer->out_len)
match_length--;
- match_positions[match_length++] = buffer->out_len;
+ match_positions[match_length++ % ARRAY_LENGTH (match_positions)] = buffer->out_len;
DEBUG_MSG (APPLY, nullptr, "Set component at %u", buffer->out_len);
}
@@ -502,7 +499,7 @@
}
DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1);
- buffer->move_to (match_positions[--cursor]);
+ buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]);
if (unlikely (!actionData->sanitize (&c->sanitizer))) break;
action = *actionData;
@@ -530,17 +527,17 @@
DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig);
buffer->replace_glyph (lig);
- unsigned int lig_end = match_positions[match_length - 1] + 1;
+ unsigned int lig_end = match_positions[(match_length - 1) % ARRAY_LENGTH (match_positions)] + 1;
/* Now go and delete all subsequent components. */
while (match_length - 1 > cursor)
{
DEBUG_MSG (APPLY, nullptr, "Skipping ligature component");
- buffer->move_to (match_positions[--match_length]);
+ buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]);
buffer->replace_glyph (DELETED_GLYPH);
}
buffer->move_to (lig_end);
- buffer->merge_out_clusters (match_positions[cursor], buffer->out_len);
+ buffer->merge_out_clusters (match_positions[cursor % ARRAY_LENGTH (match_positions)], buffer->out_len);
}
actionData++;