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