[arabic] Use manual-zwj instead of flipping joiners

This commit is contained in:
Behdad Esfahbod 2018-10-02 14:34:29 +02:00
parent 48c513fec9
commit c36f3f5bef
3 changed files with 9 additions and 47 deletions

View File

@ -68,8 +68,7 @@ enum hb_buffer_scratch_flags_t {
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u,
HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u,
HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u, HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u,
HB_BUFFER_SCRATCH_FLAG_HAS_JOINERS = 0x00000020u, HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000020u,
HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000040u,
/* Reserved for complex shapers' internal use. */ /* Reserved for complex shapers' internal use. */
HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u, HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u,

View File

@ -224,16 +224,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) if (u == 0x200Cu) props |= UPROPS_MASK_Cf_ZWNJ;
{ else if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ;
props |= UPROPS_MASK_Cf_ZWNJ;
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_JOINERS;
}
else if (u == 0x200Du)
{
props |= UPROPS_MASK_Cf_ZWJ;
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_JOINERS;
}
/* Mongolian Free Variation Selectors need to be remembered /* Mongolian Free Variation Selectors need to be remembered
* because although we need to hide them like default-ignorables, * because although we need to hide them like default-ignorables,
* they need to non-ignorable during shaping. This is similar to * they need to non-ignorable during shaping. This is similar to

View File

@ -158,11 +158,6 @@ static const struct arabic_state_table_entry {
}; };
static void
flip_joiners (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan, arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font, hb_font_t *font,
@ -217,28 +212,20 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
} }
/* Normally, Unicode says a ZWNJ means "don't ligate". In Arabic script /* Normally, Unicode says a ZWNJ means "don't ligate". In Arabic script
* however, it says a ZWJ should also mean "don't ligate". So we convert * however, it says a ZWJ should also mean "don't ligate". So we run
* a ZWJ to a ZWNJ for GSUB. We want to revert it back to ZWJ before * the main ligating features as MANUAL_ZWJ. */
* GPOS processing though. So we just flip their roles, and flip back
* later. Note that this makes a ZWNJ into ZWJ for GSUB stage, which
* means it would *not* break ligatures. But since ligatures around
* ZWNJ are rare, we don't care.
*
* Since we don't currently have a way to apply a pause before GPOS
* starts, let's just do this dance around a few required GUSB features. */
map->add_gsub_pause (flip_joiners);
map->add_feature (HB_TAG('r','l','i','g'), F_GLOBAL | F_HAS_FALLBACK); map->add_feature (HB_TAG('r','l','i','g'), F_GLOBAL | F_MANUAL_ZWJ | F_HAS_FALLBACK);
if (plan->props.script == HB_SCRIPT_ARABIC) if (plan->props.script == HB_SCRIPT_ARABIC)
map->add_gsub_pause (arabic_fallback_shape); map->add_gsub_pause (arabic_fallback_shape);
/* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */ /* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */
map->enable_feature (HB_TAG('r','c','l','t')); map->add_feature (HB_TAG('r','c','l','t'), F_GLOBAL | F_MANUAL_ZWJ);
map->enable_feature (HB_TAG('c','a','l','t')); map->add_feature (HB_TAG('c','a','l','t'), F_GLOBAL | F_MANUAL_ZWJ);
map->add_gsub_pause (nullptr);
/* And undo here. */ /* And undo here. */
map->add_gsub_pause (flip_joiners);
/* The spec includes 'cswh'. Earlier versions of Windows /* The spec includes 'cswh'. Earlier versions of Windows
* used to enable this by default, but testing suggests * used to enable this by default, but testing suggests
@ -393,22 +380,6 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script); setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script);
} }
static void
flip_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_JOINERS))
return;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if (_hb_glyph_info_is_joiner (&info[i]))
_hb_glyph_info_flip_joiners (&info[i]);
}
static void static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan, arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font, hb_font_t *font,