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