Jeff Latimer : usp10: Add ScriptShape functionality.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Feb 20 14:18:19 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 334e191175f6dfba5f2163fed8f806e7ec2a6a14
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=334e191175f6dfba5f2163fed8f806e7ec2a6a14

Author: Jeff Latimer <lats at yless4u.com.au>
Date:   Mon Feb 20 20:19:32 2006 +1100

usp10: Add ScriptShape functionality.

---

 dlls/usp10/Makefile.in   |    2 +
 dlls/usp10/tests/usp10.c |   35 +++++++++---------
 dlls/usp10/usp10.c       |   88 ++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 99 insertions(+), 26 deletions(-)

diff --git a/dlls/usp10/Makefile.in b/dlls/usp10/Makefile.in
index 72facbc..a232524 100644
--- a/dlls/usp10/Makefile.in
+++ b/dlls/usp10/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = usp10.dll
 IMPORTLIB = libusp10.$(IMPLIBEXT)
-IMPORTS   = kernel32
+IMPORTS   = gdi32 kernel32
 
 C_SRCS = \
 	usp10.c
diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c
index 0b55991..5a0cc7d 100644
--- a/dlls/usp10/tests/usp10.c
+++ b/dlls/usp10/tests/usp10.c
@@ -126,28 +126,29 @@ START_TEST(usp10)
     if (hr == 0) {
         psc = NULL;                                   /* must be null on first call           */
         cChars = cInChars;
-        cMaxGlyphs = 4;
+        cMaxGlyphs = cInChars;
         hr = ScriptShape(NULL, &psc, TestItem1, cChars,
                          cMaxGlyphs, &pItem[0].a,
                          pwOutGlyphs, pwLogClust, psva, &pcGlyphs);
-        todo_wine ok (hr == E_OUTOFMEMORY, "If not enough output area cChars (%d) is > than CMaxGlyphs (%d) but not E_OUTOFMEMORY\n",
-            cChars, cMaxGlyphs);
-        cMaxGlyphs = 256;
-        hr = ScriptShape(NULL, &psc, TestItem1, cChars,
+        ok (hr == E_PENDING, "If psc is NULL (%08x) the E_PENDING should be returned\n",
+                      (unsigned int) hr);
+        cMaxGlyphs = 4;
+        hr = ScriptShape(hdc, &psc, TestItem1, cChars,
                          cMaxGlyphs, &pItem[0].a,
                          pwOutGlyphs, pwLogClust, psva, &pcGlyphs);
-        todo_wine ok (hr == E_PENDING, "If psc is NULL (%08x) the E_PENDING should be returned\n",
-                      (unsigned int) hr);
+        ok (hr == E_OUTOFMEMORY, "If not enough output area cChars (%d) is > than CMaxGlyphs (%d) but not E_OUTOFMEMORY\n",
+            cChars, cMaxGlyphs);
+        cMaxGlyphs = 256;
         hr = ScriptShape(hdc, &psc, TestItem1, cChars,
                          cMaxGlyphs, &pItem[0].a,
                          pwOutGlyphs, pwLogClust, psva, &pcGlyphs);
-        todo_wine ok (hr == 0, "Should return 0 not (%08x)\n", (unsigned int) hr);
-        todo_wine ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
-        todo_wine ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
+        ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr);
+        ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
+        ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
         if (hr ==0) {
             hr = ScriptPlace(NULL, &psc, pwOutGlyphs, pcGlyphs, psva, &pItem[0].a, piAdvance,
                              pGoffset, pABC);
-            ok (hr == 0, "Should return 0 not (%08x)\n", (unsigned int) hr);
+            todo_wine ok (hr == 0, "Should return 0 not (%08x)\n", (unsigned int) hr);
         }
 
         /* This test will check to make sure that SCRIPT_CACHE is reused and that not translation   *
@@ -171,16 +172,16 @@ START_TEST(usp10)
                               cMaxGlyphs, &pItem[0].a,
                               pwOutGlyphs, pwLogClust, psva, &pcGlyphs);
              ok (hr != E_PENDING, "If psc should not be NULL (%08x) and the E_PENDING should be returned\n",
-                              (unsigned int) hr);
-             todo_wine ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr);
-             todo_wine ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
-             todo_wine ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
+                (unsigned int) hr);
+             ok (hr == 0, "ScriptShape should return 0 not (%08x)\n", (unsigned int) hr);
+             ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
+             ok (pcGlyphs == cChars, "Chars in (%d) should equal Glyphs out (%d)\n", cChars, pcGlyphs);
              for (cnt=0; cnt < cChars && TestItem2[cnt] == pwOutGlyphs[cnt]; cnt++) {}
-             todo_wine ok (cnt == cChars, "Translation to place when told not to. WCHAR %d - %04x != %04x\n",
+             ok (cnt == cChars, "Translation to place when told not to. WCHAR %d - %04x != %04x\n",
                            cnt, TestItem2[cnt], pwOutGlyphs[cnt]);
              if (hr ==0) {
                  hr = ScriptPlace(NULL, &psc, pwOutGlyphs, pcGlyphs, psva, &pItem[0].a, piAdvance,
-                              pGoffset, pABC);
+                                  pGoffset, pABC);
                  todo_wine ok (hr == 0, "ScriptPlace should return 0 not (%08x)\n", (unsigned int) hr);
              }
         }
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 76d0db0..dd7832d 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -68,6 +68,13 @@ static const SCRIPT_PROPERTIES *Global_S
                                        &Default_Script_6,
                                        &Default_Script_7};
 
+typedef struct scriptcache {
+       HDC hdc;
+       DWORD GlyphToChar[256];
+       int HaveWidths;
+       ABC CharWidths[256];
+} Scriptcache;
+
 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
 {
     switch(fdwReason) {
@@ -86,9 +93,12 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, 
  */
 HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
 {
-    FIXME("%p\n", psc);
+    TRACE("%p\n", psc);
 
-    if (psc) *psc = NULL;
+    if (psc) {
+       HeapFree ( GetProcessHeap(), 0, *psc);
+       *psc = NULL;
+    }
     return 0;
 }
 
@@ -159,7 +169,7 @@ HRESULT WINAPI ScriptItemize(const WCHAR
     /* This implementation currently treats the entire string represented in 
      * pwcInChars as a single entity.  Hence pcItems will be set to 1.          */
 
-    FIXME("%s,%d,%d,%p,%p,%p,%p\n", debugstr_w(pwcInChars), cInChars, cMaxItems, 
+    FIXME("%s,%d,%d,%p,%p,%p,%p: semi-stub\n", debugstr_w(pwcInChars), cInChars, cMaxItems, 
           psControl, psState, pItems, pcItems);
 
     if (!pwcInChars || !cInChars || !pItems || cMaxItems < 2)
@@ -281,13 +291,75 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRI
                            SCRIPT_ANALYSIS *psa, WORD *pwOutGlyphs, WORD *pwLogClust, 
                            SCRIPT_VISATTR *psva, int *pcGlyphs)
 {
-    FIXME("(%p,%p,%p,%s,%d,%d, %p, %p, %p, %p): stub\n",  hdc, psc, pwcChars,
-                                       debugstr_w(pwcChars), 
-                                       cChars, cMaxGlyphs,
-                                       psa, pwOutGlyphs, psva, pcGlyphs);
-    return E_NOTIMPL;
+    /*  Note SCRIPT_CACHE (*psc) appears to be a good place to save info that needs to be 
+     *  passed between functions.                                                         */
+
+    HDC phdc;
+    int cnt;
+    DWORD hr;
+    int clusterinit;
+    Scriptcache *pScriptcache;
+    *pcGlyphs = cChars;
+    FIXME("(%p, %p, %p, %d, %d, %p): semi-stub\n",  hdc, psc, pwcChars,
+                                       cChars, cMaxGlyphs, psa);
+    if (psa) TRACE("%d, %d, %d, %d, %d, %d, %d\n", psa->eScript, psa->fRTL, psa->fLayoutRTL,
+                                         psa->fLinkBefore, psa->fLinkAfter,
+                                         psa->fLogicalOrder, psa->fNoGlyphIndex);
+
+    if  (cChars > cMaxGlyphs) return E_OUTOFMEMORY;
+
+    if  (!hdc && !*psc) {
+        TRACE("No Script_Cache (psc) and no hdc. Ask for one. Hdc=%p, psc=%p\n", hdc, *psc);
+	return E_PENDING;
+    }   else 
+        if  (hdc && !*psc) {
+            pScriptcache = HeapAlloc( GetProcessHeap(), 0, sizeof(Scriptcache) );
+            pScriptcache->hdc = (HDC) hdc;
+            phdc = hdc;
+            pScriptcache->HaveWidths = 0;
+            *psc = (Scriptcache *) pScriptcache;
+       }   else
+            if  (*psc) {
+                pScriptcache = (Scriptcache *) *psc;
+                phdc = pScriptcache->hdc;
+            }
+                
+    TRACE("Before: ");
+    for (cnt = 0; cnt < cChars; cnt++)
+         TRACE("%4x",pwcChars[cnt]);
+    TRACE("\n");
+
+    if  (!psa->fNoGlyphIndex) {                                         /* Glyph translate */
+        hr = GetGlyphIndicesW(phdc, pwcChars, cChars, pwOutGlyphs, 0);
+        TRACE("After:  ");
+        for (cnt = 0; cnt < cChars; cnt++) {
+             TRACE("%04x",pwOutGlyphs[cnt]);
+             pScriptcache->GlyphToChar[pwOutGlyphs[cnt]] = pwcChars[cnt]; /* save for ScriptPlace */
+        }
+       TRACE("\n");
+    }
+    else {
+        TRACE("After:  ");
+        for (cnt = 0; cnt < cChars; cnt++) {                           /* no translate so set up */
+             pwOutGlyphs[cnt] = pwcChars[cnt];                         /* copy in to out and     */
+             TRACE("%04x",pwOutGlyphs[cnt]);
+             pScriptcache->GlyphToChar[pwcChars[cnt]] = pwcChars[cnt]; /* set up a dummy table   */
+        }
+       TRACE("\n");
+    }
 
+    /*  Set up a valid SCRIPT_VISATTR for this run */     
+    clusterinit = 1;                        /* Start of Cluster */
+    for (cnt = 0;  cnt < cChars; cnt++) {
+         psva[cnt].uJustification = 0;
+         psva[cnt].fClusterStart = clusterinit;
+         clusterinit = 0;
+         psva[cnt].fDiacritic = 0;
+         psva[cnt].fZeroWidth = 0;
+    }
+    return 0; 
 }
+
 /***********************************************************************
  *      ScriptPlace (USP10.@)
  *




More information about the wine-cvs mailing list