usp10: Add Mongolian script.
This commit is contained in:
parent
eb084562be
commit
be9369e7fe
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -118,6 +118,8 @@ static const scriptRange scriptRanges[] = {
|
|||
{ Script_Ethiopic, 0x1200, 0x139f, 0, 0},
|
||||
/* Khmer: U+1780–U+17FF */
|
||||
{ Script_Khmer, 0x1780, 0x17ff, Script_Khmer_Numeric, 0},
|
||||
/* Mongolian: U+1800–U+18AF */
|
||||
{ Script_Mongolian, 0x1800, 0x18af, Script_Mongolian_Numeric, 0},
|
||||
/* Tai Le: U+1950–U+197F */
|
||||
{ Script_Tai_Le, 0x1950, 0x197f, 0, 0},
|
||||
/* New Tai Lue: U+1980–U+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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue