usp10: Implement ScriptStringAnalyse.

This commit is contained in:
Clinton Stimpson 2006-12-15 19:28:07 -07:00 committed by Alexandre Julliard
parent d80dc79280
commit b91eb5a110
2 changed files with 119 additions and 31 deletions

View File

@ -701,21 +701,21 @@ static void test_ScriptString(void)
hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags, hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags,
ReqWidth, &Control, &State, Dx, &Tabdef, ReqWidth, &Control, &State, Dx, &Tabdef,
&InClass, &ssa); &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 */ /* test makes sure that a call with a valid pssa still works */
hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags, hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags,
ReqWidth, &Control, &State, Dx, &Tabdef, ReqWidth, &Control, &State, Dx, &Tabdef,
&InClass, &ssa); &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);
todo_wine ok(ssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n"); ok(ssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n");
if (hr == 0) if (hr == 0)
{ {
hr = ScriptStringOut(ssa, X, Y, Options, &rc, MinSel, MaxSel, Disabled); 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); todo_wine ok(hr == S_OK, "ScriptStringOut should return S_OK not %08x\n", hr);
hr = ScriptStringFree(&ssa); 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 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, Flags, hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, Flags,
ReqWidth, &Control, &State, NULL, &Tabdef, ReqWidth, &Control, &State, NULL, &Tabdef,
&InClass, &ssa); &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);
todo_wine ok(ssa != NULL, "ScriptStringAnalyse ssa should not be NULL\n"); ok(ssa != NULL, "ScriptStringAnalyse ssa should not be NULL\n");
if (hr == 0) if (hr == 0)
{ {
/* /*
@ -792,17 +792,20 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
*/ */
fTrailing = FALSE; fTrailing = FALSE;
hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); 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); 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);
if(Cp == 0)
ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X);
else
todo_wine ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); 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(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n",
iTrailing, X); iTrailing, X);
fTrailing = TRUE; fTrailing = TRUE;
hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); 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); 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 * Check that character position returned by ScriptStringXtoCP in Ch matches the
@ -810,7 +813,7 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
* again works * 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(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(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n",
iTrailing, X); iTrailing, X);
} }
@ -821,10 +824,10 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
fTrailing = TRUE; fTrailing = TRUE;
Cp = 3; Cp = 3;
hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); 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 */ X--; /* put X just inside the trailing edge */
hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); 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);
todo_wine ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X); 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", todo_wine ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n",
iTrailing, X); iTrailing, X);
@ -837,12 +840,12 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
fTrailing = TRUE; fTrailing = TRUE;
Cp = 3; Cp = 3;
hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); 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 */ X++; /* put X just outside the trailing edge */
hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); 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);
todo_wine ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); 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(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n",
iTrailing, X); iTrailing, X);
/* /*
@ -853,10 +856,10 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
fTrailing = FALSE; fTrailing = FALSE;
Cp = 3; Cp = 3;
hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X); 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 */ X--; /* put X just outside the leading edge */
hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing); 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);
todo_wine ok(Cp - 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp - 1, Ch, X); 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", todo_wine ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n",
iTrailing, X); iTrailing, X);
@ -865,7 +868,7 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
* Cleanup the the SSA for the next round of tests * Cleanup the the SSA for the next round of tests
*/ */
hr = ScriptStringFree(&ssa); 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 * Test to see that exceeding the number of chars returns E_INVALIDARG. First
@ -874,7 +877,7 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, Flags, hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, Flags,
ReqWidth, &Control, &State, NULL, &Tabdef, ReqWidth, &Control, &State, NULL, &Tabdef,
&InClass, &ssa); &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 * When ScriptStringCPtoX is called with a character position Cp that exceeds the

View File

@ -73,6 +73,27 @@ typedef struct scriptcache {
HDC hdc; HDC hdc;
} Scriptcache; } 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;
/*********************************************************************** /***********************************************************************
* DllMain * DllMain
* *
@ -448,9 +469,16 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc,
const BYTE *pbInClass, const BYTE *pbInClass,
SCRIPT_STRING_ANALYSIS *pssa) SCRIPT_STRING_ANALYSIS *pssa)
{ {
FIXME("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p): stub\n", 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, hdc, pString, cString, cGlyphs, iCharset, dwFlags,
iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa); iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa);
if (1 > cString || NULL == pString) { if (1 > cString || NULL == pString) {
return E_INVALIDARG; return E_INVALIDARG;
} }
@ -458,7 +486,64 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc,
return E_PENDING; 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;
} }
/*********************************************************************** /***********************************************************************