usp10: Resend: Support fRTL to reverse glyph strings

Jeff L lats at yless4u.com.au
Mon Sep 18 04:55:08 CDT 2006


Submitting again as the last one seems to missed the boat again.

This patch adds support and tests to reverse glyphs if the unicode input
is Arabic.  This is the start of looking at support for different scripts.

Jeff Latimer

Changelog:
Reverse glyphs for Arabic unicode.

-------------- next part --------------
>From cf5b09cbe191d078b4dc37cbda1efcd7794b945c Mon Sep 17 00:00:00 2001
From: Jeff Latimer <lats at yless4u.com.au>
Date: Tue, 12 Sep 2006 19:24:22 +1000
Subject: [PATCH] Basic support for reversing the glyphs for Arabic
---
 dlls/usp10/tests/usp10.c |   26 +++++++++++++
 dlls/usp10/usp10.c       |   93 ++++++++++++++++++++++++++++++++--------------
 2 files changed, 90 insertions(+), 29 deletions(-)

diff --git a/dlls/usp10/tests/usp10.c b/dlls/usp10/tests/usp10.c
index 45a65f2..9ef938e 100644
--- a/dlls/usp10/tests/usp10.c
+++ b/dlls/usp10/tests/usp10.c
@@ -47,6 +47,8 @@ static void test_ScriptItemIzeShapePlace
     WCHAR           TestItem2[] = {'T', 'e', 's', 't', 'b', 0}; 
     WCHAR           TestItem3[] = {'T', 'e', 's', 't', 'c',' ','1','2','3',' ',' ','e','n','d',0}; 
     WCHAR           TestItem4[] = {'T', 'e', 's', 't', 'c',' ',0x0684,0x0694,0x06a4,' ',' ','e','n','d',0}; 
+    WCHAR           TestItem5[] = {0x064a, 0x064f, 0x0633, 0x0627, 0x0648, 0x0650, 0x064a, 0}; 
+    WCHAR           TestResults5[] = {0x03f1, 0x02f6, 0x03ed, 0x038d, 0x03b1, 0x02f5, 0x03f1, 0};
 
     SCRIPT_CACHE    psc;
     int             cChars;
@@ -243,6 +245,30 @@ static void test_ScriptItemIzeShapePlace
         hr = ScriptFreeCache( &psc);
         ok (!psc, "psc is not null after ScriptFreeCache\n");
     }
+
+    /* This is to check that fRTL flag is honoured and glyphs are reversed                  */
+    lstrcpyA(lf.lfFaceName, "Arial");                    /* need a font with Arabic glyphs  */
+    zfont = (HFONT) SelectObject(hdc, CreateFontIndirectA(&lf));
+
+    cInChars = (sizeof(TestItem5)/2)-1;
+    cMaxItems = 255;
+    hr = ScriptItemize(TestItem5, cInChars, cMaxItems, NULL, NULL, pItem, &pcItems);
+    ok (hr == 0, "ScriptItemize should return 0, returned %08lx\n", hr);
+    if  (hr == 0)
+    {
+        cChars = cInChars;
+        cMaxGlyphs = 256;
+        hr = ScriptShape(hdc, &psc, &TestItem5[0], cChars,
+                         cMaxGlyphs, &pItem[0].a,
+                         pwOutGlyphs2, pwLogClust, psva, &pcGlyphs);
+        ok (hr == 0, "ScriptShape should return 0 not (%08lx)\n", hr);
+        /* check to glyphs are in the expected order     */
+        for (cnt=0; cnt < cChars && pwOutGlyphs2[cnt] == TestResults5[cnt]; cnt++) {}
+        ok (cnt == cChars, "Glyphs are incorrect, for cnt=%d expect %04x got %04x\n", 
+                           cnt, TestResults5[cnt], pwOutGlyphs2[cnt]);
+        hr = ScriptFreeCache( &psc);
+        ok (!psc, "psc is not null after ScriptFreeCache\n");
+    }
 }
 
 void test_ScriptGetCMap(HDC hdc, unsigned short pwOutGlyphs[256])
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c
index e258345..463292c 100644
--- a/dlls/usp10/usp10.c
+++ b/dlls/usp10/usp10.c
@@ -55,8 +55,8 @@ static const SCRIPT_PROPERTIES Default_S
                                             0, 0, 0, 0, 0, 0, 0};
 static const SCRIPT_PROPERTIES Default_Script_5 = {9, 0, 0, 0, 0, 0, 0, 0, 
                                             0, 0, 0, 0, 1, 0, 0};
