Bidi improvments

Shachar Shemesh wine-patches at sun.consumer.org.il
Mon Sep 2 12:51:53 CDT 2002


ChangeLog:
Shachar Shemesh <winecode at sun.consumer.org.il>

objects/font.c

    * Return old code for handling parameters to GetCharacterPlacement
      (+ fix heap overrun in it). New code did not correctly match the
      Windows behaviour.
    * Amend the BiDi algorithm so that many strings will now produce
      quite readable output.


-------------- next part --------------
Index: objects/font.c
===================================================================
RCS file: /home/sun/sources/wine/cvs/wine/objects/font.c,v
retrieving revision 1.84
diff -u -r1.84 font.c
--- objects/font.c	28 Aug 2002 23:42:36 -0000	1.84
+++ objects/font.c	2 Sep 2002 17:22:09 -0000
@@ -1924,24 +1924,18 @@
     memcpy(&resultsW, lpResults, sizeof(resultsW));
 
     lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
-    if( dwFlags&GCP_REORDER )
-    {
-        /* If the REORDER flag is not set, this field is ignored anyways */
-        if(lpResults->lpOutString)
-            resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
-        else
-            resultsW.lpOutString = NULL;
-    }
+	if(lpResults->lpOutString)
+		resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
 
     ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
 
     if(lpResults->lpOutString) {
-        if(font_cp != CP_SYMBOL)
-	    WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
-				lpResults->lpOutString, uCount, NULL, NULL );
-	else
-	    for(i = 0; i < uCount; i++)
-	        lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
+		if(font_cp != CP_SYMBOL)
+			WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
+					lpResults->lpOutString, uCount, NULL, NULL );
+		else
+	    	for(i = 0; i < uCount; i++)
+	        	lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
     }
 
     HeapFree(GetProcessHeap(), 0, lpStringW);
@@ -2002,9 +1996,23 @@
 	/* 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;
+		}
+	}
+
 	if((dwFlags&GCP_REORDER)!=0)
 	{
-		/* MSDN says lpOutString and lpOrder are ignored if GCP_REORDER not set */
 		WORD *pwCharType;
 		int run_end;
 		/* Keep a static table that translates the C2 types to something meaningful */
@@ -2027,7 +2035,10 @@
 
 		/* 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
+		 * 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 )
 		{
@@ -2057,6 +2068,14 @@
 			} 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;


More information about the wine-patches mailing list