[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.
*/
enum {
_NUKT,
_AKHN,
RPHF,
_RKRF,
PREF,
BLWF,
ABVF,
HALF,
PSTF,
_VATU,
_CJCT,
_INDIC_NUKT,
_INDIC_AKHN,
INDIC_RPHF,
_INDIC_RKRF,
INDIC_PREF,
INDIC_BLWF,
INDIC_ABVF,
INDIC_HALF,
INDIC_PSTF,
_INDIC_VATU,
_INDIC_CJCT,
INIT,
_PRES,
_ABVS,
_BLWS,
_PSTS,
_HALN,
INDIC_INIT,
_INDIC_PRES,
_INDIC_ABVS,
_INDIC_BLWS,
_INDIC_PSTS,
_INDIC_HALN,
_DIST,
_ABVM,
_BLWM,
_INDIC_DIST,
_INDIC_ABVM,
_INDIC_BLWM,
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
@ -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
* base consonants. */
unsigned int limit = start;
if (indic_plan->mask_array[RPHF] &&
if (indic_plan->mask_array[INDIC_RPHF] &&
start + 3 <= end &&
(
(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 */
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 */
mask = indic_plan->mask_array[HALF];
mask = indic_plan->mask_array[INDIC_HALF];
if (!indic_plan->is_old_spec &&
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++)
info[i].mask |= mask;
/* Base */
@ -817,7 +817,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (base < end)
info[base].mask |= mask;
/* 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++)
info[i].mask |= mask;
}
@ -849,13 +851,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
(i + 2 == base ||
info[i+2].indic_category() != OT_ZWJ))
{
info[i ].mask |= indic_plan->mask_array[BLWF];
info[i+1].mask |= indic_plan->mask_array[BLWF];
info[i ].mask |= indic_plan->mask_array[INDIC_BLWF];
info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF];
}
}
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. */
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))
{
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;
}
}
@ -886,7 +888,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* A ZWNJ disables HALF. */
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]));
}
@ -1053,7 +1055,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* syllable.
*/
bool try_pref = !!indic_plan->mask_array[PREF];
bool try_pref = !!indic_plan->mask_array[INDIC_PREF];
/* Find base again */
unsigned int base;
@ -1063,7 +1065,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (try_pref && base + 1 < end)
{
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]) &&
_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. */
{
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
* 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 ||
!(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)))
info[start].mask |= indic_plan->mask_array[INIT];
info[start].mask |= indic_plan->mask_array[INDIC_INIT];
else
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.
*/
enum {
PREF,
BLWF,
ABVF,
PSTF,
CFAR,
KHMER_PREF,
KHMER_BLWF,
KHMER_ABVF,
KHMER_PSTF,
KHMER_CFAR,
_PRES,
_ABVS,
_BLWS,
_PSTS,
_KHMER_PRES,
_KHMER_ABVS,
_KHMER_BLWS,
_KHMER_PSTS,
_DIST,
_ABVM,
_BLWM,
_KHMER_DIST,
_KHMER_ABVM,
_KHMER_BLWM,
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
@ -252,7 +252,9 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Setup masks. */
{
/* 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++)
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)
{
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. */
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+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++)
info[j].mask |= khmer_plan->mask_array[CFAR];
info[j].mask |= khmer_plan->mask_array[KHMER_CFAR];
num_coengs = 2; /* Done. */
}

View File

@ -59,7 +59,7 @@ use_basic_features[] =
HB_TAG('c','j','c','t'),
};
static const hb_tag_t
use_arabic_features[] =
use_topographical_features[] =
{
HB_TAG('i','s','o','l'),
HB_TAG('i','n','i','t'),
@ -71,13 +71,13 @@ use_arabic_features[] =
HB_TAG('f','i','n','2'),
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 {
ISOL,
INIT,
MEDI,
FINA,
_NONE
USE_ISOL,
USE_INIT,
USE_MEDI,
USE_FINA,
_USE_NONE
};
static const hb_tag_t
use_other_features[] =
@ -152,8 +152,8 @@ collect_features_use (hb_ot_shape_planner_t *plan)
map->add_gsub_pause (_hb_clear_syllables);
/* "Topographical features" */
for (unsigned int i = 0; i < ARRAY_LENGTH (use_arabic_features); i++)
map->add_feature (use_arabic_features[i]);
for (unsigned int i = 0; i < ARRAY_LENGTH (use_topographical_features); i++)
map->add_feature (use_topographical_features[i]);
map->add_gsub_pause (nullptr);
/* "Standard typographic presentation" */
@ -305,11 +305,11 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
if (use_plan->arabic_plan)
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;
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 ())
masks[i] = 0;
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;
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;
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_non_cluster:
/* These don't join. Nothing to do. */
last_form = _NONE;
last_form = _USE_NONE;
break;
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_broken_cluster:
bool join = last_form == FINA || last_form == ISOL;
bool join = last_form == USE_FINA || last_form == USE_ISOL;
if (join)
{
/* 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++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form];
}
/* Form for this syllable. */
last_form = join ? FINA : ISOL;
last_form = join ? USE_FINA : USE_ISOL;
for (unsigned int i = start; i < end; i++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form];