|  |  | 
|  | /* | 
|  | * GDI BiDirectional handling | 
|  | * | 
|  | * Copyright 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 | 
|  | * License as published by the Free Software Foundation; either | 
|  | * version 2.1 of the License, or (at your option) any later version. | 
|  | * | 
|  | * This library is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | * Lesser General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU Lesser General Public | 
|  | * License along with this library; if not, write to the Free Software | 
|  | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
|  | */ | 
|  |  | 
|  | #include "config.h" | 
|  |  | 
|  | #ifdef HAVE_UNICODE_UBIDI_H | 
|  | #include <unicode/ubidi.h> | 
|  | #endif | 
|  |  | 
|  | #include "winbase.h" | 
|  | #include "wingdi.h" | 
|  | #include "wine/debug.h" | 
|  | #include "gdi.h" | 
|  |  | 
|  | WINE_DEFAULT_DEBUG_CHANNEL(bidi); | 
|  |  | 
|  | #if HAVE_ICU | 
|  | BOOL BidiAvail = TRUE; | 
|  | #else | 
|  | BOOL BidiAvail = FALSE; | 
|  | #endif | 
|  |  | 
|  |  | 
|  | /************************************************************* | 
|  | *    BIDI_Reorder | 
|  | */ | 
|  | BOOL BIDI_Reorder( | 
|  | LPCWSTR lpString,       /* [in] The string for which information is to be returned */ | 
|  | 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 */ | 
|  | ) | 
|  | { | 
|  | #ifdef HAVE_ICU | 
|  | 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; | 
|  | UErrorCode err=0; | 
|  | UBiDiLevel level; | 
|  |  | 
|  | bidi=ubidi_open(); | 
|  | if( bidi==NULL ) { | 
|  | WARN("Failed to allocate structure\n"); | 
|  | SetLastError(ERROR_NOT_ENOUGH_MEMORY); | 
|  | return FALSE; | 
|  | } | 
|  |  | 
|  | switch( dwWineGCP_Flags&WINE_GCPW_DIR_MASK ) | 
|  | { | 
|  | case WINE_GCPW_FORCE_LTR: | 
|  | level=0; | 
|  | break; | 
|  | case WINE_GCPW_FORCE_RTL: | 
|  | level=1; | 
|  | break; | 
|  | case WINE_GCPW_LOOSE_LTR: | 
|  | level=UBIDI_DEFAULT_LTR; | 
|  | break; | 
|  | case WINE_GCPW_LOOSE_RTL: | 
|  | level=UBIDI_DEFAULT_RTL; | 
|  | break; | 
|  | } | 
|  |  | 
|  | ubidi_setPara( bidi, lpString, uCount, level, NULL, &err ); | 
|  | if( lpOutString!=NULL ) { | 
|  | ubidi_writeReordered( bidi, lpOutString, uCount, | 
|  | (dwFlags&GCP_SYMSWAPOFF)?0:UBIDI_DO_MIRRORING, &err ); | 
|  | } | 
|  |  | 
|  | if( lpOrder!=NULL ) { | 
|  | ubidi_getLogicalMap( bidi, lpOrder, &err ); | 
|  | } | 
|  |  | 
|  | ubidi_close( bidi ); | 
|  |  | 
|  | if( U_FAILURE(err) ) { | 
|  | FIXME("ICU Library return error code %d.\n", err ); | 
|  | FIXME("Please report this error to wine-devel@winehq.org so we can place " | 
|  | "descriptive Windows error codes here\n"); | 
|  | SetLastError(ERROR_INVALID_LEVEL); /* This error is cryptic enough not to mean anything, I hope */ | 
|  |  | 
|  | return FALSE; | 
|  | } | 
|  | } | 
|  | return TRUE; | 
|  | #else  /* HAVE_ICU */ | 
|  | return FALSE; | 
|  | #endif  /* HAVE_ICU */ | 
|  | } |