[amalgam] More Indic-like issues

Part of https://github.com/harfbuzz/harfbuzz/issues/1809
This commit is contained in:
Behdad Esfahbod 2019-07-02 15:17:56 -07:00
parent d8b5353e07
commit dc480fc471
3 changed files with 72 additions and 68 deletions

View File

@ -144,31 +144,31 @@ indic_features[] =
* Must be in the same order as the indic_features array. * Must be in the same order as the indic_features array.
*/ */
enum { enum {
_NUKT, _INDIC_NUKT,
_AKHN, _INDIC_AKHN,
RPHF, INDIC_RPHF,
_RKRF, _INDIC_RKRF,
PREF, INDIC_PREF,
BLWF, INDIC_BLWF,
ABVF, INDIC_ABVF,
HALF, INDIC_HALF,
PSTF, INDIC_PSTF,
_VATU, _INDIC_VATU,
_CJCT, _INDIC_CJCT,
INIT, INDIC_INIT,
_PRES, _INDIC_PRES,
_ABVS, _INDIC_ABVS,
_BLWS, _INDIC_BLWS,
_PSTS, _INDIC_PSTS,
_HALN, _INDIC_HALN,
_DIST, _INDIC_DIST,
_ABVM, _INDIC_ABVM,
_BLWM, _INDIC_BLWM,
INDIC_NUM_FEATURES, INDIC_NUM_FEATURES,
INDIC_BASIC_FEATURES = INIT, /* Don't forget to update this! */ INDIC_BASIC_FEATURES = INDIC_INIT, /* Don't forget to update this! */
}; };
static void static void
@ -467,7 +467,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* and has more than one consonant, Ra is excluded from candidates for * and has more than one consonant, Ra is excluded from candidates for
* base consonants. */ * base consonants. */
unsigned int limit = start; unsigned int limit = start;
if (indic_plan->mask_array[RPHF] && if (indic_plan->mask_array[INDIC_RPHF] &&
start + 3 <= end && start + 3 <= end &&
( (
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) || (indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
@ -803,13 +803,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Reph */ /* Reph */
for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++) for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++)
info[i].mask |= indic_plan->mask_array[RPHF]; info[i].mask |= indic_plan->mask_array[INDIC_RPHF];
/* Pre-base */ /* Pre-base */
mask = indic_plan->mask_array[HALF]; mask = indic_plan->mask_array[INDIC_HALF];
if (!indic_plan->is_old_spec && if (!indic_plan->is_old_spec &&
indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST) indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
mask |= indic_plan->mask_array[BLWF]; mask |= indic_plan->mask_array[INDIC_BLWF];
for (unsigned int i = start; i < base; i++) for (unsigned int i = start; i < base; i++)
info[i].mask |= mask; info[i].mask |= mask;
/* Base */ /* Base */
@ -817,7 +817,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (base < end) if (base < end)
info[base].mask |= mask; info[base].mask |= mask;
/* Post-base */ /* Post-base */
mask = indic_plan->mask_array[BLWF] | indic_plan->mask_array[ABVF] | indic_plan->mask_array[PSTF]; mask = indic_plan->mask_array[INDIC_BLWF] |
indic_plan->mask_array[INDIC_ABVF] |
indic_plan->mask_array[INDIC_PSTF];
for (unsigned int i = base + 1; i < end; i++) for (unsigned int i = base + 1; i < end; i++)
info[i].mask |= mask; info[i].mask |= mask;
} }
@ -849,13 +851,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
(i + 2 == base || (i + 2 == base ||
info[i+2].indic_category() != OT_ZWJ)) info[i+2].indic_category() != OT_ZWJ))
{ {
info[i ].mask |= indic_plan->mask_array[BLWF]; info[i ].mask |= indic_plan->mask_array[INDIC_BLWF];
info[i+1].mask |= indic_plan->mask_array[BLWF]; info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF];
} }
} }
unsigned int pref_len = 2; unsigned int pref_len = 2;
if (indic_plan->mask_array[PREF] && base + pref_len < end) if (indic_plan->mask_array[INDIC_PREF] && base + pref_len < end)
{ {
/* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */ /* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */
for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) { for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
@ -865,7 +867,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (indic_plan->pref.would_substitute (glyphs, pref_len, face)) if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
{ {
for (unsigned int j = 0; j < pref_len; j++) for (unsigned int j = 0; j < pref_len; j++)
info[i++].mask |= indic_plan->mask_array[PREF]; info[i++].mask |= indic_plan->mask_array[INDIC_PREF];
break; break;
} }
} }
@ -886,7 +888,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* A ZWNJ disables HALF. */ /* A ZWNJ disables HALF. */
if (non_joiner) if (non_joiner)
info[j].mask &= ~indic_plan->mask_array[HALF]; info[j].mask &= ~indic_plan->mask_array[INDIC_HALF];
} while (j > start && !is_consonant (info[j])); } while (j > start && !is_consonant (info[j]));
} }
@ -1053,7 +1055,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* syllable. * syllable.
*/ */
bool try_pref = !!indic_plan->mask_array[PREF]; bool try_pref = !!indic_plan->mask_array[INDIC_PREF];
/* Find base again */ /* Find base again */
unsigned int base; unsigned int base;
@ -1063,7 +1065,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (try_pref && base + 1 < end) if (try_pref && base + 1 < end)
{ {
for (unsigned int i = base + 1; i < end; i++) for (unsigned int i = base + 1; i < end; i++)
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0) if ((info[i].mask & indic_plan->mask_array[INDIC_PREF]) != 0)
{ {
if (!(_hb_glyph_info_substituted (&info[i]) && if (!(_hb_glyph_info_substituted (&info[i]) &&
_hb_glyph_info_ligated_and_didnt_multiply (&info[i]))) _hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
@ -1385,7 +1387,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */ if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */
{ {
for (unsigned int i = base + 1; i < end; i++) for (unsigned int i = base + 1; i < end; i++)
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0) if ((info[i].mask & indic_plan->mask_array[INDIC_PREF]) != 0)
{ {
/* 1. Only reorder a glyph produced by substitution during application /* 1. Only reorder a glyph produced by substitution during application
* of the <pref> feature. (Note that a font may shape a Ra consonant with * of the <pref> feature. (Note that a font may shape a Ra consonant with
@ -1448,7 +1450,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (!start || if (!start ||
!(FLAG_UNSAFE (_hb_glyph_info_get_general_category (&info[start - 1])) & !(FLAG_UNSAFE (_hb_glyph_info_get_general_category (&info[start - 1])) &
FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
info[start].mask |= indic_plan->mask_array[INIT]; info[start].mask |= indic_plan->mask_array[INDIC_INIT];
else else
buffer->unsafe_to_break (start - 1, start + 1); buffer->unsafe_to_break (start - 1, start + 1);
} }

View File

@ -69,23 +69,23 @@ khmer_features[] =
* Must be in the same order as the khmer_features array. * Must be in the same order as the khmer_features array.
*/ */
enum { enum {
PREF, KHMER_PREF,
BLWF, KHMER_BLWF,
ABVF, KHMER_ABVF,
PSTF, KHMER_PSTF,
CFAR, KHMER_CFAR,
_PRES, _KHMER_PRES,
_ABVS, _KHMER_ABVS,
_BLWS, _KHMER_BLWS,
_PSTS, _KHMER_PSTS,
_DIST, _KHMER_DIST,
_ABVM, _KHMER_ABVM,
_BLWM, _KHMER_BLWM,
KHMER_NUM_FEATURES, KHMER_NUM_FEATURES,
KHMER_BASIC_FEATURES = _PRES, /* Don't forget to update this! */ KHMER_BASIC_FEATURES = _KHMER_PRES, /* Don't forget to update this! */
}; };
static void static void
@ -252,7 +252,9 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Setup masks. */ /* Setup masks. */
{ {
/* Post-base */ /* Post-base */
hb_mask_t mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF]; hb_mask_t mask = khmer_plan->mask_array[KHMER_BLWF] |
khmer_plan->mask_array[KHMER_ABVF] |
khmer_plan->mask_array[KHMER_PSTF];
for (unsigned int i = start + 1; i < end; i++) for (unsigned int i = start + 1; i < end; i++)
info[i].mask |= mask; info[i].mask |= mask;
} }
@ -279,7 +281,7 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (info[i + 1].khmer_category() == OT_Ra) if (info[i + 1].khmer_category() == OT_Ra)
{ {
for (unsigned int j = 0; j < 2; j++) for (unsigned int j = 0; j < 2; j++)
info[i + j].mask |= khmer_plan->mask_array[PREF]; info[i + j].mask |= khmer_plan->mask_array[KHMER_PREF];
/* Move the Coeng,Ro sequence to the start. */ /* Move the Coeng,Ro sequence to the start. */
buffer->merge_clusters (start, i + 2); buffer->merge_clusters (start, i + 2);
@ -295,9 +297,9 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
* U+1784,U+17D2,U+179A,U+17D2,U+1782 * U+1784,U+17D2,U+179A,U+17D2,U+1782
* U+1784,U+17D2,U+1782,U+17D2,U+179A * U+1784,U+17D2,U+1782,U+17D2,U+179A
*/ */
if (khmer_plan->mask_array[CFAR]) if (khmer_plan->mask_array[KHMER_CFAR])
for (unsigned int j = i + 2; j < end; j++) for (unsigned int j = i + 2; j < end; j++)
info[j].mask |= khmer_plan->mask_array[CFAR]; info[j].mask |= khmer_plan->mask_array[KHMER_CFAR];
num_coengs = 2; /* Done. */ num_coengs = 2; /* Done. */
} }

View File

@ -59,7 +59,7 @@ use_basic_features[] =
HB_TAG('c','j','c','t'), HB_TAG('c','j','c','t'),
}; };
static const hb_tag_t static const hb_tag_t
use_arabic_features[] = use_topographical_features[] =
{ {
HB_TAG('i','s','o','l'), HB_TAG('i','s','o','l'),
HB_TAG('i','n','i','t'), HB_TAG('i','n','i','t'),
@ -71,13 +71,13 @@ use_arabic_features[] =
HB_TAG('f','i','n','2'), HB_TAG('f','i','n','2'),
HB_TAG('f','i','n','3'), HB_TAG('f','i','n','3'),
}; };
/* Same order as use_arabic_features. Don't need Syriac stuff.*/ /* Same order as use_topographical_features. Don't need Syriac stuff.*/
enum joining_form_t { enum joining_form_t {
ISOL, USE_ISOL,
INIT, USE_INIT,
MEDI, USE_MEDI,
FINA, USE_FINA,
_NONE _USE_NONE
}; };
static const hb_tag_t static const hb_tag_t
use_other_features[] = use_other_features[] =
@ -152,8 +152,8 @@ collect_features_use (hb_ot_shape_planner_t *plan)
map->add_gsub_pause (_hb_clear_syllables); map->add_gsub_pause (_hb_clear_syllables);
/* "Topographical features" */ /* "Topographical features" */
for (unsigned int i = 0; i < ARRAY_LENGTH (use_arabic_features); i++) for (unsigned int i = 0; i < ARRAY_LENGTH (use_topographical_features); i++)
map->add_feature (use_arabic_features[i]); map->add_feature (use_topographical_features[i]);
map->add_gsub_pause (nullptr); map->add_gsub_pause (nullptr);
/* "Standard typographic presentation" */ /* "Standard typographic presentation" */
@ -305,11 +305,11 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
if (use_plan->arabic_plan) if (use_plan->arabic_plan)
return; return;
static_assert ((INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4), ""); static_assert ((USE_INIT < 4 && USE_ISOL < 4 && USE_MEDI < 4 && USE_FINA < 4), "");
hb_mask_t masks[4], all_masks = 0; hb_mask_t masks[4], all_masks = 0;
for (unsigned int i = 0; i < 4; i++) for (unsigned int i = 0; i < 4; i++)
{ {
masks[i] = plan->map.get_1_mask (use_arabic_features[i]); masks[i] = plan->map.get_1_mask (use_topographical_features[i]);
if (masks[i] == plan->map.get_global_mask ()) if (masks[i] == plan->map.get_global_mask ())
masks[i] = 0; masks[i] = 0;
all_masks |= masks[i]; all_masks |= masks[i];
@ -319,7 +319,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
hb_mask_t other_masks = ~all_masks; hb_mask_t other_masks = ~all_masks;
unsigned int last_start = 0; unsigned int last_start = 0;
joining_form_t last_form = _NONE; joining_form_t last_form = _USE_NONE;
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
foreach_syllable (buffer, start, end) foreach_syllable (buffer, start, end)
{ {
@ -330,7 +330,7 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
case use_symbol_cluster: case use_symbol_cluster:
case use_non_cluster: case use_non_cluster:
/* These don't join. Nothing to do. */ /* These don't join. Nothing to do. */
last_form = _NONE; last_form = _USE_NONE;
break; break;
case use_virama_terminated_cluster: case use_virama_terminated_cluster:
@ -340,18 +340,18 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
case use_numeral_cluster: case use_numeral_cluster:
case use_broken_cluster: case use_broken_cluster:
bool join = last_form == FINA || last_form == ISOL; bool join = last_form == USE_FINA || last_form == USE_ISOL;
if (join) if (join)
{ {
/* Fixup previous syllable's form. */ /* Fixup previous syllable's form. */
last_form = last_form == FINA ? MEDI : INIT; last_form = last_form == USE_FINA ? USE_MEDI : USE_INIT;
for (unsigned int i = last_start; i < start; i++) for (unsigned int i = last_start; i < start; i++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form]; info[i].mask = (info[i].mask & other_masks) | masks[last_form];
} }
/* Form for this syllable. */ /* Form for this syllable. */
last_form = join ? FINA : ISOL; last_form = join ? USE_FINA : USE_ISOL;
for (unsigned int i = start; i < end; i++) for (unsigned int i = start; i < end; i++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form]; info[i].mask = (info[i].mask & other_masks) | masks[last_form];