From 858ecd1c54a3ee5da2a072dfb93ecd5009cb45ea Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Thu, 2 Jun 2011 14:56:37 -0500 Subject: [PATCH] usp10: Add Gujarati script. --- dlls/usp10/shape.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ dlls/usp10/tests/usp10.c | 11 +++++++++ dlls/usp10/usp10.c | 14 ++++++++++- dlls/usp10/usp10_internal.h | 3 +++ 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/dlls/usp10/shape.c b/dlls/usp10/shape.c index db8602c3bb1..5998e5ad782 100644 --- a/dlls/usp10/shape.c +++ b/dlls/usp10/shape.c @@ -47,6 +47,7 @@ static void ContextualShape_Sinhala(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS * static void ContextualShape_Devanagari(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust); static void ContextualShape_Bengali(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust); static void ContextualShape_Gurmukhi(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust); +static void ContextualShape_Gujarati(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust); typedef VOID (*ShapeCharGlyphPropProc)( HDC , ScriptCache*, SCRIPT_ANALYSIS*, const WCHAR*, const INT, const WORD*, const INT, WORD*, SCRIPT_CHARPROP*, SCRIPT_GLYPHPROP*); @@ -59,6 +60,7 @@ static void ShapeCharGlyphProp_Tibet( HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS static void ShapeCharGlyphProp_Devanagari( 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 ); static void ShapeCharGlyphProp_Bengali( 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 ); static void ShapeCharGlyphProp_Gurmukhi( 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 ); +static void ShapeCharGlyphProp_Gujarati( 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 ); extern const unsigned short wine_shaping_table[]; extern const unsigned short wine_shaping_forms[LAST_ARABIC_CHAR - FIRST_ARABIC_CHAR + 1][4]; @@ -552,6 +554,9 @@ static const ScriptShapeData ShapingData[] = {{ bengali_features, 16}, required_bengali_features, "beng", "bng2", ContextualShape_Bengali, ShapeCharGlyphProp_Bengali}, {{ gurmukhi_features, 15}, required_gurmukhi_features, "guru", "gur2", ContextualShape_Gurmukhi, ShapeCharGlyphProp_Gurmukhi}, {{ gurmukhi_features, 15}, required_gurmukhi_features, "guru", "gur2", ContextualShape_Gurmukhi, ShapeCharGlyphProp_Gurmukhi}, + {{ devanagari_features, 15}, required_devanagari_features, "gujr", "gjr2", ContextualShape_Gujarati, ShapeCharGlyphProp_Gujarati}, + {{ devanagari_features, 15}, required_devanagari_features, "gujr", "gjr2", ContextualShape_Gujarati, ShapeCharGlyphProp_Gujarati}, + {{ devanagari_features, 15}, required_devanagari_features, "gujr", "gjr2", ContextualShape_Gujarati, ShapeCharGlyphProp_Gujarati}, }; static INT GSUB_is_glyph_covered(LPCVOID table , UINT glyph) @@ -2095,6 +2100,55 @@ static void ContextualShape_Gurmukhi(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS HeapFree(GetProcessHeap(),0,input); } +static int gujarati_lex(WCHAR c) +{ + switch (c) + { + case 0x0A83: return lex_Modifier; + case 0x0AB0: return lex_Ra; + case 0x0ABC: return lex_Nukta; + case 0x0ABF: return lex_Mantra_pre; + case 0x0ABE: + case 0x0AC0: return lex_Mantra_post; + case 0x0ACD: return lex_Halant; + case 0x200C: return lex_ZWNJ; + case 0x200D: return lex_ZWJ; + default: + if (c>=0x0A81 && c<=0x0A82) return lex_Modifier; + else if (c>=0x0A85 && c<=0x0A94) return lex_Vowel; + else if (c>=0x0A95 && c<=0x0AB9) return lex_Consonant; + else if (c>=0x0AC1 && c<=0x0AC4) return lex_Mantra_below; + else if (c>=0x0AC5 && c<=0x0AC8) return lex_Mantra_above; + else if (c>=0x0AC9 && c<=0x0ACC) return lex_Mantra_post; + else if (c>=0x0AE0 && c<=0x0AE1) return lex_Vowel; + else if (c>=0x0AE2 && c<=0x0AE3) return lex_Mantra_below; + else return lex_Generic; + } +} + +static void ContextualShape_Gujarati(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust) +{ + int cCount = cChars; + WCHAR *input; + + if (*pcGlyphs != cChars) + { + ERR("Number of Glyphs and Chars need to match at the beginning\n"); + return; + } + + input = HeapAlloc(GetProcessHeap(), 0, cChars * sizeof(WCHAR)); + memcpy(input, pwcChars, cChars * sizeof(WCHAR)); + + /* Step 1: Reorder within Syllables */ + Indic_ReorderCharacters( input, cCount, gujarati_lex, Reorder_Like_Devanagari); + TRACE("reordered string %s\n",debugstr_wn(input,cCount)); + GetGlyphIndicesW(hdc, input, cCount, pwOutGlyphs, 0); + *pcGlyphs = cCount; + + HeapFree(GetProcessHeap(),0,input); +} + static void ShapeCharGlyphProp_Default( 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) { int i,k; @@ -2468,6 +2522,11 @@ static void ShapeCharGlyphProp_Gurmukhi( HDC hdc, ScriptCache *psc, SCRIPT_ANALY ShapeCharGlyphProp_BaseIndic(hdc, psc, psa, pwcChars, cChars, pwGlyphs, cGlyphs, pwLogClust, pCharProp, pGlyphProp, gurmukhi_lex); } +static void ShapeCharGlyphProp_Gujarati( 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 ) +{ + ShapeCharGlyphProp_BaseIndic(hdc, psc, psa, pwcChars, cChars, pwGlyphs, cGlyphs, pwLogClust, pCharProp, pGlyphProp, gujarati_lex); +} + 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) { if (ShapingData[psa->eScript].charGlyphPropProc) diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c index 789b9e04819..583b69e1bc7 100644 --- a/dlls/usp10/tests/usp10.c +++ b/dlls/usp10/tests/usp10.c @@ -129,6 +129,7 @@ static inline void _test_items_ok(LPCWSTR string, DWORD cchString, #define deva_tag MS_MAKE_TAG('d','e','v','a') #define beng_tag MS_MAKE_TAG('b','e','n','g') #define guru_tag MS_MAKE_TAG('g','u','r','u') +#define gujr_tag MS_MAKE_TAG('g','u','j','r') static void test_ScriptItemize( void ) { @@ -225,6 +226,12 @@ static void test_ScriptItemize( void ) static const itemTest t131[2] = {{{0,0,0,0,0},0,0,0,0,guru_tag},{{0,0,0,0,0},7,0,0,0,-1}}; static const itemTest t132[2] = {{{0,0,0,0,0},0,0,0,2,guru_tag},{{0,0,0,0,0},7,0,0,0,-1}}; + /* Gujarati */ + static const WCHAR test14[] = {0x0a97, 0x0ac1, 0x0a9c, 0x0ab0, 0x0abe, 0x0aa4, 0x0ac0}; + static const itemTest t141[2] = {{{0,0,0,0,0},0,0,0,0,gujr_tag},{{0,0,0,0,0},7,0,0,0,-1}}; + static const itemTest t142[2] = {{{0,0,0,0,0},0,0,0,2,gujr_tag},{{0,0,0,0,0},7,0,0,0,-1}}; + + SCRIPT_ITEM items[15]; SCRIPT_CONTROL Control; @@ -271,6 +278,7 @@ static void test_ScriptItemize( void ) test_items_ok(test11,8,NULL,NULL,1,t111,FALSE,0); test_items_ok(test12,5,NULL,NULL,1,t121,FALSE,0); test_items_ok(test13,7,NULL,NULL,1,t131,FALSE,0); + test_items_ok(test14,7,NULL,NULL,1,t141,FALSE,0); State.uBidiLevel = 0; test_items_ok(test1,4,&Control,&State,1,t11,FALSE,0); @@ -290,6 +298,7 @@ static void test_ScriptItemize( void ) test_items_ok(test11,8,&Control,&State,1,t111,FALSE,0); test_items_ok(test12,5,&Control,&State,1,t121,FALSE,0); test_items_ok(test13,7,&Control,&State,1,t131,FALSE,0); + test_items_ok(test14,7,&Control,&State,1,t141,FALSE,0); State.uBidiLevel = 1; test_items_ok(test1,4,&Control,&State,1,t12,FALSE,0); @@ -309,6 +318,7 @@ static void test_ScriptItemize( void ) test_items_ok(test11,8,&Control,&State,1,t112,FALSE,0); test_items_ok(test12,5,&Control,&State,1,t122,FALSE,0); test_items_ok(test13,7,&Control,&State,1,t132,FALSE,0); + test_items_ok(test14,7,&Control,&State,1,t142,FALSE,0); State.uBidiLevel = 1; Control.fMergeNeutralItems = TRUE; @@ -329,6 +339,7 @@ static void test_ScriptItemize( void ) test_items_ok(test11,8,&Control,&State,1,t112,FALSE,0); test_items_ok(test12,5,&Control,&State,1,t122,FALSE,0); test_items_ok(test13,7,&Control,&State,1,t132,FALSE,0); + test_items_ok(test14,7,&Control,&State,1,t142,FALSE,0); } static inline void _test_shape_ok(int valid, HDC hdc, LPCWSTR string, diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index bd2314dbdf0..09f4618bb26 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -83,6 +83,8 @@ static const scriptRange scriptRanges[] = { { Script_Bengali, 0x980, 0x9ff, Script_Bengali_Numeric, 0}, /* Gurmukhi: U+0A00–U+0A7F*/ { Script_Gurmukhi, 0xa00, 0xa7f, Script_Gurmukhi_Numeric, 0}, + /* Gujarati: U+0A80–U+0AFF*/ + { Script_Gujarati, 0xa80, 0xaff, Script_Gujarati_Numeric, 0}, /* Sinhala: U+0D80–U+0DFF */ { Script_Sinhala, 0xd80, 0xdff, 0, 0}, /* Thai: U+0E00–U+0E7F */ @@ -232,6 +234,15 @@ static const scriptData scriptInformation[] = { {{Script_Gurmukhi_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}}, {LANG_PUNJABI, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0}, MS_MAKE_TAG('g','u','r','u')}, + {{Script_Gujarati, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}}, + {LANG_GUJARATI, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 0, 0}, + MS_MAKE_TAG('g','u','j','r')}, + {{Script_Gujarati_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}}, + {LANG_GUJARATI, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + MS_MAKE_TAG('g','u','j','r')}, + {{Script_Gujarati_Currency, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}}, + {LANG_GUJARATI, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + MS_MAKE_TAG('g','u','j','r')}, }; static const SCRIPT_PROPERTIES *script_props[] = @@ -251,7 +262,8 @@ static const SCRIPT_PROPERTIES *script_props[] = &scriptInformation[24].props, &scriptInformation[25].props, &scriptInformation[26].props, &scriptInformation[27].props, &scriptInformation[28].props, &scriptInformation[29].props, - &scriptInformation[30].props + &scriptInformation[30].props, &scriptInformation[31].props, + &scriptInformation[32].props, &scriptInformation[33].props }; typedef struct { diff --git a/dlls/usp10/usp10_internal.h b/dlls/usp10/usp10_internal.h index d5c9a260583..b1d259b063b 100644 --- a/dlls/usp10/usp10_internal.h +++ b/dlls/usp10/usp10_internal.h @@ -58,6 +58,9 @@ #define Script_Bengali_Currency 28 #define Script_Gurmukhi 29 #define Script_Gurmukhi_Numeric 30 +#define Script_Gujarati 31 +#define Script_Gujarati_Numeric 32 +#define Script_Gujarati_Currency 33 #define GLYPH_BLOCK_SHIFT 8 #define GLYPH_BLOCK_SIZE (1UL << GLYPH_BLOCK_SHIFT) -- 2.11.4.GIT