Aric Stewart : usp10: Correct math punctuation handling in itemization.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Feb 4 10:46:13 CST 2016


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Wed Feb  3 12:55:30 2016 -0600

usp10: Correct math punctuation handling in itemization.

Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/usp10/tests/usp10.c | 40 ++++++++++++++++++++++++++++++++++++++++
 dlls/usp10/usp10.c       | 45 ++++++++++++++++++++++++++++++++++++---------
 2 files changed, 76 insertions(+), 9 deletions(-)

diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c
index 3d19b07..4a448db 100644
--- a/dlls/usp10/tests/usp10.c
+++ b/dlls/usp10/tests/usp10.c
@@ -456,6 +456,38 @@ static void test_ScriptItemize( void )
     static const itemTest t471[2] = {{{0,0,0,0,0},0,0,0,0,math_tag,TRUE,{-1,-1,-1,-1,0x0}},{{0,0,0,0,0},26,0,0,0,-1,FALSE}};
     static const itemTest t472[2] = {{{0,0,0,0,0},0,0,0,2,math_tag,TRUE,{-1,1,1,1,0x0}},{{0,0,0,0,0},26,0,0,0,-1,FALSE}};
 
+    /* Mathematical and Numeric combinations */
+    /* These have a leading hebrew character to force complicated itemization */
+    static const WCHAR test48[] = {0x05e9,' ','1','2','3','.'};
+    static const itemTest t481[4] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE},
+        {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},5,0,0,0,0,FALSE},
+        {{0,0,0,0,0},6,0,0,0,-1,FALSE}};
+    static const WCHAR test49[] = {0x05e9,' ','1','2','.','1','2'};
+    static const itemTest t491[3] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE},
+        {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},7,0,0,0,-1,FALSE}};
+    static const WCHAR test50[] = {0x05e9,' ','.','1','2','3'};
+    static const itemTest t501[4] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE},
+        {{0,0,0,0,0},2,1,1,1,0,FALSE},{{0,0,0,0,0},3,0,1,2,0,FALSE},
+        {{0,0,0,0,0},6,0,0,0,-1,FALSE}};
+    static const WCHAR test51[] = {0x05e9,' ','a','b','.','1','2'};
+    static const itemTest t511[5] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE},
+        {{0,0,0,0,0},1,0,0,0,latn_tag,FALSE},{{0,0,0,0,0},4,0,0,0,0,FALSE},
+        {{0,0,0,0,0},5,0,0,2,0,FALSE},{{0,0,0,0,0},7,0,0,0,-1,FALSE}};
+    static const WCHAR test52[] = {0x05e9,' ','1','2','.','a','b'};
+    static const itemTest t521[5] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE},
+        {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},4,0,0,0,0,FALSE},
+        {{0,0,0,0,0},5,0,0,0,latn_tag,FALSE},{{0,0,0,0,0},7,0,0,0,-1,FALSE}};
+    static const WCHAR test53[] = {0x05e9,' ','1','2','.','.','1','2'};
+    static const itemTest t531[5] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE},
+        {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},4,1,1,1,0,FALSE},
+        {{0,0,0,0,0},6,0,1,2,0,FALSE},{{0,0,0,0,0},8,0,0,0,-1,FALSE}};
+    static const WCHAR test54[] = {0x05e9,' ','1','2','+','1','2'};
+    static const itemTest t541[3] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE},
+        {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},7,0,0,0,-1,FALSE}};
+    static const WCHAR test55[] = {0x05e9,' ','1','2','+','+','1','2'};
+    static const itemTest t551[3] = {{{0,0,0,0,0},0,1,1,1,hebr_tag,FALSE},
+        {{0,0,0,0,0},2,0,1,2,0,FALSE},{{0,0,0,0,0},8,0,0,0,-1,FALSE}};
+
     SCRIPT_ITEM items[15];
     SCRIPT_CONTROL  Control;
     SCRIPT_STATE    State;
