static hb_script_t findScriptForVerticalGlyphSubstitution(hb_face_t* face) { static const unsigned maxCount = 32; unsigned scriptCount = maxCount; hb_tag_t scriptTags[maxCount]; hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCount, scriptTags); for (unsigned scriptIndex = 0; scriptIndex < scriptCount; ++scriptIndex) { unsigned languageCount = maxCount; hb_tag_t languageTags[maxCount]; hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, scriptIndex, 0, &languageCount, languageTags); for (unsigned languageIndex = 0; languageIndex < languageCount; ++languageIndex) { unsigned featureIndex; if (hb_ot_layout_language_find_feature( face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HarfBuzzFace::vertTag, &featureIndex) || hb_ot_layout_language_find_feature( face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HarfBuzzFace::vrt2Tag, &featureIndex)) return hb_ot_tag_to_script(scriptTags[scriptIndex]); } } return HB_SCRIPT_INVALID; }
static hb_script_t findScriptForVerticalGlyphSubstitution(hb_face_t* face) { static const unsigned maxCount = 32; unsigned scriptCount = maxCount; hb_tag_t scriptTags[maxCount]; hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &scriptCount, scriptTags); for (unsigned scriptIndex = 0; scriptIndex < scriptCount; ++scriptIndex) { unsigned languageCount = maxCount; hb_tag_t languageTags[maxCount]; hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, scriptIndex, 0, &languageCount, languageTags); unsigned featureIndex; for (unsigned languageIndex = 0; languageIndex < languageCount; ++languageIndex) { if (hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, languageIndex, HarfBuzzFace::vertTag, &featureIndex)) return hb_ot_tag_to_script(scriptTags[scriptIndex]); } // Try DefaultLangSys if all LangSys failed. if (hb_ot_layout_language_find_feature(face, HB_OT_TAG_GSUB, scriptIndex, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, HarfBuzzFace::vertTag, &featureIndex)) return hb_ot_tag_to_script(scriptTags[scriptIndex]); } return HB_SCRIPT_INVALID; }
bool OpenTypeCapsSupport::supportsOpenTypeFeature( hb_script_t script, uint32_t tag) const { hb_face_t* face = hb_font_get_face(m_harfBuzzFace->getScaledFont()); ASSERT(face); ASSERT((tag == HB_TAG('s', 'm', 'c', 'p') || tag == HB_TAG('c', '2', 's', 'c') || tag == HB_TAG('p', 'c', 'a', 'p') || tag == HB_TAG('c', '2', 'p', 'c') || tag == HB_TAG('s', 'u', 'p', 's') || tag == HB_TAG('s', 'u', 'b', 's') || tag == HB_TAG('t', 'i', 't', 'l') || tag == HB_TAG('u', 'n', 'i', 'c') || tag == HB_TAG('v', 'e', 'r', 't'))); bool result = false; if (!hb_ot_layout_has_substitution(face)) return false; // Get the OpenType tag(s) that match this script code const size_t kMaxScriptTags = 4; hb_tag_t scriptTags[kMaxScriptTags] = { HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE }; hb_ot_tags_from_script(static_cast<hb_script_t>(script), &scriptTags[0], &scriptTags[1]); // Replace the first remaining NONE with DEFAULT for (size_t i = 0; i < kMaxScriptTags; ++i) { if (scriptTags[i] == HB_TAG_NONE) { scriptTags[i] = HB_OT_TAG_DEFAULT_SCRIPT; break; } } // Now check for 'smcp' under the first of those scripts that is present const hb_tag_t kGSUB = HB_TAG('G', 'S', 'U', 'B'); for (size_t j = 0; j < kMaxScriptTags; ++j) { if (scriptTags[j] == HB_TAG_NONE) break; unsigned scriptIndex; if (hb_ot_layout_table_find_script(face, kGSUB, scriptTags[j], &scriptIndex)) { if (hb_ot_layout_language_find_feature(face, kGSUB, scriptIndex, HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, tag, nullptr)) { result = true; } break; } } return result; }
static void _hb_ot_layout_collect_lookups_features (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, unsigned int language_index, const hb_tag_t *features, hb_set_t *lookup_indexes /* OUT */) { if (!features) { unsigned int required_feature_index; if (hb_ot_layout_language_get_required_feature (face, table_tag, script_index, language_index, &required_feature_index, NULL)) _hb_ot_layout_collect_lookups_lookups (face, table_tag, required_feature_index, lookup_indexes); /* All features */ unsigned int feature_indices[32]; unsigned int offset, len; offset = 0; do { len = ARRAY_LENGTH (feature_indices); hb_ot_layout_language_get_feature_indexes (face, table_tag, script_index, language_index, offset, &len, feature_indices); for (unsigned int i = 0; i < len; i++) _hb_ot_layout_collect_lookups_lookups (face, table_tag, feature_indices[i], lookup_indexes); offset += len; } while (len == ARRAY_LENGTH (feature_indices)); } else { for (; *features; features++) { unsigned int feature_index; if (hb_ot_layout_language_find_feature (face, table_tag, script_index, language_index, *features, &feature_index)) _hb_ot_layout_collect_lookups_lookups (face, table_tag, feature_index, lookup_indexes); } } }