Hi,

Can I get some feedback on this patch?
It appears to have been rejected.

Thanks,
Clinton


Clinton Stimpson wrote:

This patch implements ScriptStringAnalyse, ScriptStringFree,
                      ScriptStringXtoCP, ScriptStringCPtoX.

Also, many todo_wine's are removed.


Thanks,
Clinton Stimpson

ChangeLog
    Implement ScriptStringAnalyse, ScriptStringFree,
              ScriptStringXtoCP, ScriptStringCPtoX


------------------------------------------------------------------------

Index: dlls/usp10/usp10.c
===================================================================
RCS file: /home/wine/wine/dlls/usp10/usp10.c,v
retrieving revision 1.45
diff -u -r1.45 usp10.c
--- dlls/usp10/usp10.c  12 Dec 2006 20:30:48 -0000      1.45
+++ dlls/usp10/usp10.c  13 Dec 2006 03:28:30 -0000
@@ -73,6 +73,46 @@
        HDC hdc;
 } 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;
+
+static void ME_StringAnalysisFree(StringAnalysis* analysis)
+{
+  int i;
+  for(i=0; i<analysis->numItems; i++)
+  {
+    HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].glyphs);
+    HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].pwLogClust);
+    HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].piAdvance);
+    HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].psva);
+    HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].pGoffset);
+    HeapFree(GetProcessHeap(), 0, analysis->glyphs[i].abc);
+  }
+
+  HeapFree(GetProcessHeap(), 0, analysis->glyphs);
+  HeapFree(GetProcessHeap(), 0, analysis->pItem);
+ + HeapFree(GetProcessHeap(), 0, analysis);
+}
+
 /***********************************************************************
  *      DllMain
  *
@@ -448,9 +488,16 @@
                                   const BYTE *pbInClass,
                                   SCRIPT_STRING_ANALYSIS *pssa)
 {
-  FIXME("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p): stub\n",
-       hdc, pString, cString, cGlyphs, iCharset, dwFlags,
-       iReqWidth, psControl, psState, piDx, pTabdef, pbInClass, pssa);
+  HRESULT hr;
+  StringAnalysis* analysis;
+  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) {
     return E_INVALIDARG;
   }
@@ -458,7 +505,64 @@
     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;
 }
/***********************************************************************
@@ -489,9 +593,46 @@
  */
 HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL 
fTrailing, int* pX)
 {
-    FIXME("(%p), %d, %d, (%p): stub\n", ssa, icp, fTrailing, pX);
-    *pX = 0;                             /* Set a reasonable value */
-    return S_OK;
+  int i, j;
+  int runningX = 0;
+  int runningCp = 0;
+  StringAnalysis* analysis = ssa;
+  TRACE("(%p), %d, %d, (%p)\n", ssa, icp, fTrailing, pX);
+
+  if(!ssa || !pX)
+  {
+    return 1;
+  }
+ + /* icp out of range */
+  if(icp < 0)
+  {
+    analysis->invalid = TRUE;
+    return E_INVALIDARG;
+  }
+
+  for(i=0; i<analysis->numItems; i++)
+  {
+    for(j=0; j<analysis->glyphs[i].numGlyphs; j++)
+    {
+      if(runningCp == icp && fTrailing == FALSE)
+      {
+        *pX = runningX;
+        return S_OK;
+      }
+      runningX += analysis->glyphs[i].piAdvance[j];
+      if(runningCp == icp && fTrailing == TRUE)
+      {
+        *pX = runningX;
+        return S_OK;
+      }
+      runningCp++;
+    }
+  }
+ + /* icp out of range */
+  analysis->invalid = TRUE;
+  return E_INVALIDARG;
 }
/***********************************************************************
@@ -500,19 +641,79 @@
  */
HRESULT WINAPI ScriptStringXtoCP(SCRIPT_STRING_ANALYSIS ssa, int iX, int* piCh, int* piTrailing) {
-    FIXME("(%p), %d, (%p), (%p): stub\n", ssa, iX, piCh, piTrailing);
-    *piCh = 0;                          /* Set a reasonable value */
-    *piTrailing = 0;
+  StringAnalysis* analysis = ssa;
+  int i;
+  int j;
+  int runningX = 0;
+  int runningCp = 0;
+  int width;
+ + TRACE("(%p), %d, (%p), (%p)\n", ssa, iX, piCh, piTrailing); + + if(!ssa || !piCh || !piTrailing)
+  {
+    return 1;
+  }
+
+  /* out of range */
+  if(iX < 0)
+  {
+    *piCh = -1;
+    *piTrailing = TRUE;
     return S_OK;
+  }
+ + for(i=0; i<analysis->numItems; i++)
+  {
+    for(j=0; j<analysis->glyphs[i].numGlyphs; j++)
+    {
+      width = analysis->glyphs[i].piAdvance[j];
+      if(iX < (runningX + width))
+      {
+        *piCh = runningCp;
+        if((iX - runningX) > width/2)
+          *piTrailing = TRUE;
+        else
+          *piTrailing = FALSE;
+        return S_OK;
+      }
+      runningX += width;
+      runningCp++;
+    }
+  }
+
+  /* out of range */
+  *piCh = analysis->pItem[analysis->numItems].iCharPos;
+  *piTrailing = FALSE;
+ + return S_OK;
 }
