Module: wine Branch: master Commit: 3f7ad460ef159f6e71b6909e1ced0ce698ce4ba3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3f7ad460ef159f6e71b6909e1c...
Author: Aric Stewart aric@codeweavers.com Date: Fri Mar 11 12:47:37 2011 -0600
usp10: Update ScriptCPtoX to handle RTL runs.
---
dlls/usp10/tests/usp10.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++ dlls/usp10/usp10.c | 37 ++++++++++++++- 2 files changed, 146 insertions(+), 2 deletions(-)
diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c index 1145ca9..5b7fa97 100644 --- a/dlls/usp10/tests/usp10.c +++ b/dlls/usp10/tests/usp10.c @@ -1076,6 +1076,7 @@ static void test_ScriptXtoX(void) 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}; SCRIPT_VISATTR psva[10]; int piAdvance[10] = {200, 190, 210, 180, 170, 204, 189, 195, 212, 203}; int piCP, piX; @@ -1276,6 +1277,116 @@ static void test_ScriptXtoX(void) 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); + + 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); + + 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); }
static void test_ScriptString(HDC hdc) diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index b58b60e..d575425 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -1106,13 +1106,39 @@ HRESULT WINAPI ScriptCPtoX(int iCP, int iCluster = -1; int clust_size = 1; float special_size = 0.0; + int iMaxPos = 0; + BOOL rtl = FALSE;
TRACE("(%d,%d,%d,%d,%p,%p,%p,%p,%p)\n", iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, psa, piX);
+ if (psa->fRTL && ! psa->fLogicalOrder) + rtl = TRUE; + if (fTrailing) - iCP++; + { + if (rtl) + iCP--; + else + iCP++; + } + + if (rtl) + { + int max_clust = pwLogClust[0]; + + for (item=0; item < cGlyphs; item++) + if (pwLogClust[item] > max_clust) + { + ERR("We do not handle non reversed clusters properly\n"); + break; + } + + iMaxPos = 0; + for (item = max_clust; item >=0; item --) + iMaxPos += piAdvance[item]; + }
iPosX = 0.0; for (item=0; item < iCP && item < cGlyphs; item++) @@ -1136,7 +1162,7 @@ HRESULT WINAPI ScriptCPtoX(int iCP, else break; }
- if (check >= cGlyphs) + if (check >= cGlyphs && !iMaxPos) { for (check = clust; check < cGlyphs; check++) special_size += piAdvance[check]; @@ -1153,6 +1179,13 @@ HRESULT WINAPI ScriptCPtoX(int iCP, iPosX += piAdvance[pwLogClust[iCluster]] / (float)clust_size; }
+ if (iMaxPos > 0) + { + iPosX = iMaxPos - iPosX; + if (iPosX < 0) + iPosX = 0; + } + *piX = iPosX; TRACE("*piX=%d\n", *piX); return S_OK;