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
This commit is contained in:
Behdad Esfahbod 2016-04-26 16:02:04 -07:00
parent de508516cb
commit 21ab5501f5
1 changed files with 22 additions and 18 deletions

View File

@ -218,23 +218,22 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start)
* - General_Category: 5 bits. * - General_Category: 5 bits.
* - A bit each for: * - A bit each for:
* * Is it Default_Ignorable(); we have a modified Default_Ignorable(). * * Is it Default_Ignorable(); we have a modified Default_Ignorable().
* * Is it U+200D ZWJ? * * Two free bits right now.
* * Is it U+200C ZWNJ?
* *
* The high-byte has different meanings, switched by the Gen-Cat: * The high-byte has different meanings, switched by the Gen-Cat:
* - For Mn,Mc,Me: the modified Combining_Class. * - 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 * - 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. * 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 { enum hb_unicode_props_flags_t {
UPROPS_MASK_ZWJ = 0x20u, UPROPS_MASK_GEN_CAT = 0x001Fu,
UPROPS_MASK_ZWNJ = 0x40u, UPROPS_MASK_IGNORABLE = 0x0020u,
UPROPS_MASK_IGNORABLE = 0x80u,
UPROPS_MASK_GEN_CAT = 0x1Fu /* 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); 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; buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
props |= UPROPS_MASK_IGNORABLE; props |= UPROPS_MASK_IGNORABLE;
if (u == 0x200Cu) props |= UPROPS_MASK_ZWNJ; if (u == 0x200Cu) props |= UPROPS_MASK_Cf_ZWNJ;
if (u == 0x200Du) props |= UPROPS_MASK_ZWJ; if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ;
} }
else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat))) 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); 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 static inline hb_bool_t
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) _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 static inline hb_bool_t
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info) _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 static inline hb_bool_t
_hb_glyph_info_is_joiner (const hb_glyph_info_t *info) _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 static inline void
_hb_glyph_info_flip_joiners (hb_glyph_info_t *info) _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 /* lig_props: aka lig_id / lig_comp