From 8d139c8b960249e9513492b7ca16d9311b4ef1de Mon Sep 17 00:00:00 2001 From: Jeff Latimer Date: Thu, 20 Jul 2006 22:16:50 +1000 Subject: [PATCH] usp10: Add functionality for ScriptXtoCP and ScriptCPtoX calls. --- dlls/usp10/tests/usp10.c | 91 ++++++++++++++++++++++++++++++++++++++++ dlls/usp10/usp10.c | 47 ++++++++++++++++++--- 2 files changed, 133 insertions(+), 5 deletions(-) diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c index cbaf44a0388..2a3d9c42aa1 100644 --- a/dlls/usp10/tests/usp10.c +++ b/dlls/usp10/tests/usp10.c @@ -487,6 +487,96 @@ void test_ScriptTextOut(void) DestroyWindow(hwnd); } +static void test_ScriptXtoX(void) +/**************************************************************************************** + * This routine tests the ScriptXtoCP and ScriptCPtoX functions using static variables * + ****************************************************************************************/ +{ + int iX, iCP; + int cChars; + int cGlyphs; + WORD pwLogClust[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + SCRIPT_VISATTR psva[10]; + int piAdvance[10] = {200, 190, 210, 180, 170, 204, 189, 195, 212, 203}; + SCRIPT_ANALYSIS psa; + int piCP, piX; + int piTrailing; + BOOL fTrailing; + HRESULT hr; + + iX = -1; + cChars = 10; + cGlyphs = 10; + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr); + ok(piCP == -1, "Negative iX should return piCP=-1 not %d\n", piCP); + ok(piTrailing == TRUE, "Negative iX should return piTrailing=TRUE not %d", piTrailing); + iX = 1954; + cChars = 10; + cGlyphs = 10; + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr); + ok(piCP == 10, "Excessive iX should return piCP=10 not %d\n", piCP); + ok(piTrailing == FALSE, "Excessive iX should return piTrailing=FALSE not %d\n", piTrailing); + iX = 779; + cChars = 10; + cGlyphs = 10; + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr); + ok(piCP == 3, "iX=%d should return piCP=3 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, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr); + ok(piCP == 3, "iX=%d should return piCP=3 not %d\n", iX, piCP); + ok(piTrailing == 1, "iX=%d should return piTrailing=1 not %d\n", iX, piTrailing); + iX = 868; + cChars = 10; + cGlyphs = 10; + hr = ScriptXtoCP(iX, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piCP, &piTrailing); + ok(hr == S_OK, "ScriptXtoCP should return S_OK not %d\n", (unsigned int) hr); + ok(piCP == 4, "iX=%d should return piCP=4 not %d\n", iX, piCP); + + iCP=5; + fTrailing = FALSE; + cChars = 10; + cGlyphs = 10; + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr); + ok(piX == 976, "iCP=%d should return piX=976 not %d\n", iCP, piX); + iCP=5; + fTrailing = TRUE; + cChars = 10; + cGlyphs = 10; + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr); + ok(piX == 1171, "iCP=%d should return piX=1171 not %d\n", iCP, piX); + iCP=6; + fTrailing = FALSE; + cChars = 10; + cGlyphs = 10; + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr); + ok(piX == 1171, "iCP=%d should return piX=1171 not %d\n", iCP, piX); + iCP=11; + fTrailing = FALSE; + cChars = 10; + cGlyphs = 10; + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr); + ok(piX == 1953, "iCP=%d should return piX=1953 not %d\n", iCP, piX); + iCP=11; + fTrailing = TRUE; + cChars = 10; + cGlyphs = 10; + hr = ScriptCPtoX(iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, &psa, &piX); + ok(hr == S_OK, "ScriptCPtoX should return S_OK not %d\n", (unsigned int) hr); + ok(piX == 1953, "iCP=%d should return piX=1953 not %d\n", iCP, piX); + +} + static void test_ScriptString(void) { HRESULT hr; @@ -569,5 +659,6 @@ START_TEST(usp10) test_ScriptGetCMap(pwOutGlyphs); test_ScriptGetFontProperties(); test_ScriptTextOut(); + test_ScriptXtoX(); test_ScriptString(); } diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index aa394498867..9e020072407 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -362,11 +362,20 @@ HRESULT WINAPI ScriptCPtoX(int iCP, const SCRIPT_ANALYSIS *psa, int *piX) { - FIXME("(%d,%d,%d,%d,%p,%p,%p,%p,%p): stub\n", + int item; + int iPosX; + float fMaxPosX = 0; + TRACE("(%d,%d,%d,%d,%p,%p,%p,%p,%p)\n", iCP, fTrailing, cChars, cGlyphs, pwLogClust, psva, piAdvance, psa, piX); + for (item=0; item < cGlyphs; item++) /* total piAdvance */ + fMaxPosX += piAdvance[item]; + iPosX = (fMaxPosX/cGlyphs)*(iCP+fTrailing); + if (iPosX > fMaxPosX) + iPosX = fMaxPosX; + *piX = iPosX; /* Return something in range */ - *piX = 1; /* Return something in range */ + TRACE("*piX=%d\n", *piX); return S_OK; } @@ -384,12 +393,40 @@ HRESULT WINAPI ScriptXtoCP(int iX, int *piCP, int *piTrailing) { - FIXME("(%d,%d,%d,%p,%p,%p,%p,%p,%p): stub\n", + int item; + int iPosX = 1; + float fMaxPosX = 1; + float fAvePosX; + 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 */ + { + *piCP = -1; + *piTrailing = TRUE; + return S_OK; + } - *piCP = 1; /* Return something in range */ - *piTrailing = 0; + 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; + for (item = 0; item < cGlyphs && iPosX < iX; item++) + iPosX = fAvePosX * (item +1); + if (iPosX - iX > fAvePosX/2) + *piTrailing = 0; + else + *piTrailing = 1; /* yep we are over half way */ + + *piCP = item -1; /* Return character position */ + TRACE("*piCP=%d iPposX=%d\n", *piCP, iPosX); return S_OK; }