[OT] Add shape_plan to Arabic shaper
This commit is contained in:
parent
344cc56698
commit
e9f28a38f5
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright © 2010 Google, Inc.
|
* Copyright © 2010,2012 Google, Inc.
|
||||||
*
|
*
|
||||||
* This is part of HarfBuzz, a text shaping library.
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
*
|
*
|
||||||
|
@ -99,7 +99,7 @@ static uint16_t get_ligature (hb_codepoint_t first, hb_codepoint_t second)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const hb_tag_t arabic_syriac_features[] =
|
static const hb_tag_t arabic_features[] =
|
||||||
{
|
{
|
||||||
HB_TAG('i','n','i','t'),
|
HB_TAG('i','n','i','t'),
|
||||||
HB_TAG('m','e','d','i'),
|
HB_TAG('m','e','d','i'),
|
||||||
|
@ -127,9 +127,7 @@ enum {
|
||||||
|
|
||||||
NONE,
|
NONE,
|
||||||
|
|
||||||
COMMON_NUM_FEATURES = 4,
|
ARABIC_NUM_FEATURES = NONE
|
||||||
SYRIAC_NUM_FEATURES = 7,
|
|
||||||
TOTAL_NUM_FEATURES = NONE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct arabic_state_table_entry {
|
static const struct arabic_state_table_entry {
|
||||||
|
@ -184,9 +182,8 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
|
||||||
|
|
||||||
map->add_gsub_pause (NULL);
|
map->add_gsub_pause (NULL);
|
||||||
|
|
||||||
unsigned int num_features = plan->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
|
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
|
||||||
for (unsigned int i = 0; i < num_features; i++)
|
map->add_bool_feature (arabic_features[i], false);
|
||||||
map->add_bool_feature (arabic_syriac_features[i], false);
|
|
||||||
|
|
||||||
map->add_gsub_pause (NULL);
|
map->add_gsub_pause (NULL);
|
||||||
|
|
||||||
|
@ -200,10 +197,51 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
|
||||||
map->add_bool_feature (HB_TAG('c','s','w','h'));
|
map->add_bool_feature (HB_TAG('c','s','w','h'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct arabic_shape_plan_t
|
||||||
|
{
|
||||||
|
ASSERT_POD ();
|
||||||
|
|
||||||
|
bool do_fallback;
|
||||||
|
hb_mask_t mask_array[ARABIC_NUM_FEATURES];
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *
|
||||||
|
data_create_arabic (const hb_ot_shape_plan_t *plan)
|
||||||
|
{
|
||||||
|
arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t));
|
||||||
|
if (unlikely (!arabic_plan))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
hb_mask_t total_masks = 0;
|
||||||
|
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) {
|
||||||
|
arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
|
||||||
|
total_masks |= arabic_plan->mask_array[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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_plan->do_fallback = 0 == total_masks;
|
||||||
|
|
||||||
|
return arabic_plan;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
data_destroy_arabic (void *data)
|
||||||
|
{
|
||||||
|
free (data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer)
|
arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
|
/* Only Arabic has presentation forms encoded in Unicode. */
|
||||||
|
if (buffer->props.script != HB_SCRIPT_ARABIC)
|
||||||
|
return;
|
||||||
|
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
hb_codepoint_t glyph;
|
hb_codepoint_t glyph;
|
||||||
|
|
||||||
|
@ -240,6 +278,8 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
hb_font_t *font)
|
hb_font_t *font)
|
||||||
{
|
{
|
||||||
|
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
|
||||||
|
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
unsigned int prev = 0, state = 0;
|
unsigned int prev = 0, state = 0;
|
||||||
|
|
||||||
|
@ -265,28 +305,12 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
|
||||||
state = entry->next_state;
|
state = entry->next_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0};
|
if (likely (!arabic_plan->do_fallback)) {
|
||||||
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++) {
|
|
||||||
mask_array[i] = plan->map.get_1_mask (arabic_syriac_features[i]);
|
|
||||||
total_masks |= mask_array[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (total_masks) {
|
|
||||||
/* Has OpenType tables */
|
/* Has OpenType tables */
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
buffer->info[i].mask |= mask_array[buffer->info[i].arabic_shaping_action()];
|
buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shaping_action()];
|
||||||
} else if (buffer->props.script == HB_SCRIPT_ARABIC) {
|
} else
|
||||||
/* 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 (font, buffer);
|
arabic_fallback_shape (font, buffer);
|
||||||
}
|
|
||||||
|
|
||||||
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
|
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
|
||||||
}
|
}
|
||||||
|
@ -296,8 +320,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
|
||||||
"arabic",
|
"arabic",
|
||||||
collect_features_arabic,
|
collect_features_arabic,
|
||||||
NULL, /* override_features */
|
NULL, /* override_features */
|
||||||
NULL, /* data_create */
|
data_create_arabic,
|
||||||
NULL, /* data_destroy */
|
data_destroy_arabic,
|
||||||
NULL, /* normalization_preference */
|
NULL, /* normalization_preference */
|
||||||
setup_masks_arabic,
|
setup_masks_arabic,
|
||||||
true, /* zero_width_attached_marks */
|
true, /* zero_width_attached_marks */
|
||||||
|
|
Loading…
Reference in New Issue