00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "unicode/utypes.h"
00018 #include "unicode/uchar.h"
00019 #include "unicode/ustring.h"
00020 #include "cmemory.h"
00021 #include "unicode/ushape.h"
00022
00023 #if UTF_SIZE<16
00024
00025
00026
00027
00028
00029
00030
00031
00032 # error This implementation assumes UTF-16 or UTF-32 (check UTF_SIZE)
00033 #endif
00034
00035
00036
00037
00038
00039
00040
00041 static void
00042 _shapeToArabicDigitsWithContext(UChar *s, int32_t length,
00043 UChar digitBase,
00044 UBool isLogical, UBool lastStrongWasAL) {
00045 int32_t i;
00046 UChar c;
00047
00048 digitBase-=0x30;
00049
00050
00051 if(isLogical) {
00052 for(i=0; i<length; ++i) {
00053 c=s[i];
00054 switch(u_charDirection(c)) {
00055 case U_LEFT_TO_RIGHT:
00056 case U_RIGHT_TO_LEFT:
00057 lastStrongWasAL=FALSE;
00058 break;
00059 case U_RIGHT_TO_LEFT_ARABIC:
00060 lastStrongWasAL=TRUE;
00061 break;
00062 case U_EUROPEAN_NUMBER:
00063 if(lastStrongWasAL && (uint32_t)(c-0x30)<10) {
00064 s[i]=(UChar)(digitBase+c);
00065 }
00066 break;
00067 default :
00068 break;
00069 }
00070 }
00071 } else {
00072 for(i=length; i>0; ) {
00073 c=s[--i];
00074 switch(u_charDirection(c)) {
00075 case U_LEFT_TO_RIGHT:
00076 case U_RIGHT_TO_LEFT:
00077 lastStrongWasAL=FALSE;
00078 break;
00079 case U_RIGHT_TO_LEFT_ARABIC:
00080 lastStrongWasAL=TRUE;
00081 break;
00082 case U_EUROPEAN_NUMBER:
00083 if(lastStrongWasAL && (uint32_t)(c-0x30)<10) {
00084 s[i]=(UChar)(digitBase+c);
00085 }
00086 break;
00087 default :
00088 break;
00089 }
00090 }
00091 }
00092 }
00093
00094 U_CAPI int32_t U_EXPORT2
00095 u_shapeArabic(const UChar *source, int32_t sourceLength,
00096 UChar *dest, int32_t destSize,
00097 uint32_t options,
00098 UErrorCode *pErrorCode) {
00099
00100 if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
00101 return 0;
00102 }
00103
00104
00105 if( source==NULL || sourceLength<-1 ||
00106 (dest==NULL && destSize!=0) || destSize<0 ||
00107 options>=U_SHAPE_DIGIT_TYPE_RESERVED ||
00108 (options&U_SHAPE_LENGTH_MASK)==U_SHAPE_LENGTH_RESERVED ||
00109 (options&U_SHAPE_LETTERS_MASK)==U_SHAPE_LETTERS_RESERVED ||
00110 (options&U_SHAPE_DIGITS_MASK)>=U_SHAPE_DIGITS_RESERVED
00111 ) {
00112 *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
00113 return 0;
00114 }
00115
00116
00117 if(sourceLength==-1) {
00118 sourceLength=u_strlen(source);
00119 }
00120 if(sourceLength==0) {
00121 return 0;
00122 }
00123
00124
00125 if( dest!=NULL &&
00126 ((source<=dest && dest<source+sourceLength) ||
00127 (dest<=source && source<dest+destSize))
00128 ) {
00129 *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
00130 return 0;
00131 }
00132
00133 if((options&U_SHAPE_LETTERS_MASK)!=U_SHAPE_LETTERS_NOOP) {
00134
00135 *pErrorCode=U_UNSUPPORTED_ERROR;
00136 return 0;
00137 } else {
00138
00139
00140
00141
00142 if(destSize<sourceLength) {
00143
00144 *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
00145 return sourceLength;
00146 }
00147 uprv_memcpy(dest, source, sourceLength*U_SIZEOF_UCHAR);
00148 destSize=sourceLength;
00149 }
00150
00151
00152
00153
00154
00155
00156
00157 if((options&U_SHAPE_DIGITS_MASK)!=U_SHAPE_DIGITS_NOOP) {
00158 UChar digitBase;
00159 int32_t i;
00160
00161
00162 switch(options&U_SHAPE_DIGIT_TYPE_MASK) {
00163 case U_SHAPE_DIGIT_TYPE_AN:
00164 digitBase=0x660;
00165 break;
00166 case U_SHAPE_DIGIT_TYPE_AN_EXTENDED:
00167 digitBase=0x6f0;
00168 break;
00169 default:
00170
00171 digitBase=0;
00172 break;
00173 }
00174
00175
00176 switch(options&U_SHAPE_DIGITS_MASK) {
00177 case U_SHAPE_DIGITS_EN2AN:
00178
00179 digitBase-=0x30;
00180 for(i=0; i<destSize; ++i) {
00181 if(((uint32_t)dest[i]-0x30)<10) {
00182 dest[i]+=digitBase;
00183 }
00184 }
00185 break;
00186 case U_SHAPE_DIGITS_AN2EN:
00187
00188 for(i=0; i<destSize; ++i) {
00189 if(((uint32_t)dest[i]-(uint32_t)digitBase)<10) {
00190 dest[i]-=digitBase-0x30;
00191 }
00192 }
00193 break;
00194 case U_SHAPE_DIGITS_ALEN2AN_INIT_LR:
00195 _shapeToArabicDigitsWithContext(dest, destSize,
00196 digitBase,
00197 (UBool)((options&U_SHAPE_TEXT_DIRECTION_MASK)==U_SHAPE_TEXT_DIRECTION_LOGICAL),
00198 FALSE);
00199 break;
00200 case U_SHAPE_DIGITS_ALEN2AN_INIT_AL:
00201 _shapeToArabicDigitsWithContext(dest, destSize,
00202 digitBase,
00203 (UBool)((options&U_SHAPE_TEXT_DIRECTION_MASK)==U_SHAPE_TEXT_DIRECTION_LOGICAL),
00204 TRUE);
00205 break;
00206 default:
00207
00208 break;
00209 }
00210 }
00211
00212 return destSize;
00213 }