|
|
|
@ -267,49 +267,6 @@ set_indic_properties (hb_glyph_info_t &info) |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Global Indic shaper options. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
struct indic_options_t |
|
|
|
|
{ |
|
|
|
|
int initialized : 1; |
|
|
|
|
int uniscribe_bug_compatible : 1; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
union indic_options_union_t { |
|
|
|
|
int i; |
|
|
|
|
indic_options_t opts; |
|
|
|
|
}; |
|
|
|
|
ASSERT_STATIC (sizeof (int) == sizeof (indic_options_union_t)); |
|
|
|
|
|
|
|
|
|
static indic_options_union_t |
|
|
|
|
indic_options_init (void) |
|
|
|
|
{ |
|
|
|
|
indic_options_union_t u; |
|
|
|
|
u.i = 0; |
|
|
|
|
u.opts.initialized = 1; |
|
|
|
|
|
|
|
|
|
char *c = getenv ("HB_OT_INDIC_OPTIONS"); |
|
|
|
|
u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible"); |
|
|
|
|
|
|
|
|
|
return u; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static inline indic_options_t |
|
|
|
|
indic_options (void) |
|
|
|
|
{ |
|
|
|
|
static indic_options_union_t options; |
|
|
|
|
|
|
|
|
|
if (unlikely (!options.i)) { |
|
|
|
|
/* This is idempotent and threadsafe. */ |
|
|
|
|
options = indic_options_init (); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return options.opts; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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 |
|
|
|
@ -484,7 +441,7 @@ static void |
|
|
|
|
override_features_indic (hb_ot_shape_planner_t *plan) |
|
|
|
|
{ |
|
|
|
|
/* Uniscribe does not apply 'kern'. */ |
|
|
|
|
if (indic_options ().uniscribe_bug_compatible) |
|
|
|
|
if (hb_options ().uniscribe_bug_compatible) |
|
|
|
|
plan->map.add_feature (HB_TAG('k','e','r','n'), 0, true); |
|
|
|
|
|
|
|
|
|
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, true); |
|
|
|
@ -1044,7 +1001,7 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, |
|
|
|
|
/* We treat NBSP/dotted-circle as if they are consonants, so we should just chain.
|
|
|
|
|
* Only if not in compatibility mode that is... */ |
|
|
|
|
|
|
|
|
|
if (indic_options ().uniscribe_bug_compatible) |
|
|
|
|
if (hb_options ().uniscribe_bug_compatible) |
|
|
|
|
{ |
|
|
|
|
/* For dotted-circle, this is what Uniscribe does:
|
|
|
|
|
* If dotted-circle is the last glyph, it just does nothing. |
|
|
|
@ -1380,7 +1337,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, |
|
|
|
|
* Uniscribe doesn't do this. |
|
|
|
|
* TEST: U+0930,U+094D,U+0915,U+094B,U+094D |
|
|
|
|
*/ |
|
|
|
|
if (!indic_options ().uniscribe_bug_compatible && |
|
|
|
|
if (!hb_options ().uniscribe_bug_compatible && |
|
|
|
|
unlikely (is_halant_or_coeng (info[new_reph_pos]))) { |
|
|
|
|
for (unsigned int i = base + 1; i < new_reph_pos; i++) |
|
|
|
|
if (info[i].indic_category() == OT_M) { |
|
|
|
@ -1484,7 +1441,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, |
|
|
|
|
/*
|
|
|
|
|
* Finish off the clusters and go home! |
|
|
|
|
*/ |
|
|
|
|
if (indic_options ().uniscribe_bug_compatible) |
|
|
|
|
if (hb_options ().uniscribe_bug_compatible) |
|
|
|
|
{ |
|
|
|
|
/* Uniscribe merges the entire cluster.
|
|
|
|
|
* This means, half forms are submerged into the main consonants cluster. |
|
|
|
@ -1600,7 +1557,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c, |
|
|
|
|
|
|
|
|
|
hb_codepoint_t glyph; |
|
|
|
|
|
|
|
|
|
if (indic_options ().uniscribe_bug_compatible || |
|
|
|
|
if (hb_options ().uniscribe_bug_compatible || |
|
|
|
|
(c->font->get_glyph (ab, 0, &glyph) && |
|
|
|
|
indic_plan->pstf.would_substitute (&glyph, 1, true, c->font->face))) |
|
|
|
|
{ |
|
|
|
|