1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /* $Id$ */ 19 20 package org.apache.fop.complexscripts.util; 21 22 import java.util.Arrays; 23 24 /** 25 * <p>Mirror related utilities.</p> 26 * 27 * <p>This work was originally authored by Glenn Adams (gadams@apache.org).</p> 28 */ 29 public final class CharMirror { 30 CharMirror()31 private CharMirror() { 32 } 33 34 /** 35 * Mirror characters that are designated as having the bidi mirrorred property. 36 * @param s a string whose characters are to be mirrored 37 * @return the resulting string 38 */ mirror(String s)39 public static String mirror(String s) { 40 StringBuffer sb = new StringBuffer(s); 41 for (int i = 0, n = sb.length(); i < n; ++i) { 42 sb.setCharAt(i, (char) mirror(sb.charAt(i))); 43 } 44 return sb.toString(); 45 } 46 47 /** 48 * Determine if string has a mirrorable character. 49 * @param s a string whose characters are to be tested for mirrorability 50 * @return true if some character can be mirrored 51 */ hasMirrorable(String s)52 public static boolean hasMirrorable(String s) { 53 for (int i = 0, n = s.length(); i < n; ++i) { 54 char c = s.charAt(i); 55 if (Arrays.binarySearch(mirroredCharacters, c) >= 0) { 56 return true; 57 } 58 } 59 return false; 60 } 61 62 private static int[] mirroredCharacters = { 63 0x0028, 64 0x0029, 65 0x003C, 66 0x003E, 67 0x005B, 68 0x005D, 69 0x007B, 70 0x007D, 71 0x00AB, 72 0x00BB, 73 0x0F3A, 74 0x0F3B, 75 0x0F3C, 76 0x0F3D, 77 0x169B, 78 0x169C, 79 0x2039, 80 0x203A, 81 0x2045, 82 0x2046, 83 0x207D, 84 0x207E, 85 0x208D, 86 0x208E, 87 0x2208, 88 0x2209, 89 0x220A, 90 0x220B, 91 0x220C, 92 0x220D, 93 0x2215, 94 0x223C, 95 0x223D, 96 0x2243, 97 0x2252, 98 0x2253, 99 0x2254, 100 0x2255, 101 0x2264, 102 0x2265, 103 0x2266, 104 0x2267, 105 0x2268, 106 0x2269, 107 0x226A, 108 0x226B, 109 0x226E, 110 0x226F, 111 0x2270, 112 0x2271, 113 0x2272, 114 0x2273, 115 0x2274, 116 0x2275, 117 0x2276, 118 0x2277, 119 0x2278, 120 0x2279, 121 0x227A, 122 0x227B, 123 0x227C, 124 0x227D, 125 0x227E, 126 0x227F, 127 0x2280, 128 0x2281, 129 0x2282, 130 0x2283, 131 0x2284, 132 0x2285, 133 0x2286, 134 0x2287, 135 0x2288, 136 0x2289, 137 0x228A, 138 0x228B, 139 0x228F, 140 0x2290, 141 0x2291, 142 0x2292, 143 0x2298, 144 0x22A2, 145 0x22A3, 146 0x22A6, 147 0x22A8, 148 0x22A9, 149 0x22AB, 150 0x22B0, 151 0x22B1, 152 0x22B2, 153 0x22B3, 154 0x22B4, 155 0x22B5, 156 0x22B6, 157 0x22B7, 158 0x22C9, 159 0x22CA, 160 0x22CB, 161 0x22CC, 162 0x22CD, 163 0x22D0, 164 0x22D1, 165 0x22D6, 166 0x22D7, 167 0x22D8, 168 0x22D9, 169 0x22DA, 170 0x22DB, 171 0x22DC, 172 0x22DD, 173 0x22DE, 174 0x22DF, 175 0x22E0, 176 0x22E1, 177 0x22E2, 178 0x22E3, 179 0x22E4, 180 0x22E5, 181 0x22E6, 182 0x22E7, 183 0x22E8, 184 0x22E9, 185 0x22EA, 186 0x22EB, 187 0x22EC, 188 0x22ED, 189 0x22F0, 190 0x22F1, 191 0x22F2, 192 0x22F3, 193 0x22F4, 194 0x22F6, 195 0x22F7, 196 0x22FA, 197 0x22FB, 198 0x22FC, 199 0x22FD, 200 0x22FE, 201 0x2308, 202 0x2309, 203 0x230A, 204 0x230B, 205 0x2329, 206 0x232A, 207 0x2768, 208 0x2769, 209 0x276A, 210 0x276B, 211 0x276C, 212 0x276D, 213 0x276E, 214 0x276F, 215 0x2770, 216 0x2771, 217 0x2772, 218 0x2773, 219 0x2774, 220 0x2775, 221 0x27C3, 222 0x27C4, 223 0x27C5, 224 0x27C6, 225 0x27C8, 226 0x27C9, 227 0x27D5, 228 0x27D6, 229 0x27DD, 230 0x27DE, 231 0x27E2, 232 0x27E3, 233 0x27E4, 234 0x27E5, 235 0x27E6, 236 0x27E7, 237 0x27E8, 238 0x27E9, 239 0x27EA, 240 0x27EB, 241 0x27EC, 242 0x27ED, 243 0x27EE, 244 0x27EF, 245 0x2983, 246 0x2984, 247 0x2985, 248 0x2986, 249 0x2987, 250 0x2988, 251 0x2989, 252 0x298A, 253 0x298B, 254 0x298C, 255 0x298D, 256 0x298E, 257 0x298F, 258 0x2990, 259 0x2991, 260 0x2992, 261 0x2993, 262 0x2994, 263 0x2995, 264 0x2996, 265 0x2997, 266 0x2998, 267 0x29B8, 268 0x29C0, 269 0x29C1, 270 0x29C4, 271 0x29C5, 272 0x29CF, 273 0x29D0, 274 0x29D1, 275 0x29D2, 276 0x29D4, 277 0x29D5, 278 0x29D8, 279 0x29D9, 280 0x29DA, 281 0x29DB, 282 0x29F5, 283 0x29F8, 284 0x29F9, 285 0x29FC, 286 0x29FD, 287 0x2A2B, 288 0x2A2C, 289 0x2A2D, 290 0x2A2E, 291 0x2A34, 292 0x2A35, 293 0x2A3C, 294 0x2A3D, 295 0x2A64, 296 0x2A65, 297 0x2A79, 298 0x2A7A, 299 0x2A7D, 300 0x2A7E, 301 0x2A7F, 302 0x2A80, 303 0x2A81, 304 0x2A82, 305 0x2A83, 306 0x2A84, 307 0x2A8B, 308 0x2A8C, 309 0x2A91, 310 0x2A92, 311 0x2A93, 312 0x2A94, 313 0x2A95, 314 0x2A96, 315 0x2A97, 316 0x2A98, 317 0x2A99, 318 0x2A9A, 319 0x2A9B, 320 0x2A9C, 321 0x2AA1, 322 0x2AA2, 323 0x2AA6, 324 0x2AA7, 325 0x2AA8, 326 0x2AA9, 327 0x2AAA, 328 0x2AAB, 329 0x2AAC, 330 0x2AAD, 331 0x2AAF, 332 0x2AB0, 333 0x2AB3, 334 0x2AB4, 335 0x2AC3, 336 0x2AC4, 337 0x2AC5, 338 0x2AC6, 339 0x2ACD, 340 0x2ACE, 341 0x2ACF, 342 0x2AD0, 343 0x2AD1, 344 0x2AD2, 345 0x2AD3, 346 0x2AD4, 347 0x2AD5, 348 0x2AD6, 349 0x2ADE, 350 0x2AE3, 351 0x2E02, 352 0x2E03, 353 0x2E04, 354 0x2E05, 355 0x2E09, 356 0x2E0A, 357 0x2E0C, 358 0x2E0D, 359 0x2E1C, 360 0x2E1D, 361 0x2E20, 362 0x2E21, 363 0x2E22, 364 0x2E23, 365 0x2E24, 366 0x2E25, 367 0x2E26, 368 0x300E, 369 0x300F, 370 0x3010, 371 0x3011, 372 0x3014, 373 0x3015, 374 0x3016, 375 0x3017, 376 0x3018, 377 0x3019, 378 0x301A, 379 0x301B, 380 0xFE59, 381 0xFE5A, 382 0xFF3B, 383 0xFF3D, 384 0xFF5B, 385 0xFF5D, 386 0xFF5F, 387 0xFF60, 388 0xFF62, 389 0xFF63 390 }; 391 392 private static int[] mirroredCharactersMapping = { 393 0x0029, 394 0x0028, 395 0x003E, 396 0x003C, 397 0x005D, 398 0x005B, 399 0x007D, 400 0x007B, 401 0x00BB, 402 0x00AB, 403 0x0F3B, 404 0x0F3A, 405 0x0F3D, 406 0x0F3C, 407 0x169C, 408 0x169B, 409 0x203A, 410 0x2039, 411 0x2046, 412 0x2045, 413 0x207E, 414 0x207D, 415 0x208E, 416 0x208D, 417 0x220B, 418 0x220C, 419 0x220D, 420 0x2208, 421 0x2209, 422 0x220A, 423 0x29F5, 424 0x223D, 425 0x223C, 426 0x22CD, 427 0x2253, 428 0x2252, 429 0x2255, 430 0x2254, 431 0x2265, 432 0x2264, 433 0x2267, 434 0x2266, 435 0x2269, 436 0x2268, 437 0x226B, 438 0x226A, 439 0x226F, 440 0x226E, 441 0x2271, 442 0x2270, 443 0x2273, 444 0x2272, 445 0x2275, 446 0x2274, 447 0x2277, 448 0x2276, 449 0x2279, 450 0x2278, 451 0x227B, 452 0x227A, 453 0x227D, 454 0x227C, 455 0x227F, 456 0x227E, 457 0x2281, 458 0x2280, 459 0x2283, 460 0x2282, 461 0x2285, 462 0x2284, 463 0x2287, 464 0x2286, 465 0x2289, 466 0x2288, 467 0x228B, 468 0x228A, 469 0x2290, 470 0x228F, 471 0x2292, 472 0x2291, 473 0x29B8, 474 0x22A3, 475 0x22A2, 476 0x2ADE, 477 0x2AE4, 478 0x2AE3, 479 0x2AE5, 480 0x22B1, 481 0x22B0, 482 0x22B3, 483 0x22B2, 484 0x22B5, 485 0x22B4, 486 0x22B7, 487 0x22B6, 488 0x22CA, 489 0x22C9, 490 0x22CC, 491 0x22CB, 492 0x2243, 493 0x22D1, 494 0x22D0, 495 0x22D7, 496 0x22D6, 497 0x22D9, 498 0x22D8, 499 0x22DB, 500 0x22DA, 501 0x22DD, 502 0x22DC, 503 0x22DF, 504 0x22DE, 505 0x22E1, 506 0x22E0, 507 0x22E3, 508 0x22E2, 509 0x22E5, 510 0x22E4, 511 0x22E7, 512 0x22E6, 513 0x22E9, 514 0x22E8, 515 0x22EB, 516 0x22EA, 517 0x22ED, 518 0x22EC, 519 0x22F1, 520 0x22F0, 521 0x22FA, 522 0x22FB, 523 0x22FC, 524 0x22FD, 525 0x22FE, 526 0x22F2, 527 0x22F3, 528 0x22F4, 529 0x22F6, 530 0x22F7, 531 0x2309, 532 0x2308, 533 0x230B, 534 0x230A, 535 0x232A, 536 0x2329, 537 0x2769, 538 0x2768, 539 0x276B, 540 0x276A, 541 0x276D, 542 0x276C, 543 0x276F, 544 0x276E, 545 0x2771, 546 0x2770, 547 0x2773, 548 0x2772, 549 0x2775, 550 0x2774, 551 0x27C4, 552 0x27C3, 553 0x27C6, 554 0x27C5, 555 0x27C9, 556 0x27C8, 557 0x27D6, 558 0x27D5, 559 0x27DE, 560 0x27DD, 561 0x27E3, 562 0x27E2, 563 0x27E5, 564 0x27E4, 565 0x27E7, 566 0x27E6, 567 0x27E9, 568 0x27E8, 569 0x27EB, 570 0x27EA, 571 0x27ED, 572 0x27EC, 573 0x27EF, 574 0x27EE, 575 0x2984, 576 0x2983, 577 0x2986, 578 0x2985, 579 0x2988, 580 0x2987, 581 0x298A, 582 0x2989, 583 0x298C, 584 0x298B, 585 0x2990, 586 0x298F, 587 0x298E, 588 0x298D, 589 0x2992, 590 0x2991, 591 0x2994, 592 0x2993, 593 0x2996, 594 0x2995, 595 0x2998, 596 0x2997, 597 0x2298, 598 0x29C1, 599 0x29C0, 600 0x29C5, 601 0x29C4, 602 0x29D0, 603 0x29CF, 604 0x29D2, 605 0x29D1, 606 0x29D5, 607 0x29D4, 608 0x29D9, 609 0x29D8, 610 0x29DB, 611 0x29DA, 612 0x2215, 613 0x29F9, 614 0x29F8, 615 0x29FD, 616 0x29FC, 617 0x2A2C, 618 0x2A2B, 619 0x2A2E, 620 0x2A2D, 621 0x2A35, 622 0x2A34, 623 0x2A3D, 624 0x2A3C, 625 0x2A65, 626 0x2A64, 627 0x2A7A, 628 0x2A79, 629 0x2A7E, 630 0x2A7D, 631 0x2A80, 632 0x2A7F, 633 0x2A82, 634 0x2A81, 635 0x2A84, 636 0x2A83, 637 0x2A8C, 638 0x2A8B, 639 0x2A92, 640 0x2A91, 641 0x2A94, 642 0x2A93, 643 0x2A96, 644 0x2A95, 645 0x2A98, 646 0x2A97, 647 0x2A9A, 648 0x2A99, 649 0x2A9C, 650 0x2A9B, 651 0x2AA2, 652 0x2AA1, 653 0x2AA7, 654 0x2AA6, 655 0x2AA9, 656 0x2AA8, 657 0x2AAB, 658 0x2AAA, 659 0x2AAD, 660 0x2AAC, 661 0x2AB0, 662 0x2AAF, 663 0x2AB4, 664 0x2AB3, 665 0x2AC4, 666 0x2AC3, 667 0x2AC6, 668 0x2AC5, 669 0x2ACE, 670 0x2ACD, 671 0x2AD0, 672 0x2ACF, 673 0x2AD2, 674 0x2AD1, 675 0x2AD4, 676 0x2AD3, 677 0x2AD6, 678 0x2AD5, 679 0x22A6, 680 0x22A9, 681 0x2E03, 682 0x2E02, 683 0x2E05, 684 0x2E04, 685 0x2E0A, 686 0x2E09, 687 0x2E0D, 688 0x2E0C, 689 0x2E1D, 690 0x2E1C, 691 0x2E21, 692 0x2E20, 693 0x2E23, 694 0x2E22, 695 0x2E25, 696 0x2E24, 697 0x2E27, 698 0x300F, 699 0x300E, 700 0x3011, 701 0x3010, 702 0x3015, 703 0x3014, 704 0x3017, 705 0x3016, 706 0x3019, 707 0x3018, 708 0x301B, 709 0x301A, 710 0xFE5A, 711 0xFE59, 712 0xFF3D, 713 0xFF3B, 714 0xFF5D, 715 0xFF5B, 716 0xFF60, 717 0xFF5F, 718 0xFF63, 719 0xFF62 720 }; 721 mirror(int c)722 private static int mirror(int c) { 723 int i = Arrays.binarySearch(mirroredCharacters, c); 724 if (i < 0) { 725 return c; 726 } else { 727 return mirroredCharactersMapping [ i ]; 728 } 729 } 730 731 } 732