From c7b4964b7e306cc6f5d27b68c769142a9b0f63fe Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Thu, 17 Mar 2011 14:46:15 -0500 Subject: [PATCH] usp10: Rewrite of ScriptXtoCP to handle pwLogClust for LTR and RTL runs. --- dlls/usp10/tests/usp10.c | 403 ++++++++++++--------------------------- dlls/usp10/usp10.c | 134 ++++++++++--- 2 files changed, 234 insertions(+), 303 deletions(-) diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c index 5b7fa97b48a..83bdd878214 100644 --- a/dlls/usp10/tests/usp10.c +++ b/dlls/usp10/tests/usp10.c @@ -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) diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index 10ffed0e8dc..9f1300d8a61 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -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; }