/***********************************************************************
  *      ScriptStringFree (USP10.@)
  *
  */
-HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) {
-    FIXME("(%p): stub\n",pssa);
-    return S_OK;
+HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa)
+{
+  StringAnalysis* analysis;
+  BOOL invalid;
+  TRACE("(%p)\n",pssa);
+
+  if(!pssa)
+    return E_INVALIDARG;
+
+  analysis = *pssa;
+  if(!analysis)
+    return E_INVALIDARG;
+
+  invalid = analysis->invalid;
+ + ME_StringAnalysisFree(analysis);
+
+  if(invalid)
+    return E_INVALIDARG;
+
+  return S_OK;
 }
/***********************************************************************
Index: dlls/usp10/tests/usp10.c
===================================================================
RCS file: /home/wine/wine/dlls/usp10/tests/usp10.c,v
retrieving revision 1.30
diff -u -r1.30 usp10.c
--- dlls/usp10/tests/usp10.c    12 Dec 2006 20:30:48 -0000      1.30
+++ dlls/usp10/tests/usp10.c    13 Dec 2006 03:28:30 -0000
@@ -701,21 +701,21 @@
     hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags,
                               ReqWidth, &Control, &State, Dx, &Tabdef,
                               &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 */
     hr = ScriptStringAnalyse( hdc, teststr, String, Glyphs, Charset, Flags,
                               ReqWidth, &Control, &State, Dx, &Tabdef,
                               &InClass, &ssa);
-    todo_wine 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(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr);
+    ok(ssa != NULL, "ScriptStringAnalyse pssa should not be NULL\n");
if (hr == 0)
     {
         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);
         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 @@
     hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, Flags,
                               ReqWidth, &Control, &State, NULL, &Tabdef,
                               &InClass, &ssa);
-    todo_wine 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(hr == S_OK, "ScriptStringAnalyse should return S_OK not %08x\n", hr);
+    ok(ssa != NULL, "ScriptStringAnalyse ssa should not be NULL\n");
     if  (hr == 0)
     {
         /*
@@ -792,25 +792,25 @@
              */
             fTrailing = FALSE;
             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);
-            todo_wine 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(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr);
+            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);
             fTrailing = TRUE;
             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);
-            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 * one input to ScriptStringCPtoX. This means that the Cp to X position and back
              * 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(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", + ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = %d\n", Cp + 1, Ch, X); + ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", iTrailing, X);
         }
@@ -821,12 +821,12 @@
         fTrailing = TRUE;
         Cp = 3;
         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 */
         hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing);
-        todo_wine 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(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr);
+        ok(Cp == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = 
%d\n", Cp, Ch, X);
+ ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", iTrailing, X); /*
@@ -837,12 +837,12 @@
         fTrailing = TRUE;
         Cp = 3;
         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 */
         hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing);
-        todo_wine 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(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr);
+        ok(Cp + 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = 
%d\n", Cp + 1, Ch, X);
+ ok(iTrailing == FALSE, "ScriptStringXtoCP should return iTrailing = 0 not %d for X = %d\n", iTrailing, X); /*
@@ -853,19 +853,19 @@
         fTrailing = FALSE;
         Cp = 3;
         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 */
         hr = ScriptStringXtoCP(ssa, X, &Ch, &iTrailing);
-        todo_wine 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(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", + ok(hr == S_OK, "ScriptStringXtoCP should return S_OK not %08x\n", hr);
+        ok(Cp - 1 == Ch, "ScriptStringXtoCP should return Ch = %d not %d for X = 
%d\n", Cp - 1, Ch, X);
+ ok(iTrailing == TRUE, "ScriptStringXtoCP should return iTrailing = 1 not %d for X = %d\n", iTrailing, X); /*
          * Cleanup the the SSA for the next round of tests
*/ 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
@@ -874,7 +874,7 @@
         hr = ScriptStringAnalyse( hdc, String, String_len, Glyphs, Charset, 
Flags,
                                   ReqWidth, &Control, &State, NULL, &Tabdef,
                                   &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 @@ -884,13 +884,13 @@
         fTrailing = FALSE;
Cp = String_len + 1; hr = ScriptStringCPtoX(ssa, Cp, fTrailing, &X);
-        todo_wine ok(hr == E_INVALIDARG, "ScriptStringCPtoX should return 
E_INVALIDARG not %08x\n", hr);
+        ok(hr == E_INVALIDARG, "ScriptStringCPtoX should return E_INVALIDARG not 
%08x\n", hr);
hr = ScriptStringFree(&ssa);
         /*
          * ScriptStringCPtoX should free ssa, hence ScriptStringFree should 
fail
          */
-        todo_wine ok(hr == E_INVALIDARG, "ScriptStringFree should return 
E_INVALIDARG not %08x\n", hr);
+        ok(hr == E_INVALIDARG, "ScriptStringFree should return E_INVALIDARG not 
%08x\n", hr);
     }
 }

------------------------------------------------------------------------





Reply via email to