usp10: implement ScriptStringAnalyse, ScriptStringFree, ScriptStringXtoCP, ScriptStringCPtoX

Clinton Stimpson cjstimpson at utwire.net
Thu Dec 14 08:58:02 CST 2006


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);
>      }
>  }
>  
> 
> 
> ------------------------------------------------------------------------
> 
> 




More information about the wine-devel mailing list