usp10: Implement ScriptStringAnalyse.
This commit is contained in:
parent
d80dc79280
commit
b91eb5a110
|
@ -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;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
Loading…
Reference in New Issue