Commit b91eb5a1 authored by Clinton Stimpson's avatar Clinton Stimpson Committed by Alexandre Julliard

usp10: Implement ScriptStringAnalyse.

parent d80dc792
......@@ -701,21 +701,21 @@ static void test_ScriptString(void)
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 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
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,28 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
*/
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);
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);
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
* 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(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n",
iTrailing, X);
}
......@@ -821,12 +824,12 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
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);
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",
todo_wine ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n",
iTrailing, X);
/*
......@@ -837,12 +840,12 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
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);
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(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n",
iTrailing, X);
/*
......@@ -853,19 +856,19 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
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);
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",
todo_wine 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,10 +877,10 @@ static void test_ScriptStringXtoCP_CPtoX(HDC hdc)
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
* When ScriptStringCPtoX is called with a character position Cp that exceeds the
* string length, return E_INVALIDARG. This also invalidates the ssa so a
* ScriptStringFree should also fail.
*/
......
......@@ -73,6 +73,27 @@ typedef struct scriptcache {
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;
/***********************************************************************
* DllMain
*
......@@ -448,9 +469,16 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc,
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 +486,64 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc,
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;
}
/***********************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment