1 /******************************************************************** 2 * Copyright (C) 2016 and later: Unicode, Inc. and others. 3 * License & terms of use: http://www.unicode.org/copyright.html 4 ********************************************************************/ 5 /* file name: cbiditransformtst.c 6 * encoding: US-ASCII 7 * tab size: 8 (not used) 8 * indentation:4 9 * 10 * created on: 2016aug21 11 * created by: Lina Kemmel 12 */ 13 14 #include "cintltst.h" 15 #include "unicode/ubidi.h" 16 #include "unicode/ubiditransform.h" 17 #include "unicode/ushape.h" 18 #include "unicode/ustring.h" 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 #define LATN_ZERO 0x0030 25 #define ARAB_ZERO 0x0660 26 #define MIN_HEB_LETTER 0x05D0 27 #define MIN_ARAB_LETTER 0x0630 /* relevant to this test only */ 28 #define MIN_SHAPED_LETTER 0xFEAB /* relevant to this test only */ 29 30 #define STR_CAPACITY 100 31 32 #define NUM_LETTERS 5 /* Used for arrays hereafter */ 33 static const UChar unshapedLetters[NUM_LETTERS + 1] = {0x0630, 0, 0x0631, 0, 0x0632, 2}; 34 static const UChar shapedLetters [NUM_LETTERS + 1] = {0xfeab, 0, 0xfead, 0, 0xfeaf, 1}; 35 36 typedef struct { 37 UBiDiLevel inLevel; 38 UBiDiOrder inOr; 39 UBiDiLevel outLevel; 40 UBiDiOrder outOr; 41 const char *pReorderNoMirror; 42 const char *pReorderAndMirror; 43 const char *pContextShapes; 44 const char *pMessage; 45 } UBidiTestCases; 46 47 UChar src[STR_CAPACITY] = { 0 }; 48 UChar dest[STR_CAPACITY] = { 0 }; 49 UChar expected[STR_CAPACITY] = { 0 }; 50 UChar temp[STR_CAPACITY * 2] = { 0 }; 51 char pseudo[STR_CAPACITY] = { 0 }; 52 53 void addBidiTransformTest(TestNode** root); 54 55 static void testAutoDirection(void); 56 57 static void testAllTransformOptions(void); 58 59 static char* pseudoScript(const UChar *str); 60 61 static void shapeDigits(UChar *str, UChar srcZero, UChar destZero); 62 63 static void shapeLetters(UChar *str, const UChar *from, const UChar *to); 64 65 static void logResultsForDir(const UChar *srcText, const UChar *destTxt, 66 const UChar *expectedTxt, UBiDiLevel inLevel, UBiDiLevel outLevel); 67 68 static void verifyResultsForAllOpt(const UBidiTestCases *pTest, const UChar *srcTxt, 69 const UChar *destTxt, const char *expectedChars, uint32_t digits, 70 uint32_t letters); 71 72 #if 0 73 static void substituteByPseudoChar(const UChar *src, char *dest, 74 const UChar baseReal, const char basePseudo, const char max); 75 76 77 /* TODO: This code assumes the codepage is ASCII based. */ 78 79 /* 80 * Using the following conventions: 81 * AL unshaped: A-E 82 * AL shaped: F-J 83 * R: K-Z 84 * EN: 0-4 85 * AN: 5-9 86 */ 87 static void 88 substituteByPseudoChar(const UChar *src, char *dest, const UChar baseReal, 89 const char basePseudo, const char max) { 90 *dest = basePseudo + (*src - baseReal); /* (range math won't work on EBCDIC) */ 91 if (*dest > max) { 92 *dest = max; 93 } 94 } 95 96 static char* 97 pseudoScript(const UChar *str) { 98 char *p = pseudo; 99 if (str) { 100 for (; *str; str++, p++) { 101 switch (u_charDirection(*str)) { 102 case U_RIGHT_TO_LEFT: 103 substituteByPseudoChar(str, p, MIN_HEB_LETTER, 'K', 'Z'); 104 break; 105 case U_RIGHT_TO_LEFT_ARABIC: 106 if (*str > 0xFE00) { 107 substituteByPseudoChar(str, p, MIN_SHAPED_LETTER, 'F', 'J'); 108 } else { 109 substituteByPseudoChar(str, p, MIN_ARAB_LETTER, 'A', 'E'); 110 } 111 break; 112 case U_ARABIC_NUMBER: 113 substituteByPseudoChar(str, p, ARAB_ZERO, '5', '9'); 114 break; 115 default: 116 *p = (char)*str; 117 break; 118 } 119 } 120 } 121 *p = '\0'; 122 return pseudo; 123 } 124 #else 125 static char* 126 pseudoScript(const UChar *str) { 127 return aescstrdup(str, -1); 128 } 129 #endif 130 131 static void 132 logResultsForDir(const UChar *srcTxt, const UChar *destTxt, const UChar *expectedTxt, 133 UBiDiLevel inLevel, UBiDiLevel outLevel) 134 { 135 if (u_strcmp(expectedTxt, destTxt)) { 136 log_err("Unexpected transform Dest: inLevel: 0x%02x; outLevel: 0x%02x;\ninText: %s; outText: %s; expected: %s\n", 137 inLevel, outLevel, pseudoScript(srcTxt), pseudoScript(destTxt), pseudoScript(expectedTxt)); 138 } 139 } 140 141 /** 142 * Tests various combinations of base directions, with the input either 143 * <code>UBIDI_DEFAULT_LTR</code> or <code>UBIDI_DEFAULT_RTL</code>, and the 144 * output either <code>UBIDI_LTR</code> or <code>UBIDI_RTL</code>. Order is 145 * always <code>UBIDI_LOGICAL</code> for the input and <code>UBIDI_VISUAL</code> 146 * for the output. 147 */ 148 static void 149 testAutoDirection(void) 150 { 151 static const UBiDiLevel inLevels[] = { 152 UBIDI_DEFAULT_LTR, UBIDI_DEFAULT_RTL 153 }; 154 static const UBiDiLevel outLevels[] = { 155 UBIDI_LTR, UBIDI_RTL 156 }; 157 static const char *srcTexts[] = { 158 "abc \\u05d0\\u05d1", 159 "... abc \\u05d0\\u05d1", 160 "\\u05d0\\u05d1 abc", 161 "... \\u05d0\\u05d1 abc", 162 ".*:" 163 }; 164 uint32_t nTexts = sizeof(srcTexts) / sizeof(srcTexts[0]); 165 uint32_t i, nInLevels = sizeof(inLevels) / sizeof(inLevels[0]); 166 uint32_t j, nOutLevels = sizeof(outLevels) / sizeof(outLevels[0]); 167 168 UBiDi *pBidi = ubidi_open(); 169 170 UErrorCode errorCode = U_ZERO_ERROR; 171 UBiDiTransform *pTransform = ubiditransform_open(&errorCode); 172 173 while (nTexts-- > 0) { 174 uint32_t srcLen; 175 u_unescape(srcTexts[nTexts], src, STR_CAPACITY); 176 srcLen = u_strlen(src); 177 for (i = 0; i < nInLevels; i++) { 178 for (j = 0; j < nOutLevels; j++) { 179 ubiditransform_transform(pTransform, src, -1, dest, STR_CAPACITY - 1, 180 inLevels[i], UBIDI_LOGICAL, outLevels[j], UBIDI_VISUAL, 181 UBIDI_MIRRORING_OFF, 0, &errorCode); 182 /* Use UBiDi as a model we compare to */ 183 ubidi_setPara(pBidi, src, srcLen, inLevels[i], NULL, &errorCode); 184 ubidi_writeReordered(pBidi, expected, STR_CAPACITY, UBIDI_REORDER_DEFAULT, &errorCode); 185 if (outLevels[j] == UBIDI_RTL) { 186 ubidi_writeReverse(expected, u_strlen(expected), temp, STR_CAPACITY, 187 UBIDI_OUTPUT_REVERSE, &errorCode); 188 logResultsForDir(src, dest, temp, inLevels[i], outLevels[j]); 189 } else { 190 logResultsForDir(src, dest, expected, inLevels[i], outLevels[j]); 191 } 192 } 193 } 194 } 195 ubidi_close(pBidi); 196 ubiditransform_close(pTransform); 197 } 198 199 static void 200 shapeDigits(UChar *str, UChar srcZero, UChar destZero) 201 { 202 UChar32 c = 0; 203 uint32_t i = 0, j, length = u_strlen(str); 204 while (i < length) { 205 j = i; 206 U16_NEXT(str, i, length, c); 207 if (c >= srcZero && c <= srcZero + 9) { 208 /* length of c here is always a single UChar16 */ 209 str[j] = c + (destZero - srcZero); 210 } 211 } 212 } 213 214 static void 215 shapeLetters(UChar *str, const UChar *from, const UChar *to) 216 { 217 uint32_t i = 0, j, length = u_strlen(expected), index; 218 UChar32 c = 0; 219 while (i < length) { 220 j = i; 221 U16_NEXT(str, i, length, c); 222 index = c - from[0]; 223 if (index < NUM_LETTERS && from[index * from[NUM_LETTERS]] != 0) { 224 /* The length of old and new values is always a single UChar16, 225 so can just assign a new value to str[j] */ 226 str[j] = to[index * from[NUM_LETTERS]]; 227 } 228 } 229 } 230 231 static void 232 verifyResultsForAllOpt(const UBidiTestCases *pTest, const UChar *srcTxt, 233 const UChar *destTxt, const char *expectedChars, uint32_t digits, uint32_t letters) 234 { 235 u_unescape(expectedChars, expected, STR_CAPACITY); 236 237 switch (digits) { 238 case U_SHAPE_DIGITS_EN2AN: 239 shapeDigits(expected, LATN_ZERO, ARAB_ZERO); 240 break; 241 case U_SHAPE_DIGITS_AN2EN: 242 shapeDigits(expected, ARAB_ZERO, LATN_ZERO); 243 break; 244 default: 245 break; 246 } 247 switch (letters) { 248 case U_SHAPE_LETTERS_SHAPE: 249 shapeLetters(expected, unshapedLetters, shapedLetters); 250 break; 251 case U_SHAPE_LETTERS_UNSHAPE: 252 shapeLetters(expected, shapedLetters, unshapedLetters); 253 break; 254 } 255 if (u_strcmp(expected, dest)) { 256 log_err("Unexpected transform Dest: Test: %s; Digits: 0x%08x; Letters: 0x%08x\ninText: %s; outText: %s; expected: %s\n", 257 pTest->pMessage, digits, letters, pseudoScript(srcTxt), pseudoScript(destTxt), pseudoScript(expected)); 258 } 259 } 260 261 /** 262 * This function covers: 263 * <ul> 264 * <li>all possible combinations of ordering schemes and <strong>explicit</strong> 265 * base directions, applied to both input and output,</li> 266 * <li>selected tests for auto direction (systematically, auto direction is 267 * covered in a dedicated test) applied on both input and output,</li> 268 * <li>all possible combinations of mirroring, digits and letters applied 269 * to output only.</li> 270 * </ul> 271 */ 272 static void 273 testAllTransformOptions(void) 274 { 275 static const char *inText = 276 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662"; 277 278 static const UBidiTestCases testCases[] = { 279 { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_LOGICAL, 280 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // reordering no mirroring 281 "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // mirroring 282 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u0662\\u0663\\u0660 e\\u0631\\u0664 f \\ufeaf \\u0661\\u0662", // context numeric shaping 283 "1: Logical LTR ==> Logical LTR" }, 284 { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL, 285 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", 286 "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", 287 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d \\u0662\\u0663\\u0660 \\u0630 e\\u0664\\u0631 f \\u0661\\u0662 \\ufeaf", 288 "2: Logical LTR ==> Visual LTR" }, 289 { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_LOGICAL, 290 "\\ufeaf \\u0661\\u0662 f \\u0631e4 \\u0630 23\\u0660 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 a[b]c", 291 "\\ufeaf \\u0661\\u0662 f \\u0631e4 \\u0630 23\\u0660 d \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 a[b]c", 292 "\\ufeaf \\u0661\\u0662 f \\u0631e\\u0664 \\u0630 \\u0662\\u0663\\u0660 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 a[b]c", 293 "3: Logical LTR ==> Logical RTL" }, 294 { UBIDI_LTR, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_VISUAL, 295 "\\ufeaf \\u0662\\u0661 f \\u06314e \\u0630 \\u066032 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 c]b[a", 296 "\\ufeaf \\u0662\\u0661 f \\u06314e \\u0630 \\u066032 d \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 c]b[a", 297 "\\ufeaf \\u0662\\u0661 f \\u0631\\u0664e \\u0630 \\u0660\\u0663\\u0662 d \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 c]b[a", 298 "4: Logical LTR ==> Visual RTL" }, 299 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_LOGICAL, 300 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", 301 "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // mirroring 302 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", 303 "5: Logical RTL ==> Logical RTL" }, 304 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_RTL, UBIDI_VISUAL, 305 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 306 "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 307 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 308 "6: Logical RTL ==> Visual RTL" }, 309 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_LOGICAL, 310 "\\ufeaf \\u0661\\u0662 f 4\\u0631e 23\\u0630 \\u0660 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 a[b]c", 311 "\\ufeaf \\u0661\\u0662 f 4\\u0631e 23\\u0630 \\u0660 d 1 \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 a[b]c", 312 "\\ufeaf \\u0661\\u0662 f 4\\u0631e 23\\u0630 \\u0660 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 a[b]c", 313 "7: Logical RTL ==> Logical LTR" }, 314 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL, 315 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c", 316 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 a[b]c", 317 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c", 318 "8: Logical RTL ==> Visual LTR" }, 319 { UBIDI_LTR, UBIDI_VISUAL, UBIDI_LTR, UBIDI_VISUAL, 320 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", 321 "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", // mirroring 322 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u0662\\u0663\\u0660 e\\u0631\\u0664 f \\ufeaf \\u0661\\u0662", 323 "9: Visual LTR ==> Visual LTR" }, 324 { UBIDI_LTR, UBIDI_VISUAL, UBIDI_LTR, UBIDI_LOGICAL, 325 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", 326 "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", 327 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", 328 "10: Visual LTR ==> Logical LTR" }, 329 { UBIDI_LTR, UBIDI_VISUAL, UBIDI_RTL, UBIDI_VISUAL, 330 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a", 331 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 c]b[a", 332 "\\u0662\\u0661 \\ufeaf f \\u0664\\u0631e \\u0660\\u0663\\u0662 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a", 333 "11: Visual LTR ==> Visual RTL" }, 334 { UBIDI_LTR, UBIDI_VISUAL, UBIDI_RTL, UBIDI_LOGICAL, 335 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c", 336 "\\u0661\\u0662 \\ufeaf f 4\\u0631e 23\\u0660 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 a[b]c", 337 "\\u0661\\u0662 \\ufeaf f \\u0664\\u0631e \\u0662\\u0663\\u0660 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 a[b]c", 338 "12: Visual LTR ==> Logical RTL" }, 339 { UBIDI_RTL, UBIDI_VISUAL, UBIDI_RTL, UBIDI_VISUAL, 340 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", 341 "a[b]c \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", 342 "a[b]c \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 23\\u0660 e\\u06314 f \\ufeaf \\u0661\\u0662", 343 "13: Visual RTL ==> Visual RTL" }, 344 { UBIDI_RTL, UBIDI_VISUAL, UBIDI_RTL, UBIDI_LOGICAL, 345 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 346 "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 347 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 348 "14: Visual RTL ==> Logical RTL" }, 349 { UBIDI_RTL, UBIDI_VISUAL, UBIDI_LTR, UBIDI_VISUAL, 350 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a", 351 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 c]b[a", 352 "\\u0662\\u0661 \\ufeaf f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 c]b[a", 353 "15: Visual RTL ==> Visual LTR" }, 354 { UBIDI_RTL, UBIDI_VISUAL, UBIDI_LTR, UBIDI_LOGICAL, 355 "\\ufeaf \\u0662\\u0661 f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 c]b[a", 356 "\\ufeaf \\u0662\\u0661 f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 c]b[a", 357 "\\ufeaf \\u0662\\u0661 f 4\\u0631e \\u066032 \\u0630 d 1 \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 c]b[a", 358 "16: Visual RTL ==> Logical LTR" }, 359 { UBIDI_DEFAULT_RTL, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL, 360 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", 361 "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", 362 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d \\u0662\\u0663\\u0660 \\u0630 e\\u0664\\u0631 f \\u0661\\u0662 \\ufeaf", 363 "17: Logical DEFAULT_RTL ==> Visual LTR" }, 364 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_DEFAULT_LTR, UBIDI_VISUAL, 365 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 366 "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 367 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 368 "18: Logical RTL ==> Visual DEFAULT_LTR" }, 369 { UBIDI_DEFAULT_LTR, UBIDI_LOGICAL, UBIDI_LTR, UBIDI_VISUAL, 370 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", 371 "a[b]c 1 \\u05d4(\\u05d3 \\u05d2\\u05d1)\\u05d0 d 23\\u0660 \\u0630 e4\\u0631 f \\u0661\\u0662 \\ufeaf", 372 "a[b]c 1 \\u05d4)\\u05d3 \\u05d2\\u05d1(\\u05d0 d \\u0662\\u0663\\u0660 \\u0630 e\\u0664\\u0631 f \\u0661\\u0662 \\ufeaf", 373 "19: Logical DEFAULT_LTR ==> Visual LTR" }, 374 { UBIDI_RTL, UBIDI_LOGICAL, UBIDI_DEFAULT_RTL, UBIDI_VISUAL, 375 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 376 "c]b[a \\u05d0)\\u05d1\\u05d2 \\u05d3(\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 377 "c]b[a \\u05d0(\\u05d1\\u05d2 \\u05d3)\\u05d4 1 d \\u0630 \\u066032 e\\u06314 f \\ufeaf \\u0662\\u0661", 378 "20: Logical RTL ==> Visual DEFAULT_RTL" } 379 }; 380 static const uint32_t digits[] = { 381 U_SHAPE_DIGITS_NOOP, 382 U_SHAPE_DIGITS_AN2EN, 383 U_SHAPE_DIGITS_EN2AN, 384 U_SHAPE_DIGITS_ALEN2AN_INIT_LR 385 }; 386 static const uint32_t letters[] = { 387 U_SHAPE_LETTERS_UNSHAPE, 388 U_SHAPE_LETTERS_SHAPE 389 }; 390 const char *expectedStr; 391 uint32_t i, nTestCases = sizeof(testCases) / sizeof(testCases[0]); 392 uint32_t j, nDigits = sizeof(digits) / sizeof(digits[0]); 393 uint32_t k, nLetters = sizeof(letters) / sizeof(letters[0]); 394 395 UErrorCode errorCode = U_ZERO_ERROR; 396 UBiDiTransform *pTransform = ubiditransform_open(&errorCode); 397 398 u_unescape(inText, src, STR_CAPACITY); 399 400 // Test various combinations of base levels, orders, mirroring, digits and letters 401 for (i = 0; i < nTestCases; i++) { 402 expectedStr = testCases[i].pReorderAndMirror; 403 ubiditransform_transform(pTransform, src, -1, dest, STR_CAPACITY, 404 testCases[i].inLevel, testCases[i].inOr, 405 testCases[i].outLevel, testCases[i].outOr, 406 UBIDI_MIRRORING_ON, 0, &errorCode); 407 verifyResultsForAllOpt(&testCases[i], src, dest, expectedStr, U_SHAPE_DIGITS_NOOP, 408 U_SHAPE_LETTERS_NOOP); 409 410 for (j = 0; j < nDigits; j++) { 411 expectedStr = digits[j] == U_SHAPE_DIGITS_ALEN2AN_INIT_LR ? testCases[i].pContextShapes 412 : testCases[i].pReorderNoMirror; 413 for (k = 0; k < nLetters; k++) { 414 /* Use here NULL for pTransform */ 415 ubiditransform_transform(NULL, src, -1, dest, STR_CAPACITY, 416 testCases[i].inLevel, testCases[i].inOr, 417 testCases[i].outLevel, testCases[i].outOr, 418 UBIDI_MIRRORING_OFF, digits[j] | letters[k], 419 &errorCode); 420 verifyResultsForAllOpt(&testCases[i], src, dest, expectedStr, digits[j], 421 letters[k]); 422 } 423 } 424 } 425 ubiditransform_close(pTransform); 426 } 427 428 void 429 addBidiTransformTest(TestNode** root) 430 { 431 addTest(root, testAutoDirection, "complex/bidi-transform/TestAutoDirection"); 432 addTest(root, testAllTransformOptions, "complex/bidi-transform/TestAllTransformOptions"); 433 } 434 435 #ifdef __cplusplus 436 } 437 #endif 438