さて、タイ語などではMicrosoftの仕様書にあったように、ccmpなどがデフォルトで発動していた。これってharfbuzzではどこで処理しているのだろう?ということで見てみた。
[hb-ot-shape.cc]
static hb_tag_t common_features[] = { HB_TAG('c','c','m','p'), HB_TAG('l','o','c','l'), HB_TAG('m','a','r','k'), HB_TAG('m','k','m','k'), HB_TAG('r','l','i','g'), }; ... static void hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, const hb_segment_properties_t *props, const hb_feature_t *user_features, unsigned int num_user_features) { hb_ot_map_builder_t *map = &planner->map; switch (props->direction) { case HB_DIRECTION_LTR: map->add_global_bool_feature (HB_TAG ('l','t','r','a')); map->add_global_bool_feature (HB_TAG ('l','t','r','m')); break; case HB_DIRECTION_RTL: map->add_global_bool_feature (HB_TAG ('r','t','l','a')); map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE); break; case HB_DIRECTION_TTB: case HB_DIRECTION_BTT: case HB_DIRECTION_INVALID: default: break; } map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE); map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE); map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE); if (planner->shaper->collect_features) planner->shaper->collect_features (planner); for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++) map->add_global_bool_feature (common_features[i]);
たぶんここだ。