[USP10] Sync with Wine Staging 1.9.16. CORE-11866
[reactos.git] / reactos / dll / win32 / usp10 / usp10.c
index f68e838..9d3abe5 100644 (file)
@@ -319,7 +319,7 @@ const scriptData scriptInformation[] = {
      {LANG_ARABIC, 0, 1, 0, 0, ARABIC_CHARSET, 0, 0, 0, 0, 0, 0, 1, 1, 0},
      MS_MAKE_TAG('a','r','a','b'),
      {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
-    {{Script_Arabic_Numeric, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
+    {{Script_Arabic_Numeric, 0, 1, 0, 0, 0, 0, { 2,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},
      MS_MAKE_TAG('a','r','a','b'),
      {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
@@ -331,10 +331,10 @@ const scriptData scriptInformation[] = {
      {LANG_SYRIAC, 0, 1, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, 1, 0, 0, 1, 0},
      MS_MAKE_TAG('s','y','r','c'),
      {'E','s','t','r','a','n','g','e','l','o',' ','E','d','e','s','s','a',0}},
-    {{Script_Persian, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
+    {{Script_Persian, 0, 1, 0, 0, 0, 0, { 2,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},
-     MS_MAKE_TAG('s','y','r','c'),
-     {'E','s','t','r','a','n','g','e','l','o',' ','E','d','e','s','s','a',0}},
+     MS_MAKE_TAG('a','r','a','b'),
+     {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0}},
     {{Script_Thaana, 1, 1, 0, 0, 0, 0, { 1,0,0,0,0,0,0,0,0,0,0}},
      {LANG_DIVEHI, 0, 1, 0, 1, DEFAULT_CHARSET, 0, 0, 0, 0, 0, 0, 0, 0, 0},
      MS_MAKE_TAG('t','h','a','a'),
@@ -880,7 +880,7 @@ static inline DWORD decode_surrogate_pair(LPCWSTR str, INT index, INT end)
 static WORD get_char_script( LPCWSTR str, INT index, INT end, INT *consumed)
 {
     static const WCHAR latin_punc[] = {'#','$','&','\'',',',';','<','>','?','@','\\','^','_','`','{','|','}','~', 0x00a0, 0};
-    WORD type = 0;
+    WORD type = 0, type2 = 0;
     DWORD ch;
     int i;
 
@@ -910,6 +910,7 @@ static WORD get_char_script( LPCWSTR str, INT index, INT end, INT *consumed)
     }
 
     GetStringTypeW(CT_CTYPE1, &str[index], 1, &type);
+    GetStringTypeW(CT_CTYPE2, &str[index], 1, &type2);
 
     if (type == 0)
         return SCRIPT_UNDEFINED;
@@ -931,7 +932,7 @@ static WORD get_char_script( LPCWSTR str, INT index, INT end, INT *consumed)
 
         if (ch >= scriptRanges[i].rangeFirst && ch <= scriptRanges[i].rangeLast)
         {
-            if (scriptRanges[i].numericScript && type & C1_DIGIT)
+            if (scriptRanges[i].numericScript && (type & C1_DIGIT || type2 == C2_ARABICNUMBER))
                 return scriptRanges[i].numericScript;
             if (scriptRanges[i].punctScript && type & C1_PUNCT)
                 return scriptRanges[i].punctScript;
@@ -1242,6 +1243,10 @@ static inline WORD base_indic(WORD script)
     };
 }
 
+static BOOL script_is_numeric(WORD script)
+{
+    return scriptInformation[script].props.fNumeric;
+}
 
 static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
                 int cMaxItems, const SCRIPT_CONTROL *psControl,
@@ -1250,6 +1255,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
 {
 
 #define Numeric_space 0x0020
+#define ZWSP 0x200B
 #define ZWNJ 0x200C
 #define ZWJ  0x200D
 
@@ -1440,12 +1446,12 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
             for (i = 0; i < cInChars; i++)
             {
                 if (i > 0 && i < cInChars-1 &&
-                    scripts[i-1] == Script_Numeric &&
+                    script_is_numeric(scripts[i-1]) &&
                     strchrW(math_punc, pwcInChars[i]))
                 {
-                    if (scripts[i+1] == Script_Numeric)
+                    if (script_is_numeric(scripts[i+1]))
                     {
-                        scripts[i] = Script_Numeric;
+                        scripts[i] = scripts[i+1];
                         levels[i] = levels[i-1];
                         strength[i] = strength[i-1];
                         i++;
@@ -1455,11 +1461,11 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
                         int j;
                         for (j = i+1; j < cInChars; j++)
                         {
-                            if (scripts[j] == Script_Numeric)
+                            if (script_is_numeric(scripts[j]))
                             {
                                 for(;i<j; i++)
                                 {
-                                    scripts[i] = Script_Numeric;
+                                    scripts[i] = scripts[j];
                                     levels[i] = levels[i-1];
                                     strength[i] = strength[i-1];
                                 }
@@ -1472,8 +1478,9 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
 
             for (i = 0; i < cInChars; i++)
             {
-                /* Script_Numeric at level 0 get bumped to level 2 */
-                if (!overrides[i] && (levels[i] == 0 || (odd(psState->uBidiLevel) && levels[i] == psState->uBidiLevel+1)) && scripts[i] == Script_Numeric)
+                /* Numerics at level 0 get bumped to level 2 */
+                if (!overrides[i] && (levels[i] == 0 || (odd(psState->uBidiLevel)
+                        && levels[i] == psState->uBidiLevel + 1)) && script_is_numeric(scripts[i]))
                 {
                     levels[i] = 2;
                 }
@@ -1565,8 +1572,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
         if (overrides)
             pItems[index].a.s.fOverrideDirection = (overrides[cnt] != 0);
         pItems[index].a.fRTL = odd(levels[cnt]);
-        if (pItems[index].a.eScript == Script_Numeric ||
-            pItems[index].a.eScript == Script_Numeric2)
+        if (script_is_numeric(pItems[index].a.eScript))
             pItems[index].a.fLayoutRTL = layoutRTL;
         else
             pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
@@ -1579,8 +1585,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
         layoutRTL = odd(baselayout);
         pItems[index].a.s.uBidiLevel = baselevel;
         pItems[index].a.fRTL = odd(baselevel);
-        if (pItems[index].a.eScript == Script_Numeric ||
-            pItems[index].a.eScript == Script_Numeric2)
+        if (script_is_numeric(pItems[index].a.eScript))
             pItems[index].a.fLayoutRTL = odd(baselayout);
         else
             pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
@@ -1635,8 +1640,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
         if (!new_run && strength && str == BIDI_STRONG)
         {
             layoutRTL = odd(layout_levels[cnt]);
-            if (pItems[index].a.eScript == Script_Numeric ||
-                pItems[index].a.eScript == Script_Numeric2)
+            if (script_is_numeric(pItems[index].a.eScript))
                 pItems[index].a.fLayoutRTL = layoutRTL;
         }
 
@@ -1666,8 +1670,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
                 else
                     layoutRTL = (layoutRTL || odd(layout_levels[cnt]));
                 pItems[index].a.fRTL = odd(levels[cnt]);
-                if (pItems[index].a.eScript == Script_Numeric ||
-                    pItems[index].a.eScript == Script_Numeric2)
+                if (script_is_numeric(pItems[index].a.eScript))
                     pItems[index].a.fLayoutRTL = layoutRTL;
                 else
                     pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
@@ -1679,8 +1682,7 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
                     pItems[index].a.s.fOverrideDirection = TRUE;
                 pItems[index].a.s.uBidiLevel = baselevel;
                 pItems[index].a.fRTL = odd(baselevel);
-                if (pItems[index].a.eScript == Script_Numeric||
-                    pItems[index].a.eScript == Script_Numeric2)
+                if (script_is_numeric(pItems[index].a.eScript))
                     pItems[index].a.fLayoutRTL = layoutRTL;
                 else
                     pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
@@ -2751,9 +2753,9 @@ static inline int get_cluster_advance(const int* piAdvance,
  *      ScriptXtoCP (USP10.@)
  *
  * Basic algorithm :
- *  use piAdvance to find the cluster we are looking at
- *  Find the character that is the first character of the cluster
- *  That is our base piCP
+ *  Use piAdvance to find the cluster we are looking at.
+ *  Find the character that is the first character of the cluster.
+ *  That is our base piCP.
  *  If the script snaps to cluster boundaries (Hebrew, Indic, Thai) then we
  *  are good. Otherwise if the cluster is larger than 1 glyph we need to
  *  determine how far through the cluster to advance the cursor.
@@ -3069,10 +3071,6 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
     ((ScriptCache *)*psc)->userScript = tagScript;
     ((ScriptCache *)*psc)->userLang = tagLangSys;
 
-    /* set fNoGlyphIndex non truetype/opentype fonts */
-    if (psa && !psa->fNoGlyphIndex && !((ScriptCache *)*psc)->sfnt)
-        psa->fNoGlyphIndex = TRUE;
-
     /* Initialize a SCRIPT_VISATTR and LogClust for each char in this run */
     for (i = 0; i < cChars; i++)
     {
@@ -3092,7 +3090,7 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
         pwLogClust[i] = idx;
     }
 
-    if (psa && !psa->fNoGlyphIndex)
+    if (psa && !psa->fNoGlyphIndex && ((ScriptCache *)*psc)->sfnt)
     {
         WCHAR *rChars;
         if ((hr = SHAPE_CheckFontForRequiredFeatures(hdc, (ScriptCache *)*psc, psa)) != S_OK) return hr;
@@ -3168,13 +3166,26 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
             if (rtl) idx = cChars - 1 - i;
             pwOutGlyphs[i] = pwcChars[idx];
 
+            if (!psa)
+                continue;
+
             /* overwrite some basic control glyphs to blank */
-            if (psa && psa->eScript == Script_Control &&
-                pwcChars[idx] < ((ScriptCache *)*psc)->tm.tmFirstChar)
+            if (psa->fNoGlyphIndex)
+            {
+                if (pwcChars[idx] == ZWSP || pwcChars[idx] == ZWNJ || pwcChars[idx] == ZWJ)
+                {
+                    pwOutGlyphs[i] = 0x20;
+                    pOutGlyphProps[i].sva.fZeroWidth = 1;
+                }
+            }
+            else if (psa->eScript == Script_Control)
             {
                 if (pwcChars[idx] == 0x0009 || pwcChars[idx] == 0x000A ||
                     pwcChars[idx] == 0x000D || pwcChars[idx] >= 0x001C)
+                {
                     pwOutGlyphs[i] = ((ScriptCache *)*psc)->sfp.wgBlank;
+                    pOutGlyphProps[i].sva.fZeroWidth = 1;
+                }
             }
         }
     }