Commit 9dd91d31 authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

usp10: Correct issues if a feature tag is duplicated between GSUB and GPOS.

Identified by Huw Davies.
parent 430bde34
......@@ -1949,6 +1949,7 @@ static void GSUB_initialize_feature_cache(LPCVOID table, LoadedLanguage *languag
language->features[i].lookups = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * language->features[i].lookup_count);
for (j = 0; j < language->features[i].lookup_count; j++)
language->features[i].lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
language->features[i].tableType = FEATURE_GSUB_TABLE;
}
}
}
......@@ -1989,6 +1990,7 @@ static void GPOS_expand_feature_cache(LPCVOID table, LoadedLanguage *language)
language->features[i].lookups = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * language->features[i].lookup_count);
for (j = 0; j < language->features[i].lookup_count; j++)
language->features[i].lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
language->features[i].tableType = FEATURE_GPOS_TABLE;
}
}
}
......@@ -2010,6 +2012,7 @@ static void GPOS_expand_feature_cache(LPCVOID table, LoadedLanguage *language)
language->features[idx].lookups = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * language->features[idx].lookup_count);
for (j = 0; j < language->features[idx].lookup_count; j++)
language->features[idx].lookups[j] = GET_BE_WORD(feature->LookupListIndex[j]);
language->features[idx].tableType = FEATURE_GPOS_TABLE;
}
language->feature_count += count;
}
......@@ -2024,7 +2027,7 @@ static void _initialize_feature_cache(ScriptCache *psc, LoadedLanguage *language
}
}
HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature** feature)
HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, char tableType, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature** feature)
{
int i;
HRESULT rc = S_OK;
......@@ -2075,7 +2078,15 @@ HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, O
_initialize_feature_cache(psc, language);
*pcTags = language->feature_count;
if (tableType)
{
*pcTags = 0;
for (i = 0; i < language->feature_count; i++)
if (language->features[i].tableType == tableType)
*pcTags = (*pcTags)+1;
}
else
*pcTags = language->feature_count;
if (!searchingFor && cMaxTags < *pcTags)
rc = E_OUTOFMEMORY;
......@@ -2085,11 +2096,15 @@ HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, O
for (i = 0; i < language->feature_count; i++)
{
if (i < cMaxTags)
pFeatureTags[i] = language->features[i].tag;
{
if (!tableType || language->features[i].tableType == tableType)
pFeatureTags[i] = language->features[i].tag;
}
if (searchingFor)
{
if (searchingFor == language->features[i].tag)
if ((searchingFor == language->features[i].tag) &&
(!tableType || language->features[i].tableType == tableType))
{
pFeatureTags[0] = language->features[i].tag;
*pcTags = 1;
......
......@@ -602,7 +602,7 @@ static OPENTYPE_TAG get_opentype_script(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCac
}
}
static LoadedFeature* load_OT_feature(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache *psc, const char* feat)
static LoadedFeature* load_OT_feature(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache *psc, char tableType, const char* feat)
{
LoadedFeature *feature = NULL;
......@@ -623,13 +623,13 @@ static LoadedFeature* load_OT_feature(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache
language = MS_MAKE_TAG('d','f','l','t');
attempt--;
OpenType_GetFontFeatureTags(psc, script, language, FALSE, MS_MAKE_TAG(feat[0],feat[1],feat[2],feat[3]), 1, &tags, &cTags, &feature);
OpenType_GetFontFeatureTags(psc, script, language, FALSE, MS_MAKE_TAG(feat[0],feat[1],feat[2],feat[3]), tableType, 1, &tags, &cTags, &feature);
} while(attempt && !feature);
/* try in the default (latin) table */
if (!feature)
OpenType_GetFontFeatureTags(psc, MS_MAKE_TAG('l','a','t','n'), MS_MAKE_TAG('d','f','l','t'), FALSE, MS_MAKE_TAG(feat[0],feat[1],feat[2],feat[3]), 1, &tags, &cTags, &feature);
OpenType_GetFontFeatureTags(psc, MS_MAKE_TAG('l','a','t','n'), MS_MAKE_TAG('d','f','l','t'), FALSE, MS_MAKE_TAG(feat[0],feat[1],feat[2],feat[3]), tableType, 1, &tags, &cTags, &feature);
}
TRACE("Feature %s located at %p\n",debugstr_an(feat,4),feature);
......@@ -640,7 +640,7 @@ static INT apply_GSUB_feature_to_glyph(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCach
{
LoadedFeature *feature;
feature = load_OT_feature(hdc, psa, psc, feat);
feature = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, feat);
if (!feature)
return GSUB_E_NOFEATURE;
......@@ -825,7 +825,7 @@ static int apply_GSUB_feature(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, W
LoadedFeature *feature;
int lookup_index;
feature = load_OT_feature(hdc, psa, psc, feat);
feature = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, feat);
if (!feature)
return GSUB_E_NOFEATURE;
......@@ -2020,17 +2020,17 @@ static void ShapeIndicSyllables(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa,
{
int c;
int overall_shift = 0;
LoadedFeature *locl = (modern)?load_OT_feature(hdc, psa, psc, "locl"):NULL;
LoadedFeature *nukt = load_OT_feature(hdc, psa, psc, "nukt");
LoadedFeature *akhn = load_OT_feature(hdc, psa, psc, "akhn");
LoadedFeature *rkrf = (modern)?load_OT_feature(hdc, psa, psc, "rkrf"):NULL;
LoadedFeature *pstf = load_OT_feature(hdc, psa, psc, "pstf");
LoadedFeature *vatu = (!rkrf)?load_OT_feature(hdc, psa, psc, "vatu"):NULL;
LoadedFeature *cjct = (modern)?load_OT_feature(hdc, psa, psc, "cjct"):NULL;
BOOL rphf = (load_OT_feature(hdc, psa, psc, "rphf") != NULL);
BOOL pref = (load_OT_feature(hdc, psa, psc, "pref") != NULL);
BOOL blwf = (load_OT_feature(hdc, psa, psc, "blwf") != NULL);
BOOL half = (load_OT_feature(hdc, psa, psc, "half") != NULL);
LoadedFeature *locl = (modern)?load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "locl"):NULL;
LoadedFeature *nukt = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "nukt");
LoadedFeature *akhn = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "akhn");
LoadedFeature *rkrf = (modern)?load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "rkrf"):NULL;
LoadedFeature *pstf = load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "pstf");
LoadedFeature *vatu = (!rkrf)?load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "vatu"):NULL;
LoadedFeature *cjct = (modern)?load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "cjct"):NULL;
BOOL rphf = (load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "rphf") != NULL);
BOOL pref = (load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "pref") != NULL);
BOOL blwf = (load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "blwf") != NULL);
BOOL half = (load_OT_feature(hdc, psa, psc, FEATURE_GSUB_TABLE, "half") != NULL);
IndicSyllable glyph_indexs;
for (c = 0; c < syllable_count; c++)
......@@ -3307,7 +3307,7 @@ void SHAPE_ApplyOpenTypePositions(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *ps
{
LoadedFeature *feature;
feature = load_OT_feature(hdc, psa, psc, (const char*)&rpRangeProperties->potfRecords[i].tagFeature);
feature = load_OT_feature(hdc, psa, psc, FEATURE_GPOS_TABLE, (const char*)&rpRangeProperties->potfRecords[i].tagFeature);
if (!feature)
continue;
......@@ -3330,7 +3330,7 @@ HRESULT SHAPE_CheckFontForRequiredFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANA
i = 0;
while (ShapingData[psa->eScript].requiredFeatures[i])
{
feature = load_OT_feature(hdc, psa, psc, ShapingData[psa->eScript].requiredFeatures[i]);
feature = load_OT_feature(hdc, psa, psc, FEATURE_ALL_TABLES, ShapingData[psa->eScript].requiredFeatures[i]);
if (feature)
return S_OK;
i++;
......@@ -3401,7 +3401,7 @@ HRESULT SHAPE_GetFontFeatureTags( HDC hdc, ScriptCache *psc,
filter = TRUE;
}
hr = OpenType_GetFontFeatureTags(psc, tagScript, tagLangSys, filter, 0x00000000, cMaxTags, pFeatureTags, pcTags, NULL);
hr = OpenType_GetFontFeatureTags(psc, tagScript, tagLangSys, filter, 0x00000000, FEATURE_ALL_TABLES, cMaxTags, pFeatureTags, pcTags, NULL);
if (FAILED(hr))
*pcTags = 0;
......
......@@ -128,8 +128,13 @@
#define GSUB_E_NOFEATURE -2
#define GSUB_E_NOGLYPH -1
#define FEATURE_ALL_TABLES 0
#define FEATURE_GSUB_TABLE 1
#define FEATURE_GPOS_TABLE 2
typedef struct {
OPENTYPE_TAG tag;
CHAR tableType;
LPCVOID feature;
INT lookup_count;
WORD *lookups;
......@@ -242,4 +247,4 @@ INT OpenType_apply_GSUB_lookup(LPCVOID table, INT lookup_index, WORD *glyphs, IN
INT OpenType_apply_GPOS_lookup(LPOUTLINETEXTMETRICW lpotm, LPLOGFONTW lplogfont, INT* piAdvance, LPCVOID table, INT lookup_index, const WORD *glyphs, INT glyph_index, INT write_dir, INT glyph_count, GOFFSET *pGoffset) DECLSPEC_HIDDEN;
HRESULT OpenType_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags) DECLSPEC_HIDDEN;
HRESULT OpenType_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags) DECLSPEC_HIDDEN;
HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature** feature) DECLSPEC_HIDDEN;
HRESULT OpenType_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG language_tag, BOOL filtered, OPENTYPE_TAG searchingFor, char tableType, int cMaxTags, OPENTYPE_TAG *pFeatureTags, int *pcTags, LoadedFeature** feature) DECLSPEC_HIDDEN;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment