FeatureCollector: check for alternates only in GSUB
hb_ot_layout_lookup_get_glyph_alternates() does not take a table ta and
GSUB table is assumed, but if we are checking GPOS table then we will
passing a lookup index from a different table and the result will be
garbage (e.g. think Inter’s kern feature has 8 alternate glyphs).
Change-Id: I78d5eb8304aee3321f492d15e3fc10db47cdc628
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139138
Tested-by: خالد حسني <khaled@aliftype.com>
Reviewed-by: خالد حسني <khaled@aliftype.com>
diff --git a/vcl/source/font/FeatureCollector.cxx b/vcl/source/font/FeatureCollector.cxx
index 9430a78..134462e 100644
--- a/vcl/source/font/FeatureCollector.cxx
+++ b/vcl/source/font/FeatureCollector.cxx
@@ -162,29 +162,34 @@ void FeatureCollector::collectForTable(hb_tag_t aTableTag)
}
}
// Collect lookups in this feature, and input glyphs for each
// lookup, and calculate the max number of alternates they have.
unsigned int nLookups = hb_ot_layout_feature_get_lookups(
m_pHbFace, aTableTag, nFeatureIdx, 0, nullptr, nullptr);
std::vector<unsigned int> aLookups(nLookups);
hb_ot_layout_feature_get_lookups(m_pHbFace, aTableTag, nFeatureIdx, 0, &nLookups,
aLookups.data());
unsigned int nAlternates = 0;
hb_set_t* pGlyphs = hb_set_create();
for (unsigned int nLookupIdx : aLookups)
if (aTableTag == HB_OT_TAG_GSUB)
{
hb_set_clear(pGlyphs);
hb_ot_layout_lookup_collect_glyphs(m_pHbFace, aTableTag, nLookupIdx, nullptr,
pGlyphs, nullptr, nullptr);
hb_codepoint_t nGlyphIdx = HB_SET_VALUE_INVALID;
while (hb_set_next(pGlyphs, &nGlyphIdx))
// Collect lookups in this feature, and input glyphs for each
// lookup, and calculate the max number of alternates they have.
unsigned int nLookups = hb_ot_layout_feature_get_lookups(
m_pHbFace, aTableTag, nFeatureIdx, 0, nullptr, nullptr);
std::vector<unsigned int> aLookups(nLookups);
hb_ot_layout_feature_get_lookups(m_pHbFace, aTableTag, nFeatureIdx, 0, &nLookups,
aLookups.data());
hb_set_t* pGlyphs = hb_set_create();
for (unsigned int nLookupIdx : aLookups)
{
nAlternates = std::max(
nAlternates, hb_ot_layout_lookup_get_glyph_alternates(
m_pHbFace, nLookupIdx, nGlyphIdx, 0, nullptr, nullptr));
hb_set_clear(pGlyphs);
hb_ot_layout_lookup_collect_glyphs(m_pHbFace, aTableTag, nLookupIdx, nullptr,
pGlyphs, nullptr, nullptr);
hb_codepoint_t nGlyphIdx = HB_SET_VALUE_INVALID;
while (hb_set_next(pGlyphs, &nGlyphIdx))
{
nAlternates
= std::max(nAlternates,
hb_ot_layout_lookup_get_glyph_alternates(
m_pHbFace, nLookupIdx, nGlyphIdx, 0, nullptr, nullptr));
}
}
hb_set_destroy(pGlyphs);
}
hb_set_destroy(pGlyphs);
// Append the alternates to the feature parameters, keeping any
// existing ones calculated from cvXX features above.