Arabic shaping support

Shachar Shemesh shachar at shemesh.biz
Sun Dec 31 13:19:18 CST 2006


Attached.

There is a theoretically unhandled case when the string becomes LONGER
as a result of the shaping. It's theoretical because it's listed in the
ICU docs, but none of the Arabic speaking people I pinged about it could
come up with any plausible scenario where it will actually happen.

Shachar
-------------- next part --------------
>From 7d4a953fe907006aaf7b8b24864bf0490af8bcea Mon Sep 17 00:00:00 2001
From: Shachar Shemesh <wine at shemesh.biz>
Date: Sun, 31 Dec 2006 20:14:59 +0200
Subject: [PATCH] Implement Arabic shaping.
To: wine-patches <wine-patches at winehq.org>

---
 dlls/gdi32/bidi.c        |   23 +++++++++++++++++++++--
 dlls/gdi32/font.c        |    8 ++++----
 dlls/gdi32/gdi_private.h |    3 ++-
 3 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/dlls/gdi32/bidi.c b/dlls/gdi32/bidi.c
index ec8b36c..ee05c35 100644
--- a/dlls/gdi32/bidi.c
+++ b/dlls/gdi32/bidi.c
@@ -24,6 +24,7 @@
 #include <stdarg.h>
 #ifdef HAVE_UNICODE_UBIDI_H
 #include <unicode/ubidi.h>
+#include <unicode/ushape.h>
 #endif
 
 #include "windef.h"
@@ -49,7 +50,7 @@ BOOL BIDI_Reorder(
                 INT uCount,     /* [in] Number of WCHARs in string. */
                 DWORD dwFlags,  /* [in] GetCharacterPlacement compatible flags specifying how to process the string */
                 DWORD dwWineGCP_Flags,       /* [in] Wine internal flags - Force paragraph direction */
-                LPWSTR lpOutString, /* [out] Reordered string */
+                LPWSTR *lpOutString, /* [out] Reordered string */
                 INT uCountOut,  /* [in] Size of output buffer */
                 UINT *lpOrder /* [out] Logical -> Visual order map */
     )
@@ -88,9 +89,27 @@ BOOL BIDI_Reorder(
         }
 
         ubidi_setPara( bidi, lpString, uCount, level, NULL, &err );
+
         if( lpOutString!=NULL ) {
-            ubidi_writeReordered( bidi, lpOutString, uCount,
+	    LPWSTR lpIntermediateString;
+	    
+	    if( dwWineGCP_Flags&WINE_GCPW_SHAPE )
+		lpIntermediateString=HeapAlloc(GetProcessHeap(), 0, uCount*sizeof(WCHAR) );
+	    else
+		lpIntermediateString=*lpOutString;
+
+            ubidi_writeReordered( bidi, lpIntermediateString, uCount,
                     (dwFlags&GCP_SYMSWAPOFF)?0:UBIDI_DO_MIRRORING, &err );
+
+	    if( dwWineGCP_Flags&WINE_GCPW_SHAPE ) {
+		/* Perform Arabic shaping */
+		u_shapeArabic( lpIntermediateString, uCount, *lpOutString, uCount,
+			U_SHAPE_LENGTH_GROW_SHRINK|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR|U_SHAPE_LETTERS_SHAPE,
+			&err );
+
+		//if( U_FAILURE(err) && )
+		HeapFree( GetProcessHeap(), 0, lpIntermediateString );
+	    }
         }
 
         if( lpOrder!=NULL ) {
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 22ebd8a..7b32b02 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -1784,9 +1784,9 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
         reordered_str = HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
 
         BIDI_Reorder( str, count, GCP_REORDER,
-                      ((flags&ETO_RTLREADING)!=0 || (GetTextAlign(hdc)&TA_RTLREADING)!=0)?
-                      WINE_GCPW_FORCE_RTL:WINE_GCPW_FORCE_LTR,
-                      reordered_str, count, NULL );
+                      ((flags&ETO_RTLREADING)!=0 || ((GetTextAlign(hdc)&TA_RTLREADING)!=0)?
+                      WINE_GCPW_FORCE_RTL:WINE_GCPW_FORCE_LTR)|WINE_GCPW_SHAPE,
+                      &reordered_str, count, NULL );
     
         flags |= ETO_IGNORELANGUAGE;
     }
@@ -2878,7 +2878,7 @@ GetCharacterPlacementW(
 		}
 	} else
 	{
-            BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
+            BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, &lpResults->lpOutString,
                           nSet, lpResults->lpOrder );
 	}
 
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 07e9d49..ed45b22 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -379,8 +379,9 @@ typedef struct tagBITMAPOBJ
 #define WINE_GCPW_LOOSE_LTR 2
 #define WINE_GCPW_LOOSE_RTL 3
 #define WINE_GCPW_DIR_MASK 3
