1471 * Given a specific sequence composed of a regular character and
1472 * combining marks that follow it, produce the alternation that will
1473 * match all canonical equivalences of that sequence.
1474 */
1475 private String produceEquivalentAlternation(String source) {
1476 int len = countChars(source, 0, 1);
1477 if (source.length() == len)
1478 // source has one character.
1479 return source;
1480
1481 String base = source.substring(0,len);
1482 String combiningMarks = source.substring(len);
1483
1484 String[] perms = producePermutations(combiningMarks);
1485 StringBuilder result = new StringBuilder(source);
1486
1487 // Add combined permutations
1488 for(int x=0; x<perms.length; x++) {
1489 String next = base + perms[x];
1490 if (x>0)
1491 result.append("|"+next);
1492 next = composeOneStep(next);
1493 if (next != null)
1494 result.append("|"+produceEquivalentAlternation(next));
1495 }
1496 return result.toString();
1497 }
1498
1499 /**
1500 * Returns an array of strings that have all the possible
1501 * permutations of the characters in the input string.
1502 * This is used to get a list of all possible orderings
1503 * of a set of combining marks. Note that some of the permutations
1504 * are invalid because of combining class collisions, and these
1505 * possibilities must be removed because they are not canonically
1506 * equivalent.
1507 */
1508 private String[] producePermutations(String input) {
1509 if (input.length() == countChars(input, 0, 1))
1510 return new String[] {input};
1511
1512 if (input.length() == countChars(input, 0, 2)) {
1513 int c0 = Character.codePointAt(input, 0);
1514 int c1 = Character.codePointAt(input, Character.charCount(c0));
|
1471 * Given a specific sequence composed of a regular character and
1472 * combining marks that follow it, produce the alternation that will
1473 * match all canonical equivalences of that sequence.
1474 */
1475 private String produceEquivalentAlternation(String source) {
1476 int len = countChars(source, 0, 1);
1477 if (source.length() == len)
1478 // source has one character.
1479 return source;
1480
1481 String base = source.substring(0,len);
1482 String combiningMarks = source.substring(len);
1483
1484 String[] perms = producePermutations(combiningMarks);
1485 StringBuilder result = new StringBuilder(source);
1486
1487 // Add combined permutations
1488 for(int x=0; x<perms.length; x++) {
1489 String next = base + perms[x];
1490 if (x>0)
1491 result.append('|').append(next);
1492 next = composeOneStep(next);
1493 if (next != null)
1494 result.append('|').append(produceEquivalentAlternation(next));
1495 }
1496 return result.toString();
1497 }
1498
1499 /**
1500 * Returns an array of strings that have all the possible
1501 * permutations of the characters in the input string.
1502 * This is used to get a list of all possible orderings
1503 * of a set of combining marks. Note that some of the permutations
1504 * are invalid because of combining class collisions, and these
1505 * possibilities must be removed because they are not canonically
1506 * equivalent.
1507 */
1508 private String[] producePermutations(String input) {
1509 if (input.length() == countChars(input, 0, 1))
1510 return new String[] {input};
1511
1512 if (input.length() == countChars(input, 0, 2)) {
1513 int c0 = Character.codePointAt(input, 0);
1514 int c1 = Character.codePointAt(input, Character.charCount(c0));
|