usp10: Rewrite of ScriptXtoCP to handle pwLogClust for LTR and RTL runs.

This commit is contained in:
Aric Stewart 2011-03-17 14:46:15 -05:00 committed by Alexandre Julliard
parent 7acd2ba264
commit c7b4964b7e
2 changed files with 234 additions and 303 deletions

View File

@ -1074,15 +1074,16 @@ static void test_ScriptXtoX(void)
int iX, iCP;
int cChars;
int cGlyphs;
WORD pwLogClustXtoCP[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
WORD pwLogClustCPtoX[10] = {0, 0, 0, 1, 1, 2, 2, 3, 3, 3};
WORD pwLogClustCPtoX_RTL[10] = {3, 3, 3, 2, 2, 1, 1, 0, 0, 0};
WORD pwLogClust[10] = {0, 0, 0, 1, 1, 2, 2, 3, 3, 3};
WORD pwLogClust_RTL[10] = {3, 3, 3, 2, 2, 1, 1, 0, 0, 0};
SCRIPT_VISATTR psva[10];
int piAdvance[10] = {200, 190, 210, 180, 170, 204, 189, 195, 212, 203};
int piCP, piX;
int piTrailing;
BOOL fTrailing;
HRESULT hr;
static const int offsets[13] = {0, 66, 133, 200, 295, 390, 495, 600, 1051, 1502, 1953, 1953, 1953};
static const int offsets_RTL[13] = {780, 720, 660, 600, 495, 390, 295, 200, 133, 66, 0, 0, 0};
hr = ScriptItemize(test, lstrlenW(test), sizeof(items)/sizeof(items[0]), NULL, NULL, items, NULL);
ok(!hr, "ScriptItemize should return S_OK not %08x\n", hr);
@ -1090,7 +1091,53 @@ static void test_ScriptXtoX(void)
iX = -1;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClustXtoCP, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
if (piTrailing)
ok(piCP == -1, "Negative iX should return piCP=-1 not %d\n", piCP);
else /* win2k3 */
ok(piCP == 10, "Negative iX should return piCP=10 not %d\n", piCP);
for(iCP = 0; iCP < 10; iCP++)
{
iX = offsets[iCP]+1;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == iCP, "iX=%d should return piCP=%d not %d\n", iX, iCP, piCP);
ok(piTrailing == 0, "iX=%d should return piTrailing=0 not %d\n", iX, piTrailing);
}
for(iCP = 0; iCP < 10; iCP++)
{
iX = offsets[iCP+1]-1;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == iCP, "iX=%d should return piCP=%d not %d\n", iX, iCP, piCP);
ok(piTrailing == 1, "iX=%d should return piTrailing=1 not %d\n", iX, piTrailing);
}
/* 0,1,2 are actaully fractional offsets meaning that they will not be reporting the same iCP as comes in so dont test those */
for(iCP = 3; iCP < 10; iCP++)
{
iX = offsets[iCP];
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == iCP, "iX=%d should return piCP=%d not %d\n", iX, iCP, piCP);
ok(piTrailing == 0, "iX=%d should return piTrailing=0 not %d\n", iX, piTrailing);
}
items[0].a.fRTL = TRUE;
iX = -1;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust_RTL, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
if (piTrailing)
ok(piCP == -1, "Negative iX should return piCP=-1 not %d\n", piCP);
@ -1100,293 +1147,91 @@ static void test_ScriptXtoX(void)
iX = 1954;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClustXtoCP, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust_RTL, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
if (piTrailing) /* win2k3 */
ok(piCP == -1, "Negative iX should return piCP=-1 not %d\n", piCP);
else
ok(piCP == 10, "Negative iX should return piCP=10 not %d\n", piCP);
iX = 779;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClustXtoCP, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == 3 ||
piCP == -1, /* win2k3 */
"iX=%d should return piCP=3 or piCP=-1 not %d\n", iX, piCP);
ok(piCP == -1, "iX=%d should return piCP=-1 not %d\n", iX, piCP);
ok(piTrailing == 1, "iX=%d should return piTrailing=1 not %d\n", iX, piTrailing);
iX = 780;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClustXtoCP, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == 3 ||
piCP == -1, /* win2k3 */
"iX=%d should return piCP=3 or piCP=-1 not %d\n", iX, piCP);
ok(piTrailing == 1, "iX=%d should return piTrailing=1 not %d\n", iX, piTrailing);
for(iCP = 0; iCP < 10; iCP++)
{
iX = offsets_RTL[iCP]-1;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust_RTL, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == iCP, "iX=%d should return piCP=%d not %d\n", iX, iCP, piCP);
ok(piTrailing == 0, "iX=%d should return piTrailing=0 not %d\n", iX, piTrailing);
}
iX = 868;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClustXtoCP, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == 4 ||
piCP == -1, /* win2k3 */
"iX=%d should return piCP=4 or piCP=-1 not %d\n", iX, piCP);
for(iCP = 0; iCP < 10; iCP++)
{
iX = offsets_RTL[iCP+1]+1;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust_RTL, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == iCP, "iX=%d should return piCP=%d not %d\n", iX, iCP, piCP);
ok(piTrailing == 1, "iX=%d should return piTrailing=1 not %d\n", iX, piTrailing);
}
iX = 0;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClustXtoCP, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == 0 ||
piCP == 10, /* win2k3 */
"iX=%d should return piCP=0 piCP=10 not %d\n", iX, piCP);
for(iCP = 0; iCP < 10; iCP++)
{
iX = offsets_RTL[iCP];
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust_RTL, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == iCP, "iX=%d should return piCP=%d not %d\n", iX, iCP, piCP);
ok(piTrailing == 0, "iX=%d should return piTrailing=0 not %d\n", iX, piTrailing);
}
iX = 195;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClustXtoCP, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == 0, "iX=%d should return piCP=0 not %d\n", iX, piCP);
items[0].a.fRTL = FALSE;
iX = 196;
cChars = 10;
cGlyphs = 10;
hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClustXtoCP, psva, piAdvance, &items[0].a, &piCP, &piTrailing);
ok(hr == S_OK, "ScriptXtoCP should return S_OK not %08x\n", hr);
ok(piCP == 1 ||
piCP == 0, /* win2k3 */
"iX=%d should return piCP=1 or piCP=0 not %d\n", iX, piCP);
for(iCP = 0; iCP <= 11; iCP++)
{
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == offsets[iCP],
"iCP=%d should return piX=%d not %d\n", iCP, offsets[iCP], piX);
}
iCP=0;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 0,
"iCP=%d should return piX=0 not %d\n", iCP, piX);
iCP=1;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 66,
"iCP=%d should return piX=66 not %d\n", iCP, piX);
iCP=2;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 133,
"iCP=%d should return piX=133 not %d\n", iCP, piX);
iCP=3;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 200,
"iCP=%d should return piX=200 not %d\n", iCP, piX);
iCP=4;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 295,
"iCP=%d should return piX=295 not %d\n", iCP, piX);
iCP=5;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 390,
"iCP=%d should return piX=390 not %d\n", iCP, piX);
iCP=6;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 495,
"iCP=%d should return piX=495 not %d\n", iCP, piX);
iCP=7;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 600,
"iCP=%d should return piX=600 not %d\n", iCP, piX);
iCP=8;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 1051,
"iCP=%d should return piX=1051 not %d\n", iCP, piX);
iCP=9;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 1502,
"iCP=%d should return piX=1502 not %d\n", iCP, piX);
iCP=10;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 1953,
"iCP=%d should return piX=1953 not %d\n", iCP, piX);
iCP=11;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 1953,
"iCP=%d should return piX=1953 %d\n", iCP, piX);
iCP=11;
fTrailing = TRUE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 1953,
"iCP=%d should return piX=1953 not %d\n", iCP, piX);
for(iCP = 0; iCP <= 11; iCP++)
{
fTrailing = TRUE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == offsets[iCP+1],
"iCP=%d should return piX=%d not %d\n", iCP, offsets[iCP+1], piX);
}
items[0].a.fRTL = TRUE;
iCP=0;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 780,
"iCP=%d should return piX=780 not %d\n", iCP, piX);
for(iCP = 0; iCP <= 11; iCP++)
{
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == offsets_RTL[iCP],
"iCP=%d should return piX=%d not %d\n", iCP, offsets_RTL[iCP], piX);
}
iCP=1;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 720,
"iCP=%d should return piX=720 not %d\n", iCP, piX);
iCP=2;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 660,
"iCP=%d should return piX=660 not %d\n", iCP, piX);
iCP=3;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 600,
"iCP=%d should return piX=600 not %d\n", iCP, piX);
iCP=4;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 495,
"iCP=%d should return piX=495 not %d\n", iCP, piX);
iCP=5;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 390,
"iCP=%d should return piX=390 not %d\n", iCP, piX);
iCP=6;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 295,
"iCP=%d should return piX=295 not %d\n", iCP, piX);
iCP=7;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 200,
"iCP=%d should return piX=200 not %d\n", iCP, piX);
iCP=8;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 133,
"iCP=%d should return piX=133 not %d\n", iCP, piX);
iCP=9;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 66,
"iCP=%d should return piX=66 not %d\n", iCP, piX);
iCP=10;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 0,
"iCP=%d should return piX=0 not %d\n", iCP, piX);
iCP=11;
fTrailing = FALSE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClustCPtoX_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == 0,
"iCP=%d should return piX=0 %d\n", iCP, piX);
for(iCP = 0; iCP <= 11; iCP++)
{
fTrailing = TRUE;
cChars = 10;
cGlyphs = 10;
hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust_RTL, psva, piAdvance, &items[0].a, &piX);
ok(hr == S_OK, "ScriptCPtoX should return S_OK not %08x\n", hr);
ok(piX == offsets_RTL[iCP+1],
"iCP=%d should return piX=%d not %d\n", iCP, offsets_RTL[iCP+1], piX);
}
}
static void test_ScriptString(HDC hdc)

