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