Aric Stewart : usp10: Add Mongolian script.
Alexandre Julliard
julliard at winehq.org
Wed Dec 14 13:23:34 CST 2011
Module: wine
Branch: master
Commit: be9369e7fe9c71a8e432363811ede5ba2a7d09e8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=be9369e7fe9c71a8e432363811ede5ba2a7d09e8
Author: Aric Stewart <aric at codeweavers.com>
Date: Wed Dec 14 07:27:56 2011 -0600
usp10: Add Mongolian script.
---
dlls/usp10/shape.c | 78 +++++++++++++++++++++++++++++++++++++++++++
dlls/usp10/tests/usp10.c | 12 +++++++
dlls/usp10/usp10.c | 13 +++++++-
dlls/usp10/usp10_internal.h | 2 +
4 files changed, 104 insertions(+), 1 deletions(-)
diff --git a/dlls/usp10/shape.c b/dlls/usp10/shape.c
index 578f7ce..02457cb 100644
--- a/dlls/usp10/shape.c
+++ b/dlls/usp10/shape.c
@@ -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;
diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c
index 464dd2a..43edc76 100644
--- a/dlls/usp10/tests/usp10.c
+++ b/dlls/usp10/tests/usp10.c
@@ -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,
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 3a1ff9f..5d7ba33 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -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 {
diff --git a/dlls/usp10/usp10_internal.h b/dlls/usp10/usp10_internal.h
index aa72f08..1b3f31c 100644
--- a/dlls/usp10/usp10_internal.h
+++ b/dlls/usp10/usp10_internal.h
@@ -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)
More information about the wine-cvs
mailing list