Aric Stewart : usp10: Improve handling of tabs and SSA_TAB.

Alexandre Julliard julliard at winehq.org
Tue Oct 11 14:03:37 CDT 2011


Module: wine
Branch: master
Commit: 314553f194da4e9392d8dbd3d92e51dbb28f0842
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=314553f194da4e9392d8dbd3d92e51dbb28f0842

Author: Aric Stewart <aric at codeweavers.com>
Date:   Mon Oct 10 14:59:30 2011 -0500

usp10: Improve handling of tabs and SSA_TAB.

---

 dlls/usp10/usp10.c |   81 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 5a8a468..b48d8c9 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -897,6 +897,72 @@ HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItem
     return res;
 }
 
+static inline int getGivenTabWidth(ScriptCache *psc, SCRIPT_TABDEF *pTabdef, int charPos, int current_x)
+{
+    int defWidth;
+    int cTabStops=0;
+    INT *lpTabPos = NULL;
+    INT nTabOrg = 0;
+    INT x = 0;
+
+    if (pTabdef)
+        lpTabPos = pTabdef->pTabStops;
+
+    if (pTabdef && pTabdef->iTabOrigin)
+    {
+        if (pTabdef->iScale)
+            nTabOrg = (pTabdef->iTabOrigin * pTabdef->iScale)/4;
+        else
+            nTabOrg = pTabdef->iTabOrigin * psc->tm.tmAveCharWidth;
+    }
+
+    if (pTabdef)
+        cTabStops = pTabdef->cTabStops;
+
+    if (cTabStops == 1)
+    {
+        if (pTabdef->iScale)
+            defWidth = ((pTabdef->pTabStops[0])*pTabdef->iScale) / 4;
+        else
+            defWidth = (pTabdef->pTabStops[0])*psc->tm.tmAveCharWidth;
+        cTabStops = 0;
+    }
+    else
+        defWidth = 8 * psc->tm.tmAveCharWidth;
+
+    for (; cTabStops>0 ; lpTabPos++, cTabStops--)
+    {
+        int position = *lpTabPos;
+        if (position < 0)
+            position = -1 * position;
+        if (pTabdef->iScale)
+            position = (position * pTabdef->iScale) / 4;
+        else
+            position = position * psc->tm.tmAveCharWidth;
+
+        if( nTabOrg + position > current_x)
+        {
+            if( *lpTabPos >= 0)
+            {
+                /* a left aligned tab */
+                x = (nTabOrg + *lpTabPos) - current_x;
+                break;
+            }
+            else
+            {
+                FIXME("Negative tabstop\n");
+                break;
+            }
+        }
+    }
+    if ((!cTabStops) && (defWidth > 0))
+        x =((((current_x - nTabOrg) / defWidth)+1) * defWidth) - current_x;
+    else if ((!cTabStops) && (defWidth < 0))
+        FIXME("TODO: Negative defWidth\n");
+
+    return x;
+}
+
 /***********************************************************************
  *      ScriptStringAnalyse (USP10.@)
  *
@@ -989,6 +1055,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
 
     if (dwFlags & SSA_GLYPHS)
     {
+        int tab_x = 0;
         if (!(analysis->glyphs = heap_alloc_zero(sizeof(StringGlyphs) * analysis->numItems)))
             goto error;
 
@@ -1013,6 +1080,17 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString,
             hr = ScriptPlace(hdc, sc, glyphs, numGlyphsReturned, psva, &analysis->pItem[i].a,
                              piAdvance, pGoffset, abc);
 
+            if (dwFlags & SSA_TAB)
+            {
+                int tabi = 0;
+                for (tabi = 0; tabi < cChar; tabi++)
+                {
+                    if (pStr[analysis->pItem[i].iCharPos+tabi] == 0x0009)
+                        piAdvance[tabi] = getGivenTabWidth(analysis->sc, pTabdef, analysis->pItem[i].iCharPos+tabi, tab_x);
+                    tab_x+=piAdvance[tabi];
+                }
+            }
+
             analysis->glyphs[i].numGlyphs = numGlyphsReturned;
             analysis->glyphs[i].glyphs = glyphs;
             analysis->glyphs[i].pwLogClust = pwLogClust;
@@ -1798,6 +1876,9 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
                 chInput = mirror_char(pwcChars[idx]);
             else
                 chInput = pwcChars[idx];
+            /* special case for tabs */
+            if (chInput == 0x0009)
+                chInput = 0x0020;
             if (!(pwOutGlyphs[i] = get_cache_glyph(psc, chInput)))
             {
                 WORD glyph;




More information about the wine-cvs mailing list