View File

@ -1201,40 +1201,126 @@ HRESULT WINAPI ScriptXtoCP(int iX,
int *piTrailing)
{
int item;
int iPosX;
float fMaxPosX = 1;
float fAvePosX;
float iPosX;
float iLastPosX;
int iSpecial = -1;
int iCluster = -1;
int clust_size = 1;
float special_size = 0.0;
int direction = 1;
TRACE("(%d,%d,%d,%p,%p,%p,%p,%p,%p)\n",
iX, cChars, cGlyphs, pwLogClust, psva, piAdvance,
psa, piCP, piTrailing);
if (iX < 0) /* iX is before start of run */
if (psa->fRTL && ! psa->fLogicalOrder)
direction = -1;
if (direction<0)
{
int max_clust = pwLogClust[0];
if (iX < 0)
{
*piCP = cGlyphs;
*piTrailing = 0;
return S_OK;
}
for (item=0; item < cGlyphs; item++)
if (pwLogClust[item] > max_clust)
{
ERR("We do not handle non reversed clusters properly\n");
break;
}
}
if (iX < 0)
{
*piCP = -1;
*piTrailing = TRUE;
*piTrailing = 1;
return S_OK;
}
for (item=0; item < cGlyphs; item++) /* total piAdvance */
fMaxPosX += piAdvance[item];
if (iX >= fMaxPosX) /* iX too large */
{
*piCP = cChars;
*piTrailing = FALSE;
return S_OK;
}
fAvePosX = fMaxPosX / cGlyphs;
iPosX = fAvePosX;
for (item = 1; item < cGlyphs && iPosX < iX; item++)
iPosX += fAvePosX;
if (iPosX - iX > fAvePosX/2)
*piTrailing = 0;
iPosX = iLastPosX = 0;
if (direction > 0)
item = 0;
else
*piTrailing = 1; /* yep we are over halfway */
item = cGlyphs - 1;
for (; iPosX <= iX && item < cGlyphs && item >= 0; item+=direction)
{
iLastPosX = iPosX;
if (iSpecial == -1 &&
(iCluster == -1 ||
(iCluster != -1 &&
((direction > 0 && iCluster+clust_size <= item) ||
(direction < 0 && iCluster-clust_size >= item))
)
)
)
{
int check;
int clust = pwLogClust[item];
*piCP = item -1; /* Return character position */
TRACE("*piCP=%d iPposX=%d\n", *piCP, iPosX);
clust_size = 1;
iCluster = -1;
for (check = item+direction; check < cGlyphs && check >= 0; check+=direction)
{
if (pwLogClust[check] == clust)
{
clust_size ++;
if (iCluster == -1)
iCluster = item;
}
else break;
}
if (check >= cGlyphs && direction > 0)
{
for (check = clust; check < cGlyphs; check++)
special_size += piAdvance[check];
iSpecial = item;
special_size /= (cChars - item);
iPosX += special_size;
}
else
iPosX += piAdvance[clust] / (float)clust_size;
}
else if (iSpecial != -1)
iPosX += special_size;
else /* (iCluster != -1) */
iPosX += piAdvance[pwLogClust[iCluster]] / (float)clust_size;
}
if (direction > 0)
{
if (iPosX > iX)
item--;
if (item < cGlyphs && ((iPosX - iLastPosX) / 2.0) + iX > iPosX)
*piTrailing = 1;
else
*piTrailing = 0;
}
else
{
if (iX == iLastPosX)
item++;
if (iX >= iLastPosX && iX <= iPosX)
item++;
if (iLastPosX == iX)
*piTrailing = 0;
else if (item < 0 || ((iLastPosX - iPosX) / 2.0) + iX <= iLastPosX)
*piTrailing = 1;
else
*piTrailing = 0;
}
*piCP = item;
TRACE("*piCP=%d\n", *piCP);
TRACE("*piTrailing=%d\n", *piTrailing);
return S_OK;
}