Re: usp10: implement ScriptStringAnalyse, ScriptStringFree, ScriptStringXtoCP, ScriptStringCPtoX
Hi, Can I get some feedback on this patch? It appears to have been rejected. Thanks, Clinton Clinton Stimpson wrote:
This patch implements ScriptStringAnalyse, ScriptStringFree, ScriptStringXtoCP, ScriptStringCPtoX.
Also, many todo_wine's are removed.
Thanks, Clinton Stimpson
ChangeLog Implement ScriptStringAnalyse, ScriptStringFree, ScriptStringXtoCP, ScriptStringCPtoX
------------------------------------------------------------------------
Index: dlls/usp10/usp10.c =================================================================== RCS file: /home/wine/wine/dlls/usp10/usp10.c,v retrieving revision 1.45 diff -u -r1.45 usp10.c --- dlls/usp10/usp10.c 12 Dec 2006 20:30:48 -0000 1.45 +++ dlls/usp10/usp10.c 13 Dec 2006 03:28:30 -0000 @@ -73,6 +73,46 @@ HDC hdc; } Scriptcache;
+typedef struct { + int numGlyphs; + WORD* glyphs; + WORD* pwLogClust; + int* piAdvance; + SCRIPT_VISATTR* psva; + GOFFSET* pGoffset; + ABC* abc; +} StringGlyphs; + +typedef struct { + BOOL invalid; + HDC hdc; + int cItems; + int cMaxGlyphs; + SCRIPT_ITEM* pItem; + int numItems; + StringGlyphs* glyphs; + SIZE* sz; +} StringAnalysis; + +static void ME_StringAnalysisFree(StringAnalysis* analysis) +{ + int i; + for(i=0; i<analysis->numItems; i++) + { + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].glyphs); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].pwLogClust); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].piAdvance); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].psva); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].pGoffset); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].abc); + } + + HeapFree(GetProcessHeap(), 0, analysis->glyphs); + HeapFree(GetProcessHeap(), 0, analysis->pItem); + + HeapFree(GetProcessHeap(), 0, analysis); +} + /*********************************************************************** * DllMain * @@ -448,9 +488,16 @@ const BYTE *pbInClass, SCRIPT_STRING_ANALYSIS *pssa) { - FIXME("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p): stub\n", - hdc, pString, cString, cGlyphs, iCharset, dwFlags, - iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa); + HRESULT hr; + StringAnalysis* analysis; + int numItemizedItems; + int i; + SCRIPT_CACHE* sc = 0; + + TRACE("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p)\n", + hdc, pString, cString, cGlyphs, iCharset, dwFlags, + iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa); + if (1 > cString || NULL == pString) { return E_INVALIDARG; } @@ -458,7 +505,64 @@ return E_PENDING; }
- return E_NOTIMPL; + analysis = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(StringAnalysis)); + + analysis->hdc = hdc; + numItemizedItems = 255; + analysis->pItem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + numItemizedItems*sizeof(SCRIPT_ITEM)+1); + + hr = ScriptItemize(pString, cString, numItemizedItems, psControl, + psState, analysis->pItem, &analysis->numItems); + + while(hr == E_OUTOFMEMORY) + { + numItemizedItems *= 2; + HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, analysis->pItem, + numItemizedItems*sizeof(SCRIPT_ITEM)+1); + hr = ScriptItemize(pString, cString, numItemizedItems, psControl, + psState, analysis->pItem, &analysis->numItems); + } + + analysis->glyphs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(StringGlyphs)*analysis->numItems); + sc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SCRIPT_CACHE)); + + for(i=0; i<analysis->numItems; i++) + { + int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos; + int numGlyphs = 1.5 * cChar + 16; + WORD* glyphs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WORD)*numGlyphs); + WORD* pwLogClust = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WORD)*cChar); + int* piAdvance = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(int)*numGlyphs); + SCRIPT_VISATTR* psva = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SCRIPT_VISATTR)*cChar); + GOFFSET* pGoffset = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GOFFSET)*numGlyphs); + ABC* abc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ABC)); + int numGlyphsReturned; + + /* FIXME: non unicode strings */ + WCHAR* pStr = (WCHAR*)pString; + hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], + cChar, numGlyphs, &analysis->pItem[i].a, + glyphs, pwLogClust, psva, &numGlyphsReturned); + hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a, + piAdvance, pGoffset, abc); + + analysis->glyphs[i].numGlyphs = numGlyphsReturned; + analysis->glyphs[i].glyphs = glyphs; + analysis->glyphs[i].pwLogClust = pwLogClust; + analysis->glyphs[i].piAdvance = piAdvance; + analysis->glyphs[i].psva = psva; + analysis->glyphs[i].pGoffset = pGoffset; + analysis->glyphs[i].abc = abc; + } + + HeapFree(GetProcessHeap(), 0, sc); + + *pssa = analysis; + + return S_OK; }
/*********************************************************************** @@ -489,9 +593,46 @@ */ HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int* pX) { - FIXME("(%p), %d, %d, (%p): stub\n", ssa, icp, fTrailing, pX); - *pX = 0; /* Set a reasonable value */ - return S_OK; + int i, j; + int runningX = 0; + int runningCp = 0; + StringAnalysis* analysis = ssa; + TRACE("(%p), %d, %d, (%p)\n", ssa, icp, fTrailing, pX); + + if(!ssa || !pX) + { + return 1; + } + + /* icp out of range */ + if(icp < 0) + { + analysis->invalid = TRUE; + return E_INVALIDARG; + } + + for(i=0; i<analysis->numItems; i++) + { + for(j=0; j<analysis->glyphs[i].numGlyphs; j++) + { + if(runningCp == icp && fTrailing == FALSE) + { + *pX = runningX; + return S_OK; + } + runningX += analysis->glyphs[i].piAdvance[j]; + if(runningCp == icp && fTrailing == TRUE) + { + *pX = runningX; + return S_OK; + } + runningCp++; + } + } + + /* icp out of range */ + analysis->invalid = TRUE; + return E_INVALIDARG; }
/*********************************************************************** @@ -500,19 +641,79 @@ */ HRESULT WINAPI ScriptStringXtoCP(SCRIPT_STRING_ANALYSIS ssa, int iX, int* piCh, int* piTrailing) { - FIXME("(%p), %d, (%p), (%p): stub\n", ssa, iX, piCh, piTrailing); - *piCh = 0; /* Set a reasonable value */ - *piTrailing = 0; + StringAnalysis* analysis = ssa; + int i; + int j; + int runningX = 0; + int runningCp = 0; + int width; + + TRACE("(%p), %d, (%p), (%p)\n", ssa, iX, piCh, piTrailing); + + if(!ssa || !piCh || !piTrailing) + { + return 1; + } + + /* out of range */ + if(iX < 0) + { + *piCh = -1; + *piTrailing = TRUE; return S_OK; + } + + for(i=0; i<analysis->numItems; i++) + { + for(j=0; j<analysis->glyphs[i].numGlyphs; j++) + { + width = analysis->glyphs[i].piAdvance[j]; + if(iX < (runningX + width)) + { + *piCh = runningCp; + if((iX - runningX) > width/2) + *piTrailing = TRUE; + else + *piTrailing = FALSE; + return S_OK; + } + runningX += width; + runningCp++; + } + } + + /* out of range */ + *piCh = analysis->pItem[analysis->numItems].iCharPos; + *piTrailing = FALSE; + + return S_OK; }
/*********************************************************************** * ScriptStringFree (USP10.@) * */ -HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) { - FIXME("(%p): stub\n",pssa); - return S_OK; +HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) +{ + StringAnalysis* analysis; + BOOL invalid; + TRACE("(%p)\n",pssa); + + if(!pssa) + return E_INVALIDARG; + + analysis = *pssa; + if(!analysis) + return E_INVALIDARG; + + invalid = analysis->invalid; + + ME_StringAnalysisFree(analysis); + + if(invalid) + return E_INVALIDARG; + + return S_OK; }
/*********************************************************************** Index: dlls/usp10/tests/usp10.c =================================================================== RCS file: /home/wine/wine/dlls/usp10/tests/usp10.c,v retrieving revision 1.30 diff -u -r1.30 usp10.c --- dlls/usp10/tests/usp10.c 12 Dec 2006 20:30:48 -0000 1.30 +++ dlls/usp10/tests/usp10.c 13 Dec 2006 03:28:30 -0000 @@ -701,21 +701,21 @@ hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags, ReqWidth, &Control, &State, Dx, &Tabdef, &InClass, &ssa); - todo_wine ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr);
/* test makes sure that a call with a valid pssa still works */ hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags, ReqWidth, &Control, &State, Dx, &Tabdef, &InClass, &ssa); - todo_wine ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); - todo_wine ok(ssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n"); + ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); + ok(ssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n");
if (hr == 0) { hr = ScriptStringOut(ssa, X, Y, Options, &rc, MinSel, MaxSel, Disabled); todo_wine ok(hr == S_OK, "ScriptStringOut should return S_OK not %08x\n", hr); hr = ScriptStringFree(&ssa); - todo_wine ok(hr == S_OK, "ScriptStringFree should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringFree should return S_OK not %08x\n", hr); } }
@@ -774,8 +774,8 @@ hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, Flags, ReqWidth, &Control, &State, NULL, &Tabdef, &InClass, &ssa); - todo_wine ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); - todo_wine ok(ssa != NULL, "ScriptStringAnalyse ssa should not be NULL\n"); + ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); + ok(ssa != NULL, "ScriptStringAnalyse ssa should not be NULL\n"); if (hr == 0) { /* @@ -792,25 +792,25 @@ */ fTrailing = FALSE; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); - todo_wine ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); - todo_wine ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); + ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", iTrailing, X); fTrailing = TRUE; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr);
/* * Check that character position returned by ScriptStringXtoCP in Ch matches the * one input to ScriptStringCPtoX. This means that the Cp to X position and back * again works */ - todo_wine ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); - todo_wine ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", + ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); + ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", iTrailing, X); }
@@ -821,12 +821,12 @@ fTrailing = TRUE; Cp = 3; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); X--; /* put X just inside the trailing edge */ hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); - todo_wine ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); - todo_wine ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); + ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", iTrailing, X);
/* @@ -837,12 +837,12 @@ fTrailing = TRUE; Cp = 3; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); X++; /* put X just outside the trailing edge */ hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); - todo_wine ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); - todo_wine ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); + ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", iTrailing, X);
/* @@ -853,19 +853,19 @@ fTrailing = FALSE; Cp = 3; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); X--; /* put X just outside the leading edge */ hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); - todo_wine ok(Cp - 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp - 1, Ch, X); - todo_wine ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(Cp - 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp - 1, Ch, X); + ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", iTrailing, X);
/* * Cleanup the the SSA for the next round of tests */ hr = ScriptStringFree(&ssa); - todo_wine ok(hr == S_OK, "ScriptStringFree should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringFree should return S_OK not %08x\n", hr);
/* * Test to see that exceeding the number of chars returns E_INVALIDARG. First @@ -874,7 +874,7 @@ hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, Flags, ReqWidth, &Control, &State, NULL, &Tabdef, &InClass, &ssa); - todo_wine ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr);
/* * When ScriptStringCPtoX is called with a character position Cp that exceeds the @@ -884,13 +884,13 @@ fTrailing = FALSE; Cp = String_len + 1; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == E_INVALIDARG, "ScriptStringCPtoX should return E_INVALIDARG not %08x\n", hr); + ok(hr == E_INVALIDARG, "ScriptStringCPtoX should return E_INVALIDARG not %08x\n", hr);
hr = ScriptStringFree(&ssa); /* * ScriptStringCPtoX should free ssa, hence ScriptStringFree should fail */ - todo_wine ok(hr == E_INVALIDARG, "ScriptStringFree should return E_INVALIDARG not %08x\n", hr); + ok(hr == E_INVALIDARG, "ScriptStringFree should return E_INVALIDARG not %08x\n", hr); } }
------------------------------------------------------------------------
Am Donnerstag 14 Dezember 2006 15:58 schrieb Clinton Stimpson:
Hi,
Can I get some feedback on this patch? It appears to have been rejected. I don't know about the details of usp10, but from the topic of your mail I think you should send 4 patches, one for each function.
Hi, It may be because you need to split it into smaller individual patches. Its rather a one big patch. Cheers, VJ On 12/14/06, Clinton Stimpson <cjstimpson(a)utwire.net> wrote:
Hi,
Can I get some feedback on this patch? It appears to have been rejected.
Thanks, Clinton
Clinton Stimpson wrote:
This patch implements ScriptStringAnalyse, ScriptStringFree, ScriptStringXtoCP, ScriptStringCPtoX.
Also, many todo_wine's are removed.
Thanks, Clinton Stimpson
ChangeLog Implement ScriptStringAnalyse, ScriptStringFree, ScriptStringXtoCP, ScriptStringCPtoX
------------------------------------------------------------------------
Index: dlls/usp10/usp10.c =================================================================== RCS file: /home/wine/wine/dlls/usp10/usp10.c,v retrieving revision 1.45 diff -u -r1.45 usp10.c --- dlls/usp10/usp10.c 12 Dec 2006 20:30:48 -0000 1.45 +++ dlls/usp10/usp10.c 13 Dec 2006 03:28:30 -0000 @@ -73,6 +73,46 @@ HDC hdc; } Scriptcache;
+typedef struct { + int numGlyphs; + WORD* glyphs; + WORD* pwLogClust; + int* piAdvance; + SCRIPT_VISATTR* psva; + GOFFSET* pGoffset; + ABC* abc; +} StringGlyphs; + +typedef struct { + BOOL invalid; + HDC hdc; + int cItems; + int cMaxGlyphs; + SCRIPT_ITEM* pItem; + int numItems; + StringGlyphs* glyphs; + SIZE* sz; +} StringAnalysis; + +static void ME_StringAnalysisFree(StringAnalysis* analysis) +{ + int i; + for(i=0; i<analysis->numItems; i++) + { + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].glyphs); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].pwLogClust); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].piAdvance); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].psva); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].pGoffset); + HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].abc); + } + + HeapFree(GetProcessHeap(), 0, analysis->glyphs); + HeapFree(GetProcessHeap(), 0, analysis->pItem); + + HeapFree(GetProcessHeap(), 0, analysis); +} + /*********************************************************************** * DllMain * @@ -448,9 +488,16 @@ const BYTE *pbInClass, SCRIPT_STRING_ANALYSIS *pssa) { - FIXME("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p): stub\n", - hdc, pString, cString, cGlyphs, iCharset, dwFlags, - iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa); + HRESULT hr; + StringAnalysis* analysis; + int numItemizedItems; + int i; + SCRIPT_CACHE* sc = 0; + + TRACE("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p)\n", + hdc, pString, cString, cGlyphs, iCharset, dwFlags, + iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa); + if (1 > cString || NULL == pString) { return E_INVALIDARG; } @@ -458,7 +505,64 @@ return E_PENDING; }
- return E_NOTIMPL; + analysis = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(StringAnalysis)); + + analysis->hdc = hdc; + numItemizedItems = 255; + analysis->pItem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + numItemizedItems*sizeof(SCRIPT_ITEM)+1); + + hr = ScriptItemize(pString, cString, numItemizedItems, psControl, + psState, analysis->pItem, &analysis->numItems); + + while(hr == E_OUTOFMEMORY) + { + numItemizedItems *= 2; + HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, analysis->pItem, + numItemizedItems*sizeof(SCRIPT_ITEM)+1); + hr = ScriptItemize(pString, cString, numItemizedItems, psControl, + psState, analysis->pItem, &analysis->numItems); + } + + analysis->glyphs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(StringGlyphs)*analysis->numItems); + sc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SCRIPT_CACHE)); + + for(i=0; i<analysis->numItems; i++) + { + int cChar = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos; + int numGlyphs = 1.5 * cChar + 16; + WORD* glyphs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WORD)*numGlyphs); + WORD* pwLogClust = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WORD)*cChar); + int* piAdvance = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(int)*numGlyphs); + SCRIPT_VISATTR* psva = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SCRIPT_VISATTR)*cChar); + GOFFSET* pGoffset = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GOFFSET)*numGlyphs); + ABC* abc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ABC)); + int numGlyphsReturned; + + /* FIXME: non unicode strings */ + WCHAR* pStr = (WCHAR*)pString; + hr = ScriptShape(hdc, sc, &pStr[analysis->pItem[i].iCharPos], + cChar, numGlyphs, &analysis->pItem[i].a, + glyphs, pwLogClust, psva, &numGlyphsReturned); + hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a, + piAdvance, pGoffset, abc); + + analysis->glyphs[i].numGlyphs = numGlyphsReturned; + analysis->glyphs[i].glyphs = glyphs; + analysis->glyphs[i].pwLogClust = pwLogClust; + analysis->glyphs[i].piAdvance = piAdvance; + analysis->glyphs[i].psva = psva; + analysis->glyphs[i].pGoffset = pGoffset; + analysis->glyphs[i].abc = abc; + } + + HeapFree(GetProcessHeap(), 0, sc); + + *pssa = analysis; + + return S_OK; }
/*********************************************************************** @@ -489,9 +593,46 @@ */ HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int* pX) { - FIXME("(%p), %d, %d, (%p): stub\n", ssa, icp, fTrailing, pX); - *pX = 0; /* Set a reasonable value */ - return S_OK; + int i, j; + int runningX = 0; + int runningCp = 0; + StringAnalysis* analysis = ssa; + TRACE("(%p), %d, %d, (%p)\n", ssa, icp, fTrailing, pX); + + if(!ssa || !pX) + { + return 1; + } + + /* icp out of range */ + if(icp < 0) + { + analysis->invalid = TRUE; + return E_INVALIDARG; + } + + for(i=0; i<analysis->numItems; i++) + { + for(j=0; j<analysis->glyphs[i].numGlyphs; j++) + { + if(runningCp == icp && fTrailing == FALSE) + { + *pX = runningX; + return S_OK; + } + runningX += analysis->glyphs[i].piAdvance[j]; + if(runningCp == icp && fTrailing == TRUE) + { + *pX = runningX; + return S_OK; + } + runningCp++; + } + } + + /* icp out of range */ + analysis->invalid = TRUE; + return E_INVALIDARG; }
/*********************************************************************** @@ -500,19 +641,79 @@ */ HRESULT WINAPI ScriptStringXtoCP(SCRIPT_STRING_ANALYSIS ssa, int iX, int* piCh, int* piTrailing) { - FIXME("(%p), %d, (%p), (%p): stub\n", ssa, iX, piCh, piTrailing); - *piCh = 0; /* Set a reasonable value */ - *piTrailing = 0; + StringAnalysis* analysis = ssa; + int i; + int j; + int runningX = 0; + int runningCp = 0; + int width; + + TRACE("(%p), %d, (%p), (%p)\n", ssa, iX, piCh, piTrailing); + + if(!ssa || !piCh || !piTrailing) + { + return 1; + } + + /* out of range */ + if(iX < 0) + { + *piCh = -1; + *piTrailing = TRUE; return S_OK; + } + + for(i=0; i<analysis->numItems; i++) + { + for(j=0; j<analysis->glyphs[i].numGlyphs; j++) + { + width = analysis->glyphs[i].piAdvance[j]; + if(iX < (runningX + width)) + { + *piCh = runningCp; + if((iX - runningX) > width/2) + *piTrailing = TRUE; + else + *piTrailing = FALSE; + return S_OK; + } + runningX += width; + runningCp++; + } + } + + /* out of range */ + *piCh = analysis->pItem[analysis->numItems].iCharPos; + *piTrailing = FALSE; + + return S_OK; }
/*********************************************************************** * ScriptStringFree (USP10.@) * */ -HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) { - FIXME("(%p): stub\n",pssa); - return S_OK; +HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) +{ + StringAnalysis* analysis; + BOOL invalid; + TRACE("(%p)\n",pssa); + + if(!pssa) + return E_INVALIDARG; + + analysis = *pssa; + if(!analysis) + return E_INVALIDARG; + + invalid = analysis->invalid; + + ME_StringAnalysisFree(analysis); + + if(invalid) + return E_INVALIDARG; + + return S_OK; }
/*********************************************************************** Index: dlls/usp10/tests/usp10.c =================================================================== RCS file: /home/wine/wine/dlls/usp10/tests/usp10.c,v retrieving revision 1.30 diff -u -r1.30 usp10.c --- dlls/usp10/tests/usp10.c 12 Dec 2006 20:30:48 -0000 1.30 +++ dlls/usp10/tests/usp10.c 13 Dec 2006 03:28:30 -0000 @@ -701,21 +701,21 @@ hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags, ReqWidth, &Control, &State, Dx, &Tabdef, &InClass, &ssa); - todo_wine ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr);
/* test makes sure that a call with a valid pssa still works */ hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags, ReqWidth, &Control, &State, Dx, &Tabdef, &InClass, &ssa); - todo_wine ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); - todo_wine ok(ssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n"); + ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); + ok(ssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n");
if (hr == 0) { hr = ScriptStringOut(ssa, X, Y, Options, &rc, MinSel, MaxSel, Disabled); todo_wine ok(hr == S_OK, "ScriptStringOut should return S_OK not %08x\n", hr); hr = ScriptStringFree(&ssa); - todo_wine ok(hr == S_OK, "ScriptStringFree should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringFree should return S_OK not %08x\n", hr); } }
@@ -774,8 +774,8 @@ hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, Flags, ReqWidth, &Control, &State, NULL, &Tabdef, &InClass, &ssa); - todo_wine ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); - todo_wine ok(ssa != NULL, "ScriptStringAnalyse ssa should not be NULL\n"); + ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); + ok(ssa != NULL, "ScriptStringAnalyse ssa should not be NULL\n"); if (hr == 0) { /* @@ -792,25 +792,25 @@ */ fTrailing = FALSE; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); - todo_wine ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); - todo_wine ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); + ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", iTrailing, X); fTrailing = TRUE; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr);
/* * Check that character position returned by ScriptStringXtoCP in Ch matches the * one input to ScriptStringCPtoX. This means that the Cp to X position and back * again works */ - todo_wine ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); - todo_wine ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", + ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); + ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", iTrailing, X); }
@@ -821,12 +821,12 @@ fTrailing = TRUE; Cp = 3; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); X--; /* put X just inside the trailing edge */ hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); - todo_wine ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); - todo_wine ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); + ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", iTrailing, X);
/* @@ -837,12 +837,12 @@ fTrailing = TRUE; Cp = 3; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); X++; /* put X just outside the trailing edge */ hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); - todo_wine ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); - todo_wine ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); + ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", iTrailing, X);
/* @@ -853,19 +853,19 @@ fTrailing = FALSE; Cp = 3; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringCPtoX should return S_OK not %08x\n", hr); X--; /* put X just outside the leading edge */ hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); - todo_wine ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); - todo_wine ok(Cp - 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp - 1, Ch, X); - todo_wine ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr); + ok(Cp - 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp - 1, Ch, X); + ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", iTrailing, X);
/* * Cleanup the the SSA for the next round of tests */ hr = ScriptStringFree(&ssa); - todo_wine ok(hr == S_OK, "ScriptStringFree should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringFree should return S_OK not %08x\n", hr);
/* * Test to see that exceeding the number of chars returns E_INVALIDARG. First @@ -874,7 +874,7 @@ hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, Flags, ReqWidth, &Control, &State, NULL, &Tabdef, &InClass, &ssa); - todo_wine ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr); + ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr);
/* * When ScriptStringCPtoX is called with a character position Cp that exceeds the @@ -884,13 +884,13 @@ fTrailing = FALSE; Cp = String_len + 1; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); - todo_wine ok(hr == E_INVALIDARG, "ScriptStringCPtoX should return E_INVALIDARG not %08x\n", hr); + ok(hr == E_INVALIDARG, "ScriptStringCPtoX should return E_INVALIDARG not %08x\n", hr);
hr = ScriptStringFree(&ssa); /* * ScriptStringCPtoX should free ssa, hence ScriptStringFree should fail */ - todo_wine ok(hr == E_INVALIDARG, "ScriptStringFree should return E_INVALIDARG not %08x\n", hr); + ok(hr == E_INVALIDARG, "ScriptStringFree should return E_INVALIDARG not %08x\n", hr); } }
------------------------------------------------------------------------
participants (3)
-
Clinton Stimpson -
Stefan Dösinger -
Vijay Kiran Kamuju