- define additional shell paths for CSIDL_... constants
[wine] / dlls / gdi / bidi.c
1
2 /*
3  * GDI BiDirectional handling
4  *
5  * Copyright 2003 Shachar Shemesh
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include "config.h"
23
24 #include <stdarg.h>
25 #ifdef HAVE_UNICODE_UBIDI_H
26 #include <unicode/ubidi.h>
27 #endif
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "wine/debug.h"
33 #include "gdi.h"
34 #include "gdi_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(bidi);
37
38 #ifdef HAVE_ICU
39 BOOL BidiAvail = TRUE;
40 #else
41 BOOL BidiAvail = FALSE;
42 #endif
43
44
45 /*************************************************************
46  *    BIDI_Reorder
47  */
48 BOOL BIDI_Reorder(
49                 LPCWSTR lpString,       /* [in] The string for which information is to be returned */
50                 INT uCount,     /* [in] Number of WCHARs in string. */
51                 DWORD dwFlags,  /* [in] GetCharacterPlacement compatible flags specifying how to process the string */
52                 DWORD dwWineGCP_Flags,       /* [in] Wine internal flags - Force paragraph direction */
53                 LPWSTR lpOutString, /* [out] Reordered string */
54                 INT uCountOut,  /* [in] Size of output buffer */
55                 UINT *lpOrder /* [out] Logical -> Visual order map */
56     )
57 {
58 #ifdef HAVE_ICU
59     TRACE("%s, %d, 0x%08lx\n",
60           debugstr_wn(lpString, uCount), uCount, dwFlags);
61
62     TRACE("lpOutString=%p, lpOrder=%p", lpOutString, lpOrder );
63
64     if ((dwFlags & GCP_REORDER) != 0) {
65         UBiDi *bidi;
66         UErrorCode err=0;
67         UBiDiLevel level=0;
68
69         bidi=ubidi_open();
70         if( bidi==NULL ) {
71             WARN("Failed to allocate structure\n");
72             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
73             return FALSE;
74         }
75
76         switch( dwWineGCP_Flags&WINE_GCPW_DIR_MASK )
77         {
78         case WINE_GCPW_FORCE_LTR:
79             level=0;
80             break;
81         case WINE_GCPW_FORCE_RTL:
82             level=1;
83             break;
84         case WINE_GCPW_LOOSE_LTR:
85             level=UBIDI_DEFAULT_LTR;
86             break;
87         case WINE_GCPW_LOOSE_RTL:
88             level=UBIDI_DEFAULT_RTL;
89             break;
90         }
91
92         ubidi_setPara( bidi, lpString, uCount, level, NULL, &err );
93         if( lpOutString!=NULL ) {
94             ubidi_writeReordered( bidi, lpOutString, uCount,
95                     (dwFlags&GCP_SYMSWAPOFF)?0:UBIDI_DO_MIRRORING, &err );
96         }
97
98         if( lpOrder!=NULL ) {
99             ubidi_getLogicalMap( bidi, lpOrder, &err );
100         }
101
102         ubidi_close( bidi );
103
104         if( U_FAILURE(err) ) {
105             FIXME("ICU Library return error code %d.\n", err );
106             FIXME("Please report this error to wine-devel@winehq.org so we can place "
107                     "descriptive Windows error codes here\n");
108             SetLastError(ERROR_INVALID_LEVEL); /* This error is cryptic enough not to mean anything, I hope */
109
110             return FALSE;
111         }
112     }
113     return TRUE;
114 #else  /* HAVE_ICU */
115     return FALSE;
116 #endif  /* HAVE_ICU */
117 }