Ok, so for all those of you with no imagination, here is the actual
patch. Happy?? Hah??
--
Shachar Shemesh
Open Source integration consultant
Home page & resume -
http://www.shemesh.biz/
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);
}