Aric Stewart : usp10: Implement mirroring for bidi support.

Alexandre Julliard julliard at winehq.org
Fri May 7 09:41:13 CDT 2010


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Thu May  6 08:28:57 2010 -0500

usp10: Implement mirroring for bidi support.

---

 dlls/usp10/tests/usp10.c |   24 ++++++++++++++++++++++++
 dlls/usp10/usp10.c       |   39 ++++++++++++++++++++++++++++++++-------
 2 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c
index f76f95c..2d7641d 100644
--- a/dlls/usp10/tests/usp10.c
+++ b/dlls/usp10/tests/usp10.c
@@ -582,12 +582,15 @@ static void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256])
     SCRIPT_CACHE    psc = NULL;
     int             cInChars;
     int             cChars;
+    unsigned short  pwOutGlyphs2[256];
     unsigned short  pwOutGlyphs3[256];
     DWORD           dwFlags;
     int             cnt;
 
     static const WCHAR TestItem1[] = {'T', 'e', 's', 't', 'a', 0};
     static const WCHAR TestItem2[] = {0x202B, 'i', 'n', 0x202C,0};
+    static const WCHAR TestItem3[] = {'a','b','c','d','(','<','{','[',0x2039,0};
+    static const WCHAR TestItem3b[] = {'a','b','c','d',')','>','}',']',0x203A,0};
 
     /*  Check to make sure that SCRIPT_CACHE gets allocated ok                     */
     dwFlags = 0;
@@ -640,6 +643,27 @@ static void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256])
     ok(pwOutGlyphs3[0] == 0, "Glyph 0 should be default glyph\n");
     ok(pwOutGlyphs3[3] == 0, "Glyph 0 should be default glyph\n");
 
+
+    cInChars = cChars = 9;
+    hr = ScriptGetCMap(hdc, &psc, TestItem3b, cInChars, dwFlags, pwOutGlyphs2);
+    ok (hr == S_OK, "ScriptGetCMap should return S_OK not (%08x)\n", hr);
+    ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
+
+    cInChars = cChars = 9;
+    dwFlags = SGCM_RTL;
+    hr = ScriptGetCMap(hdc, &psc, TestItem3, cInChars, dwFlags, pwOutGlyphs3);
+    ok (hr == S_OK, "ScriptGetCMap should return S_OK not (%08x)\n", hr);
+    ok (psc != NULL, "psc should not be null and have SCRIPT_CACHE buffer address\n");
+    ok(pwOutGlyphs3[0] == pwOutGlyphs2[0], "glyph incorrectly altered\n");
+    ok(pwOutGlyphs3[1] == pwOutGlyphs2[1], "glyph incorreclty altered\n");
+    ok(pwOutGlyphs3[2] == pwOutGlyphs2[2], "glyph incorreclty altered\n");
+    ok(pwOutGlyphs3[3] == pwOutGlyphs2[3], "glyph incorreclty altered\n");
+    ok(pwOutGlyphs3[4] == pwOutGlyphs2[4], "glyph not mirrored correctly\n");
+    ok(pwOutGlyphs3[5] == pwOutGlyphs2[5], "glyph not mirrored correctly\n");
+    ok(pwOutGlyphs3[6] == pwOutGlyphs2[6], "glyph not mirrored correctly\n");
+    ok(pwOutGlyphs3[7] == pwOutGlyphs2[7], "glyph not mirrored correctly\n");
+    ok(pwOutGlyphs3[8] == pwOutGlyphs2[8], "glyph not mirrored correctly\n");
+
     hr = ScriptFreeCache( &psc);
     ok (!psc, "psc is not null after ScriptFreeCache\n");
 }
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index 3a7fcd1..43a3b5e 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -271,6 +271,12 @@ static HRESULT init_script_cache(const HDC hdc, SCRIPT_CACHE *psc)
     return S_OK;
 }
 
+static WCHAR mirror_char( WCHAR ch )
+{
+    extern const WCHAR wine_mirror_map[];
+    return ch + wine_mirror_map[wine_mirror_map[ch >> 8] + (ch & 0xff)];
+}
+
 /***********************************************************************
  *      DllMain
  *
@@ -1392,13 +1398,18 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
         for (i = 0; i < cChars; i++)
         {
             int idx = i;
+            WCHAR chInput;
             if (rtl) idx = cChars - 1 - i;
-            if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcChars[idx])))
+            if (psa->fRTL)
+                chInput = mirror_char(pwcChars[idx]);
+            else
+                chInput = pwcChars[idx];
+            if (!(pwOutGlyphs[i] = get_cache_glyph(psc, chInput)))
             {
                 WORD glyph;
                 if (!hdc) return E_PENDING;
-                if (GetGlyphIndicesW(hdc, &pwcChars[idx], 1, &glyph, 0) == GDI_ERROR) return S_FALSE;
-                pwOutGlyphs[i] = set_cache_glyph(psc, pwcChars[idx], glyph);
+                if (GetGlyphIndicesW(hdc, &chInput, 1, &glyph, 0) == GDI_ERROR) return S_FALSE;
+                pwOutGlyphs[i] = set_cache_glyph(psc, chInput, glyph);
             }
         }
     }
@@ -1408,6 +1419,7 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars,
         for (i = 0; i < cChars; i++)
         {
             int idx = i;
+            /* No mirroring done here */
             if (rtl) idx = cChars - 1 - i;
             pwOutGlyphs[i] = pwcChars[idx];
         }
@@ -1534,24 +1546,37 @@ HRESULT WINAPI ScriptGetCMap(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcInChars
     {
         for (i = 0; i < cChars; i++)
         {
-            if (!(pwOutGlyphs[i] = get_cache_glyph(psc, pwcInChars[i])))
+            WCHAR inChar;
+            if (dwFlags == SGCM_RTL)
+                inChar = mirror_char(pwcInChars[i]);
+            else
+                inChar = pwcInChars[i];
+            if (!(pwOutGlyphs[i] = get_cache_glyph(psc, inChar)))
             {
                 WORD glyph;
                 if (!hdc) return E_PENDING;
-                if (GetGlyphIndicesW(hdc, &pwcInChars[i], 1, &glyph, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR) return S_FALSE;
+                if (GetGlyphIndicesW(hdc, &inChar, 1, &glyph, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR) return S_FALSE;
                 if (glyph == 0xffff)
                 {
                     hr = S_FALSE;
                     glyph = 0x0;
                 }
-                pwOutGlyphs[i] = set_cache_glyph(psc, pwcInChars[i], glyph);
+                pwOutGlyphs[i] = set_cache_glyph(psc, inChar, glyph);
             }
         }
     }
     else
     {
         TRACE("no glyph translation\n");
-        for (i = 0; i < cChars; i++) pwOutGlyphs[i] = pwcInChars[i];
+        for (i = 0; i < cChars; i++)
+        {
+            WCHAR inChar;
+            if (dwFlags == SGCM_RTL)
+                inChar = mirror_char(pwcInChars[i]);
+            else
+                inChar = pwcInChars[i];
+            pwOutGlyphs[i] = inChar;
+        }
     }
     return hr;
 }




More information about the wine-cvs mailing list