gdi32: Load the vertical feature when loading the GSUB table.

This commit is contained in:
Aric Stewart 2013-05-20 11:24:21 -05:00 committed by Alexandre Julliard
parent 70cdd2ff9a
commit accad0957c
1 changed files with 140 additions and 117 deletions

View File

@ -354,6 +354,7 @@ struct tagGdiFont {
FONTSIGNATURE fs;
GdiFont *base_font;
VOID *GSUB_Table;
const VOID *vert_feature;
DWORD cache_num;
};
@ -4692,6 +4693,137 @@ done:
return ret;
}
static const GSUB_Script* GSUB_get_script_table( const GSUB_Header* header, const char* tag)
{
const GSUB_ScriptList *script;
const GSUB_Script *deflt = NULL;
int i;
script = (const GSUB_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
TRACE("%i scripts in this font\n",GET_BE_WORD(script->ScriptCount));
for (i = 0; i < GET_BE_WORD(script->ScriptCount); i++)
{
const GSUB_Script *scr;
int offset;
offset = GET_BE_WORD(script->ScriptRecord[i].Script);
scr = (const GSUB_Script*)((const BYTE*)script + offset);
if (strncmp(script->ScriptRecord[i].ScriptTag, tag,4)==0)
return scr;
if (strncmp(script->ScriptRecord[i].ScriptTag, "dflt",4)==0)
deflt = scr;
}
return deflt;
}
static const GSUB_LangSys* GSUB_get_lang_table( const GSUB_Script* script, const char* tag)
{
int i;
int offset;
const GSUB_LangSys *Lang;
TRACE("Deflang %x, LangCount %i\n",GET_BE_WORD(script->DefaultLangSys), GET_BE_WORD(script->LangSysCount));
for (i = 0; i < GET_BE_WORD(script->LangSysCount) ; i++)
{
offset = GET_BE_WORD(script->LangSysRecord[i].LangSys);
Lang = (const GSUB_LangSys*)((const BYTE*)script + offset);
if ( strncmp(script->LangSysRecord[i].LangSysTag,tag,4)==0)
return Lang;
}
offset = GET_BE_WORD(script->DefaultLangSys);
if (offset)
{
Lang = (const GSUB_LangSys*)((const BYTE*)script + offset);
return Lang;
}
return NULL;
}
static const GSUB_Feature * GSUB_get_feature(const GSUB_Header *header, const GSUB_LangSys *lang, const char* tag)
{
int i;
const GSUB_FeatureList *feature;
feature = (const GSUB_FeatureList*)((const BYTE*)header + GET_BE_WORD(header->FeatureList));
TRACE("%i features\n",GET_BE_WORD(lang->FeatureCount));
for (i = 0; i < GET_BE_WORD(lang->FeatureCount); i++)
{
int index = GET_BE_WORD(lang->FeatureIndex[i]);
if (strncmp(feature->FeatureRecord[index].FeatureTag,tag,4)==0)
{
const GSUB_Feature *feat;
feat = (const GSUB_Feature*)((const BYTE*)feature + GET_BE_WORD(feature->FeatureRecord[index].Feature));
return feat;
}
}
return NULL;
}
static const char* get_opentype_script(const GdiFont *font)
{
/*
* I am not sure if this is the correct way to generate our script tag
*/
switch (font->charset)
{
case ANSI_CHARSET: return "latn";
case BALTIC_CHARSET: return "latn"; /* ?? */
case CHINESEBIG5_CHARSET: return "hani";
case EASTEUROPE_CHARSET: return "latn"; /* ?? */
case GB2312_CHARSET: return "hani";
case GREEK_CHARSET: return "grek";
case HANGUL_CHARSET: return "hang";
case RUSSIAN_CHARSET: return "cyrl";
case SHIFTJIS_CHARSET: return "kana";
case TURKISH_CHARSET: return "latn"; /* ?? */
case VIETNAMESE_CHARSET: return "latn";
case JOHAB_CHARSET: return "latn"; /* ?? */
case ARABIC_CHARSET: return "arab";
case HEBREW_CHARSET: return "hebr";
case THAI_CHARSET: return "thai";
default: return "latn";
}
}
static const VOID * get_GSUB_vert_feature(const GdiFont *font)
{
const GSUB_Header *header;
const GSUB_Script *script;
const GSUB_LangSys *language;
const GSUB_Feature *feature;
if (!font->GSUB_Table)
return NULL;
header = font->GSUB_Table;
script = GSUB_get_script_table(header, get_opentype_script(font));
if (!script)
{
TRACE("Script not found\n");
return NULL;
}
language = GSUB_get_lang_table(script, "xxxx"); /* Need to get Lang tag */
if (!language)
{
TRACE("Language not found\n");
return NULL;
}
feature = GSUB_get_feature(header, language, "vrt2");
if (!feature)
feature = GSUB_get_feature(header, language, "vert");
if (!feature)
{
TRACE("vrt2/vert feature not found\n");
return NULL;
}
return feature;
}
/*************************************************************
* freetype_SelectFont
*/
@ -5104,6 +5236,13 @@ found_face:
ret->GSUB_Table = HeapAlloc(GetProcessHeap(),0,length);
get_font_data(ret, GSUB_TAG , 0, ret->GSUB_Table, length);
TRACE("Loaded GSUB table of %i bytes\n",length);
ret->vert_feature = get_GSUB_vert_feature(ret);
if (!ret->vert_feature)
{
TRACE("Vertical feature not found\n");
HeapFree(GetProcessHeap(), 0, ret->GSUB_Table);
ret->GSUB_Table = NULL;
}
}
}
ret->aa_flags = HIWORD( face->flags );
@ -5563,75 +5702,6 @@ static INT GSUB_is_glyph_covered(LPCVOID table , UINT glyph)
return -1;
}
static const GSUB_Script* GSUB_get_script_table( const GSUB_Header* header, const char* tag)
{
const GSUB_ScriptList *script;
const GSUB_Script *deflt = NULL;
int i;
script = (const GSUB_ScriptList*)((const BYTE*)header + GET_BE_WORD(header->ScriptList));
TRACE("%i scripts in this font\n",GET_BE_WORD(script->ScriptCount));
for (i = 0; i < GET_BE_WORD(script->ScriptCount); i++)
{
const GSUB_Script *scr;
int offset;
offset = GET_BE_WORD(script->ScriptRecord[i].Script);
scr = (const GSUB_Script*)((const BYTE*)script + offset);
if (strncmp(script->ScriptRecord[i].ScriptTag, tag,4)==0)
return scr;
if (strncmp(script->ScriptRecord[i].ScriptTag, "dflt",4)==0)
deflt = scr;
}
return deflt;
}
static const GSUB_LangSys* GSUB_get_lang_table( const GSUB_Script* script, const char* tag)
{
int i;
int offset;
const GSUB_LangSys *Lang;
TRACE("Deflang %x, LangCount %i\n",GET_BE_WORD(script->DefaultLangSys), GET_BE_WORD(script->LangSysCount));
for (i = 0; i < GET_BE_WORD(script->LangSysCount) ; i++)
{
offset = GET_BE_WORD(script->LangSysRecord[i].LangSys);
Lang = (const GSUB_LangSys*)((const BYTE*)script + offset);
if ( strncmp(script->LangSysRecord[i].LangSysTag,tag,4)==0)
return Lang;
}
offset = GET_BE_WORD(script->DefaultLangSys);
if (offset)
{
Lang = (const GSUB_LangSys*)((const BYTE*)script + offset);
return Lang;
}
return NULL;
}
static const GSUB_Feature * GSUB_get_feature(const GSUB_Header *header, const GSUB_LangSys *lang, const char* tag)
{
int i;
const GSUB_FeatureList *feature;
feature = (const GSUB_FeatureList*)((const BYTE*)header + GET_BE_WORD(header->FeatureList));
TRACE("%i features\n",GET_BE_WORD(lang->FeatureCount));
for (i = 0; i < GET_BE_WORD(lang->FeatureCount); i++)
{
int index = GET_BE_WORD(lang->FeatureIndex[i]);
if (strncmp(feature->FeatureRecord[index].FeatureTag,tag,4)==0)
{
const GSUB_Feature *feat;
feat = (const GSUB_Feature*)((const BYTE*)feature + GET_BE_WORD(feature->FeatureRecord[index].Feature));
return feat;
}
}
return NULL;
}
static FT_UInt GSUB_apply_feature(const GSUB_Header * header, const GSUB_Feature* feature, UINT glyph)
{
int i;
@ -5692,65 +5762,18 @@ static FT_UInt GSUB_apply_feature(const GSUB_Header * header, const GSUB_Feature
return glyph;
}
static const char* get_opentype_script(const GdiFont *font)
{
/*
* I am not sure if this is the correct way to generate our script tag
*/
switch (font->charset)
{
case ANSI_CHARSET: return "latn";
case BALTIC_CHARSET: return "latn"; /* ?? */
case CHINESEBIG5_CHARSET: return "hani";
case EASTEUROPE_CHARSET: return "latn"; /* ?? */
case GB2312_CHARSET: return "hani";
case GREEK_CHARSET: return "grek";
case HANGUL_CHARSET: return "hang";
case RUSSIAN_CHARSET: return "cyrl";
case SHIFTJIS_CHARSET: return "kana";
case TURKISH_CHARSET: return "latn"; /* ?? */
case VIETNAMESE_CHARSET: return "latn";
case JOHAB_CHARSET: return "latn"; /* ?? */
case ARABIC_CHARSET: return "arab";
case HEBREW_CHARSET: return "hebr";
case THAI_CHARSET: return "thai";
default: return "latn";
}
}
static FT_UInt get_GSUB_vert_glyph(const GdiFont *font, UINT glyph)
{
const GSUB_Header *header;
const GSUB_Script *script;
const GSUB_LangSys *language;
const GSUB_Feature *feature;
if (!font->GSUB_Table)
return glyph;
header = font->GSUB_Table;
feature = font->vert_feature;
script = GSUB_get_script_table(header, get_opentype_script(font));
if (!script)
{
TRACE("Script not found\n");
return glyph;
}
language = GSUB_get_lang_table(script, "xxxx"); /* Need to get Lang tag */
if (!language)
{
TRACE("Language not found\n");
return glyph;
}
feature = GSUB_get_feature(header, language, "vrt2");
if (!feature)
feature = GSUB_get_feature(header, language, "vert");
if (!feature)
{
TRACE("vrt2/vert feature not found\n");
return glyph;
}
return GSUB_apply_feature(header, feature, glyph);
}