usp10: Add Mongolian script.

This commit is contained in:
Aric Stewart 2011-12-14 07:27:56 -06:00 committed by Alexandre Julliard
parent eb084562be
commit be9369e7fe
4 changed files with 104 additions and 1 deletions

View File

@ -54,6 +54,7 @@ static void ContextualShape_Telugu(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *p
static void ContextualShape_Kannada(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust);
static void ContextualShape_Malayalam(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust);
static void ContextualShape_Khmer(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust);
static void ContextualShape_Mongolian(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*);
@ -581,6 +582,14 @@ static OPENTYPE_FEATURE_RECORD ethiopic_features[] =
{ MS_MAKE_TAG('l','i','g','a'), 1},
};
static OPENTYPE_FEATURE_RECORD mongolian_features[] =
{
{ MS_MAKE_TAG('c','c','m','p'), 1},
{ MS_MAKE_TAG('l','o','c','l'), 1},
{ MS_MAKE_TAG('c','a','l','t'), 1},
{ MS_MAKE_TAG('r','l','i','g'), 1},
};
typedef struct ScriptShapeDataTag {
TEXTRANGE_PROPERTIES defaultTextRange;
const char** requiredFeatures;
@ -655,6 +664,8 @@ static const ScriptShapeData ShapingData[] =
{{ no_features, 0}, NULL, "yi ", "", NULL, NULL},
{{ ethiopic_features, 4}, NULL, "ethi", "", NULL, NULL},
{{ ethiopic_features, 4}, NULL, "ethi", "", NULL, NULL},
{{ mongolian_features, 4}, NULL, "mong", "", ContextualShape_Mongolian, NULL},
{{ mongolian_features, 4}, NULL, "mong", "", ContextualShape_Mongolian, NULL},
};
static INT GSUB_is_glyph_covered(LPCVOID table , UINT glyph)
@ -3048,6 +3059,73 @@ static void ContextualShape_Khmer(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *ps
HeapFree(GetProcessHeap(),0,syllables);
}
static inline BOOL mongolian_wordbreak(WCHAR chr)
{
return ((chr == 0x0020) || (chr == 0x200C) || (chr == 0x202F) || (chr == 0x180E) || (chr == 0x1800) || (chr == 0x1802) || (chr == 0x1803) || (chr == 0x1805) || (chr == 0x1808) || (chr == 0x1809) || (chr == 0x1807));
}
static void ContextualShape_Mongolian(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust)
{
INT *context_shape;
INT dirL;
int i;
if (*pcGlyphs != cChars)
{
ERR("Number of Glyphs and Chars need to match at the beginning\n");
return;
}
if (!psa->fLogicalOrder && psa->fRTL)
dirL = -1;
else
dirL = 1;
if (!psc->GSUB_Table)
psc->GSUB_Table = load_gsub_table(hdc);
if (!psc->GSUB_Table)
return;
context_shape = HeapAlloc(GetProcessHeap(),0,sizeof(INT) * cChars);
for (i = 0; i < cChars; i++)
{
if (i == 0 || mongolian_wordbreak(pwcChars[i-1]))
{
if ((i == cChars-1) || mongolian_wordbreak(pwcChars[i+1]))
context_shape[i] = Xn;
else
context_shape[i] = Xl;
}
else
{
if ((i == cChars-1) || mongolian_wordbreak(pwcChars[i+1]))
context_shape[i] = Xr;
else
context_shape[i] = Xm;
}
}
/* Contextual Shaping */
i = 0;
while(i < *pcGlyphs)
{
INT nextIndex;
INT prevCount = *pcGlyphs;
nextIndex = apply_GSUB_feature_to_glyph(hdc, psa, psc, pwOutGlyphs, i, dirL, pcGlyphs, contextual_features[context_shape[i]]);
if (nextIndex > GSUB_E_NOGLYPH)
{
UpdateClusters(nextIndex, *pcGlyphs - prevCount, dirL, cChars, pwLogClust);
i = nextIndex;
}
else
i++;
}
HeapFree(GetProcessHeap(),0,context_shape);
}
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;

View File

