From 21ab5501f5f5267d20cf23256866dd9d82a667ef Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 26 Apr 2016 16:02:04 -0700 Subject: [PATCH] Move ZWJ/ZWNJ bits to top byte of unicode_props() To make room to remember Mongolian Free Variation Selectors. Part of fixing https://github.com/behdad/harfbuzz/issues/234 --- src/hb-ot-layout-private.hh | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index b5c670f..22faa48 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -218,23 +218,22 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start) * - General_Category: 5 bits. * - A bit each for: * * Is it Default_Ignorable(); we have a modified Default_Ignorable(). - * * Is it U+200D ZWJ? - * * Is it U+200C ZWNJ? + * * Two free bits right now. * * The high-byte has different meanings, switched by the Gen-Cat: * - For Mn,Mc,Me: the modified Combining_Class. + * - For Cf: whether it's ZWJ, ZWNJ, or something else. * - For Ws: index of which space character this is, if space fallback * is needed, ie. we don't set this by default, only if asked to. - * - * If needed, we can use the ZWJ/ZWNJ to use the high byte as well, - * freeing two more bits. */ enum hb_unicode_props_flags_t { - UPROPS_MASK_ZWJ = 0x20u, - UPROPS_MASK_ZWNJ = 0x40u, - UPROPS_MASK_IGNORABLE = 0x80u, - UPROPS_MASK_GEN_CAT = 0x1Fu + UPROPS_MASK_GEN_CAT = 0x001Fu, + UPROPS_MASK_IGNORABLE = 0x0020u, + + /* If GEN_CAT=FORMAT, top byte masks: */ + UPROPS_MASK_Cf_ZWJ = 0x0100u, + UPROPS_MASK_Cf_ZWNJ = 0x0200u }; HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); @@ -253,8 +252,8 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) { buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES; props |= UPROPS_MASK_IGNORABLE; - if (u == 0x200Cu) props |= UPROPS_MASK_ZWNJ; - if (u == 0x200Du) props |= UPROPS_MASK_ZWJ; + if (u == 0x200Cu) props |= UPROPS_MASK_Cf_ZWNJ; + if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ; } else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat))) { @@ -353,28 +352,33 @@ _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && !_hb_glyph_info_ligated (info); } +static inline bool +_hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info) +{ + return _hb_glyph_info_get_general_category (info) == + HB_UNICODE_GENERAL_CATEGORY_FORMAT; +} static inline hb_bool_t _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) { - return !!(info->unicode_props() & UPROPS_MASK_ZWNJ); + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWNJ); } - static inline hb_bool_t _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) { - return !!(info->unicode_props() & UPROPS_MASK_ZWJ); + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ); } - static inline hb_bool_t _hb_glyph_info_is_joiner (const hb_glyph_info_t *info) { - return !!(info->unicode_props() & (UPROPS_MASK_ZWNJ | UPROPS_MASK_ZWJ)); + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ)); } - static inline void _hb_glyph_info_flip_joiners (hb_glyph_info_t *info) { - info->unicode_props() ^= UPROPS_MASK_ZWNJ | UPROPS_MASK_ZWJ; + if (!_hb_glyph_info_is_unicode_format (info)) + return; + info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ; } /* lig_props: aka lig_id / lig_comp -- 2.7.4