@@ -590,6 +622,14 @@ static void test_ScriptItemize( void )
     test_items_ok(test45,24,&Control,&State,1,t451,FALSE,0);
     test_items_ok(test46,16,&Control,&State,1,t461,FALSE,0);
     test_items_ok(test47,26,&Control,&State,1,t471,FALSE,0);
+    test_items_ok(test48,6,&Control,&State,3,t481,FALSE,0);
+    test_items_ok(test49,7,&Control,&State,2,t491,FALSE,0);
+    test_items_ok(test50,6,&Control,&State,3,t501,FALSE,0);
+    test_items_ok(test51,7,&Control,&State,4,t511,FALSE,0);
+    test_items_ok(test52,7,&Control,&State,4,t521,FALSE,0);
+    test_items_ok(test53,8,&Control,&State,4,t531,FALSE,0);
+    test_items_ok(test54,7,&Control,&State,2,t541,FALSE,0);
+    test_items_ok(test55,8,&Control,&State,2,t551,FALSE,0);
 
     State.uBidiLevel = 1;
     test_items_ok(test1,4,&Control,&State,1,t12,FALSE,0);
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index a3ca3c2..5420861 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -1391,8 +1391,8 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
         }
         else
         {
-            BOOL inNumber = FALSE;
             static const WCHAR math_punc[] = {'#','$','%','+',',','-','.','/',':',0x2212, 0x2044, 0x00a0,0};
+            static const WCHAR repeatable_math_punc[] = {'#','$','%','+','-','/',0x2212, 0x2044,0};
 
             strength = heap_alloc_zero(cInChars * sizeof(WORD));
             if (!strength)
@@ -1407,21 +1407,48 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
                     strength[i] = BIDI_STRONG;
                 }
 
+            /* Math punctuation bordered on both sides by numbers can be
+               merged into the number */
             for (i = 0; i < cInChars; i++)
             {
-                /* Script_Numeric and select puncuation at level 0 get bumped to level 2 */
-                if ((levels[i] == 0 || (odd(psState->uBidiLevel) && levels[i] == psState->uBidiLevel+1)) && inNumber && strchrW(math_punc,pwcInChars[i]))
+                if (i > 0 && i < cInChars-1 &&
+                    scripts[i-1] == Script_Numeric &&
+                    strchrW(math_punc, pwcInChars[i]))
                 {
-                    scripts[i] = Script_Numeric;
-                    levels[i] = 2;
+                    if (scripts[i+1] == Script_Numeric)
+                    {
+                        scripts[i] = Script_Numeric;
+                        levels[i] = levels[i-1];
+                        strength[i] = strength[i-1];
+                        i++;
+                    }
+                    else if (strchrW(repeatable_math_punc, pwcInChars[i]))
+                    {
+                        int j;
+                        for (j = i+1; j < cInChars; j++)
+                        {
+                            if (scripts[j] == Script_Numeric)
+                            {
+                                for(;i<j; i++)
+                                {
+                                    scripts[i] = Script_Numeric;
+                                    levels[i] = levels[i-1];
+                                    strength[i] = strength[i-1];
+                                }
+                            }
+                            else if (pwcInChars[i] != pwcInChars[j]) break;
+                        }
+                    }
                 }
-                else if ((levels[i] == 0 || (odd(psState->uBidiLevel) && levels[i] == psState->uBidiLevel+1)) && scripts[i] == Script_Numeric)
+            }
+
+            for (i = 0; i < cInChars; i++)
+            {
+                /* Script_Numeric at level 0 get bumped to level 2 */
+                if ((levels[i] == 0 || (odd(psState->uBidiLevel) && levels[i] == psState->uBidiLevel+1)) && scripts[i] == Script_Numeric)
                 {
                     levels[i] = 2;
-                    inNumber = TRUE;
                 }
-                else
-                    inNumber = FALSE;
 
                 /* Joiners get merged preferencially right */
                 if (i > 0 && (pwcInChars[i] == ZWJ || pwcInChars[i] == ZWNJ))




More information about the wine-cvs mailing list