-static const SCRIPT_PROPERTIES Default_Script_6 = {9, 1, 0, 0, 0, 0, 0, 0, 
-                                            0, 0, 0, 0, 1, 0, 0};
+static const SCRIPT_PROPERTIES Default_Script_6 = {1, 0, 1, 0, 0, 178, 0, 0, 
+                                            0, 0, 0, 0, 1, 1, 0};
 static const SCRIPT_PROPERTIES Default_Script_7 = {8, 0, 0, 0, 0, 161, 0, 0, 
                                             0, 0, 0, 0, 0, 0, 0};
 static const SCRIPT_PROPERTIES *Global_Script[MAX_SCRIPTS] =
@@ -276,6 +276,7 @@ HRESULT WINAPI ScriptApplyDigitSubstitut
         default:
             return E_INVALIDARG;
     }
+
 }
 
 /***********************************************************************
@@ -317,19 +318,26 @@ #define Script_Numeric 5
         pItems[index].a.eScript = Script_Latin;
     else
         pItems[index].a.eScript = SCRIPT_UNDEFINED;
+    New_Script = pItems[index].a.eScript;
     pItems[index].iCharPos = 0;
     /*  Set the SCRIPT_ANALYSIS                             */
-    pItems[index].a.fRTL = 0;
-    pItems[index].a.fLayoutRTL = 0;
+    if  (New_Script == Script_Arabic)
+    {
+        pItems[index].a.fRTL = 1;
+        pItems[index].a.fLayoutRTL = 1;
+        pItems[index].a.s.uBidiLevel = 1;
+    }
+    else
+    {
+        pItems[index].a.fRTL = 0;
+        pItems[index].a.fLayoutRTL = 0;
+        pItems[index].a.s.uBidiLevel = 0;
+    }
     pItems[index].a.fLinkBefore = 0;
     pItems[index].a.fLinkAfter = 0;
     pItems[index].a.fLogicalOrder = 0;
     pItems[index].a.fNoGlyphIndex = 0;
     /*  set the SCRIPT_STATE                                */
-    if  (New_Script == Script_Arabic)
-        pItems[index].a.s.uBidiLevel = 1;
-    else
-        pItems[index].a.s.uBidiLevel = 0;
     pItems[index].a.s.fOverrideDirection = 0;
     pItems[index].a.s.fInhibitSymSwap = FALSE;
     pItems[index].a.s.fCharShape = 0;
@@ -365,23 +373,27 @@ #define Script_Numeric 5
             if  (index+1 > cMaxItems)
                 return E_OUTOFMEMORY;
             pItems[index].iCharPos = cnt;
-            if  (New_Script == Script_Arabic)
-                pItems[index].a.s.uBidiLevel = 1;
             /*  Set SCRIPT_ITEM                                     */
             pItems[index].iCharPos = cnt;
             /*  Set the SCRIPT_ANALYSIS                             */
             pItems[index].a.eScript = New_Script;
-            pItems[index].a.fRTL = 0;
-            pItems[index].a.fLayoutRTL = 0;
+            if  (New_Script == Script_Arabic)
+            {
+                pItems[index].a.fRTL = 1;
+                pItems[index].a.fLayoutRTL = 1;
+                pItems[index].a.s.uBidiLevel = 1;
+            }
+            else
+            {
+                pItems[index].a.fRTL = 0;
+                pItems[index].a.fLayoutRTL = 0;
+                pItems[index].a.s.uBidiLevel = 0;
+            }
             pItems[index].a.fLinkBefore = 0;
             pItems[index].a.fLinkAfter = 0;
             pItems[index].a.fLogicalOrder = 0;
             pItems[index].a.fNoGlyphIndex = 0;
             /*  set the SCRIPT_STATE                                */
