usp10: Factor out script ranges in an more expandable way.
authorAric Stewart <aric@codeweavers.com>
Thu, 12 Aug 2010 19:57:06 +0000 (14:57 -0500)
committerAlexandre Julliard <julliard@winehq.org>
Mon, 16 Aug 2010 13:54:22 +0000 (15:54 +0200)
dlls/usp10/shape.c
dlls/usp10/usp10.c
dlls/usp10/usp10_internal.h

index 210022d..a93eb6c 100644 (file)
@@ -655,6 +655,8 @@ static const char* get_opentype_script(HDC hdc, SCRIPT_ANALYSIS *psa)
     switch (psa->eScript)
     {
         case Script_Arabic:
+        case Script_Persian:
+        case Script_Arabic_Numeric:
             return "arab";
         case Script_Syriac:
             return "syrc";
@@ -663,7 +665,6 @@ static const char* get_opentype_script(HDC hdc, SCRIPT_ANALYSIS *psa)
         case Script_Latin:
         case Script_Numeric:
         case Script_CR:
-        case Script_LF:
             return "latn";
     }
 
@@ -834,7 +835,9 @@ void SHAPE_ShapeArabicGlyphs(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WC
     INT dirR, dirL;
     int i;
 
-    if (psa->eScript != Script_Arabic)
+    if (psa->eScript != Script_Arabic &&
+        psa->eScript != Script_Persian &&
+        psa->eScript != Script_Arabic_Numeric)
         return;
 
     if (*pcGlyphs != cChars)
index 51fbbc0..ccdd874 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(uniscribe);
 
+typedef struct _scriptRange
+{
+    WORD script;
+    WORD rangeFirst;
+    WORD rangeLast;
+    WORD numericScript;
+    WORD punctScript;
+} scriptRange;
+
+static const scriptRange scriptRanges[] = {
+
+    /* Basic Latin: U+0000–U+007A */
+    /* Latin-1 Supplement: U+0080–U+00FF */
+    /* Latin Extended-A: U+0100–U+017F */
+    /* Latin Extended-B: U+0180–U+024F */
+    /* IPA Extensions: U+0250–U+02AF */
+    { Script_Latin,      0x00,   0x2af ,  Script_Numeric, Script_Punctuation},
+    /* Hebrew: U+0590–U+05FF */
+    { Script_Hebrew,     0x590,  0x5ff,  0, 0},
+    /* Arabic: U+0600–U+06FF */
+    { Script_Arabic,     0x600,  0x6ef,  Script_Arabic_Numeric, 0},
+    /* Defined by Windows */
+    { Script_Persian,    0x6f0,  0x6f9,  0, 0},
+    /* Continue Arabic: U+0600–U+06FF */
+    { Script_Arabic,     0x6fa,  0x6ff,  0, 0},
+    /* Syriac: U+0700–U+074F*/
+    { Script_Syriac,     0x700,  0x74f,  0, 0},
+    /* Arabic Supplement: U+0750–U+077F */
+    { Script_Arabic,     0x750,  0x77f,  0, 0},
+    /* Phonetic Extensions: U+1D00–U+1DBF */
+    { Script_Latin,      0x1d00, 0x1dbf, 0, 0},
+    /* Latin Extended Additional: U+1E00–U+1EFF */
+    { Script_Latin,      0x1e00, 0x1eff, 0, 0},
+    /* Latin Extended-C: U+2C60–U+2C7F */
+    { Script_Latin,      0x2c60, 0x2c7f, 0, 0},
+    /* Modifier Tone Letters: U+A700–U+A71F */
+    /* Latin Extended-D: U+A720–U+A7FF */
+    { Script_Latin,      0xa700, 0xa7ff, 0, 0},
+    /* Latin Ligatures: U+FB00–U+FB06 */
+    { Script_Latin,      0xfb00, 0xfb06, 0, 0},
+    /* Alphabetic Presentation Forms: U+FB1D–U+FB4F */
+    { Script_Hebrew,     0xfb1d, 0xfb4f, 0, 0},
+    /* Arabic Presentation Forms-A: U+FB50–U+FDFF*/
+    { Script_Arabic,     0xfb50, 0xfdff, 0, 0},
+    /* Arabic Presentation Forms-B: U+FE70–U+FEFF*/
+    { Script_Arabic,     0xfe70, 0xfeff, 0, 0},
+    /* END */
+    { SCRIPT_UNDEFINED,  0, 0, 0}
+};
+
+typedef struct _scriptData
+{
+    SCRIPT_ANALYSIS a;
+    SCRIPT_PROPERTIES props;
+} scriptData;
+
+/* the must be in order so that the index matches the Script value */
+static const scriptData scriptInformation[] = {
+    {{SCRIPT_UNDEFINED, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_NEUTRAL, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+    {{Script_Latin, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_ENGLISH, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
+    {{Script_CR, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_NEUTRAL, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+    {{Script_Numeric, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_ENGLISH, 1, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+    {{Script_Control, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_ENGLISH, 0, 1, 0, 0, ANSI_CHARSET, 1, 0, 0, 0, 0, 0, 1, 0, 0}},
+    {{Script_Punctuation, 0, 0, 0, 0, 0, 0, { 0,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_NEUTRAL, 0, 0, 0, 0, ANSI_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+    {{Script_Arabic, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_ARABIC, 0, 1, 0, 0, ARABIC_CHARSET, 0, 0, 0, 0, 0, 0, 1, 1, 0}},
+    {{Script_Arabic_Numeric, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_ARABIC, 1, 1, 0, 0, ARABIC_CHARSET, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
+    {{Script_Hebrew, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_HEBREW, 0, 1, 0, 1, HEBREW_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+    {{Script_Syriac, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_SYRIAC, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 1, 0}},
+    {{Script_Persian, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
+     {LANG_PERSIAN, 1, 1, 0, 0, ARABIC_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+};
+
 static const SCRIPT_PROPERTIES props[] =
 {
     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@@ -265,6 +347,42 @@ static WCHAR mirror_char( WCHAR ch )
     return ch + wine_mirror_map[wine_mirror_map[ch >> 8] + (ch & 0xff)];
 }
 
+static WORD get_char_script( WCHAR ch)
+{
+    WORD type = 0;
+    int i;
+
+    if (ch == 0xc || ch == 0x20 || ch == 0x202f)
+        return Script_CR;
+
+    GetStringTypeW(CT_CTYPE1, &ch, 1, &type);
+
+    if (type == 0)
+        return SCRIPT_UNDEFINED;
+
+    if (type & C1_CNTRL)
+        return Script_Control;
+
+    i = 0;
+    do
+    {
+        if (ch < scriptRanges[i].rangeFirst || scriptRanges[i].script == SCRIPT_UNDEFINED)
+            break;
+
+        if (ch >= scriptRanges[i].rangeFirst && ch <= scriptRanges[i].rangeLast)
+        {
+            if (scriptRanges[i].numericScript && type & C1_DIGIT)
+                return scriptRanges[i].numericScript;
+            if (scriptRanges[i].punctScript && type & C1_PUNCT)
+                return scriptRanges[i].punctScript;
+            return scriptRanges[i].script;
+        }
+        i++;
+    } while (1);
+
+    return SCRIPT_UNDEFINED;
+}
+
 /***********************************************************************
  *      DllMain
  *
@@ -507,17 +625,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
                              SCRIPT_ITEM *pItems, int *pcItems)
 {
 
-#define Numeric_start 0x0030
-#define Numeric_stop  0x0039
 #define Numeric_space 0x0020
-#define Arabic_start  0x0600
-#define Arabic_stop   0x06ff
-#define Hebrew_start  0x0590
-#define Hebrew_stop   0x05ff
-#define Syriac_start  0x0700
-#define Syriac_stop   0x074f
-#define Latin_start   0x0001
-#define Latin_stop    0x024f
 
     int   cnt = 0, index = 0;
     int   New_Script = SCRIPT_UNDEFINED;
@@ -550,28 +658,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
     }
 
     pItems[index].iCharPos = 0;
-    memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
-
-    if  (pwcInChars[cnt] == '\r')
-        pItems[index].a.eScript = Script_CR;
-    else
-    if  (pwcInChars[cnt] == '\n')
-        pItems[index].a.eScript = Script_LF;
-    else
-    if  (pwcInChars[cnt] >= Numeric_start && pwcInChars[cnt] <= Numeric_stop)
-        pItems[index].a.eScript = Script_Numeric;
-    else
-    if  (pwcInChars[cnt] >= Arabic_start && pwcInChars[cnt] <= Arabic_stop)
-        pItems[index].a.eScript = Script_Arabic;
-    else
-    if  (pwcInChars[cnt] >= Hebrew_start && pwcInChars[cnt] <= Hebrew_stop)
-        pItems[index].a.eScript = Script_Hebrew;
-    else
-    if  (pwcInChars[cnt] >= Syriac_start && pwcInChars[cnt] <= Syriac_stop)
-        pItems[index].a.eScript = Script_Syriac;
-    else
-    if  (pwcInChars[cnt] >= Latin_start && pwcInChars[cnt] <= Latin_stop)
-        pItems[index].a.eScript = Script_Latin;
+    pItems[index].a = scriptInformation[get_char_script(pwcInChars[cnt])].a;
 
     if (levels)
     {
@@ -579,15 +666,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
         pItems[index].a.fLayoutRTL = odd(levels[cnt]);
         pItems[index].a.s.uBidiLevel = levels[cnt];
     }
-    else if ((pItems[index].a.eScript  == Script_Arabic) ||
-             (pItems[index].a.eScript  == Script_Hebrew) ||
-             (pItems[index].a.eScript  == Script_Syriac))
-    {
-        pItems[index].a.s.uBidiLevel = 1;
-        pItems[index].a.fRTL = 1;
-        pItems[index].a.fLayoutRTL = 1;
-    }
-    else
+    else if (!pItems[index].a.s.uBidiLevel)
     {
         pItems[index].a.s.uBidiLevel = baselevel;
         pItems[index].a.fLayoutRTL = odd(baselevel);
@@ -603,35 +682,10 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
         if (levels && (levels[cnt] == pItems[index].a.s.uBidiLevel))
             continue;
 
-        if  (pwcInChars[cnt] == '\r')
-            New_Script = Script_CR;
-        else
-        if  (pwcInChars[cnt] == '\n')
-            New_Script = Script_LF;
-        else
-        if  ((pwcInChars[cnt] >= Numeric_start && pwcInChars[cnt] <= Numeric_stop)
-             || (New_Script == Script_Numeric && pwcInChars[cnt] == Numeric_space))
-            New_Script = Script_Numeric;
-        else
-        if  ((pwcInChars[cnt] >= Arabic_start && pwcInChars[cnt] <= Arabic_stop)
-             || (New_Script == Script_Arabic && pwcInChars[cnt] == Numeric_space))
-            New_Script = Script_Arabic;
-        else
-        if  ((pwcInChars[cnt] >= Hebrew_start && pwcInChars[cnt] <= Hebrew_stop)
-             || (New_Script == Script_Hebrew && pwcInChars[cnt] == Numeric_space))
-            New_Script = Script_Hebrew;
-        else
-        if  ((pwcInChars[cnt] >= Syriac_start && pwcInChars[cnt] <= Syriac_stop)
-             || (New_Script == Script_Syriac && pwcInChars[cnt] == Numeric_space))
-            New_Script = Script_Syriac;
-        else
-        if  ((pwcInChars[cnt] >= Latin_start && pwcInChars[cnt] <= Latin_stop)
-             || (New_Script == Script_Latin && pwcInChars[cnt] == Numeric_space))
-            New_Script = Script_Latin;
-        else
-            New_Script = SCRIPT_UNDEFINED;
+        if(pwcInChars[cnt] != Numeric_space)
+            New_Script = get_char_script(pwcInChars[cnt]);
 
-        if ((levels && (levels[cnt] != pItems[index].a.s.uBidiLevel)) || New_Script != pItems[index].a.eScript)
+        if ((levels && (levels[cnt] != pItems[index].a.s.uBidiLevel)) || New_Script != pItems[index].a.eScript || New_Script == Script_Control)
         {
             TRACE("New_Level = %i, New_Script=%d, eScript=%d ", levels?levels[cnt]:-1, New_Script, pItems[index].a.eScript);
             index++;
@@ -641,29 +695,20 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
             pItems[index].iCharPos = cnt;
             memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
 
+            pItems[index].a = scriptInformation[New_Script].a;
             if (levels)
             {
                 pItems[index].a.fRTL = odd(levels[cnt]);
                 pItems[index].a.fLayoutRTL = odd(levels[cnt]);
                 pItems[index].a.s.uBidiLevel = levels[cnt];
             }
-            else if  ((New_Script == Script_Arabic) ||
-                      (New_Script == Script_Hebrew) ||
-                      (New_Script == Script_Syriac))
-            {
-                pItems[index].a.s.uBidiLevel = 1;
-                pItems[index].a.fRTL = 1;
-                pItems[index].a.fLayoutRTL = 1;
-            }
-            else
+            else if (!pItems[index].a.s.uBidiLevel)
             {
                 pItems[index].a.s.uBidiLevel = baselevel;
                 pItems[index].a.fLayoutRTL = odd(baselevel);
                 pItems[index].a.fRTL = odd(baselevel);
             }
 
-            pItems[index].a.eScript = New_Script;
-
             TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos);
         }
     }
index 56226ee..d431d27 100644 (file)
  *
  */
 
-#define Script_Syriac  8
-#define Script_Hebrew  7
-#define Script_Arabic  6
 #define Script_Latin   1
-#define Script_Numeric 5
-#define Script_CR      22
-#define Script_LF      23
+#define Script_CR      2
+#define Script_Numeric 3
+#define Script_Control 4
+#define Script_Punctuation 5
+#define Script_Arabic  6
+#define Script_Arabic_Numeric  7
+#define Script_Hebrew  8
+#define Script_Syriac  9
+#define Script_Persian 10
 
 #define GLYPH_BLOCK_SHIFT 8
 #define GLYPH_BLOCK_SIZE  (1UL << GLYPH_BLOCK_SHIFT)