From 2123f049d30cad9d79867999eb49f46211e0e23c Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Mon, 16 Jul 2012 07:23:42 -0500 Subject: [PATCH] usp10: Change OpenType_GSUB_GetFontLangaugeTags to OpenType_GetFontLanguageTags and load languages from GPOS table as well. --- dlls/usp10/opentype.c | 92 +++++++++++++++++++++++++++++++++++++-------- dlls/usp10/shape.c | 4 +- dlls/usp10/usp10_internal.h | 5 ++- 3 files changed, 82 insertions(+), 19 deletions(-) diff --git a/dlls/usp10/opentype.c b/dlls/usp10/opentype.c index 1aa77c02c2d..369cfcc1697 100644 --- a/dlls/usp10/opentype.c +++ b/dlls/usp10/opentype.c @@ -992,7 +992,7 @@ static void GSUB_initialize_language_cache(LoadedScript *script) { int i; - if (!script->language_count && script->gsub_table) + if (script->gsub_table) { DWORD offset; const OT_Script* table = script->gsub_table; @@ -1001,12 +1001,12 @@ static void GSUB_initialize_language_cache(LoadedScript *script) if (offset) { script->default_language.tag = MS_MAKE_TAG('d','f','l','t'); - script->default_language.table = (const BYTE*)table + offset; + script->default_language.gsub_table = (const BYTE*)table + offset; } if (script->language_count) { - TRACE("Deflang %p, LangCount %i\n",script->default_language.table, script->language_count); + TRACE("Deflang %p, LangCount %i\n",script->default_language.gsub_table, script->language_count); script->languages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LoadedLanguage) * script->language_count); @@ -1014,13 +1014,79 @@ static void GSUB_initialize_language_cache(LoadedScript *script) { int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys); script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]); - script->languages[i].table = ((const BYTE*)table + offset); + script->languages[i].gsub_table = ((const BYTE*)table + offset); } } } } -HRESULT OpenType_GSUB_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags, LPCVOID* language_table) +static void GPOS_expand_language_cache(LoadedScript *script) +{ + int count; + const OT_Script* table = script->gpos_table; + DWORD offset; + + if (!table) + return; + + offset = GET_BE_WORD(table->DefaultLangSys); + if (offset) + script->default_language.gpos_table = (const BYTE*)table + offset; + + count = GET_BE_WORD(table->LangSysCount); + + TRACE("Deflang %p, LangCount %i\n",script->default_language.gpos_table, count); + if (!script->language_count) + { + int i; + script->language_count = count; + + script->languages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LoadedLanguage) * script->language_count); + + for (i = 0; i < script->language_count; i++) + { + int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys); + script->languages[i].tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]); + script->languages[i].gpos_table = ((const BYTE*)table + offset); + } + } + else if (count) + { + int i,j; + for (i = 0; i < count; i++) + { + int offset = GET_BE_WORD(table->LangSysRecord[i].LangSys); + OPENTYPE_TAG tag = MS_MAKE_TAG(table->LangSysRecord[i].LangSysTag[0], table->LangSysRecord[i].LangSysTag[1], table->LangSysRecord[i].LangSysTag[2], table->LangSysRecord[i].LangSysTag[3]); + + for (j = 0; j < script->language_count; j++) + { + if (script->languages[j].tag == tag) + { + script->languages[j].gpos_table = ((const BYTE*)table + offset); + break; + } + } + if (j == script->language_count) + { + script->language_count++; + script->languages = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,script->languages, sizeof(LoadedLanguage) * script->language_count); + script->languages[j].tag = tag; + script->languages[j].gpos_table = ((const BYTE*)table + offset); + } + } + } +} + +static void _initialize_language_cache(LoadedScript *script) +{ + if (!script->language_count) + { + GSUB_initialize_language_cache(script); + GPOS_expand_language_cache(script); + } +} + +HRESULT OpenType_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags) { int i; HRESULT rc = S_OK; @@ -1040,7 +1106,7 @@ HRESULT OpenType_GSUB_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_ if (!script) return E_INVALIDARG; - GSUB_initialize_language_cache(script); + _initialize_language_cache(script); if (!searchingFor && cMaxTags < script->language_count) rc = E_OUTOFMEMORY; @@ -1060,15 +1126,13 @@ HRESULT OpenType_GSUB_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_ { pLanguageTags[0] = script->languages[i].tag; *pcTags = 1; - if (language_table) - *language_table = script->languages[i].table; rc = S_OK; break; } } } - if (script->default_language.table) + if (script->default_language.gsub_table) { if (i < cMaxTags) pLanguageTags[i] = script->default_language.tag; @@ -1076,8 +1140,6 @@ HRESULT OpenType_GSUB_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_ if (searchingFor && FAILED(rc)) { pLanguageTags[0] = script->default_language.tag; - if (language_table) - *language_table = script->default_language.table; } i++; *pcTags = (*pcTags) + 1; @@ -1091,9 +1153,9 @@ static void GSUB_initialize_feature_cache(LPCVOID table, LoadedLanguage *languag { int i; - if (!language->feature_count) + if (!language->feature_count && language->gsub_table) { - const OT_LangSys *lang= language->table; + const OT_LangSys *lang = language->gsub_table; const GSUB_Header *header = (const GSUB_Header *)table; const OT_FeatureList *feature_list; @@ -1151,9 +1213,9 @@ HRESULT OpenType_GSUB_GetFontFeatureTags(ScriptCache *psc, OPENTYPE_TAG script_t return E_INVALIDARG; } - GSUB_initialize_language_cache(script); + _initialize_language_cache(script); - if (script->default_language.table && script->default_language.tag == language_tag) + if (script->default_language.gsub_table && script->default_language.tag == language_tag) language = &script->default_language; else { diff --git a/dlls/usp10/shape.c b/dlls/usp10/shape.c index b7d282241c8..1655992c8ac 100644 --- a/dlls/usp10/shape.c +++ b/dlls/usp10/shape.c @@ -3264,11 +3264,11 @@ HRESULT SHAPE_GetFontLanguageTags( HDC hdc, ScriptCache *psc, if (psa && psc->userLang != 0) searching = psc->userLang; - hr = OpenType_GSUB_GetFontLanguageTags(psc, tagScript, searching, cMaxTags, pLangSysTags, pcTags, NULL); + hr = OpenType_GetFontLanguageTags(psc, tagScript, searching, cMaxTags, pLangSysTags, pcTags); if (FAILED(hr)) { fellback = TRUE; - hr = OpenType_GSUB_GetFontLanguageTags(psc, MS_MAKE_TAG('l','a','t','n'), searching, cMaxTags, pLangSysTags, pcTags, NULL); + hr = OpenType_GetFontLanguageTags(psc, MS_MAKE_TAG('l','a','t','n'), searching, cMaxTags, pLangSysTags, pcTags); } if (FAILED(hr) || fellback) diff --git a/dlls/usp10/usp10_internal.h b/dlls/usp10/usp10_internal.h index 3cb48d8bdae..4077833c22e 100644 --- a/dlls/usp10/usp10_internal.h +++ b/dlls/usp10/usp10_internal.h @@ -137,7 +137,8 @@ typedef struct { typedef struct { OPENTYPE_TAG tag; - LPCVOID table; + LPCVOID gsub_table; + LPCVOID gpos_table; INT feature_count; LoadedFeature *features; } LoadedLanguage; @@ -236,5 +237,5 @@ DWORD OpenType_CMAP_GetGlyphIndex(HDC hdc, ScriptCache *psc, DWORD utf32c, LPWOR void OpenType_GDEF_UpdateGlyphProps(HDC hdc, ScriptCache *psc, const WORD *pwGlyphs, const WORD cGlyphs, WORD* pwLogClust, const WORD cChars, SCRIPT_GLYPHPROP *pGlyphProp) DECLSPEC_HIDDEN; INT OpenType_apply_GSUB_lookup(LPCVOID table, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count) DECLSPEC_HIDDEN; HRESULT OpenType_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags) DECLSPEC_HIDDEN; -HRESULT OpenType_GSUB_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags, LPCVOID* language_table) 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_GSUB_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; -- 2.11.4.GIT