usp10: Implement ScriptGetFontLanguageTags.
This commit is contained in:
parent
acaa258054
commit
0661d2d202
|
@ -3778,7 +3778,7 @@ static void GSUB_initialize_script_cache(ScriptCache *psc)
|
||||||
script = (const GSUB_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
|
script = (const GSUB_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
|
||||||
psc->script_count = GET_BE_WORD(script->ScriptCount);
|
psc->script_count = GET_BE_WORD(script->ScriptCount);
|
||||||
TRACE("initializing %i scripts in this font\n",psc->script_count);
|
TRACE("initializing %i scripts in this font\n",psc->script_count);
|
||||||
psc->scripts = HeapAlloc(GetProcessHeap(),0,sizeof(LoadedScript) * psc->script_count);
|
psc->scripts = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(LoadedScript) * psc->script_count);
|
||||||
for (i = 0; i < psc->script_count; i++)
|
for (i = 0; i < psc->script_count; i++)
|
||||||
{
|
{
|
||||||
int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
|
int offset = GET_BE_WORD(script->ScriptRecord[i].Script);
|
||||||
|
@ -3822,6 +3822,96 @@ static HRESULT GSUB_GetFontScriptTags(ScriptCache *psc, OPENTYPE_TAG searchingFo
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void GSUB_initialize_language_cache(LoadedScript *script)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!script->language_count)
|
||||||
|
{
|
||||||
|
const GSUB_Script* table = script->table;
|
||||||
|
script->language_count = GET_BE_WORD(table->LangSysCount);
|
||||||
|
script->default_language.tag = MS_MAKE_TAG('d','f','l','t');
|
||||||
|
script->default_language.table = (const BYTE*)table + GET_BE_WORD(table->DefaultLangSys);
|
||||||
|
|
||||||
|
TRACE("Deflang %p, LangCount %i\n",script->default_language.table, script->language_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].table = ((const BYTE*)table + offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT GSUB_GetFontLanguageTags(ScriptCache *psc, OPENTYPE_TAG script_tag, OPENTYPE_TAG searchingFor, int cMaxTags, OPENTYPE_TAG *pLanguageTags, int *pcTags, LPCVOID* language_table)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
HRESULT rc = S_OK;
|
||||||
|
LoadedScript *script = NULL;
|
||||||
|
|
||||||
|
GSUB_initialize_script_cache(psc);
|
||||||
|
|
||||||
|
for (i = 0; i < psc->script_count; i++)
|
||||||
|
{
|
||||||
|
if (psc->scripts[i].tag == script_tag)
|
||||||
|
{
|
||||||
|
script = &psc->scripts[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!script)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
GSUB_initialize_language_cache(script);
|
||||||
|
|
||||||
|
if (!searchingFor && cMaxTags < script->language_count)
|
||||||
|
rc = E_OUTOFMEMORY;
|
||||||
|
else if (searchingFor)
|
||||||
|
rc = E_INVALIDARG;
|
||||||
|
|
||||||
|
*pcTags = script->language_count;
|
||||||
|
|
||||||
|
for (i = 0; i < script->language_count; i++)
|
||||||
|
{
|
||||||
|
if (i < cMaxTags)
|
||||||
|
pLanguageTags[i] = script->languages[i].tag;
|
||||||
|
|
||||||
|
if (searchingFor)
|
||||||
|
{
|
||||||
|
if (searchingFor == script->languages[i].tag)
|
||||||
|
{
|
||||||
|
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 (i < cMaxTags)
|
||||||
|
pLanguageTags[i] = script->default_language.tag;
|
||||||
|
|
||||||
|
if (searchingFor && FAILED(rc))
|
||||||
|
{
|
||||||
|
pLanguageTags[0] = script->default_language.tag;
|
||||||
|
if (language_table)
|
||||||
|
*language_table = script->default_language.table;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
*pcTags = (*pcTags) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT SHAPE_GetFontScriptTags( HDC hdc, ScriptCache *psc,
|
HRESULT SHAPE_GetFontScriptTags( HDC hdc, ScriptCache *psc,
|
||||||
SCRIPT_ANALYSIS *psa, int cMaxTags,
|
SCRIPT_ANALYSIS *psa, int cMaxTags,
|
||||||
OPENTYPE_TAG *pScriptTags, int *pcTags)
|
OPENTYPE_TAG *pScriptTags, int *pcTags)
|
||||||
|
@ -3840,3 +3930,32 @@ HRESULT SHAPE_GetFontScriptTags( HDC hdc, ScriptCache *psc,
|
||||||
*pcTags = 0;
|
*pcTags = 0;
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT SHAPE_GetFontLanguageTags( HDC hdc, ScriptCache *psc,
|
||||||
|
SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript,
|
||||||
|
int cMaxTags, OPENTYPE_TAG *pLangSysTags,
|
||||||
|
int *pcTags)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
OPENTYPE_TAG searching = 0x00000000;
|
||||||
|
BOOL fellback = FALSE;
|
||||||
|
|
||||||
|
if (!psc->GSUB_Table)
|
||||||
|
psc->GSUB_Table = load_gsub_table(hdc);
|
||||||
|
|
||||||
|
if (psa && psc->userLang != 0)
|
||||||
|
searching = psc->userLang;
|
||||||
|
|
||||||
|
hr = GSUB_GetFontLanguageTags(psc, tagScript, searching, cMaxTags, pLangSysTags, pcTags, NULL);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
fellback = TRUE;
|
||||||
|
hr = GSUB_GetFontLanguageTags(psc, MS_MAKE_TAG('l','a','t','n'), searching, cMaxTags, pLangSysTags, pcTags, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr) || fellback)
|
||||||
|
*pcTags = 0;
|
||||||
|
if (SUCCEEDED(hr) && fellback && psa)
|
||||||
|
hr = E_INVALIDARG;
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ static HRESULT (WINAPI *pScriptShapeOpenType)( HDC hdc, SCRIPT_CACHE *psc, SCRIP
|
||||||
static DWORD (WINAPI *pGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags);
|
static DWORD (WINAPI *pGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags);
|
||||||
|
|
||||||
static HRESULT (WINAPI *pScriptGetFontScriptTags)( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags);
|
static HRESULT (WINAPI *pScriptGetFontScriptTags)( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags);
|
||||||
|
static HRESULT (WINAPI *pScriptGetFontLanguageTags)( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, int cMaxTags, OPENTYPE_TAG *pLangSysTags, int *pcTags);
|
||||||
|
|
||||||
static inline void _test_items_ok(LPCWSTR string, DWORD cchString,
|
static inline void _test_items_ok(LPCWSTR string, DWORD cchString,
|
||||||
SCRIPT_CONTROL *Control, SCRIPT_STATE *State,
|
SCRIPT_CONTROL *Control, SCRIPT_STATE *State,
|
||||||
|
@ -2871,9 +2872,10 @@ static void test_ScriptGetFontFunctions(HDC hdc)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
pScriptGetFontScriptTags = (void*)GetProcAddress(GetModuleHandleA("usp10.dll"), "ScriptGetFontScriptTags");
|
pScriptGetFontScriptTags = (void*)GetProcAddress(GetModuleHandleA("usp10.dll"), "ScriptGetFontScriptTags");
|
||||||
if (!pScriptGetFontScriptTags)
|
pScriptGetFontLanguageTags = (void*)GetProcAddress(GetModuleHandleA("usp10.dll"), "ScriptGetFontLanguageTags");
|
||||||
|
if (!pScriptGetFontScriptTags || !pScriptGetFontLanguageTags)
|
||||||
{
|
{
|
||||||
win_skip("ScriptGetFontScriptTags not available on this platform\n");
|
win_skip("ScriptGetFontScriptTags or ScriptGetFontLanguageTags not available on this platform\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2909,6 +2911,31 @@ static void test_ScriptGetFontFunctions(HDC hdc)
|
||||||
ok(count == 0, "Count should be 0 with E_OUTOFMEMORY return\n");
|
ok(count == 0, "Count should be 0 with E_OUTOFMEMORY return\n");
|
||||||
ok(sc != NULL, "ScriptCache should be initialized\n");
|
ok(sc != NULL, "ScriptCache should be initialized\n");
|
||||||
|
|
||||||
|
ScriptFreeCache(&sc);
|
||||||
|
sc = NULL;
|
||||||
|
|
||||||
|
hr = pScriptGetFontLanguageTags(hdc, &sc, NULL, latn_tag, 0, NULL, NULL);
|
||||||
|
ok(hr == E_INVALIDARG,"Incorrect return code\n");
|
||||||
|
ok(sc == NULL, "ScriptCache should remain uninitialized\n");
|
||||||
|
hr = pScriptGetFontLanguageTags(hdc, &sc, NULL, latn_tag, 0, NULL, &count);
|
||||||
|
ok(hr == E_INVALIDARG,"Incorrect return code\n");
|
||||||
|
ok(sc == NULL, "ScriptCache should remain uninitialized\n");
|
||||||
|
hr = pScriptGetFontLanguageTags(hdc, &sc, NULL, latn_tag, 5, tags, NULL);
|
||||||
|
ok(hr == E_INVALIDARG,"Incorrect return code\n");
|
||||||
|
ok(sc == NULL, "ScriptCache should remain uninitialized\n");
|
||||||
|
hr = pScriptGetFontLanguageTags(hdc, &sc, NULL, latn_tag, 0, tags, &count);
|
||||||
|
ok(hr == E_INVALIDARG,"Incorrect return code\n");
|
||||||
|
ok(sc == NULL, "ScriptCache should remain uninitialized\n");
|
||||||
|
hr = pScriptGetFontLanguageTags(NULL, &sc, NULL, latn_tag, 5, tags, &count);
|
||||||
|
ok(hr == E_PENDING,"Incorrect return code\n");
|
||||||
|
ok(sc == NULL, "ScriptCache should remain uninitialized\n");
|
||||||
|
hr = pScriptGetFontLanguageTags(hdc, &sc, NULL, latn_tag, 5, tags, &count);
|
||||||
|
ok((hr == S_OK || hr == E_OUTOFMEMORY),"Incorrect return code\n");
|
||||||
|
if (hr == S_OK)
|
||||||
|
ok(count <= 5, "Count should be less or equal to 5 with S_OK return\n");
|
||||||
|
else if (hr == E_OUTOFMEMORY)
|
||||||
|
ok(count == 0, "Count should be 0 with E_OUTOFMEMORY return\n");
|
||||||
|
|
||||||
memset(&Control, 0, sizeof(Control));
|
memset(&Control, 0, sizeof(Control));
|
||||||
memset(&State, 0, sizeof(State));
|
memset(&State, 0, sizeof(State));
|
||||||
|
|
||||||
|
@ -2917,6 +2944,12 @@ static void test_ScriptGetFontFunctions(HDC hdc)
|
||||||
memset(tags,0,sizeof(tags));
|
memset(tags,0,sizeof(tags));
|
||||||
hr = pScriptGetFontScriptTags(hdc, &sc, &outpItems[0].a, 5, tags, &count);
|
hr = pScriptGetFontScriptTags(hdc, &sc, &outpItems[0].a, 5, tags, &count);
|
||||||
ok( hr == USP_E_SCRIPT_NOT_IN_FONT || broken(hr == S_OK), "wrong return code\n");
|
ok( hr == USP_E_SCRIPT_NOT_IN_FONT || broken(hr == S_OK), "wrong return code\n");
|
||||||
|
|
||||||
|
hr = pScriptGetFontLanguageTags(hdc, &sc, NULL, dsrt_tag, 5, tags, &count);
|
||||||
|
ok( hr == S_OK, "wrong return code\n");
|
||||||
|
hr = pScriptGetFontLanguageTags(hdc, &sc, &outpItems[0].a, dsrt_tag, 5, tags, &count);
|
||||||
|
ok( hr == E_INVALIDARG || broken(hr == S_OK), "wrong return code\n");
|
||||||
|
|
||||||
ScriptFreeCache(&sc);
|
ScriptFreeCache(&sc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -925,6 +925,8 @@ HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
|
||||||
heap_free(((ScriptCache *)*psc)->GSUB_Table);
|
heap_free(((ScriptCache *)*psc)->GSUB_Table);
|
||||||
heap_free(((ScriptCache *)*psc)->GDEF_Table);
|
heap_free(((ScriptCache *)*psc)->GDEF_Table);
|
||||||
heap_free(((ScriptCache *)*psc)->CMAP_Table);
|
heap_free(((ScriptCache *)*psc)->CMAP_Table);
|
||||||
|
for (i = 0; i < ((ScriptCache *)*psc)->script_count; i++)
|
||||||
|
heap_free(((ScriptCache *)*psc)->scripts[i].languages);
|
||||||
heap_free(((ScriptCache *)*psc)->scripts);
|
heap_free(((ScriptCache *)*psc)->scripts);
|
||||||
heap_free(((ScriptCache *)*psc)->features);
|
heap_free(((ScriptCache *)*psc)->features);
|
||||||
heap_free(*psc);
|
heap_free(*psc);
|
||||||
|
@ -3552,3 +3554,12 @@ HRESULT WINAPI ScriptGetFontScriptTags( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALY
|
||||||
|
|
||||||
return SHAPE_GetFontScriptTags(hdc, (ScriptCache *)*psc, psa, cMaxTags, pScriptTags, pcTags);
|
return SHAPE_GetFontScriptTags(hdc, (ScriptCache *)*psc, psa, cMaxTags, pScriptTags, pcTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT WINAPI ScriptGetFontLanguageTags( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, int cMaxTags, OPENTYPE_TAG *pLangSysTags, int *pcTags)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
if (!pLangSysTags || !pcTags || cMaxTags == 0) return E_INVALIDARG;
|
||||||
|
if ((hr = init_script_cache(hdc, psc)) != S_OK) return hr;
|
||||||
|
|
||||||
|
return SHAPE_GetFontLanguageTags(hdc, (ScriptCache *)*psc, psa, tagScript, cMaxTags, pLangSysTags, pcTags);
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
@ stdcall ScriptGetCMap(ptr ptr ptr long long ptr)
|
@ stdcall ScriptGetCMap(ptr ptr ptr long long ptr)
|
||||||
@ stub ScriptGetFontAlternateGlyphs
|
@ stub ScriptGetFontAlternateGlyphs
|
||||||
@ stub ScriptGetFontFeatureTags
|
@ stub ScriptGetFontFeatureTags
|
||||||
@ stub ScriptGetFontLanguageTags
|
@ stdcall ScriptGetFontLanguageTags(long ptr ptr long long ptr ptr)
|
||||||
@ stdcall ScriptGetFontProperties(long ptr ptr)
|
@ stdcall ScriptGetFontProperties(long ptr ptr)
|
||||||
@ stdcall ScriptGetFontScriptTags(long ptr ptr long ptr ptr)
|
@ stdcall ScriptGetFontScriptTags(long ptr ptr long ptr ptr)
|
||||||
@ stdcall ScriptGetGlyphABCWidth(ptr ptr long ptr)
|
@ stdcall ScriptGetGlyphABCWidth(ptr ptr long ptr)
|
||||||
|
|
|
@ -134,6 +134,14 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
OPENTYPE_TAG tag;
|
OPENTYPE_TAG tag;
|
||||||
LPCVOID table;
|
LPCVOID table;
|
||||||
|
} LoadedLanguage;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
OPENTYPE_TAG tag;
|
||||||
|
LPCVOID table;
|
||||||
|
LoadedLanguage default_language;
|
||||||
|
INT language_count;
|
||||||
|
LoadedLanguage *languages;
|
||||||
} LoadedScript;
|
} LoadedScript;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -204,6 +212,7 @@ HRESULT SHAPE_CheckFontForRequiredFeatures(HDC hdc, ScriptCache *psc, SCRIPT_ANA
|
||||||
void SHAPE_CharGlyphProp(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp) DECLSPEC_HIDDEN;
|
void SHAPE_CharGlyphProp(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, const WCHAR* pwcChars, const INT cChars, const WORD* pwGlyphs, const INT cGlyphs, WORD *pwLogClust, SCRIPT_CHARPROP *pCharProp, SCRIPT_GLYPHPROP *pGlyphProp) DECLSPEC_HIDDEN;
|
||||||
INT SHAPE_does_GSUB_feature_apply_to_chars(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, const WCHAR *chars, INT write_dir, INT count, const char* feature) DECLSPEC_HIDDEN;
|
INT SHAPE_does_GSUB_feature_apply_to_chars(HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, const WCHAR *chars, INT write_dir, INT count, const char* feature) DECLSPEC_HIDDEN;
|
||||||
HRESULT SHAPE_GetFontScriptTags( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags) DECLSPEC_HIDDEN;
|
HRESULT SHAPE_GetFontScriptTags( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, int cMaxTags, OPENTYPE_TAG *pScriptTags, int *pcTags) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT SHAPE_GetFontLanguageTags( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, OPENTYPE_TAG tagScript, int cMaxTags, OPENTYPE_TAG *pLangSysTags, int *pcTags) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
void Indic_ReorderCharacters( HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, LPWSTR input, int cChars, IndicSyllable **syllables, int *syllable_count, lexical_function lexical_f, reorder_function reorder_f, BOOL modern) DECLSPEC_HIDDEN;
|
void Indic_ReorderCharacters( HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, LPWSTR input, int cChars, IndicSyllable **syllables, int *syllable_count, lexical_function lexical_f, reorder_function reorder_f, BOOL modern) DECLSPEC_HIDDEN;
|
||||||
void Indic_ParseSyllables( HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, LPCWSTR input, const int cChar, IndicSyllable **syllables, int *syllable_count, lexical_function lex, BOOL modern) DECLSPEC_HIDDEN;
|
void Indic_ParseSyllables( HDC hdc, SCRIPT_ANALYSIS *psa, ScriptCache* psc, LPCWSTR input, const int cChar, IndicSyllable **syllables, int *syllable_count, lexical_function lex, BOOL modern) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue