usp10 1/3: Implement ScriptStringAnalysis and ScriptStringFree

Jeff L lats at yless4u.com.au
Thu Sep 21 06:24:28 CDT 2006


The patch is the first implementing ScriptString functions.  It replaces 
the previous patch by reducing the functionality to the smallest 
meaningful set.  The functions test out ok using scriptstring.exe from 
http://www.catch22.net/tuts/editor12.asp .  Testing this function is 
difficult as the results are intermediate and opaque.

Jeff Latimer

Changelog:
Implement ScriptStringAnalysis and ScriptStringFree
-------------- next part --------------
>From f84212933fd0006869955a8d353cf22fa42a773f Mon Sep 17 00:00:00 2001
From: Jeff Latimer <lats at yless4u.com.au>
Date: Wed, 20 Sep 2006 22:21:48 +1000
Subject: [PATCH] Implement ScriptStringAnalysis and ScriptStringFree
---
 dlls/usp10/tests/usp10.c |   23 ++++---
 dlls/usp10/usp10.c       |  160 ++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 160 insertions(+), 23 deletions(-)

diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c
index 45a65f2..c8c60f1 100644
--- a/dlls/usp10/tests/usp10.c
+++ b/dlls/usp10/tests/usp10.c
@@ -656,22 +656,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);
         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);
     }
 }
 
@@ -1003,13 +1007,12 @@ START_TEST(usp10)
     test_ScriptCacheGetHeight(hdc);
     test_ScriptGetGlyphABCWidth(hdc);
 
-    ReleaseDC(hwnd, hdc);
-    DestroyWindow(hwnd);
-
     test_ScriptGetFontProperties();
     test_ScriptTextOut();
     test_ScriptXtoX();
     test_ScriptString();
-
     test_digit_substitution();
+
+    ReleaseDC(hwnd, hdc);
+    DestroyWindow(hwnd);
 }
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index e258345..3318259 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -73,6 +73,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
  *
@@ -89,6 +110,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.@)
  *
@@ -447,17 +491,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)                     /* If allocated, 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;
 }
 
 /***********************************************************************
@@ -509,8 +618,33 @@ HRESULT WINAPI ScriptStringXtoCP(SCRIPT_
  *      ScriptStringFree (USP10.@)
  *
  */
-HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) {
-    FIXME("(%p): stub\n",pssa);
+HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) 
+{
+    string_analysis *analysis;
+
+    TRACE("(%p)\n", pssa);
+
+    if  (!*pssa)
+    {
+        return E_INVALIDARG;
+    }
+    else
+    {
+        print_ssa(*pssa);
+        analysis = * pssa;
+        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