Aric Stewart : usp10: Break with a better understanding on the handling of bidi strengths.

Alexandre Julliard julliard at winehq.org
Tue Nov 15 13:17:31 CST 2011


Module: wine
Branch: master
Commit: 9c9513f94a632241ed7be0e9bd724696ed677d3c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9c9513f94a632241ed7be0e9bd724696ed677d3c

Author: Aric Stewart <aric at codeweavers.com>
Date:   Mon Nov 14 13:16:59 2011 -0700

usp10: Break with a better understanding on the handling of bidi strengths.

---

 dlls/usp10/bidi.c           |   10 ++++++--
 dlls/usp10/usp10.c          |   44 +++++++++++++++++++++++++++++++++++-------
 dlls/usp10/usp10_internal.h |    3 ++
 3 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/dlls/usp10/bidi.c b/dlls/usp10/bidi.c
index 9c3942c..a2edfa6 100644
--- a/dlls/usp10/bidi.c
+++ b/dlls/usp10/bidi.c
@@ -901,7 +901,7 @@ BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c,
             case AL:
             case RLE:
             case RLO:
-                lpStrength[i] = 1;
+                lpStrength[i] = BIDI_STRONG;
                 break;
             case PDF:
             case EN:
@@ -910,10 +910,14 @@ BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c,
             case AN:
             case CS:
             case BN:
-                lpStrength[i] = 2;
+                lpStrength[i] = BIDI_WEAK;
                 break;
+            case B:
+            case S:
+            case WS:
+            case ON:
             default: /* Neutrals and NSM */
-                lpStrength[i] = 0;
+                lpStrength[i] = BIDI_NEUTRAL;
         }
     }
     return TRUE;
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 4ac7b8f..0496a56 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -805,6 +805,7 @@ HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int
     WORD  *levels = NULL;
     WORD  *strength = NULL;
     WORD  baselevel = 0;
+    BOOL  new_run;
 
     TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems, 
           psControl, psState, pItems, pcItems);
@@ -876,10 +877,13 @@ HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int
     pItems[index].a = scriptInformation[get_char_script(pwcInChars[cnt])].a;
     pScriptTags[index] = scriptInformation[get_char_script(pwcInChars[cnt])].scriptTag;
 
-    if (strength)
+    if (strength && strength[cnt] == BIDI_STRONG)
         str = strength[cnt];
+    else if (strength)
+        str = strength[0];
 
     cnt = 0;
+
     if (levels)
     {
         pItems[index].a.fRTL = odd(levels[cnt]);
@@ -899,9 +903,6 @@ HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int
 
     for (cnt=1; cnt < cInChars; cnt++)
     {
-        if (levels && (levels[cnt] == pItems[index].a.s.uBidiLevel && (!strength || (strength[cnt] == 0 || strength[cnt] == str))))
-            continue;
-
         if(pwcInChars[cnt] != Numeric_space && pwcInChars[cnt] != ZWJ && pwcInChars[cnt] != ZWNJ)
             New_Script = get_char_script(pwcInChars[cnt]);
         else if (levels)
@@ -915,17 +916,44 @@ HRESULT WINAPI ScriptItemizeOpenType(const WCHAR *pwcInChars, int cInChars, int
                 New_Script = get_char_script(pwcInChars[cnt]);
         }
 
-        if ((levels && (levels[cnt] != pItems[index].a.s.uBidiLevel || (strength && (strength[cnt] != str)))) || (New_Script != -1 && New_Script != pItems[index].a.eScript) || New_Script == Script_Control)
+        new_run = FALSE;
+        /* merge space strengths*/
+        if (strength && strength[cnt] == BIDI_STRONG && str != BIDI_STRONG && New_Script == pItems[index].a.eScript)
+            str = BIDI_STRONG;
+
+        if (strength && strength[cnt] == BIDI_NEUTRAL && str == BIDI_STRONG && pwcInChars[cnt] != Numeric_space && New_Script == pItems[index].a.eScript)
+            str = BIDI_NEUTRAL;
+
+        /* changes in level */
+        if (levels && (levels[cnt] != pItems[index].a.s.uBidiLevel))
         {
-            TRACE("New_Level = %i, New_Strength = %i, New_Script=%d, eScript=%d\n", levels?levels[cnt]:-1, strength?strength[cnt]:str, New_Script, pItems[index].a.eScript);
+            TRACE("Level break(%i/%i)\n",pItems[index].a.s.uBidiLevel,levels[cnt]);
+            new_run = TRUE;
+        }
+        /* changes in strength */
+        else if (strength && pwcInChars[cnt] != Numeric_space && str != strength[cnt])
+        {
+            TRACE("Strength break (%i/%i)\n",str,strength[cnt]);
+            new_run = TRUE;
+        }
+        /* changes in script */
+        else if ((!levels) && (((pwcInChars[cnt] != Numeric_space) && (New_Script != -1) && (New_Script != pItems[index].a.eScript)) || (New_Script == Script_Control)))
+        {
+            TRACE("Script break(%i/%i)\n",pItems[index].a.eScript,New_Script);
+            new_run = TRUE;
+        }
 
-            if (strength && strength[cnt] != 0)
-                str = strength[cnt];
+        if (new_run)
+        {
+            TRACE("New_Level = %i, New_Strength = %i, New_Script=%d, eScript=%d\n", levels?levels[cnt]:-1, strength?strength[cnt]:str, New_Script, pItems[index].a.eScript);
 
             index++;
             if  (index+1 > cMaxItems)
                 return E_OUTOFMEMORY;
 
+            if (strength)
+                str = strength[cnt];
+
             pItems[index].iCharPos = cnt;
             memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS));
 
diff --git a/dlls/usp10/usp10_internal.h b/dlls/usp10/usp10_internal.h
index 7a88ac7..9f13b40 100644
--- a/dlls/usp10/usp10_internal.h
+++ b/dlls/usp10/usp10_internal.h
@@ -122,6 +122,9 @@ typedef int (*lexical_function)(WCHAR c);
 typedef void (*reorder_function)(LPWSTR pwChar, IndicSyllable *syllable, lexical_function lex);
 
 #define odd(x) ((x) & 1)
+#define BIDI_STRONG  1
+#define BIDI_WEAK    2
+#define BIDI_NEUTRAL 0
 
 BOOL BIDI_DetermineLevels( LPCWSTR lpString, INT uCount, const SCRIPT_STATE *s,
                 const SCRIPT_CONTROL *c, WORD *lpOutLevels ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list