[indic] Use categories from the machine

This commit is contained in:
Behdad Esfahbod 2022-06-09 17:46:15 -06:00
parent 37217fc9be
commit 3289e81532
8 changed files with 118 additions and 115 deletions

View File

@ -31,6 +31,14 @@
#include "hb.hh" #include "hb.hh"
#include "hb-ot-layout.hh"
#include "hb-ot-shaper-indic.hh"
using indic_category_t = ot_category_t;
using indic_position_t = ot_position_t;
#define I_Cat(Cat) indic_syllable_machine_ex_##Cat
enum indic_syllable_type_t { enum indic_syllable_type_t {
indic_consonant_syllable, indic_consonant_syllable,
indic_vowel_syllable, indic_vowel_syllable,
@ -41,7 +49,7 @@ enum indic_syllable_type_t {
}; };
#line 45 "hb-ot-shaper-indic-machine.hh" #line 53 "hb-ot-shaper-indic-machine.hh"
#define indic_syllable_machine_ex_A 9u #define indic_syllable_machine_ex_A 9u
#define indic_syllable_machine_ex_C 1u #define indic_syllable_machine_ex_C 1u
#define indic_syllable_machine_ex_CM 16u #define indic_syllable_machine_ex_CM 16u
@ -62,7 +70,7 @@ enum indic_syllable_type_t {
#define indic_syllable_machine_ex_ZWNJ 5u #define indic_syllable_machine_ex_ZWNJ 5u
#line 66 "hb-ot-shaper-indic-machine.hh" #line 74 "hb-ot-shaper-indic-machine.hh"
static const unsigned char _indic_syllable_machine_trans_keys[] = { static const unsigned char _indic_syllable_machine_trans_keys[] = {
8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 15u, 15u, 4u, 8u, 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 15u, 15u, 4u, 8u,
4u, 12u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 15u, 15u, 4u, 12u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 15u, 15u,
@ -401,11 +409,11 @@ static const int indic_syllable_machine_error = -1;
static const int indic_syllable_machine_en_main = 39; static const int indic_syllable_machine_en_main = 39;
#line 46 "hb-ot-shaper-indic-machine.rl" #line 54 "hb-ot-shaper-indic-machine.rl"
#line 103 "hb-ot-shaper-indic-machine.rl" #line 111 "hb-ot-shaper-indic-machine.rl"
#define found_syllable(syllable_type) \ #define found_syllable(syllable_type) \
@ -424,7 +432,7 @@ find_syllables_indic (hb_buffer_t *buffer)
int cs; int cs;
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
#line 428 "hb-ot-shaper-indic-machine.hh" #line 436 "hb-ot-shaper-indic-machine.hh"
{ {
cs = indic_syllable_machine_start; cs = indic_syllable_machine_start;
ts = 0; ts = 0;
@ -432,7 +440,7 @@ find_syllables_indic (hb_buffer_t *buffer)
act = 0; act = 0;
} }
#line 123 "hb-ot-shaper-indic-machine.rl" #line 131 "hb-ot-shaper-indic-machine.rl"
p = 0; p = 0;
@ -440,7 +448,7 @@ find_syllables_indic (hb_buffer_t *buffer)
unsigned int syllable_serial = 1; unsigned int syllable_serial = 1;
#line 444 "hb-ot-shaper-indic-machine.hh" #line 452 "hb-ot-shaper-indic-machine.hh"
{ {
int _slen; int _slen;
int _trans; int _trans;
@ -454,7 +462,7 @@ _resume:
#line 1 "NONE" #line 1 "NONE"
{ts = p;} {ts = p;}
break; break;
#line 458 "hb-ot-shaper-indic-machine.hh" #line 466 "hb-ot-shaper-indic-machine.hh"
} }
_keys = _indic_syllable_machine_trans_keys + (cs<<1); _keys = _indic_syllable_machine_trans_keys + (cs<<1);
@ -477,51 +485,51 @@ _eof_trans:
{te = p+1;} {te = p+1;}
break; break;
case 11: case 11:
#line 99 "hb-ot-shaper-indic-machine.rl" #line 107 "hb-ot-shaper-indic-machine.rl"
{te = p+1;{ found_syllable (indic_non_indic_cluster); }} {te = p+1;{ found_syllable (indic_non_indic_cluster); }}
break; break;
case 13: case 13:
#line 94 "hb-ot-shaper-indic-machine.rl" #line 102 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_consonant_syllable); }} {te = p;p--;{ found_syllable (indic_consonant_syllable); }}
break; break;
case 14: case 14:
#line 95 "hb-ot-shaper-indic-machine.rl" #line 103 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_vowel_syllable); }} {te = p;p--;{ found_syllable (indic_vowel_syllable); }}
break; break;
case 17: case 17:
#line 96 "hb-ot-shaper-indic-machine.rl" #line 104 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_standalone_cluster); }} {te = p;p--;{ found_syllable (indic_standalone_cluster); }}
break; break;
case 19: case 19:
#line 97 "hb-ot-shaper-indic-machine.rl" #line 105 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_symbol_cluster); }} {te = p;p--;{ found_syllable (indic_symbol_cluster); }}
break; break;
case 15: case 15:
#line 98 "hb-ot-shaper-indic-machine.rl" #line 106 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_broken_cluster); }} {te = p;p--;{ found_syllable (indic_broken_cluster); }}
break; break;
case 16: case 16:
#line 99 "hb-ot-shaper-indic-machine.rl" #line 107 "hb-ot-shaper-indic-machine.rl"
{te = p;p--;{ found_syllable (indic_non_indic_cluster); }} {te = p;p--;{ found_syllable (indic_non_indic_cluster); }}
break; break;
case 1: case 1:
#line 94 "hb-ot-shaper-indic-machine.rl" #line 102 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }} {{p = ((te))-1;}{ found_syllable (indic_consonant_syllable); }}
break; break;
case 3: case 3:
#line 95 "hb-ot-shaper-indic-machine.rl" #line 103 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }} {{p = ((te))-1;}{ found_syllable (indic_vowel_syllable); }}
break; break;
case 7: case 7:
#line 96 "hb-ot-shaper-indic-machine.rl" #line 104 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }} {{p = ((te))-1;}{ found_syllable (indic_standalone_cluster); }}
break; break;
case 8: case 8:
#line 97 "hb-ot-shaper-indic-machine.rl" #line 105 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }} {{p = ((te))-1;}{ found_syllable (indic_symbol_cluster); }}
break; break;
case 4: case 4:
#line 98 "hb-ot-shaper-indic-machine.rl" #line 106 "hb-ot-shaper-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (indic_broken_cluster); }} {{p = ((te))-1;}{ found_syllable (indic_broken_cluster); }}
break; break;
case 6: case 6:
@ -542,22 +550,22 @@ _eof_trans:
case 18: case 18:
#line 1 "NONE" #line 1 "NONE"
{te = p+1;} {te = p+1;}
#line 94 "hb-ot-shaper-indic-machine.rl" #line 102 "hb-ot-shaper-indic-machine.rl"
{act = 1;} {act = 1;}
break; break;
case 5: case 5:
#line 1 "NONE" #line 1 "NONE"
{te = p+1;} {te = p+1;}
#line 98 "hb-ot-shaper-indic-machine.rl" #line 106 "hb-ot-shaper-indic-machine.rl"
{act = 5;} {act = 5;}
break; break;
case 12: case 12:
#line 1 "NONE" #line 1 "NONE"
{te = p+1;} {te = p+1;}
#line 99 "hb-ot-shaper-indic-machine.rl" #line 107 "hb-ot-shaper-indic-machine.rl"
{act = 6;} {act = 6;}
break; break;
#line 561 "hb-ot-shaper-indic-machine.hh" #line 569 "hb-ot-shaper-indic-machine.hh"
} }
_again: _again:
@ -566,7 +574,7 @@ _again:
#line 1 "NONE" #line 1 "NONE"
{ts = 0;} {ts = 0;}
break; break;
#line 570 "hb-ot-shaper-indic-machine.hh" #line 578 "hb-ot-shaper-indic-machine.hh"
} }
if ( ++p != pe ) if ( ++p != pe )
@ -582,7 +590,7 @@ _again:
} }
#line 131 "hb-ot-shaper-indic-machine.rl" #line 139 "hb-ot-shaper-indic-machine.rl"
} }

