1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/unicharutil/util/nsBidiUtils.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,99 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 +#include "nsBidiUtils.h" 1.10 + 1.11 +#define ARABIC_TO_HINDI_DIGIT_INCREMENT (START_HINDI_DIGITS - START_ARABIC_DIGITS) 1.12 +#define PERSIAN_TO_HINDI_DIGIT_INCREMENT (START_HINDI_DIGITS - START_FARSI_DIGITS) 1.13 +#define ARABIC_TO_PERSIAN_DIGIT_INCREMENT (START_FARSI_DIGITS - START_ARABIC_DIGITS) 1.14 +#define NUM_TO_ARABIC(c) \ 1.15 + ((((c)>=START_HINDI_DIGITS) && ((c)<=END_HINDI_DIGITS)) ? \ 1.16 + ((c) - (uint16_t)ARABIC_TO_HINDI_DIGIT_INCREMENT) : \ 1.17 + ((((c)>=START_FARSI_DIGITS) && ((c)<=END_FARSI_DIGITS)) ? \ 1.18 + ((c) - (uint16_t)ARABIC_TO_PERSIAN_DIGIT_INCREMENT) : \ 1.19 + (c))) 1.20 +#define NUM_TO_HINDI(c) \ 1.21 + ((((c)>=START_ARABIC_DIGITS) && ((c)<=END_ARABIC_DIGITS)) ? \ 1.22 + ((c) + (uint16_t)ARABIC_TO_HINDI_DIGIT_INCREMENT): \ 1.23 + ((((c)>=START_FARSI_DIGITS) && ((c)<=END_FARSI_DIGITS)) ? \ 1.24 + ((c) + (uint16_t)PERSIAN_TO_HINDI_DIGIT_INCREMENT) : \ 1.25 + (c))) 1.26 +#define NUM_TO_PERSIAN(c) \ 1.27 + ((((c)>=START_HINDI_DIGITS) && ((c)<=END_HINDI_DIGITS)) ? \ 1.28 + ((c) - (uint16_t)PERSIAN_TO_HINDI_DIGIT_INCREMENT) : \ 1.29 + ((((c)>=START_ARABIC_DIGITS) && ((c)<=END_ARABIC_DIGITS)) ? \ 1.30 + ((c) + (uint16_t)ARABIC_TO_PERSIAN_DIGIT_INCREMENT) : \ 1.31 + (c))) 1.32 + 1.33 +char16_t HandleNumberInChar(char16_t aChar, bool aPrevCharArabic, uint32_t aNumFlag) 1.34 +{ 1.35 + // IBMBIDI_NUMERAL_NOMINAL * 1.36 + // IBMBIDI_NUMERAL_REGULAR 1.37 + // IBMBIDI_NUMERAL_HINDICONTEXT 1.38 + // IBMBIDI_NUMERAL_ARABIC 1.39 + // IBMBIDI_NUMERAL_HINDI 1.40 + 1.41 + switch (aNumFlag) { 1.42 + case IBMBIDI_NUMERAL_HINDI: 1.43 + return NUM_TO_HINDI(aChar); 1.44 + case IBMBIDI_NUMERAL_ARABIC: 1.45 + return NUM_TO_ARABIC(aChar); 1.46 + case IBMBIDI_NUMERAL_PERSIAN: 1.47 + return NUM_TO_PERSIAN(aChar); 1.48 + case IBMBIDI_NUMERAL_REGULAR: 1.49 + case IBMBIDI_NUMERAL_HINDICONTEXT: 1.50 + case IBMBIDI_NUMERAL_PERSIANCONTEXT: 1.51 + // for clipboard handling 1.52 + //XXX do we really want to convert numerals when copying text? 1.53 + if (aPrevCharArabic) { 1.54 + if (aNumFlag == IBMBIDI_NUMERAL_PERSIANCONTEXT) 1.55 + return NUM_TO_PERSIAN(aChar); 1.56 + else 1.57 + return NUM_TO_HINDI(aChar); 1.58 + } 1.59 + else 1.60 + return NUM_TO_ARABIC(aChar); 1.61 + case IBMBIDI_NUMERAL_NOMINAL: 1.62 + default: 1.63 + return aChar; 1.64 + } 1.65 +} 1.66 + 1.67 +nsresult HandleNumbers(char16_t* aBuffer, uint32_t aSize, uint32_t aNumFlag) 1.68 +{ 1.69 + uint32_t i; 1.70 + 1.71 + switch (aNumFlag) { 1.72 + case IBMBIDI_NUMERAL_HINDI: 1.73 + case IBMBIDI_NUMERAL_ARABIC: 1.74 + case IBMBIDI_NUMERAL_PERSIAN: 1.75 + case IBMBIDI_NUMERAL_REGULAR: 1.76 + case IBMBIDI_NUMERAL_HINDICONTEXT: 1.77 + case IBMBIDI_NUMERAL_PERSIANCONTEXT: 1.78 + for (i=0;i<aSize;i++) 1.79 + aBuffer[i] = HandleNumberInChar(aBuffer[i], !!(i>0 ? aBuffer[i-1] : 0), aNumFlag); 1.80 + break; 1.81 + case IBMBIDI_NUMERAL_NOMINAL: 1.82 + default: 1.83 + break; 1.84 + } 1.85 + return NS_OK; 1.86 +} 1.87 + 1.88 +bool HasRTLChars(const nsAString& aString) 1.89 +{ 1.90 +// This is used to determine whether to enable bidi if a string has 1.91 +// right-to-left characters. To simplify things, anything that could be a 1.92 +// surrogate or RTL presentation form is covered just by testing >= 0xD800). 1.93 +// It's fine to enable bidi in rare cases where it actually isn't needed. 1.94 + int32_t length = aString.Length(); 1.95 + for (int32_t i = 0; i < length; i++) { 1.96 + char16_t ch = aString.CharAt(i); 1.97 + if (ch >= 0xD800 || IS_IN_BMP_RTL_BLOCK(ch)) { 1.98 + return true; 1.99 + } 1.100 + } 1.101 + return false; 1.102 +}