Index: source/common/loclikely.cpp |
diff --git a/source/common/loclikely.cpp b/source/common/loclikely.cpp |
index 6fbf873bdefd2daed0b30e17fc773994836f7230..e5887081308262e8d1363f28e9f38fec5682d9af 100644 |
--- a/source/common/loclikely.cpp |
+++ b/source/common/loclikely.cpp |
@@ -1,7 +1,7 @@ |
/* |
******************************************************************************* |
* |
-* Copyright (C) 1997-2012, International Business Machines |
+* Copyright (C) 1997-2014, International Business Machines |
* Corporation and others. All Rights Reserved. |
* |
******************************************************************************* |
@@ -18,9 +18,11 @@ |
*/ |
#include "unicode/utypes.h" |
+#include "unicode/locid.h" |
#include "unicode/putil.h" |
#include "unicode/uloc.h" |
#include "unicode/ures.h" |
+#include "unicode/uscript.h" |
#include "cmemory.h" |
#include "cstring.h" |
#include "ulocimp.h" |
@@ -1273,3 +1275,59 @@ uloc_minimizeSubtags(const char* localeID, |
err); |
} |
} |
+ |
+// Pairs of (language subtag, + or -) for finding out fast if common languages |
+// are LTR (minus) or RTL (plus). |
+static const char* LANG_DIR_STRING = |
+ "root-en-es-pt-zh-ja-ko-de-fr-it-ar+he+fa+ru-nl-pl-th-tr-"; |
+ |
+// Implemented here because this calls uloc_addLikelySubtags(). |
+U_CAPI UBool U_EXPORT2 |
+uloc_isRightToLeft(const char *locale) { |
+ UErrorCode errorCode = U_ZERO_ERROR; |
+ char script[8]; |
+ int32_t scriptLength = uloc_getScript(locale, script, UPRV_LENGTHOF(script), &errorCode); |
+ if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING || |
+ scriptLength == 0) { |
+ // Fastpath: We know the likely scripts and their writing direction |
+ // for some common languages. |
+ errorCode = U_ZERO_ERROR; |
+ char lang[8]; |
+ int32_t langLength = uloc_getLanguage(locale, lang, UPRV_LENGTHOF(lang), &errorCode); |
+ if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING || |
+ langLength == 0) { |
+ return FALSE; |
+ } |
+ const char* langPtr = uprv_strstr(LANG_DIR_STRING, lang); |
+ if (langPtr != NULL) { |
+ switch (langPtr[langLength]) { |
+ case '-': return FALSE; |
+ case '+': return TRUE; |
+ default: break; // partial match of a longer code |
+ } |
+ } |
+ // Otherwise, find the likely script. |
+ errorCode = U_ZERO_ERROR; |
+ char likely[ULOC_FULLNAME_CAPACITY]; |
+ (void)uloc_addLikelySubtags(locale, likely, UPRV_LENGTHOF(likely), &errorCode); |
+ if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING) { |
+ return FALSE; |
+ } |
+ scriptLength = uloc_getScript(likely, script, UPRV_LENGTHOF(script), &errorCode); |
+ if (U_FAILURE(errorCode) || errorCode == U_STRING_NOT_TERMINATED_WARNING || |
+ scriptLength == 0) { |
+ return FALSE; |
+ } |
+ } |
+ UScriptCode scriptCode = (UScriptCode)u_getPropertyValueEnum(UCHAR_SCRIPT, script); |
+ return uscript_isRightToLeft(scriptCode); |
+} |
+ |
+U_NAMESPACE_BEGIN |
+ |
+UBool |
+Locale::isRightToLeft() const { |
+ return uloc_isRightToLeft(getBaseName()); |
+} |
+ |
+U_NAMESPACE_END |