diff --git a/src/hb-common.cc b/src/hb-common.cc index 41b1601de..f698a4406 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -47,8 +47,27 @@ _hb_options_init (void) u.i = 0; u.opts.initialized = 1; - char *c = getenv ("HB_OPTIONS"); - u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible"); + const char *c = getenv ("HB_OPTIONS"); + if (c) + { + while (*c) + { + const char *p = strchr (c, ':'); + if (!p) + p = c + strlen (c); + +#define OPTION(name, symbol) \ + if (0 == strncmp (c, name, p - c)) u.opts.symbol = true; + + OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible); + OPTION ("aat", aat); + +#undef OPTION + + c = *p ? p + 1 : p; + } + + } /* This is idempotent and threadsafe. */ _hb_options.set_relaxed (u.i); diff --git a/src/hb-debug.hh b/src/hb-debug.hh index 12b6c49ae..58c190d27 100644 --- a/src/hb-debug.hh +++ b/src/hb-debug.hh @@ -43,9 +43,10 @@ struct hb_options_t { - unsigned int unused : 1; /* In-case sign bit is here. */ - unsigned int initialized : 1; - unsigned int uniscribe_bug_compatible : 1; + bool unused : 1; /* In-case sign bit is here. */ + bool initialized : 1; + bool uniscribe_bug_compatible : 1; + bool aat : 1; }; union hb_options_union_t { diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index cf808c2a5..7a15d5234 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -42,6 +42,17 @@ #include "hb-aat-layout.hh" +static bool +_hb_apply_morx (hb_face_t *face) +{ + if (hb_options ().aat && + hb_aat_layout_has_substitution (face)) + return true; + + return !hb_ot_layout_has_substitution (face) && + hb_aat_layout_has_substitution (face); +} + void hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, const int *coords, @@ -76,17 +87,15 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, * Decide who does substitutions. GSUB, morx, or fallback. */ - if (!hb_ot_layout_has_substitution (face)) - { /* No GSUB. */ - if (hb_aat_layout_has_substitution (face)) - plan.apply_morx = true; - } + plan.apply_morx = _hb_apply_morx (face); /* * Decide who does positioning. GPOS, kerx, kern, or fallback. */ - if (!disable_gpos && hb_ot_layout_has_positioning (face)) + if (hb_options ().aat && hb_aat_layout_has_positioning (face)) + plan.apply_kerx = true; + else if (!disable_gpos && hb_ot_layout_has_positioning (face)) plan.apply_gpos = true; else if (hb_aat_layout_has_positioning (face)) plan.apply_kerx = true; @@ -263,8 +272,7 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, /* Ugly that we have to do this here... * If we are going to apply morx, choose default shaper. */ - if (!hb_ot_layout_has_substitution (planner.face) && - hb_aat_layout_has_substitution (planner.face)) + if (_hb_apply_morx (planner.face)) planner.shaper = &_hb_ot_complex_shaper_default; else planner.shaper = hb_ot_shape_complex_categorize (&planner);