Do Arabic fallback shaping

This commit is contained in:
Behdad Esfahbod 2012-04-10 16:44:38 -04:00
parent ae4a2b9365
commit b7d04eb606
1 changed files with 33 additions and 5 deletions

View File

@ -58,8 +58,6 @@ enum {
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
{
/* TODO Macroize the magic bit operations */
if (likely (hb_in_range<hb_codepoint_t> (u, JOINING_TABLE_FIRST, JOINING_TABLE_LAST))) {
unsigned int j_type = joining_table[u - JOINING_TABLE_FIRST];
if (likely (j_type != JOINING_TYPE_X))
@ -82,6 +80,12 @@ static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ
JOINING_TYPE_T : JOINING_TYPE_U;
}
static hb_codepoint_t get_arabic_shape (hb_codepoint_t u, unsigned int shape)
{
if (likely (hb_in_range<hb_codepoint_t> (u, SHAPING_TABLE_FIRST, SHAPING_TABLE_LAST)) && shape < 4)
return shaping_table[u - SHAPING_TABLE_FIRST][shape];
return u;
}
static const hb_tag_t arabic_syriac_features[] =
@ -189,6 +193,15 @@ _hb_ot_shape_complex_normalization_preference_arabic (void)
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
}
static void
arabic_fallback_shape (hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
buffer->info[i].codepoint = get_arabic_shape (buffer->info[i].codepoint, buffer->info[i].arabic_shaping_action());
}
void
_hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map, hb_buffer_t *buffer)
{
@ -218,12 +231,27 @@ _hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map, hb_buffer_t *buffer)
}
hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0};
hb_mask_t total_masks = 0;
unsigned int num_masks = buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
for (unsigned int i = 0; i < num_masks; i++)
for (unsigned int i = 0; i < num_masks; i++) {
mask_array[i] = map->get_1_mask (arabic_syriac_features[i]);
total_masks |= mask_array[i];
}
for (unsigned int i = 0; i < count; i++)
buffer->info[i].mask |= mask_array[buffer->info[i].arabic_shaping_action()];
if (total_masks) {
/* Has OpenType tables */
for (unsigned int i = 0; i < count; i++)
buffer->info[i].mask |= mask_array[buffer->info[i].arabic_shaping_action()];
} else if (buffer->props.script == HB_SCRIPT_ARABIC) {
/* Fallback Arabic shaping to Presentation Forms */
/* Pitfalls:
* - This path fires if user force-set init/medi/fina/isol off,
* - If font does not declare script 'arab', well, what to do?
* Most probably it's safe to assume that init/medi/fina/isol
* still mean Arabic shaping, although they do not have to.
*/
arabic_fallback_shape (buffer);
}
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}