Aric Stewart : gdi32: Load the vertical feature when loading the GSUB table .
Alexandre Julliard
julliard at winehq.org
Tue May 21 13:56:27 CDT 2013
Module: wine
Branch: master
Commit: accad0957c18da3afa1406ffcd8969436ce1c86e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=accad0957c18da3afa1406ffcd8969436ce1c86e
Author: Aric Stewart <aric at codeweavers.com>
Date: Mon May 20 11:24:21 2013 -0500
gdi32: Load the vertical feature when loading the GSUB table.
---
dlls/gdi32/freetype.c | 257 +++++++++++++++++++++++++++----------------------
1 files changed, 140 insertions(+), 117 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index ea13c37..b0a124f 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -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);
}
More information about the wine-cvs
mailing list