diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 865ccb2273b220c62f6608003d59f654ab92b663..88f1f4c2e9602853cc93a347a4e5fe4c6c66eb57 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -307,7 +307,8 @@ typedef enum { /*< flags >*/ HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */ HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u, HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u, - HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u + HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u, + HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u } hb_buffer_flags_t; HB_EXTERN void diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index b537ba0055a6445c9c5f43a6d4287b2d942ed199..6086b9b296132a1ae48e65dc26b9de648a05d2f3 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -535,7 +535,17 @@ struct hb_ot_apply_context_t : bool prev () { assert (num_items > 0); - while (idx > num_items - 1) + /* The alternate condition below is faster at string boundaries, + * but produces subpar "unsafe-to-concat" values. */ + unsigned stop = num_items - 1; + if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) + stop = 1 - 1; + /*When looking back, limit how far we search; this function is mostly + * used for looking back for base glyphs when attaching marks. If we + * don't limit, we can get O(n^2) behavior where n is the number of + * consecutive marks. */ + stop = (unsigned) hb_max ((int) stop, (int) idx - HB_MAX_CONTEXT_LENGTH); + while (idx > stop) { idx--; const hb_glyph_info_t &info = c->buffer->out_info[idx];