@ -159,6 +159,7 @@ static inline void _test_items_ok(LPCWSTR string, DWORD cchString,
#define hang_tag MS_MAKE_TAG('h','a','n','g')
#define yi_tag MS_MAKE_TAG('y','i',' ',' ')
#define ethi_tag MS_MAKE_TAG('e','t','h','i')
#define mong_tag MS_MAKE_TAG('m','o','n','g')
static void test_ScriptItemize( void )
{
@ -372,6 +373,13 @@ static void test_ScriptItemize( void )
static const itemTest t342[2] = {{{0,0,0,0,0},0,0,0,2,ethi_tag,FALSE},{{0,0,0,0,0},3,0,0,0,-1,FALSE}};
static const int b342[2] = {2,2};
/* Mongolian */
static const WCHAR test35[] = {0x182e,0x1823,0x1829,0x182d,0x1823,0x182f,0x0020,0x182a,0x1822,0x1834,0x1822,0x182d,0x180c};
static const itemTest t351[2] = {{{0,0,0,0,0},0,0,0,0,mong_tag,FALSE},{{0,0,0,0,0},13,0,0,0,-1,FALSE}};
static const itemTest t352[2] = {{{0,0,0,0,0},0,0,0,2,mong_tag,TRUE,{-1,1,1,1,-1}},{{0,0,0,0,0},13,0,0,0,-1,FALSE}};
static const int b351[2] = {2,2};
static const int b352[2] = {2,3};
SCRIPT_ITEM items[15];
SCRIPT_CONTROL Control;
SCRIPT_STATE State;
@ -439,6 +447,7 @@ static void test_ScriptItemize( void )
test_items_ok(test32,3,NULL,NULL,1,t321,FALSE,0);
test_items_ok(test33,4,NULL,NULL,1,t331,FALSE,0);
test_items_ok(test34,3,NULL,NULL,1,t341,FALSE,0);
test_items_ok(test35,13,NULL,NULL,1,t351,FALSE,b351);
State.uBidiLevel = 0;
test_items_ok(test1,4,&Control,&State,1,t11,FALSE,0);
@ -480,6 +489,7 @@ static void test_ScriptItemize( void )
test_items_ok(test32,3,&Control,&State,1,t321,FALSE,0);
test_items_ok(test33,4,&Control,&State,1,t331,FALSE,0);
test_items_ok(test34,3,&Control,&State,1,t341,FALSE,0);
test_items_ok(test35,13,&Control,&State,1,t351,FALSE,b351);
State.uBidiLevel = 1;
test_items_ok(test1,4,&Control,&State,1,t12,FALSE,0);
@ -521,6 +531,7 @@ static void test_ScriptItemize( void )
test_items_ok(test32,3,&Control,&State,1,t322,FALSE,0);
test_items_ok(test33,4,&Control,&State,1,t332,FALSE,0);
test_items_ok(test34,3,&Control,&State,1,t342,FALSE,b342);
test_items_ok(test35,13,&Control,&State,1,t352,FALSE,b352);
State.uBidiLevel = 1;
Control.fMergeNeutralItems = TRUE;
@ -563,6 +574,7 @@ static void test_ScriptItemize( void )
test_items_ok(test32,3,&Control,&State,1,t322,FALSE,0);
test_items_ok(test33,4,&Control,&State,1,t332,FALSE,0);
test_items_ok(test34,3,&Control,&State,1,t342,FALSE,b342);
test_items_ok(test35,13,&Control,&State,1,t352,FALSE,b352);
}
static inline void _test_shape_ok(int valid, HDC hdc, LPCWSTR string,

View File

@ -118,6 +118,8 @@ static const scriptRange scriptRanges[] = {
{ Script_Ethiopic, 0x1200, 0x139f, 0, 0},
/* Khmer: U+1780U+17FF */
{ Script_Khmer, 0x1780, 0x17ff, Script_Khmer_Numeric, 0},
/* Mongolian: U+1800U+18AF */
{ Script_Mongolian, 0x1800, 0x18af, Script_Mongolian_Numeric, 0},
/* Tai Le: U+1950U+197F */
{ Script_Tai_Le, 0x1950, 0x197f, 0, 0},
/* New Tai Lue: U+1980U+19DF */
@ -522,6 +524,14 @@ static const scriptData scriptInformation[] = {
{0x5e, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
MS_MAKE_TAG('e','t','h','i'),
{'N','y','a','l','a'}},
{{Script_Mongolian, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_MONGOLIAN, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
MS_MAKE_TAG('m','o','n','g'),
{'M','o','n','g','o','l','i','a','n',' ','B','a','i','t','i'}},
{{Script_Mongolian_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
{LANG_MONGOLIAN, 1, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
MS_MAKE_TAG('m','o','n','g'),
{'M','o','n','g','o','l','i','a','n',' ','B','a','i','t','i'}},
};
static const SCRIPT_PROPERTIES *script_props[] =
@ -556,7 +566,8 @@ static const SCRIPT_PROPERTIES *script_props[] =
&scriptInformation[54].props, &scriptInformation[55].props,
&scriptInformation[56].props, &scriptInformation[57].props,
&scriptInformation[58].props, &scriptInformation[59].props,
&scriptInformation[60].props, &scriptInformation[61].props
&scriptInformation[60].props, &scriptInformation[61].props,
&scriptInformation[62].props, &scriptInformation[63].props
};
typedef struct {

View File

@ -93,6 +93,8 @@
/* Unicode Chapter 13 */
#define Script_Ethiopic 60
#define Script_Ethiopic_Numeric 61
#define Script_Mongolian 62
#define Script_Mongolian_Numeric 63
#define GLYPH_BLOCK_SHIFT 8
#define GLYPH_BLOCK_SIZE (1UL << GLYPH_BLOCK_SHIFT)