|
|
|
@ -291,7 +291,7 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) |
|
|
|
|
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
|
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array, |
|
|
|
|
initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *basic_mask_array, |
|
|
|
|
unsigned int start, unsigned int end) |
|
|
|
|
{ |
|
|
|
|
hb_glyph_info_t *info = buffer->info; |
|
|
|
@ -319,7 +319,7 @@ initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buff |
|
|
|
|
* and has more than one consonant, Ra is excluded from candidates for |
|
|
|
|
* base consonants. */ |
|
|
|
|
unsigned int limit = start; |
|
|
|
|
if (mask_array[RPHF] && |
|
|
|
|
if (basic_mask_array[RPHF] && |
|
|
|
|
start + 3 <= end && |
|
|
|
|
info[start].indic_category() == OT_Ra && |
|
|
|
|
info[start + 1].indic_category() == OT_H && |
|
|
|
@ -480,17 +480,17 @@ initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buff |
|
|
|
|
|
|
|
|
|
/* Reph */ |
|
|
|
|
for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++) |
|
|
|
|
info[i].mask |= mask_array[RPHF]; |
|
|
|
|
info[i].mask |= basic_mask_array[RPHF]; |
|
|
|
|
|
|
|
|
|
/* Pre-base */ |
|
|
|
|
mask = mask_array[HALF] | mask_array[AKHN] | mask_array[CJCT]; |
|
|
|
|
mask = basic_mask_array[HALF] | basic_mask_array[AKHN] | basic_mask_array[CJCT]; |
|
|
|
|
for (unsigned int i = start; i < base; i++) |
|
|
|
|
info[i].mask |= mask; |
|
|
|
|
/* Base */ |
|
|
|
|
mask = mask_array[AKHN] | mask_array[CJCT]; |
|
|
|
|
mask = basic_mask_array[AKHN] | basic_mask_array[CJCT]; |
|
|
|
|
info[base].mask |= mask; |
|
|
|
|
/* Post-base */ |
|
|
|
|
mask = mask_array[BLWF] | mask_array[ABVF] | mask_array[PSTF] | mask_array[CJCT]; |
|
|
|
|
mask = basic_mask_array[BLWF] | basic_mask_array[ABVF] | basic_mask_array[PSTF] | basic_mask_array[CJCT]; |
|
|
|
|
for (unsigned int i = base + 1; i < end; i++) |
|
|
|
|
info[i].mask |= mask; |
|
|
|
|
} |
|
|
|
@ -504,9 +504,9 @@ initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buff |
|
|
|
|
do { |
|
|
|
|
j--; |
|
|
|
|
|
|
|
|
|
info[j].mask &= ~mask_array[CJCT]; |
|
|
|
|
info[j].mask &= ~basic_mask_array[CJCT]; |
|
|
|
|
if (non_joiner) |
|
|
|
|
info[j].mask &= ~mask_array[HALF]; |
|
|
|
|
info[j].mask &= ~basic_mask_array[HALF]; |
|
|
|
|
|
|
|
|
|
} while (j > start && !is_consonant (info[j])); |
|
|
|
|
} |
|
|
|
@ -516,17 +516,17 @@ initial_reordering_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buff |
|
|
|
|
static void |
|
|
|
|
initial_reordering_vowel_syllable (const hb_ot_map_t *map, |
|
|
|
|
hb_buffer_t *buffer, |
|
|
|
|
hb_mask_t *mask_array, |
|
|
|
|
hb_mask_t *basic_mask_array, |
|
|
|
|
unsigned int start, unsigned int end) |
|
|
|
|
{ |
|
|
|
|
/* We made the vowels look like consonants. So let's call the consonant logic! */ |
|
|
|
|
initial_reordering_consonant_syllable (map, buffer, mask_array, start, end); |
|
|
|
|
initial_reordering_consonant_syllable (map, buffer, basic_mask_array, start, end); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
initial_reordering_standalone_cluster (const hb_ot_map_t *map, |
|
|
|
|
hb_buffer_t *buffer, |
|
|
|
|
hb_mask_t *mask_array, |
|
|
|
|
hb_mask_t *basic_mask_array, |
|
|
|
|
unsigned int start, unsigned int end) |
|
|
|
|
{ |
|
|
|
|
/* We treat NBSP/dotted-circle as if they are consonants, so we should just chain.
|
|
|
|
@ -541,13 +541,13 @@ initial_reordering_standalone_cluster (const hb_ot_map_t *map, |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
initial_reordering_consonant_syllable (map, buffer, mask_array, start, end); |
|
|
|
|
initial_reordering_consonant_syllable (map, buffer, basic_mask_array, start, end); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
initial_reordering_non_indic (const hb_ot_map_t *map HB_UNUSED, |
|
|
|
|
hb_buffer_t *buffer HB_UNUSED, |
|
|
|
|
hb_mask_t *mask_array HB_UNUSED, |
|
|
|
|
hb_mask_t *basic_mask_array HB_UNUSED, |
|
|
|
|
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED) |
|
|
|
|
{ |
|
|
|
|
/* Nothing to do right now. If we ever switch to using the output
|
|
|
|
@ -562,16 +562,16 @@ initial_reordering (const hb_ot_map_t *map, |
|
|
|
|
hb_buffer_t *buffer, |
|
|
|
|
void *user_data HB_UNUSED) |
|
|
|
|
{ |
|
|
|
|
hb_mask_t mask_array[ARRAY_LENGTH (indic_basic_features)] = {0}; |
|
|
|
|
hb_mask_t basic_mask_array[ARRAY_LENGTH (indic_basic_features)] = {0}; |
|
|
|
|
unsigned int num_masks = ARRAY_LENGTH (indic_basic_features); |
|
|
|
|
for (unsigned int i = 0; i < num_masks; i++) |
|
|
|
|
mask_array[i] = map->get_1_mask (indic_basic_features[i].tag); |
|
|
|
|
basic_mask_array[i] = map->get_1_mask (indic_basic_features[i].tag); |
|
|
|
|
|
|
|
|
|
find_syllables (map, buffer, mask_array); |
|
|
|
|
find_syllables (map, buffer, basic_mask_array); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
final_reordering_syllable (hb_buffer_t *buffer, hb_mask_t *mask_array, |
|
|
|
|
final_reordering_syllable (hb_buffer_t *buffer, hb_mask_t *other_mask_array, |
|
|
|
|
unsigned int start, unsigned int end) |
|
|
|
|
{ |
|
|
|
|
hb_glyph_info_t *info = buffer->info; |
|
|
|
@ -831,7 +831,7 @@ final_reordering_syllable (hb_buffer_t *buffer, hb_mask_t *mask_array, |
|
|
|
|
FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | |
|
|
|
|
FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | |
|
|
|
|
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))))) |
|
|
|
|
info[start].mask |= mask_array[INIT]; |
|
|
|
|
info[start].mask |= other_mask_array[INIT]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -866,21 +866,21 @@ final_reordering (const hb_ot_map_t *map, |
|
|
|
|
unsigned int count = buffer->len; |
|
|
|
|
if (!count) return; |
|
|
|
|
|
|
|
|
|
hb_mask_t mask_array[ARRAY_LENGTH (indic_other_features)] = {0}; |
|
|
|
|
hb_mask_t other_mask_array[ARRAY_LENGTH (indic_other_features)] = {0}; |
|
|
|
|
unsigned int num_masks = ARRAY_LENGTH (indic_other_features); |
|
|
|
|
for (unsigned int i = 0; i < num_masks; i++) |
|
|
|
|
mask_array[i] = map->get_1_mask (indic_other_features[i].tag); |
|
|
|
|
other_mask_array[i] = map->get_1_mask (indic_other_features[i].tag); |
|
|
|
|
|
|
|
|
|
hb_glyph_info_t *info = buffer->info; |
|
|
|
|
unsigned int last = 0; |
|
|
|
|
unsigned int last_syllable = info[0].syllable(); |
|
|
|
|
for (unsigned int i = 1; i < count; i++) |
|
|
|
|
if (last_syllable != info[i].syllable()) { |
|
|
|
|
final_reordering_syllable (buffer, mask_array, last, i); |
|
|
|
|
final_reordering_syllable (buffer, other_mask_array, last, i); |
|
|
|
|
last = i; |
|
|
|
|
last_syllable = info[last].syllable(); |
|
|
|
|
} |
|
|
|
|
final_reordering_syllable (buffer, mask_array, last, count); |
|
|
|
|
final_reordering_syllable (buffer, other_mask_array, last, count); |
|
|
|
|
|
|
|
|
|
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category); |
|
|
|
|
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position); |
|
|
|
|