Aric Stewart : usp10: Handle advance for multi-glyph clusters correctly.

Alexandre Julliard julliard at winehq.org
Tue Oct 18 12:56:26 CDT 2011


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Mon Oct 17 10:40:53 2011 -0500

usp10: Handle advance for multi-glyph clusters correctly.

---

 dlls/usp10/usp10.c |   64 +++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 941b918..8f472ac 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -1641,6 +1641,39 @@ static inline int get_cluster_size(const WORD *pwLogClust, int cChars, int item,
     return clust_size;
 }
 
+static inline int get_glyph_cluster_advance(const int* piAdvance, const SCRIPT_VISATTR *pva, const WORD *pwLogClust, int cGlyphs, int cChars, int glyph, int direction)
+{
+    int advance;
+    int log_clust_max = 0;
+    int i;
+
+    advance = piAdvance[glyph];
+
+    for (i = 0; i < cChars; i++)
+    {
+        if (pwLogClust[i] > log_clust_max)
+            log_clust_max = pwLogClust[i];
+    }
+
+    if (glyph > log_clust_max)
+        return advance;
+
+    for (glyph+=direction; glyph < cGlyphs && glyph >= 0; glyph +=direction)
+    {
+        if (pva[glyph].fClusterStart)
+            break;
+        for (i = 0; i < cChars; i++)
+            if (pwLogClust[i] == glyph) break;
+        if (i != cChars)
+            break;
+        if (glyph > log_clust_max)
+            break;
+        advance += piAdvance[glyph];
+    }
+
+    return advance;
+}
+
 /***********************************************************************
  *      ScriptCPtoX (USP10.@)
  *
@@ -1662,6 +1695,7 @@ HRESULT WINAPI ScriptCPtoX(int iCP,
     int clust_size = 1;
     float special_size = 0.0;
     int iMaxPos = 0;
+    int advance = 0;
     BOOL rtl = FALSE;
 
     TRACE("(%d,%d,%d,%d,%p,%p,%p,%p,%p)\n",
@@ -1702,10 +1736,12 @@ HRESULT WINAPI ScriptCPtoX(int iCP,
             clust_size = get_cluster_size(pwLogClust, cChars, item, 1, &iCluster,
                                           &check);
 
+            advance = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, clust, 1);
+
             if (check >= cChars && !iMaxPos)
             {
                 for (check = clust; check < cChars; check++)
-                    special_size += piAdvance[check];
+                    special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, check, 1);
                 iSpecial = item;
                 special_size /= (cChars - item);
                 iPosX += special_size;
@@ -1716,24 +1752,25 @@ HRESULT WINAPI ScriptCPtoX(int iCP,
                 {
                     clust_size --;
                     if (clust_size == 0)
-                        iPosX += piAdvance[clust];
+                        iPosX += advance;
                 }
                 else
-                    iPosX += piAdvance[clust] / (float)clust_size;
+                    iPosX += advance / (float)clust_size;
             }
         }
         else if (iSpecial != -1)
             iPosX += special_size;
         else /* (iCluster != -1) */
         {
+            int adv = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, pwLogClust[iCluster], 1);
             if (scriptInformation[psa->eScript].props.fNeedsCaretInfo)
             {
                 clust_size --;
                 if (clust_size == 0)
-                    iPosX += piAdvance[pwLogClust[iCluster]];
+                    iPosX += adv;
             }
             else
-                iPosX += piAdvance[pwLogClust[iCluster]] / (float)clust_size;
+                iPosX += adv / (float)clust_size;
         }
     }
 
@@ -1770,6 +1807,7 @@ HRESULT WINAPI ScriptXtoCP(int iX,
     int iCluster = -1;
     int clust_size = 1;
     int cjump = 0;
+    int advance;
     float special_size = 0.0;
     int direction = 1;
 
@@ -1830,11 +1868,12 @@ HRESULT WINAPI ScriptXtoCP(int iX,
             cjump = 0;
             clust_size = get_cluster_size(pwLogClust, cChars, item, direction,
                                           &iCluster, &check);
+            advance = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, clust, direction);
 
             if (check >= cChars && direction > 0)
             {
                 for (check = clust; check < cChars; check++)
-                    special_size += piAdvance[check];
+                    special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, check, direction);
                 iSpecial = item;
                 special_size /= (cChars - item);
                 iPosX += special_size;
@@ -1844,25 +1883,26 @@ HRESULT WINAPI ScriptXtoCP(int iX,
                 if (scriptInformation[psa->eScript].props.fNeedsCaretInfo)
                 {
                     if (!cjump)
-                        iPosX += piAdvance[clust];
+                        iPosX += advance;
                     cjump++;
                 }
                 else
-                    iPosX += piAdvance[clust] / (float)clust_size;
+                    iPosX += advance / (float)clust_size;
             }
         }
         else if (iSpecial != -1)
             iPosX += special_size;
         else /* (iCluster != -1) */
         {
+            int adv = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, pwLogClust[iCluster], direction);
             if (scriptInformation[psa->eScript].props.fNeedsCaretInfo)
             {
                 if (!cjump)
-                    iPosX += piAdvance[pwLogClust[iCluster]];
+                    iPosX += adv;
                 cjump++;
             }
             else
-                iPosX += piAdvance[pwLogClust[iCluster]] / (float)clust_size;
+                iPosX += adv / (float)clust_size;
         }
     }
 
@@ -2584,9 +2624,11 @@ HRESULT WINAPI ScriptStringGetLogicalWidths(SCRIPT_STRING_ANALYSIS ssa, int *piD
             int glyph = analysis->glyphs[i].pwLogClust[j];
             int clust_size = get_cluster_size(analysis->glyphs[i].pwLogClust,
                                               cChar, j, direction, NULL, NULL);
+            int advance = get_glyph_cluster_advance(analysis->glyphs[i].piAdvance, analysis->glyphs[i].psva, analysis->glyphs[i].pwLogClust, analysis->glyphs[i].numGlyphs, cChar, glyph, direction);
+
             for (k = 0; k < clust_size; k++)
             {
-                piDx[next] = analysis->glyphs[i].piAdvance[glyph] / clust_size;
+                piDx[next] = advance / clust_size;
                 next++;
                 if (k) j++;
             }




More information about the wine-cvs mailing list