Aric Stewart : usp10: Handle surrogate pairs when shaping.

Alexandre Julliard julliard at winehq.org
Mon Dec 19 13:39:22 CST 2011


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Fri Dec 16 13:15:47 2011 -0600

usp10: Handle surrogate pairs when shaping.

---

 dlls/usp10/usp10.c |   67 +++++++++++++++++++++++++++++++++++----------------
 1 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 5f1ac5c..7a32937 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -708,7 +708,7 @@ static inline BYTE get_cache_pitch_family(SCRIPT_CACHE *psc)
     return ((ScriptCache *)*psc)->tm.tmPitchAndFamily;
 }
 
-static inline WORD get_cache_glyph(SCRIPT_CACHE *psc, WCHAR c)
+static inline WORD get_cache_glyph(SCRIPT_CACHE *psc, DWORD c)
 {
     WORD *block = ((ScriptCache *)*psc)->glyphs[c >> GLYPH_BLOCK_SHIFT];
 
@@ -2631,8 +2631,9 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
                                     SCRIPT_GLYPHPROP *pOutGlyphProps, int *pcGlyphs)
 {
     HRESULT hr;
-    unsigned int i;
+    unsigned int i,g;
     BOOL rtl;
+    int cluster;
 
     TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %d, %d, %p, %p, %p, %p, %p )\n",
      hdc, psc, psa,
@@ -2688,35 +2689,59 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
 
         rChars = heap_alloc(sizeof(WCHAR) * cChars);
         if (!rChars) return E_OUTOFMEMORY;
-        for (i = 0; i < cChars; i++)
+        for (i = 0, g = 0, cluster = 0; i < cChars; i++)
         {
             int idx = i;
-            WCHAR chInput;
+            DWORD chInput;
+
             if (rtl) idx = cChars - 1 - i;
-            if (psa->fRTL)
-                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)))
+            if (!cluster)
             {
-                WORD glyph;
-                if (!hdc)
+                chInput = decode_surrogate_pair(pwcChars, idx, cChars);
+                if (!chInput)
                 {
-                    heap_free(rChars);
-                    return E_PENDING;
+                    if (psa->fRTL)
+                        chInput = mirror_char(pwcChars[idx]);
+                    else
+                        chInput = pwcChars[idx];
+                    /* special case for tabs */
+                    if (chInput == 0x0009)
+                        chInput = 0x0020;
+                    rChars[i] = chInput;
                 }
-                if (GetGlyphIndicesW(hdc, &chInput, 1, &glyph, 0) == GDI_ERROR)
+                else
                 {
-                    heap_free(rChars);
-                    return S_FALSE;
+                    rChars[i] = pwcChars[idx];
+                    rChars[i+1] = pwcChars[(rtl)?idx-1:idx+1];
+                    cluster = 1;
                 }
-                pwOutGlyphs[i] = set_cache_glyph(psc, chInput, glyph);
+                if (!(pwOutGlyphs[g] = get_cache_glyph(psc, chInput)))
+                {
+                    WORD glyph;
+                    if (!hdc)
+                    {
+                        heap_free(rChars);
+                        return E_PENDING;
+                    }
+                    if (CMAP_GetGlyphIndex(hdc, (ScriptCache *)*psc, chInput, &glyph, 0) == GDI_ERROR)
+                    {
+                        heap_free(rChars);
+                        return S_FALSE;
+                    }
+                    pwOutGlyphs[g] = set_cache_glyph(psc, chInput, glyph);
+                }
+                g++;
+            }
+            else
+            {
+                int k;
+                cluster--;
+                pwLogClust[idx] = (rtl)?pwLogClust[idx+1]:pwLogClust[idx-1];
+                for (k = (rtl)?idx-1:idx+1; k >= 0 && k < cChars; (rtl)?k--:k++)
+                    pwLogClust[k]--;
             }
-            rChars[i] = chInput;
         }
+        *pcGlyphs = g;
 
         SHAPE_ContextualShaping(hdc, (ScriptCache *)*psc, psa, rChars, cChars, pwOutGlyphs, pcGlyphs, cMaxGlyphs, pwLogClust);
         SHAPE_ApplyDefaultOpentypeFeatures(hdc, (ScriptCache *)*psc, psa, pwOutGlyphs, pcGlyphs, cMaxGlyphs, cChars, pwLogClust);




More information about the wine-cvs mailing list