Bidi B3 - GetCharacterPlacement final cleanups

Shachar Shemesh wine-patches at shemesh.biz
Sat May 31 11:06:25 CDT 2003


Andreas Mohr wrote:

>Hi,
>
>On Sat, May 31, 2003 at 06:49:57PM +0300, Shachar Shemesh wrote:
>  
>
>>Apply with -p1
>>
>>Changelog:
>>Shachar Shemesh <winecode at shemesh.biz>
>>
>>   * Removed all redundant "GetCharacterPlacement" code from the
>>     internal reordering function. WINE_BiDi_reorder now does only that.
>>   * Removed all reordering code from "GetCharacterPlacementW". It now
>>     has only the non-reordering stuff, calling "WINE_BiDi_reorder" for
>>     the reordering code.
>>    
>>
>Nice ChangeLog!
>
>And... what am I supposed to apply with -p1 here? Your mail or what? :)
>
>Andreas Mohr
>  
>
I just wrote the changelog, isn't it clear what the actual patch should be?

Ok, so for all those of you with no imagination, here is the actual 
patch. Happy?? Hah??

          Shachar

-- 
Shachar Shemesh
Open Source integration consultant
Home page & resume - http://www.shemesh.biz/

-------------- next part --------------
diff -u -r -x '*.o' -x CVS wine.ref/dlls/gdi/bidi.c wine/dlls/gdi/bidi.c
--- wine.ref/dlls/gdi/bidi.c	2003-05-31 12:49:58.000000000 +0300
+++ wine/dlls/gdi/bidi.c	2003-05-31 15:52:20.000000000 +0300
@@ -48,56 +48,20 @@
     return BidiAvail;
 }
 
