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,
|
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,25 +792,28 @@ 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);
|
||||||
todo_wine ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp, Ch, X);
|
if(Cp == 0)
|
||||||
todo_wine ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n",
|
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);
|
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
|
||||||
* one input to ScriptStringCPtoX. This means that the Cp to X position and back
|
* one input to ScriptStringCPtoX. This means that the Cp to X position and back
|
||||||
* 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,12 +824,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 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,19 +856,19 @@ 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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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,10 +877,10 @@ 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
|
||||||
* string length, return E_INVALIDARG. This also invalidates the ssa so a
|
* string length, return E_INVALIDARG. This also invalidates the ssa so a
|
||||||
* ScriptStringFree should also fail.
|
* ScriptStringFree should also fail.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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;
|
||||||
hdc, pString, cString, cGlyphs, iCharset, dwFlags,
|
StringAnalysis* analysis;
|
||||||
iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa);
|
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) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
Loading…
Reference in New Issue