From d277addb2f198e7bb710a79d7ae0c97c85613719 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 30 Jul 2022 10:10:21 -0600 Subject: [PATCH] [buffer] Add HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_KASHIDA --- src/hb-buffer.h | 3 ++- src/hb-buffer.hh | 5 +++++ src/hb-ot-shape.cc | 21 +++++++++++++++++---- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 820a90517..aee2d7392 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -389,8 +389,9 @@ typedef enum { /*< flags >*/ HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE = 0x00000010u, HB_BUFFER_FLAG_VERIFY = 0x00000020u, HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT = 0x00000040u, + HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_KASHIDA = 0x00000070u, - HB_BUFFER_FLAG_DEFINED = 0x0000007Fu + HB_BUFFER_FLAG_DEFINED = 0x000000FFu } hb_buffer_flags_t; HB_EXTERN void diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh index 561c07c43..c370a3148 100644 --- a/src/hb-buffer.hh +++ b/src/hb-buffer.hh @@ -464,6 +464,11 @@ struct hb_buffer_t } void safe_to_insert_kashida (unsigned int start = 0, unsigned int end = -1) { + if ((flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_KASHIDA) == 0) + { + unsafe_to_break (start, end); + return; + } _set_glyph_flags (HB_GLYPH_FLAG_SAFE_TO_INSERT_KASHIDA, start, end, true); diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 842c74000..09f21a69b 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -1141,6 +1141,16 @@ hb_propagate_flags (hb_buffer_t *buffer) if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS)) return; + /* If we are producing SAFE_TO_INSERT_KASHIDA, then do two things: + * + * - If the places that the Arabic shaper marked as SAFE_TO_INSERT_KASHIDA, + * are UNSAFE_TO_BREAK, then clear the SAFE_TO_INSERT_KASHIDA, + * - Any place that is SAFE_TO_INSERT_KASHIDA, is also now UNSAFE_TO_BREAK. + * + * We couldn't make this interaction earlier. It has to be done here. + */ + bool flip_kashida = buffer->flags & HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_KASHIDA; + hb_glyph_info_t *info = buffer->info; foreach_cluster (buffer, start, end) @@ -1149,10 +1159,13 @@ hb_propagate_flags (hb_buffer_t *buffer) for (unsigned int i = start; i < end; i++) mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED; - if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) - mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_KASHIDA; - if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_KASHIDA) - mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + if (flip_kashida) + { + if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) + mask &= ~HB_GLYPH_FLAG_SAFE_TO_INSERT_KASHIDA; + if (mask & HB_GLYPH_FLAG_SAFE_TO_INSERT_KASHIDA) + mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT; + } if (mask) for (unsigned int i = start; i < end; i++)