-DWORD Wine_GCPW(HDC hdc,        /* [in] Device context for which the rendering is to be done */
+BOOL Wine_BiDi_reorder(
                 LPCWSTR lpString,       /* [in] The string for which information is to be returned */
-                INT uCount,     /* [in] Number of WORDS in string. */
-                INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
-                GCP_RESULTSW * lpResults,       /* [in/out] A pointer to a GCP_RESULTSW struct */
-                DWORD dwFlags,  /* [in] Flags specifying how to process the string */
-                DWORD dwWineGCP_Flags       /* [in] Wine internal flags - Force paragraph direction */
+                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 */
+                UINT *lpOrder /* [out] Logical -> Visual order map */
     )
 {
-    DWORD ret = 0;
-    SIZE size;
-    UINT i, nSet;
-
-    TRACE("%s, %d, %d, 0x%08lx\n",
-          debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
-
-    TRACE
-        ("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
-         "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
-         lpResults->lStructSize, lpResults->lpOutString,
-         lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
-         lpResults->lpClass, lpResults->lpGlyphs, lpResults->nGlyphs,
-         lpResults->nMaxFit);
-
-    if (dwFlags & (~GCP_REORDER))
-        FIXME("flags 0x%08lx ignored\n", dwFlags);
-    if (lpResults->lpCaretPos)
-        FIXME("caret positions not implemented\n");
-    if (lpResults->lpClass)
-        FIXME("classes not implemented\n");
-
-    nSet = (UINT) uCount;
-    if (nSet > lpResults->nGlyphs)
-        nSet = lpResults->nGlyphs;
-
-    /* return number of initialized fields */
-    lpResults->nGlyphs = nSet;
-
-    if (dwFlags == 0) {
-        /* Treat the case where no special handling was requested in a fastpath way */
-        /* copy will do if the GCP_REORDER flag is not set */
-        if (lpResults->lpOutString)
-            for (i = 0; i < nSet && lpString[i] != 0; ++i)
-                lpResults->lpOutString[i] = lpString[i];
-
-        if (lpResults->lpOrder) {
-            for (i = 0; i < nSet; i++)
-                lpResults->lpOrder[i] = i;
-        }
-    }
+    TRACE("%s, %d, 0x%08lx\n",
+          debugstr_wn(lpString, uCount), uCount, dwFlags);
+
+    TRACE("lpOutString=%p, lpOrder=%p", lpOutString, lpOrder );
 
     if ((dwFlags & GCP_REORDER) != 0) {
         UBiDi *bidi;
@@ -108,7 +72,7 @@
         if( bidi==NULL ) {
             WARN("Failed to allocate structure\n");
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            return 0;
+            return FALSE;
         }
 
         switch( dwWineGCP_Flags&WINE_GCPW_DIR_MASK )
@@ -128,13 +92,13 @@
         }
 
         ubidi_setPara( bidi, lpString, uCount, level, NULL, &err );
-        if( lpResults->lpOutString!=NULL ) {
-            ubidi_writeReordered( bidi, lpResults->lpOutString, uCount,
+        if( lpOutString!=NULL ) {
+            ubidi_writeReordered( bidi, lpOutString, uCount,
                     (dwFlags&GCP_SYMSWAPOFF)?0:UBIDI_DO_MIRRORING, &err );
         }
 
-        if( lpResults->lpOrder!=NULL ) {
-            ubidi_getLogicalMap( bidi, lpResults->lpOrder, &err );
+        if( lpOrder!=NULL ) {
+            ubidi_getLogicalMap( bidi, lpOrder, &err );
         }
 
         ubidi_close( bidi );
@@ -145,26 +109,11 @@
                     "descriptive Windows error codes here\n");
             SetLastError(ERROR_INVALID_LEVEL); /* This error is cryptic enough not to mean anything, I hope */
 
-            return 0;
-        }
-    }
-
-    /* FIXME: Will use the placement chars */
-    if (lpResults->lpDx) {
-        int c;
-        for (i = 0; i < nSet; i++) {
-            if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
-                lpResults->lpDx[i] = c;
+            return FALSE;
         }
     }
 
-    if (lpResults->lpGlyphs)
-        GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
-
-    if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
-        ret = MAKELONG(size.cx, size.cy);
-
-    return ret;
+    return TRUE;
 }
 
 #endif                          /* HAVE_BIDI */
diff -u -r -x '*.o' -x CVS wine.ref/dlls/gdi/gdibidi.h wine/dlls/gdi/gdibidi.h
--- wine.ref/dlls/gdi/gdibidi.h	2003-05-31 12:37:36.000000000 +0300
+++ wine/dlls/gdi/gdibidi.h	2003-05-31 18:36:40.000000000 +0300
@@ -28,13 +28,14 @@
 
 BOOL WineBidiInit(void);
 
-DWORD Wine_GCPW(HDC hdc,        /* [in] Device context for which the rendering is to be done */
+BOOL Wine_BiDi_reorder(
                 LPCWSTR lpString,       /* [in] The string for which information is to be returned */
-                INT uCount,     /* [in] Number of WORDS in string. */
-                INT nMaxExtent, /* [in] Maximum extent the string is to take (in HDC logical units) */
-                GCP_RESULTSW * lpResults,       /* [in/out] A pointer to a GCP_RESULTSW struct */
-                DWORD dwFlags,  /* [in] Flags specifying how to process the string */
-                DWORD dwWineFlags       /* [in] Wine internal flags - Force paragraph direction */
+                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 */
+                UINT *lpOrder /* [out] Logical -> Visual order map */
     );
 
 #define HAVE_BIDI 1
diff -u -r -x '*.o' -x CVS wine.ref/objects/font.c wine/objects/font.c
--- wine.ref/objects/font.c	2003-05-20 02:24:30.000000000 +0300
+++ wine/objects/font.c	2003-05-31 18:38:39.000000000 +0300
@@ -3,6 +3,7 @@
  *
  * Copyright 1993 Alexandre Julliard
  *           1997 Alex Korobka
+ * Copyright 2002,2003 Shachar Shemesh
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -19,18 +20,19 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "config.h"
-#include "wine/port.h"
+#include <config.h>
+#include <wine/port.h>
 
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
-#include "winerror.h"
-#include "winnls.h"
-#include "wownt32.h"
-#include "gdi.h"
-#include "wine/unicode.h"
-#include "wine/debug.h"
+#include <winerror.h>
+#include <winnls.h>
+#include <wownt32.h>
+#include <gdi.h>
+#include <wine/unicode.h>
+#include <wine/debug.h>
+#include "gdibidi.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(font);
 WINE_DECLARE_DEBUG_CHANNEL(gdi);
@@ -1989,105 +1991,22 @@
 	/* return number of initialized fields */
 	lpResults->nGlyphs = nSet;
 
-	if(dwFlags==0)
+	if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
 	{
 		/* Treat the case where no special handling was requested in a fastpath way */
 		/* copy will do if the GCP_REORDER flag is not set */
 		if(lpResults->lpOutString)
-			for(i=0; i<nSet && lpString[i]!=0; ++i )
-				lpResults->lpOutString[i]=lpString[i];
+                    strncpyW( lpResults->lpOutString, lpString, nSet );
 
 		if(lpResults->lpOrder)
 		{
 			for(i = 0; i < nSet; i++)
 				lpResults->lpOrder[i] = i;
 		}
-	}
-
-	if((dwFlags&GCP_REORDER)!=0)
+	} else
 	{
-		WORD *pwCharType;
-		int run_end;
-		/* Keep a static table that translates the C2 types to something meaningful */
-		/* 1 - left to right
-		 * -1 - right to left
-		 * 0 - neutral
-		 */
-		static const int chardir[]={ 0, 1, -1, 1, 0, 0, -1, 0, 0, 0, 0, 0 };
-
-		WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
-		if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
-		{
-			SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-
-			return 0;
-		}
-
-		/* Fill in the order array with directionality values */
-		GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
-
-		/* The complete and correct (at least according to MS) BiDi algorythm is not
-		 * yet implemented here. Instead, we just make sure that consecutive runs of
-		 * the same direction (or neutral) are ordered correctly. We also assign Neutrals
-		 * that are between runs of opposing directions the base (ok, always LTR) dir.
-		 * While this is a LONG way from a BiDi algorithm, it does produce more or less
-		 * readable results.
-		 */
-		for( i=0; i<uCount; i+=run_end )
-		{
-			for( run_end=1; i+run_end<uCount &&
-			     (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
-			     chardir[pwCharType[i+run_end]]==0); ++run_end )
-				;
-
-			if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
-			{
-				/* A LTR run */
-				if(lpResults->lpOutString)
-				{
-					int j;
-					for( j=0; j<run_end; j++ )
-					{
-						lpResults->lpOutString[i+j]=lpString[i+j];
-					}
-				}
-
-				if(lpResults->lpOrder)
-				{
-					int j;
-					for( j=0; j<run_end; j++ )
-						lpResults->lpOrder[i+j] = i+j;
-				}
-			} else
-			{
-				/* A RTL run */
-
-				/* Since, at this stage, the paragraph context is always LTR,
-				 * remove any neutrals from the end of this run.
-				 */
-				if( chardir[pwCharType[i]]!=0 )
-					while( chardir[pwCharType[i+run_end-1]]==0 )
-						--run_end;
-
-				if(lpResults->lpOutString)
-				{
-					int j;
-					for( j=0; j<run_end; j++ )
-					{
-						lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
-					}
-				}
-
-				if(lpResults->lpOrder)
-				{
-					int j;
-					for( j=0; j<run_end; j++ )
-						lpResults->lpOrder[i+j] = i+run_end-j-1;
-				}
-			}
-		}
-
-		HeapFree(GetProcessHeap(), 0, pwCharType);
+            Wine_BiDi_reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
+                    nSet, lpResults->lpOrder );
 	}
 
 	/* FIXME: Will use the placement chars */
diff -u -r -x '*.o' -x CVS wine.ref/objects/text.c wine/objects/text.c
--- wine.ref/objects/text.c	2003-05-31 12:37:36.000000000 +0300
+++ wine/objects/text.c	2003-05-31 18:43:44.000000000 +0300
@@ -164,25 +164,16 @@
 			{
 				/* The caller did not specify that language processing was already done.
 				 */
-				GCP_RESULTSW gcp;
+                                LPWSTR lpReorderedString=HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
 
-				gcp.lStructSize=sizeof(gcp);
-				gcp.lpOutString=HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
-				gcp.lpOrder=NULL;
-				gcp.lpDx=NULL;
-				gcp.lpCaretPos=NULL;
-				gcp.lpClass=NULL;
-				gcp.lpGlyphs=NULL;
-				gcp.nGlyphs=0;
-				gcp.nMaxFit=0;
-
-				Wine_GCPW(hdc, str, count, 0, &gcp, GCP_REORDER,
+				Wine_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_FORCE_RTL:WINE_GCPW_FORCE_LTR,
+                                        lpReorderedString, count, NULL );
 
 				ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags|ETO_IGNORELANGUAGE,
-					lprect,gcp.lpOutString,count,lpDx);
-				HeapFree(GetProcessHeap(), 0, gcp.lpOutString);
+					lprect,lpReorderedString,count,lpDx);
+				HeapFree(GetProcessHeap(), 0, lpReorderedString);
 			} else
 				ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags,lprect,str,count,lpDx);
 		}


More information about the wine-devel mailing list