usp10: Resend - Add funtionality for ScriptStringAnalyse
Jeff L
lats at yless4u.com.au
Fri Aug 25 09:25:28 CDT 2006
Is this patch likely to be committed or is there something more I need
to do? It has been waiting in various forms without comment for quite a
while.
Well here is a second one with the git.
Alexandre, I think I have addressed the points you raised.
Tidied some untidy code Alexandre pointed out.
A resend after protracted detour in fixing up the test suite. This
tidys up the syntax and shortening of the variable names, fixing the
handelling of multiple scripts and a slight rework to remove tests
before HeapFree calls and meanigful variables.
This patch adds functionality for ScriptStringAnalyse and by the way for
ScriptStringOut and ScriptStringFree. This goes some of the way to
getting Abiword working under wine.
Jeff Latimer
Change log: Add funtionality for ScriptStringAnalyse, ScriptStringOut
and ScriptStringFree.
-------------- next part --------------
>From 571223937f0d268953fc4540c10003e916e11e34 Mon Sep 17 00:00:00 2001
From: Jeff Latimer <lats at yless4u.com.au>
Date: Tue, 22 Aug 2006 21:51:04 +1000
Subject: [PATCH] Add funtionality for ScriptStringAnalyse, ScriptStringOut and ScriptStringFree
---
dlls/usp10/tests/usp10.c | 25 +++---
dlls/usp10/usp10.c | 196 ++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 195 insertions(+), 26 deletions(-)
diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c
index 6677964..1273730 100644
--- a/dlls/usp10/tests/usp10.c
+++ b/dlls/usp10/tests/usp10.c
@@ -655,22 +655,26 @@ static void test_ScriptString(void)
hr = ScriptStringAnalyse( NULL, pString, cString, cGlyphs, iCharset, dwFlags,
iReqWidth, &psControl, &psState, piDx, &pTabdef,
&pbInClass, &pssa);
- ok(hr == E_PENDING, "ScriptStringAnalyse Stub should return E_PENDING not %08lx\n", hr);
+ ok(hr == E_PENDING, "ScriptStringAnalyse should return E_PENDING not %08lx\n", hr);
/* test with hdc, this should be a valid test */
hr = ScriptStringAnalyse( hdc, pString, cString, cGlyphs, iCharset, dwFlags,
iReqWidth, &psControl, &psState, piDx, &pTabdef,
&pbInClass, &pssa);
- ok(hr == E_NOTIMPL, "ScriptStringAnalyse Stub should return E_NOTIMPL not %08lx\n", hr);
-/* Commented code it pending new code in ScriptStringAnalysis */
-/* ok(hr == S_OK, "ScriptStringAnalyse Stub should return S_OK not %08x\n", (unsigned int) hr);*/
-/* ok(pssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n");*/
+ ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08lx\n", hr);
+
+ /* test makes sure that a call with a valid pssa still works */
+ hr = ScriptStringAnalyse( hdc, pString, cString, cGlyphs, iCharset, dwFlags,
+ iReqWidth, &psControl, &psState, piDx, &pTabdef,
+ &pbInClass, &pssa);
+ ok(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08lx\n", hr);
+ ok(pssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n");
if (hr == 0)
{
hr = ScriptStringOut(pssa, iX, iY, uOptions, &prc, iMinSel, iMaxSel,fDisabled);
- ok(hr == E_NOTIMPL, "ScriptStringOut Stub should return E_NOTIMPL not %08lx\n", hr);
+ ok(hr == S_OK, "ScriptStringOut should return S_OK not %08lx\n", hr);
hr = ScriptStringFree(&pssa);
- ok(hr == S_OK, "ScriptStringFree Stub should return S_OK not %08lx\n", hr);
+ ok(hr == S_OK, "ScriptStringFree should return S_OK not %08lx\n", hr);
}
}
@@ -748,12 +752,11 @@ START_TEST(usp10)
test_ScriptGetCMap(hdc, pwOutGlyphs);
test_ScriptCacheGetHeight(hdc);
test_ScriptGetGlyphABCWidth(hdc);
-
- ReleaseDC(hwnd, hdc);
- DestroyWindow(hwnd);
-
test_ScriptGetFontProperties();
test_ScriptTextOut();
test_ScriptXtoX();
test_ScriptString();
+
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
}
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index f65768d..b31d5f2 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -72,6 +72,27 @@ typedef struct scriptcache {
HDC hdc;
} Scriptcache;
+typedef struct script_string_analysis_ptrs
+{
+ int cGlyphs;
+ SCRIPT_VISATTR *psva;
+ int *piAdvance;
+ ABC pABC;
+ WORD *pwLogClust;
+ GOFFSET *pGoffset;
+ WORD *pwOutGlyphs;
+} script_blk;
+
+typedef struct script_string_analysis
+{
+ HDC hdc;
+ int cItems;
+ int cMaxGlyphs;
+ script_blk *script_blk;
+ SCRIPT_ITEM *pItem;
+ long p[10];
+} string_analysis;
+
/***********************************************************************
* DllMain
*
@@ -88,6 +109,29 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL,
return TRUE;
}
+void print_ssa (SCRIPT_STRING_ANALYSIS *pssa)
+{
+ /* Output the contents of the script string analysis cache for diagnostics */
+ string_analysis *analysis;
+ analysis = (string_analysis*)pssa;
+ TRACE("Start print of SCRIPT_STRING_ANALYSIS\n");
+ TRACE(" analysis(%p)\n", analysis);
+ if (analysis)
+ {
+ TRACE(" hdc:%08lx cItems:%d cMaxGlyphs:%d script_blk(%p) pItem(%p)",
+ (unsigned long int)analysis->hdc, analysis->cItems,
+ analysis->cMaxGlyphs,
+ &analysis->script_blk, &analysis->pItem);
+ if (analysis->script_blk)
+ {
+ TRACE(" cGlyphs:%d psva(%p)",
+ analysis->script_blk->cGlyphs,
+ analysis->script_blk->psva);
+ }
+ TRACE("\n");
+ }
+}
+
/***********************************************************************
* ScriptFreeCache (USP10.@)
*
@@ -356,17 +400,82 @@ HRESULT WINAPI ScriptStringAnalyse(HDC h
const BYTE *pbInClass,
SCRIPT_STRING_ANALYSIS *pssa)
{
- FIXME("(%p,%p,%d,%d,%d,0x%lx,%d,%p,%p,%p,%p,%p,%p): stub\n",
- hdc, pString, cString, cGlyphs, iCharset, dwFlags,
- iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa);
- if (1 > cString || NULL == pString) {
- return E_INVALIDARG;
- }
- if ((dwFlags & SSA_GLYPHS) && NULL == hdc) {
- return E_PENDING;
- }
-
- return E_NOTIMPL;
+ HRESULT hr;
+ WCHAR *pStr;
+ int cMaxItems;
+ int pcItems;
+ SCRIPT_CACHE psc = NULL;
+ string_analysis *analysis;
+ int item, cChars;
+
+ TRACE("(%p,%p,%d,%d,%d,0x%lx,%d,%p,%p,%p,%p,%p,%p)\n",
+ hdc, pString, cString, cGlyphs, iCharset, dwFlags,
+ iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa);
+ /* Check parameters meet the API spec */
+ if (1 > cString || NULL == pString)
+ return E_INVALIDARG;
+ if ((dwFlags & SSA_GLYPHS) && NULL == hdc) {
+ TRACE("For SSA_GLYPHS, hdc can't be NULL-dwFlags %08lx, hdc(%p)\n", dwFlags, hdc);
+ return E_PENDING;
+ }
+ cMaxItems = 255; /* Pick an abritary size for buffers */
+ if (!*pssa) /* Clean it out and start again */
+ ScriptStringFree(pssa);
+ analysis = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(string_analysis));
+ *pssa = analysis;
+
+ analysis->hdc = hdc;
+ analysis->pItem = HeapAlloc( GetProcessHeap(), 0, sizeof(SCRIPT_ITEM)*cMaxItems );
+ hr = ScriptItemize(pString, cString, cMaxItems, psControl,
+ psState, analysis->pItem, &pcItems);
+ while (hr == E_OUTOFMEMORY) /* too may items for the the buffer realloc */
+ {
+ cMaxItems *= 2; /* double the count and reallocate the buffer */
+ analysis->pItem = HeapReAlloc( GetProcessHeap(), 0, analysis->pItem,
+ sizeof(SCRIPT_ITEM)*cMaxItems );
+ hr = ScriptItemize(pString, cString, cMaxItems, psControl, psState,
+ analysis->pItem, &pcItems);
+ TRACE("ScriptItemize hr=%08lx cMaxItems=%d\n", hr, cMaxItems);
+ }
+
+ analysis->cItems = pcItems;
+ analysis->script_blk = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(script_blk)*pcItems);
+ TRACE("(%p) (%p) cItems %d, pcItems=%d\n", analysis,
+ &analysis->script_blk, analysis->cItems, pcItems);
+ for (item = 0; item < pcItems; item++)
+ {
+ cChars = analysis->pItem[item+1].iCharPos
+ - analysis->pItem[item].iCharPos;
+ analysis->script_blk[item].pwOutGlyphs = HeapAlloc( GetProcessHeap(),
+ 0, sizeof(WORD)*cGlyphs);
+ analysis->script_blk[item].piAdvance = HeapAlloc( GetProcessHeap(),
+ 0, sizeof(WORD)*cGlyphs);
+ analysis->script_blk[item].pGoffset = HeapAlloc( GetProcessHeap(),
+ 0, sizeof(GOFFSET)*cGlyphs);
+ analysis->script_blk[item].psva = HeapAlloc( GetProcessHeap(),
+ 0, sizeof(SCRIPT_VISATTR)*cGlyphs);
+ analysis->script_blk[item].pwLogClust = HeapAlloc( GetProcessHeap(),
+ 0, sizeof(WORD)*cGlyphs);
+ pStr = (WCHAR *)pString;
+ hr = ScriptShape(hdc, &psc, &pStr[analysis->pItem[item].iCharPos], cChars,
+ cGlyphs, &analysis->pItem[item].a,
+ analysis->script_blk[item].pwOutGlyphs,
+ analysis->script_blk[item].pwLogClust,
+ analysis->script_blk[item].psva,
+ &analysis->script_blk[item].cGlyphs);
+ hr = ScriptPlace(hdc, &psc, analysis->script_blk[item].pwOutGlyphs,
+ analysis->script_blk[item].cGlyphs,
+ analysis->script_blk[item].psva,
+ &analysis->pItem[item].a,
+ analysis->script_blk[item].piAdvance,
+ analysis->script_blk[item].pGoffset,
+ &analysis->script_blk[item].pABC);
+ analysis->cMaxGlyphs += analysis->script_blk[item].cGlyphs;
+ }
+ hr = ScriptFreeCache(&psc);
+ print_ssa(*pssa);
+ return S_OK;
}
/***********************************************************************
@@ -382,13 +491,51 @@ HRESULT WINAPI ScriptStringOut(SCRIPT_ST
int iMaxSel,
BOOL fDisabled)
{
- FIXME("(%p,%d,%d,0x%1x,%p,%d,%d,%d): stub\n",
+ string_analysis *analysis;
+ SCRIPT_CACHE psc = NULL;
+ WCHAR *pwOutGlyphs;
+ int item, cnt, x;
+ HRESULT hr;
+
+ TRACE("(%p,%d,%d,0x%1x,%p,%d,%d,%d)\n",
ssa, iX, iY, uOptions, prc, iMinSel, iMaxSel, fDisabled);
+ print_ssa(ssa);
if (!ssa) {
return E_INVALIDARG;
}
-
- return E_NOTIMPL;
+ analysis = ssa;
+ TRACE("cMaxGlyphs %d cItems %d a.eScript %08x pwGlyphsOut %p iX %d, iY %d\n",
+ analysis->cMaxGlyphs, analysis->cItems,
+ analysis->pItem[0].a.eScript,
+ analysis->script_blk->pwOutGlyphs, iX, iY);
+ pwOutGlyphs = HeapAlloc( GetProcessHeap(), 0,
+ sizeof(WCHAR)*analysis->cMaxGlyphs+200 );
+ cnt = 0;
+ analysis->pItem[0].a.fNoGlyphIndex = FALSE;
+ uOptions |= ETO_GLYPH_INDEX;
+ for (item = 0; item < analysis->cItems; item++)
+ {
+ memcpy((WCHAR*)&pwOutGlyphs[cnt],
+ (WCHAR *)analysis->script_blk[item].pwOutGlyphs,
+ sizeof(WCHAR)*analysis->script_blk[item].cGlyphs);
+ TRACE("cGlyphs %d\n", analysis->script_blk[item].cGlyphs);
+ for (x = 0; x < analysis->script_blk[item].cGlyphs; x ++)
+ TRACE("%04x", pwOutGlyphs[x]);
+ TRACE("\n");
+ for (x = 0; x < analysis->script_blk[item].cGlyphs; x ++)
+ TRACE("%04x", analysis->script_blk[item].pwOutGlyphs[x]);
+ cnt += analysis->script_blk[item].cGlyphs;
+ }
+ hr = ScriptTextOut(analysis->hdc, &psc, iX, iY, uOptions, (RECT*) prc,
+ &analysis->pItem->a, NULL, 0,
+ (WCHAR*) pwOutGlyphs, analysis->cMaxGlyphs,
+ analysis->script_blk->piAdvance, NULL,
+ analysis->script_blk->pGoffset);
+ TRACE("ScriptTextOut hr=%08lx\n", hr);
+ HeapFree(GetProcessHeap(), 0, pwOutGlyphs);
+ ScriptFreeCache(&psc);
+ print_ssa((SCRIPT_STRING_ANALYSIS*)analysis);
+ return hr;
}
/***********************************************************************
@@ -419,7 +566,26 @@ HRESULT WINAPI ScriptStringXtoCP(SCRIPT_
*
*/
HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) {
- FIXME("(%p): stub\n",pssa);
+ string_analysis *analysis;
+ TRACE("(%p)\n", pssa);
+ if (*pssa)
+ {
+ print_ssa(*pssa);
+ analysis = * pssa;
+ print_ssa((SCRIPT_STRING_ANALYSIS *)analysis);
+ HeapFree(GetProcessHeap(), 0, analysis->pItem);
+ if (analysis->script_blk)
+ {
+ HeapFree(GetProcessHeap(), 0, analysis->script_blk->psva);
+ HeapFree(GetProcessHeap(), 0, analysis->script_blk->piAdvance);
+ HeapFree(GetProcessHeap(), 0, analysis->script_blk->pGoffset);
+ HeapFree(GetProcessHeap(), 0, analysis->script_blk->pwOutGlyphs);
+ HeapFree(GetProcessHeap(), 0, analysis->script_blk);
+ }
+ HeapFree(GetProcessHeap(), 0, analysis);
+ *pssa = NULL;
+ }
+
return S_OK;
}
--
1.4.1
More information about the wine-patches
mailing list