View File

@ -29,6 +29,14 @@
#include "hb.hh" #include "hb.hh"
#include "hb-ot-layout.hh"
#include "hb-ot-shaper-indic.hh"
using indic_category_t = ot_category_t;
using indic_position_t = ot_position_t;
#define I_Cat(Cat) indic_syllable_machine_ex_##Cat
enum indic_syllable_type_t { enum indic_syllable_type_t {
indic_consonant_syllable, indic_consonant_syllable,
indic_vowel_syllable, indic_vowel_syllable,

View File

@ -39,6 +39,43 @@
*/ */
static inline void
set_indic_properties (hb_glyph_info_t &info)
{
hb_codepoint_t u = info.codepoint;
unsigned int type = hb_indic_get_categories (u);
info.indic_category() = (indic_category_t) (type & 0xFFu);
info.indic_position() = (indic_position_t) (type >> 8);
}
struct hb_indic_would_substitute_feature_t
{
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
}
bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
bool zero_context;
};
/* /*
* Indic configurations. Note that we do not want to keep every single script-specific * Indic configurations. Note that we do not want to keep every single script-specific
* behavior in these tables necessarily. This should mainly be used for per-script * behavior in these tables necessarily. This should mainly be used for per-script
@ -417,9 +454,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
*/ */
if (buffer->props.script == HB_SCRIPT_KANNADA && if (buffer->props.script == HB_SCRIPT_KANNADA &&
start + 3 <= end && start + 3 <= end &&
is_one_of (info[start ], FLAG (OT_Ra)) && is_one_of (info[start ], FLAG (I_Cat(Ra))) &&
is_one_of (info[start+1], FLAG (OT_H)) && is_one_of (info[start+1], FLAG (I_Cat(H))) &&
is_one_of (info[start+2], FLAG (OT_ZWJ))) is_one_of (info[start+2], FLAG (I_Cat(ZWJ))))
{ {
buffer->merge_clusters (start+1, start+3); buffer->merge_clusters (start+1, start+3);
hb_glyph_info_t tmp = info[start+1]; hb_glyph_info_t tmp = info[start+1];
@ -453,7 +490,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
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])) ||
(indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ) (indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == I_Cat(ZWJ))
)) ))
{ {
/* See if it matches the 'rphf' feature. */ /* See if it matches the 'rphf' feature. */
@ -471,7 +508,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
base = start; base = start;
has_reph = true; has_reph = true;
} }
} else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == OT_Repha) } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == I_Cat(Repha))
{ {
limit += 1; limit += 1;
while (limit < end && is_joiner (info[limit])) while (limit < end && is_joiner (info[limit]))
@ -523,8 +560,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* search continues. This is particularly important for Bengali * search continues. This is particularly important for Bengali
* sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */ * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
if (start < i && if (start < i &&
info[i].indic_category() == OT_ZWJ && info[i].indic_category() == I_Cat(ZWJ) &&
info[i - 1].indic_category() == OT_H) info[i - 1].indic_category() == I_Cat(H))
break; break;
} }
} while (i > limit); } while (i > limit);
@ -546,7 +583,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
for (unsigned int i = limit; i < end; i++) for (unsigned int i = limit; i < end; i++)
if (is_consonant (info[i])) if (is_consonant (info[i]))
{ {
if (limit < i && info[i - 1].indic_category() == OT_ZWJ) if (limit < i && info[i - 1].indic_category() == I_Cat(ZWJ))
break; break;
else else
base = i; base = i;
@ -615,7 +652,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Mark final consonants. A final consonant is one appearing after a matra. /* Mark final consonants. A final consonant is one appearing after a matra.
* Happens in Sinhala. */ * Happens in Sinhala. */
for (unsigned int i = base + 1; i < end; i++) for (unsigned int i = base + 1; i < end; i++)
if (info[i].indic_category() == OT_M) { if (info[i].indic_category() == I_Cat(M)) {
for (unsigned int j = i + 1; j < end; j++) for (unsigned int j = i + 1; j < end; j++)
if (is_consonant (info[j])) { if (is_consonant (info[j])) {
info[j].indic_position() = POS_FINAL_C; info[j].indic_position() = POS_FINAL_C;
@ -660,14 +697,14 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
{ {
bool disallow_double_halants = buffer->props.script == HB_SCRIPT_KANNADA; bool disallow_double_halants = buffer->props.script == HB_SCRIPT_KANNADA;
for (unsigned int i = base + 1; i < end; i++) for (unsigned int i = base + 1; i < end; i++)
if (info[i].indic_category() == OT_H) if (info[i].indic_category() == I_Cat(H))
{ {
unsigned int j; unsigned int j;
for (j = end - 1; j > i; j--) for (j = end - 1; j > i; j--)
if (is_consonant (info[j]) || if (is_consonant (info[j]) ||
(disallow_double_halants && info[j].indic_category() == OT_H)) (disallow_double_halants && info[j].indic_category() == I_Cat(H)))
break; break;
if (info[j].indic_category() != OT_H && j > i) { if (info[j].indic_category() != I_Cat(H) && j > i) {
/* Move Halant to after last consonant. */ /* Move Halant to after last consonant. */
hb_glyph_info_t t = info[i]; hb_glyph_info_t t = info[i];
memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0])); memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0]));
@ -682,10 +719,10 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
indic_position_t last_pos = POS_START; indic_position_t last_pos = POS_START;
for (unsigned int i = start; i < end; i++) for (unsigned int i = start; i < end; i++)
{ {
if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_H)))) if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (I_Cat(N)) | FLAG (I_Cat(RS)) | MEDIAL_FLAGS | FLAG (I_Cat(H)))))
{ {
info[i].indic_position() = last_pos; info[i].indic_position() = last_pos;
if (unlikely (info[i].indic_category() == OT_H && if (unlikely (info[i].indic_category() == I_Cat(H) &&
info[i].indic_position() == POS_PRE_M)) info[i].indic_position() == POS_PRE_M))
{ {
/* /*
@ -719,7 +756,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (info[j].indic_position() < POS_SMVD) if (info[j].indic_position() < POS_SMVD)
info[j].indic_position() = info[i].indic_position(); info[j].indic_position() = info[i].indic_position();
last = i; last = i;
} else if (info[i].indic_category() == OT_M) } else if (info[i].indic_category() == I_Cat(M))
last = i; last = i;
} }
@ -850,10 +887,10 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915 * Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915
*/ */
for (unsigned int i = start; i + 1 < base; i++) for (unsigned int i = start; i + 1 < base; i++)
if (info[i ].indic_category() == OT_Ra && if (info[i ].indic_category() == I_Cat(Ra) &&
info[i+1].indic_category() == OT_H && info[i+1].indic_category() == I_Cat(H) &&
(i + 2 == base || (i + 2 == base ||
info[i+2].indic_category() != OT_ZWJ)) info[i+2].indic_category() != I_Cat(ZWJ)))
{ {
info[i ].mask |= indic_plan->mask_array[INDIC_BLWF]; info[i ].mask |= indic_plan->mask_array[INDIC_BLWF];
info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF]; info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF];
@ -880,7 +917,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Apply ZWJ/ZWNJ effects */ /* Apply ZWJ/ZWNJ effects */
for (unsigned int i = start + 1; i < end; i++) for (unsigned int i = start + 1; i < end; i++)
if (is_joiner (info[i])) { if (is_joiner (info[i])) {
bool non_joiner = info[i].indic_category() == OT_ZWNJ; bool non_joiner = info[i].indic_category() == I_Cat(ZWNJ);
unsigned int j = i; unsigned int j = i;
do { do {
@ -913,7 +950,7 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
/* For dotted-circle, this is what Uniscribe does: /* For dotted-circle, this is what Uniscribe does:
* If dotted-circle is the last glyph, it just does nothing. * If dotted-circle is the last glyph, it just does nothing.
* Ie. It doesn't form Reph. */ * Ie. It doesn't form Reph. */
if (buffer->info[end - 1].indic_category() == OT_DOTTEDCIRCLE) if (buffer->info[end - 1].indic_category() == I_Cat(DOTTEDCIRCLE))
return; return;
} }
@ -956,8 +993,8 @@ initial_reordering_indic (const hb_ot_shape_plan_t *plan,
update_consonant_positions_indic (plan, font, buffer); update_consonant_positions_indic (plan, font, buffer);
hb_syllabic_insert_dotted_circles (font, buffer, hb_syllabic_insert_dotted_circles (font, buffer,
indic_broken_cluster, indic_broken_cluster,
OT_DOTTEDCIRCLE, I_Cat(DOTTEDCIRCLE),
OT_Repha, I_Cat(Repha),
POS_END); POS_END);
foreach_syllable (buffer, start, end) foreach_syllable (buffer, start, end)
@ -979,7 +1016,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
* and possibly multiple substitutions happened prior to this * and possibly multiple substitutions happened prior to this
* phase, and that might have messed up our properties. Recover * phase, and that might have messed up our properties. Recover
* from a particular case of that where we're fairly sure that a * from a particular case of that where we're fairly sure that a
* class of OT_H is desired but has been lost. */ * class of I_Cat(H) is desired but has been lost. */
/* We don't call load_virama_glyph(), since we know it's already /* We don't call load_virama_glyph(), since we know it's already
* loaded. */ * loaded. */
hb_codepoint_t virama_glyph = indic_plan->virama_glyph.get_relaxed (); hb_codepoint_t virama_glyph = indic_plan->virama_glyph.get_relaxed ();
@ -991,7 +1028,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
_hb_glyph_info_multiplied (&info[i])) _hb_glyph_info_multiplied (&info[i]))
{ {
/* This will make sure that this glyph passes is_halant() test. */ /* This will make sure that this glyph passes is_halant() test. */
info[i].indic_category() = OT_H; info[i].indic_category() = I_Cat(H);
_hb_glyph_info_clear_ligated_and_multiplied (&info[i]); _hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
} }
} }
@ -1057,11 +1094,11 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
break; break;
} }
if (base == end && start < base && if (base == end && start < base &&
is_one_of (info[base - 1], FLAG (OT_ZWJ))) is_one_of (info[base - 1], FLAG (I_Cat(ZWJ))))
base--; base--;
if (base < end) if (base < end)
while (start < base && while (start < base &&
is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_H)))) is_one_of (info[base], (FLAG (I_Cat(N)) | FLAG (I_Cat(H)))))
base--; base--;
@ -1106,7 +1143,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
{ {
search: search:
while (new_pos > start && while (new_pos > start &&
!(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H))))) !(is_one_of (info[new_pos], (FLAG (I_Cat(M)) | FLAG (I_Cat(H))))))
new_pos--; new_pos--;
/* If we found no Halant we are done. /* If we found no Halant we are done.
@ -1123,7 +1160,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
if (new_pos + 1 < end) if (new_pos + 1 < end)
{ {
/* -> If ZWJ follows this halant, matra is NOT repositioned after this halant. */ /* -> If ZWJ follows this halant, matra is NOT repositioned after this halant. */
if (info[new_pos + 1].indic_category() == OT_ZWJ) if (info[new_pos + 1].indic_category() == I_Cat(ZWJ))
{ {
/* Keep searching. */ /* Keep searching. */
if (new_pos > start) if (new_pos > start)
@ -1196,7 +1233,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
*/ */
if (start + 1 < end && if (start + 1 < end &&
info[start].indic_position() == POS_RA_TO_BECOME_REPH && info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
((info[start].indic_category() == OT_Repha) ^ ((info[start].indic_category() == I_Cat(Repha)) ^
_hb_glyph_info_ligated_and_didnt_multiply (&info[start]))) _hb_glyph_info_ligated_and_didnt_multiply (&info[start])))
{ {
unsigned int new_reph_pos; unsigned int new_reph_pos;
@ -1306,7 +1343,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
unlikely (is_halant (info[new_reph_pos]))) unlikely (is_halant (info[new_reph_pos])))
{ {
for (unsigned int i = base + 1; i < new_reph_pos; i++) for (unsigned int i = base + 1; i < new_reph_pos; i++)
if (info[i].indic_category() == OT_M) { if (info[i].indic_category() == I_Cat(M)) {
/* Ok, got it. */ /* Ok, got it. */
new_reph_pos--; new_reph_pos--;
} }
@ -1366,7 +1403,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL) if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
{ {
while (new_pos > start && while (new_pos > start &&
!(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_H)))) !(is_one_of (info[new_pos - 1], FLAG(I_Cat(M)) | FLAG (I_Cat(H)))))
new_pos--; new_pos--;
} }

View File

@ -42,7 +42,7 @@
*/ */
/* Note: This enum is duplicated in the -machine.rl source file. /* Note: This enum is duplicated in the -machine.rl source file.
* Not sure how to avoid duplication. */ * Not sure how to avoid duplication. */
enum indic_category_t { enum ot_category_t {
OT_X = 0, OT_X = 0,
OT_C = 1, OT_C = 1,
OT_V = 2, OT_V = 2,
@ -103,7 +103,7 @@ enum indic_category_t {
/* Visual positions in a syllable from left to right. */ /* Visual positions in a syllable from left to right. */
enum indic_position_t { enum ot_position_t {
POS_START = 0, POS_START = 0,
POS_RA_TO_BECOME_REPH = 1, POS_RA_TO_BECOME_REPH = 1,
@ -162,55 +162,5 @@ is_halant (const hb_glyph_info_t &info)
return is_one_of (info, FLAG (OT_H)); return is_one_of (info, FLAG (OT_H));
} }
#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base))
#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u))
#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u))
#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u))
#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u))
#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u))
#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u))
#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u))
#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u))
#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u))
#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u))
static inline void
set_indic_properties (hb_glyph_info_t &info)
{
hb_codepoint_t u = info.codepoint;
unsigned int type = hb_indic_get_categories (u);
info.indic_category() = (indic_category_t) (type & 0xFFu);
info.indic_position() = (indic_position_t) (type >> 8);
}
struct hb_indic_would_substitute_feature_t
{
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
}
bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
bool zero_context;
};
#endif /* HB_OT_SHAPER_INDIC_HH */ #endif /* HB_OT_SHAPER_INDIC_HH */

View File

@ -37,7 +37,7 @@
/* buffer var allocations */ /* buffer var allocations */
#define khmer_category() indic_category() /* khmer_category_t */ #define khmer_category() indic_category() /* khmer_category_t */
using khmer_category_t = unsigned; using khmer_category_t = ot_category_t;
#define K_Cat(Cat) khmer_syllable_machine_ex_##Cat #define K_Cat(Cat) khmer_syllable_machine_ex_##Cat

View File

@ -35,7 +35,7 @@
/* buffer var allocations */ /* buffer var allocations */
#define khmer_category() indic_category() /* khmer_category_t */ #define khmer_category() indic_category() /* khmer_category_t */
using khmer_category_t = unsigned; using khmer_category_t = ot_category_t;
#define K_Cat(Cat) khmer_syllable_machine_ex_##Cat #define K_Cat(Cat) khmer_syllable_machine_ex_##Cat

View File

@ -38,8 +38,8 @@
#define myanmar_category() indic_category() /* myanmar_category_t */ #define myanmar_category() indic_category() /* myanmar_category_t */
#define myanmar_position() indic_position() /* myanmar_position_t */ #define myanmar_position() indic_position() /* myanmar_position_t */
using myanmar_category_t = unsigned; using myanmar_category_t = ot_category_t;
using myanmar_position_t = indic_position_t; using myanmar_position_t = ot_position_t;
#define M_Cat(Cat) myanmar_syllable_machine_ex_##Cat #define M_Cat(Cat) myanmar_syllable_machine_ex_##Cat

View File

@ -36,8 +36,8 @@
#define myanmar_category() indic_category() /* myanmar_category_t */ #define myanmar_category() indic_category() /* myanmar_category_t */
#define myanmar_position() indic_position() /* myanmar_position_t */ #define myanmar_position() indic_position() /* myanmar_position_t */
using myanmar_category_t = unsigned; using myanmar_category_t = ot_category_t;
using myanmar_position_t = indic_position_t; using myanmar_position_t = ot_position_t;
#define M_Cat(Cat) myanmar_syllable_machine_ex_##Cat #define M_Cat(Cat) myanmar_syllable_machine_ex_##Cat