usp10: Correct math punctuation handling in itemization.

Signed-off-by: Aric Stewart <aric@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Aric Stewart 2016-02-03 12:55:30 -06:00 committed by Alexandre Julliard
parent 6c470a8bd3
commit 144a7aa6ef
2 changed files with 76 additions and 9 deletions

View File

@ -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);

View File

@ -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))