usp10: Implement handling fMergeNeutralItems.
This commit is contained in:
parent
2425999573
commit
facc7b0306
|
@ -883,3 +883,38 @@ int BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE* plevel, int cch, B
|
|||
|
||||
return ich;
|
||||
}
|
||||
|
||||
BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c,
|
||||
WORD* lpStrength)
|
||||
{
|
||||
int i;
|
||||
classify(lpString, lpStrength, uCount, c);
|
||||
|
||||
for ( i = 0; i < uCount; i++)
|
||||
{
|
||||
switch(lpStrength[i])
|
||||
{
|
||||
case L:
|
||||
case LRE:
|
||||
case LRO:
|
||||
case R:
|
||||
case AL:
|
||||
case RLE:
|
||||
case RLO:
|
||||
lpStrength[i] = 1;
|
||||
break;
|
||||
case PDF:
|
||||
case EN:
|
||||
case ES:
|
||||
case ET:
|
||||
case AN:
|
||||
case CS:
|
||||
case BN:
|
||||
lpStrength[i] = 2;
|
||||
break;
|
||||
default: /* Neutrals and NSM */
|
||||
lpStrength[i] = 0;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ typedef struct _itemTest {
|
|||
|
||||
static inline void _test_items_ok(LPCWSTR string, DWORD cchString,
|
||||
SCRIPT_CONTROL *Control, SCRIPT_STATE *State,
|
||||
DWORD nItems, const itemTest* items, BOOL nItemsToDo)
|
||||
DWORD nItems, const itemTest* items, BOOL nItemsToDo,
|
||||
INT nItemsBroken)
|
||||
{
|
||||
HRESULT hr;
|
||||
int x, outnItems;
|
||||
|
@ -49,6 +50,11 @@ static inline void _test_items_ok(LPCWSTR string, DWORD cchString,
|
|||
|
||||
hr = ScriptItemize(string, cchString, 15, Control, State, outpItems, &outnItems);
|
||||
winetest_ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr);
|
||||
if (nItemsBroken && broken(nItemsBroken == outnItems))
|
||||
{
|
||||
winetest_win_skip("This test broken on this platform\n");
|
||||
return;
|
||||
}
|
||||
if (nItemsToDo)
|
||||
todo_wine winetest_ok(outnItems == nItems, "Wrong number of items\n");
|
||||
else
|
||||
|
@ -75,7 +81,7 @@ static inline void _test_items_ok(LPCWSTR string, DWORD cchString,
|
|||
}
|
||||
}
|
||||
|
||||
#define test_items_ok(a,b,c,d,e,f,g) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _test_items_ok(a,b,c,d,e,f,g)
|
||||
#define test_items_ok(a,b,c,d,e,f,g,h) (winetest_set_location(__FILE__,__LINE__), 0) ? 0 : _test_items_ok(a,b,c,d,e,f,g,h)
|
||||
|
||||
|
||||
static void test_ScriptItemize( void )
|
||||
|
@ -90,6 +96,11 @@ static void test_ScriptItemize( void )
|
|||
static const itemTest t22[5] = {{{0,0,0,1},0,0,0,2},{{0,0,0,0},6,1,1,1},{{0,0,1,0},13,0,1,2},{{0,0,0,0},15,0,0,0},{{0,0,0,0},16,0,0,0}};
|
||||
static const itemTest t23[5] = {{{0,0,1,0},0,0,1,2},{{0,0,0,0},6,1,1,1},{{0,0,1,0},13,0,1,2},{{0,0,0,0},15,1,1,1},{{0,0,0,0},16,0,0,0}};
|
||||
|
||||
static const WCHAR test2b[] = {'A','B','C','-','D','E','F',' ',0x0621,0x0623,0x0624,0};
|
||||
static const itemTest t2b1[5] = {{{0,0,0,0},0,0,0,0},{{0,0,0,0},3,0,0,0},{{0,0,0,0},4,0,0,0},{{0,0,0,0},8,1,1,1},{{0,0,0,0},11,0,0,0}};
|
||||
static const itemTest t2b2[5] = {{{0,0,0,0},0,0,0,2},{{0,0,0,0},3,0,0,2},{{0,0,0,0},4,0,0,2},{{0,0,0,0},7,1,1,1},{{0,0,0,0},11,0,0,0}};
|
||||
static const itemTest t2b3[3] = {{{0,0,0,0},0,0,0,2},{{0,0,0,0},7,1,1,1},{{0,0,0,0},11,0,0,0}};
|
||||
|
||||
/* Thai */
|
||||
static const WCHAR test3[] =
|
||||
{0x0e04,0x0e27,0x0e32,0x0e21,0x0e1e,0x0e22,0x0e32,0x0e22,0x0e32, 0x0e21
|
||||
|
@ -103,7 +114,8 @@ static void test_ScriptItemize( void )
|
|||
static const WCHAR test4[] = {'1','2','3','-','5','2',' ','i','s',' ','7','1','.',0};
|
||||
|
||||
static const itemTest t41[6] = {{{0,0,0,0},0,0,0,0},{{0,0,0,0},3,0,0,0},{{0,0,0,0},4,0,0,0},{{0,0,0,0},7,0,0,0},{{0,0,0,0},10,0,0,0},{{0,0,0,0},12,0,0,0}};
|
||||
static const itemTest t42[5] = {{{0,0,1,0},0,0,1,2},{{0,0,0,0},6,1,1,1},{{0,0,0,0},7,0,0,2},{{1,0,0,1},10,0,0,2},{{1,0,0,0},12,0,0,0}};
|
||||
static const itemTest t42[5] = {{{0,0,1,0},0,0,1,2},{{0,0,0,0},6,1,1,1},{{0,0,0,0},7,0,0,2},{{0,0,0,0},10,0,0,2},{{0,0,0,0},12,0,0,0}};
|
||||
static const itemTest t43[4] = {{{0,0,1,0},0,0,1,2},{{0,0,0,0},6,1,1,1},{{0,0,0,0},7,0,0,2},{{0,0,0,0},12,0,0,0}};
|
||||
|
||||
/* Arabic */
|
||||
static const WCHAR test5[] =
|
||||
|
@ -117,6 +129,7 @@ static void test_ScriptItemize( void )
|
|||
static const WCHAR test6[] = {0x05e9, 0x05dc, 0x05d5, 0x05dd, '.',0};
|
||||
static const itemTest t61[3] = {{{0,0,0,0},0,1,1,1},{{0,0,0,0},4,0,0,0},{{0,0,0,0},5,0,0,0}};
|
||||
static const itemTest t62[3] = {{{0,0,0,0},0,1,1,1},{{0,0,0,0},4,1,1,1},{{0,0,0,0},5,0,0,0}};
|
||||
static const itemTest t63[2] = {{{0,0,0,0},0,1,1,1},{{0,0,0,0},5,0,0,0}};
|
||||
static const WCHAR test7[] = {'p','a','r','t',' ','o','n','e',' ',0x05d7, 0x05dc, 0x05e7, ' ', 0x05e9, 0x05ea, 0x05d9, 0x05d9, 0x05dd, ' ','p','a','r','t',' ','t','h','r','e','e', 0};
|
||||
static const itemTest t71[4] = {{{0,0,0,0},0,0,0,0},{{0,0,0,0},9,1,1,1},{{0,0,0,0},19,0,0,0},{{0,0,0,0},29,0,0,0}};
|
||||
static const itemTest t72[4] = {{{0,0,0,0},0,0,0,0},{{0,0,0,0},9,1,1,1},{{0,0,0,0},18,0,0,0},{{0,0,0,0},29,0,0,0}};
|
||||
|
@ -128,6 +141,7 @@ static void test_ScriptItemize( void )
|
|||
static const WCHAR test9[] = {0x0710, 0x0712, 0x0712, 0x0714, '.',0};
|
||||
static const itemTest t91[3] = {{{0,0,0,0},0,1,1,1},{{0,0,0,0},4,0,0,0},{{0,0,0,0},5,0,0,0}};
|
||||
static const itemTest t92[3] = {{{0,0,0,0},0,1,1,1},{{0,0,0,0},4,1,1,1},{{0,0,0,0},5,0,0,0}};
|
||||
static const itemTest t93[2] = {{{0,0,0,0},0,1,1,1},{{0,0,0,0},5,0,0,0}};
|
||||
|
||||
static const WCHAR test10[] = {0x0717, 0x0718, 0x071a, 0x071b,0};
|
||||
static const itemTest t101[2] = {{{0,0,0,0},0,1,1,1},{{0,0,0,0},4,0,0,0}};
|
||||
|
@ -153,40 +167,57 @@ static void test_ScriptItemize( void )
|
|||
hr = ScriptItemize(test1, 0, 10, NULL, NULL, items, &nItems);
|
||||
ok (hr == E_INVALIDARG, "ScriptItemize should return E_INVALIDARG if cInChars is 0\n");
|
||||
|
||||
test_items_ok(test1,4,NULL,NULL,1,t11,FALSE);
|
||||
test_items_ok(test2,16,NULL,NULL,6,t21,FALSE);
|
||||
test_items_ok(test3,41,NULL,NULL,1,t31,FALSE);
|
||||
test_items_ok(test4,12,NULL,NULL,5,t41,FALSE);
|
||||
test_items_ok(test5,38,NULL,NULL,1,t51,FALSE);
|
||||
test_items_ok(test6,5,NULL,NULL,2,t61,FALSE);
|
||||
test_items_ok(test7,29,NULL,NULL,3,t71,FALSE);
|
||||
test_items_ok(test8,4,NULL,NULL,1,t81,FALSE);
|
||||
test_items_ok(test9,5,NULL,NULL,2,t91,FALSE);
|
||||
test_items_ok(test10,4,NULL,NULL,1,t101,FALSE);
|
||||
test_items_ok(test1,4,NULL,NULL,1,t11,FALSE,0);
|
||||
test_items_ok(test2,16,NULL,NULL,6,t21,FALSE,0);
|
||||
test_items_ok(test2b,11,NULL,NULL,4,t2b1,FALSE,0);
|
||||
test_items_ok(test3,41,NULL,NULL,1,t31,FALSE,0);
|
||||
test_items_ok(test4,12,NULL,NULL,5,t41,FALSE,0);
|
||||
test_items_ok(test5,38,NULL,NULL,1,t51,FALSE,0);
|
||||
test_items_ok(test6,5,NULL,NULL,2,t61,FALSE,0);
|
||||
test_items_ok(test7,29,NULL,NULL,3,t71,FALSE,0);
|
||||
test_items_ok(test8,4,NULL,NULL,1,t81,FALSE,0);
|
||||
test_items_ok(test9,5,NULL,NULL,2,t91,FALSE,0);
|
||||
test_items_ok(test10,4,NULL,NULL,1,t101,FALSE,0);
|
||||
|
||||
State.uBidiLevel = 0;
|
||||
test_items_ok(test1,4,&Control,&State,1,t11,FALSE);
|
||||
test_items_ok(test2,16,&Control,&State,4,t22,FALSE);
|
||||
test_items_ok(test3,41,&Control,&State,1,t31,FALSE);
|
||||
test_items_ok(test4,12,&Control,&State,5,t41,FALSE);
|
||||
test_items_ok(test5,38,&Control,&State,1,t51,FALSE);
|
||||
test_items_ok(test6,5,&Control,&State,2,t61,FALSE);
|
||||
test_items_ok(test7,29,&Control,&State,3,t72,FALSE);
|
||||
test_items_ok(test8,4,&Control,&State,1,t81,FALSE);
|
||||
test_items_ok(test9,5,&Control,&State,2,t91,FALSE);
|
||||
test_items_ok(test10,4,&Control,&State,1,t101,FALSE);
|
||||
test_items_ok(test1,4,&Control,&State,1,t11,FALSE,0);
|
||||
test_items_ok(test2,16,&Control,&State,4,t22,FALSE,0);
|
||||
test_items_ok(test2b,11,&Control,&State,4,t2b1,FALSE,0);
|
||||
test_items_ok(test3,41,&Control,&State,1,t31,FALSE,0);
|
||||
test_items_ok(test4,12,&Control,&State,5,t41,FALSE,0);
|
||||
test_items_ok(test5,38,&Control,&State,1,t51,FALSE,0);
|
||||
test_items_ok(test6,5,&Control,&State,2,t61,FALSE,0);
|
||||
test_items_ok(test7,29,&Control,&State,3,t72,FALSE,0);
|
||||
test_items_ok(test8,4,&Control,&State,1,t81,FALSE,0);
|
||||
test_items_ok(test9,5,&Control,&State,2,t91,FALSE,0);
|
||||
test_items_ok(test10,4,&Control,&State,1,t101,FALSE,0);
|
||||
|
||||
State.uBidiLevel = 1;
|
||||
test_items_ok(test1,4,&Control,&State,1,t12,FALSE);
|
||||
test_items_ok(test2,16,&Control,&State,4,t23,FALSE);
|
||||
test_items_ok(test3,41,&Control,&State,1,t32,FALSE);
|
||||
test_items_ok(test4,12,&Control,&State,4,t42,TRUE);
|
||||
test_items_ok(test5,38,&Control,&State,1,t51,FALSE);
|
||||
test_items_ok(test6,5,&Control,&State,2,t62,FALSE);
|
||||
test_items_ok(test7,29,&Control,&State,3,t73,FALSE);
|
||||
test_items_ok(test8,4,&Control,&State,1,t81,FALSE);
|
||||
test_items_ok(test9,5,&Control,&State,2,t92,FALSE);
|
||||
test_items_ok(test10,4,&Control,&State,1,t101,FALSE);
|
||||
test_items_ok(test1,4,&Control,&State,1,t12,FALSE,0);
|
||||
test_items_ok(test2,16,&Control,&State,4,t23,FALSE,0);
|
||||
test_items_ok(test2b,11,&Control,&State,4,t2b2,FALSE,0);
|
||||
test_items_ok(test3,41,&Control,&State,1,t32,FALSE,0);
|
||||
test_items_ok(test4,12,&Control,&State,4,t42,FALSE,0);
|
||||
test_items_ok(test5,38,&Control,&State,1,t51,FALSE,0);
|
||||
test_items_ok(test6,5,&Control,&State,2,t62,FALSE,0);
|
||||
test_items_ok(test7,29,&Control,&State,3,t73,FALSE,0);
|
||||
test_items_ok(test8,4,&Control,&State,1,t81,FALSE,0);
|
||||
test_items_ok(test9,5,&Control,&State,2,t92,FALSE,0);
|
||||
test_items_ok(test10,4,&Control,&State,1,t101,FALSE,0);
|
||||
|
||||
State.uBidiLevel = 1;
|
||||
Control.fMergeNeutralItems = TRUE;
|
||||
test_items_ok(test1,4,&Control,&State,1,t12,FALSE,0);
|
||||
test_items_ok(test2,16,&Control,&State,4,t23,FALSE,0);
|
||||
test_items_ok(test2b,11,&Control,&State,2,t2b3,FALSE,4);
|
||||
test_items_ok(test3,41,&Control,&State,1,t32,FALSE,0);
|
||||
test_items_ok(test4,12,&Control,&State,3,t43,FALSE,4);
|
||||
test_items_ok(test5,38,&Control,&State,1,t51,FALSE,0);
|
||||
test_items_ok(test6,5,&Control,&State,1,t63,FALSE,2);
|
||||
test_items_ok(test7,29,&Control,&State,3,t73,FALSE,0);
|
||||
test_items_ok(test8,4,&Control,&State,1,t81,FALSE,0);
|
||||
test_items_ok(test9,5,&Control,&State,1,t93,FALSE,2);
|
||||
test_items_ok(test10,4,&Control,&State,1,t101,FALSE,0);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -599,9 +599,10 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
|||
|
||||
#define Numeric_space 0x0020
|
||||
|
||||
int cnt = 0, index = 0;
|
||||
int cnt = 0, index = 0, str = 0;
|
||||
int New_Script = SCRIPT_UNDEFINED;
|
||||
WORD *levels = NULL;
|
||||
WORD *strength = NULL;
|
||||
WORD baselevel = 0;
|
||||
|
||||
TRACE("%s,%d,%d,%p,%p,%p,%p\n", debugstr_wn(pwcInChars, cInChars), cInChars, cMaxItems,
|
||||
|
@ -622,11 +623,19 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
|||
for (i = 0; i < cInChars; i++)
|
||||
if (levels[i]!=levels[0])
|
||||
break;
|
||||
if (i >= cInChars)
|
||||
if (i >= cInChars && !odd(baselevel))
|
||||
{
|
||||
heap_free(levels);
|
||||
levels = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!psControl->fMergeNeutralItems)
|
||||
{
|
||||
strength = heap_alloc_zero(cInChars * sizeof(WORD));
|
||||
BIDI_GetStrengths(pwcInChars, cInChars, psControl, strength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pItems[index].iCharPos = 0;
|
||||
|
@ -645,21 +654,28 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
|||
pItems[index].a.fRTL = odd(baselevel);
|
||||
}
|
||||
|
||||
TRACE("New_Level=%i New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
|
||||
levels?levels[cnt]:-1, New_Script, pItems[index].a.eScript, index, cnt,
|
||||
if (strength)
|
||||
str = strength[0];
|
||||
|
||||
TRACE("New_Level=%i New_Strength=%i New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
|
||||
levels?levels[cnt]:-1, str, New_Script, pItems[index].a.eScript, index, cnt,
|
||||
pItems[index].iCharPos);
|
||||
|
||||
for (cnt=1; cnt < cInChars; cnt++)
|
||||
{
|
||||
if (levels && (levels[cnt] == pItems[index].a.s.uBidiLevel))
|
||||
if (levels && (levels[cnt] == pItems[index].a.s.uBidiLevel && (!strength || (strength[cnt] == 0 || strength[cnt] == str))))
|
||||
continue;
|
||||
|
||||
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 || New_Script == Script_Control)
|
||||
if ((levels && (levels[cnt] != pItems[index].a.s.uBidiLevel || (strength && (strength[cnt] != str)))) || 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);
|
||||
TRACE("New_Level = %i, New_Strength = %i, New_Script=%d, eScript=%d ", levels?levels[cnt]:-1, strength?strength[cnt]:str, New_Script, pItems[index].a.eScript);
|
||||
|
||||
if (strength && strength[cnt] != 0)
|
||||
str = strength[cnt];
|
||||
|
||||
index++;
|
||||
if (index+1 > cMaxItems)
|
||||
return E_OUTOFMEMORY;
|
||||
|
@ -700,6 +716,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
|
|||
/* Set SCRIPT_ITEM */
|
||||
pItems[index].iCharPos = cnt; /* the last item contains the ptr to the lastchar */
|
||||
heap_free(levels);
|
||||
heap_free(strength);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,8 @@ typedef struct {
|
|||
|
||||
BOOL BIDI_DetermineLevels( LPCWSTR lpString, INT uCount, const SCRIPT_STATE *s,
|
||||
const SCRIPT_CONTROL *c, WORD *lpOutLevels );
|
||||
|
||||
BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c,
|
||||
WORD* lpStrength);
|
||||
INT BIDI_ReorderV2lLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse);
|
||||
INT BIDI_ReorderL2vLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse);
|
||||
void SHAPE_ContextualShaping(HDC hdc, ScriptCache *psc, SCRIPT_ANALYSIS *psa, WCHAR* pwcChars, INT cChars, WORD* pwOutGlyphs, INT* pcGlyphs, INT cMaxGlyphs, WORD *pwLogClust);
|
||||
|
|
Loading…
Reference in New Issue