+#define WINE_GCPW_SHAPE 4
 extern BOOL BIDI_Reorder( LPCWSTR lpString, INT uCount, DWORD dwFlags, DWORD dwWineGCP_Flags,
-                          LPWSTR lpOutString, INT uCountOut, UINT *lpOrder );
+                          LPWSTR *lpOutString, INT uCountOut, UINT *lpOrder );
 extern BOOL BidiAvail;
 
 /* bitmap.c */
-- 
1.4.4.2

-------------- next part --------------
>From 51d0fc375805e23fc29593d8330db2a3b6f9b951 Mon Sep 17 00:00:00 2001
From: Shachar Shemesh <wine at shemesh.biz>
Date: Sun, 31 Dec 2006 21:13:09 +0200
Subject: [PATCH] Handle the case where, after shaping, the string is shorter than before.
To: wine-patches <wine-patches at winehq.org>

---
 dlls/gdi32/bidi.c        |    8 ++++----
 dlls/gdi32/font.c        |    4 ++--
 dlls/gdi32/gdi_private.h |    2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/dlls/gdi32/bidi.c b/dlls/gdi32/bidi.c
index ee05c35..7b93065 100644
--- a/dlls/gdi32/bidi.c
+++ b/dlls/gdi32/bidi.c
@@ -50,8 +50,8 @@ BOOL BIDI_Reorder(
                 INT uCount,     /* [in] Number of WCHARs in string. */
                 DWORD dwFlags,  /* [in] GetCharacterPlacement compatible flags specifying how to process the string */
                 DWORD dwWineGCP_Flags,       /* [in] Wine internal flags - Force paragraph direction */
-                LPWSTR *lpOutString, /* [out] Reordered string */
-                INT uCountOut,  /* [in] Size of output buffer */
+                LPWSTR *lpOutString, /* [in/out] Reordered string. Pointer to pointer */
+                INT *uCountOut,  /* [in/out] Size of output buffer */
                 UINT *lpOrder /* [out] Logical -> Visual order map */
     )
 {
@@ -94,7 +94,7 @@ BOOL BIDI_Reorder(
 	    LPWSTR lpIntermediateString;
 	    
 	    if( dwWineGCP_Flags&WINE_GCPW_SHAPE )
-		lpIntermediateString=HeapAlloc(GetProcessHeap(), 0, uCount*sizeof(WCHAR) );
+		lpIntermediateString=HeapAlloc(GetProcessHeap(), 0, *uCountOut*sizeof(WCHAR) );
 	    else
 		lpIntermediateString=*lpOutString;
 
@@ -103,7 +103,7 @@ BOOL BIDI_Reorder(
 
 	    if( dwWineGCP_Flags&WINE_GCPW_SHAPE ) {
 		/* Perform Arabic shaping */
-		u_shapeArabic( lpIntermediateString, uCount, *lpOutString, uCount,
+		*uCountOut=u_shapeArabic( lpIntermediateString, uCount, *lpOutString, *uCountOut,
 			U_SHAPE_LENGTH_GROW_SHRINK|U_SHAPE_TEXT_DIRECTION_VISUAL_LTR|U_SHAPE_LETTERS_SHAPE,
 			&err );
 
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 7b32b02..b089dc5 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -1786,7 +1786,7 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags,
         BIDI_Reorder( str, count, GCP_REORDER,
                       ((flags&ETO_RTLREADING)!=0 || ((GetTextAlign(hdc)&TA_RTLREADING)!=0)?
                       WINE_GCPW_FORCE_RTL:WINE_GCPW_FORCE_LTR)|WINE_GCPW_SHAPE,
-                      &reordered_str, count, NULL );
+                      &reordered_str, &count, NULL );
     
         flags |= ETO_IGNORELANGUAGE;
     }
@@ -2879,7 +2879,7 @@ GetCharacterPlacementW(
 	} else
 	{
             BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, &lpResults->lpOutString,
-                          nSet, lpResults->lpOrder );
+                          &nSet, lpResults->lpOrder );
 	}
 
 	/* FIXME: Will use the placement chars */
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index ed45b22..2676dd2 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -381,7 +381,7 @@ typedef struct tagBITMAPOBJ
 #define WINE_GCPW_DIR_MASK 3
 #define WINE_GCPW_SHAPE 4
 extern BOOL BIDI_Reorder( LPCWSTR lpString, INT uCount, DWORD dwFlags, DWORD dwWineGCP_Flags,
-                          LPWSTR *lpOutString, INT uCountOut, UINT *lpOrder );
+                          LPWSTR *lpOutString, INT *uCountOut, UINT *lpOrder );
 extern BOOL BidiAvail;
 
 /* bitmap.c */
-- 
1.4.4.2



More information about the wine-patches mailing list