-            if  (New_Script == Script_Arabic)
-                pItems[index].a.s.uBidiLevel = 1;
-            else
-                pItems[index].a.s.uBidiLevel = 0;
             pItems[index].a.s.fOverrideDirection = 0;
             pItems[index].a.s.fInhibitSymSwap = FALSE;
             pItems[index].a.s.fCharShape = 0;
@@ -811,9 +823,11 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRI
      *  passed between functions.                                                         */
 
     HDC phdc;
-    int cnt;
+    int cnt, cnt_reorder;
     DWORD hr;
     Scriptcache *pScriptcache;
+    WCHAR *glyph_reorder;
+
     *pcGlyphs = cChars;
     FIXME("(%p, %p, %p, %d, %d, %p): semi-stub\n",  hdc, psc, pwcChars,
                                        cChars, cMaxGlyphs, psa);
@@ -843,22 +857,43 @@ HRESULT WINAPI ScriptShape(HDC hdc, SCRI
          TRACE("%4x",pwcChars[cnt]);
     TRACE("\n");
 
-    if  (!psa->fNoGlyphIndex) {                                         /* Glyph translate */
-        hr = GetGlyphIndicesW(phdc, pwcChars, cChars, pwOutGlyphs, 0);
-        TRACE("After:  ");
-        for (cnt = 0; cnt < cChars; cnt++) {
-             TRACE("%04x",pwOutGlyphs[cnt]);
+    TRACE("After:  ");
+    if  (!psa->fRTL)                                                   /* Not rigth to Left */
+    {
+         if  (!psa->fNoGlyphIndex) {                                    /* Glyph translate */
+            hr = GetGlyphIndicesW(phdc, pwcChars, cChars, pwOutGlyphs, 0);
+            for (cnt = 0; cnt < cChars; cnt++) {
+                TRACE("%04x",pwOutGlyphs[cnt]);
+            }
+        }
+        else {
+            for (cnt = 0; cnt < cChars; cnt++) {                       /* no translate so set up */
+                pwOutGlyphs[cnt] = pwcChars[cnt];                      /* copy in to out and     */
+                TRACE("%04x",pwOutGlyphs[cnt]);
+            }
         }
-        TRACE("\n");
     }
-    else {
-        TRACE("After:  ");
-        for (cnt = 0; cnt < cChars; cnt++) {                           /* no translate so set up */
-             pwOutGlyphs[cnt] = pwcChars[cnt];                         /* copy in to out and     */
-             TRACE("%04x",pwOutGlyphs[cnt]);
+    else
+    {
+        glyph_reorder = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR)*cChars);
+        for (cnt=0, cnt_reorder=cChars-1; cnt < cChars ; cnt++, cnt_reorder--)
+            glyph_reorder[cnt] = pwcChars[cnt_reorder];
+        if  (!psa->fNoGlyphIndex) {                                    /* Glyph translate */
+            hr = GetGlyphIndicesW(phdc, glyph_reorder, cChars, pwOutGlyphs, 0);
+            TRACE("After:  ");
+            for (cnt = 0; cnt < cChars; cnt++) {
+                TRACE("%04x",pwOutGlyphs[cnt]);
+            }
         }
-       TRACE("\n");
+        else {
+            for (cnt = 0; cnt < cChars; cnt++) {                       /* no translate so set up */
+                pwOutGlyphs[cnt] = glyph_reorder[cnt];                 /* copy in to out and     */
+                TRACE("%04x",pwOutGlyphs[cnt]);
+            }
+        }
+        HeapFree(GetProcessHeap(), 0, glyph_reorder);
     }
+    TRACE("\n");
 
     /*  Set up a valid SCRIPT_VISATTR and LogClust for each char in this run */     
     for (cnt = 0;  cnt < cChars; cnt++) {
-- 
1.4.1




More information about the wine-patches mailing list