OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2011,2012 Google, Inc. | 2 * Copyright © 2011,2012 Google, Inc. |
3 * | 3 * |
4 * This is part of HarfBuzz, a text shaping library. | 4 * This is part of HarfBuzz, a text shaping library. |
5 * | 5 * |
6 * Permission is hereby granted, without written agreement and without | 6 * Permission is hereby granted, without written agreement and without |
7 * license or royalty fees, to use, copy, modify, and distribute this | 7 * license or royalty fees, to use, copy, modify, and distribute this |
8 * software and its documentation for any purpose, provided that the | 8 * software and its documentation for any purpose, provided that the |
9 * above copyright notice and the following two paragraphs appear in | 9 * above copyright notice and the following two paragraphs appear in |
10 * all copies of this software. | 10 * all copies of this software. |
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1005 } | 1005 } |
1006 | 1006 |
1007 | 1007 |
1008 { | 1008 { |
1009 /* Use syllable() for sort accounting temporarily. */ | 1009 /* Use syllable() for sort accounting temporarily. */ |
1010 unsigned int syllable = info[start].syllable(); | 1010 unsigned int syllable = info[start].syllable(); |
1011 for (unsigned int i = start; i < end; i++) | 1011 for (unsigned int i = start; i < end; i++) |
1012 info[i].syllable() = i - start; | 1012 info[i].syllable() = i - start; |
1013 | 1013 |
1014 /* Sit tight, rock 'n roll! */ | 1014 /* Sit tight, rock 'n roll! */ |
1015 hb_bubble_sort (info + start, end - start, compare_indic_order); | 1015 hb_stable_sort (info + start, end - start, compare_indic_order); |
1016 /* Find base again */ | 1016 /* Find base again */ |
1017 base = end; | 1017 base = end; |
1018 for (unsigned int i = start; i < end; i++) | 1018 for (unsigned int i = start; i < end; i++) |
1019 if (info[i].indic_position() == POS_BASE_C) | 1019 if (info[i].indic_position() == POS_BASE_C) |
1020 { | 1020 { |
1021 base = i; | 1021 base = i; |
1022 break; | 1022 break; |
1023 } | 1023 } |
1024 /* Things are out-of-control for post base positions, they may shuffle | 1024 /* Things are out-of-control for post base positions, they may shuffle |
1025 * around like crazy. In old-spec mode, we move halants around, so in | 1025 * around like crazy. In old-spec mode, we move halants around, so in |
1026 * that case merge all clusters after base. Otherwise, check the sort | 1026 * that case merge all clusters after base. Otherwise, check the sort |
1027 * order and merge as needed. | 1027 * order and merge as needed. |
1028 * For pre-base stuff, we handle cluster issues in final reordering. */ | 1028 * For pre-base stuff, we handle cluster issues in final reordering. |
| 1029 * |
| 1030 * We could use buffer->sort() for this, if there was no special |
| 1031 * reordering of pre-base stuff happening later... |
| 1032 */ |
1029 if (indic_plan->is_old_spec || end - base > 127) | 1033 if (indic_plan->is_old_spec || end - base > 127) |
1030 buffer->merge_clusters (base, end); | 1034 buffer->merge_clusters (base, end); |
1031 else | 1035 else |
1032 { | 1036 { |
1033 /* Note! syllable() is a one-byte field. */ | 1037 /* Note! syllable() is a one-byte field. */ |
1034 for (unsigned int i = base; i < end; i++) | 1038 for (unsigned int i = base; i < end; i++) |
1035 if (info[i].syllable() != 255) | 1039 if (info[i].syllable() != 255) |
1036 { | 1040 { |
1037 unsigned int max = i; | 1041 unsigned int max = i; |
1038 unsigned int j = start + info[i].syllable(); | 1042 unsigned int j = start + info[i].syllable(); |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1397 new_pos = start; /* No move. */ | 1401 new_pos = start; /* No move. */ |
1398 } | 1402 } |
1399 | 1403 |
1400 if (start < new_pos && info[new_pos].indic_position () != POS_PRE_M) | 1404 if (start < new_pos && info[new_pos].indic_position () != POS_PRE_M) |
1401 { | 1405 { |
1402 /* Now go see if there's actually any matras... */ | 1406 /* Now go see if there's actually any matras... */ |
1403 for (unsigned int i = new_pos; i > start; i--) | 1407 for (unsigned int i = new_pos; i > start; i--) |
1404 if (info[i - 1].indic_position () == POS_PRE_M) | 1408 if (info[i - 1].indic_position () == POS_PRE_M) |
1405 { | 1409 { |
1406 unsigned int old_pos = i - 1; | 1410 unsigned int old_pos = i - 1; |
| 1411 if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. *
/ |
| 1412 base--; |
| 1413 |
1407 hb_glyph_info_t tmp = info[old_pos]; | 1414 hb_glyph_info_t tmp = info[old_pos]; |
1408 memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * siz
eof (info[0])); | 1415 memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * siz
eof (info[0])); |
1409 info[new_pos] = tmp; | 1416 info[new_pos] = tmp; |
1410 » if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. *
/ | 1417 |
1411 » base--; | 1418 » /* Note: this merge_clusters() is intentionally *after* the reordering
. |
| 1419 » * Indic matra reordering is special and tricky... */ |
1412 buffer->merge_clusters (new_pos, MIN (end, base + 1)); | 1420 buffer->merge_clusters (new_pos, MIN (end, base + 1)); |
| 1421 |
1413 new_pos--; | 1422 new_pos--; |
1414 } | 1423 } |
1415 } else { | 1424 } else { |
1416 for (unsigned int i = start; i < base; i++) | 1425 for (unsigned int i = start; i < base; i++) |
1417 if (info[i].indic_position () == POS_PRE_M) { | 1426 if (info[i].indic_position () == POS_PRE_M) { |
1418 buffer->merge_clusters (i, MIN (end, base + 1)); | 1427 buffer->merge_clusters (i, MIN (end, base + 1)); |
1419 break; | 1428 break; |
1420 } | 1429 } |
1421 } | 1430 } |
1422 } | 1431 } |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 if (info[i].indic_category() == OT_M) { | 1564 if (info[i].indic_category() == OT_M) { |
1556 /* Ok, got it. */ | 1565 /* Ok, got it. */ |
1557 new_reph_pos--; | 1566 new_reph_pos--; |
1558 } | 1567 } |
1559 } | 1568 } |
1560 goto reph_move; | 1569 goto reph_move; |
1561 } | 1570 } |
1562 | 1571 |
1563 reph_move: | 1572 reph_move: |
1564 { | 1573 { |
| 1574 /* Move */ |
1565 buffer->merge_clusters (start, new_reph_pos + 1); | 1575 buffer->merge_clusters (start, new_reph_pos + 1); |
1566 | |
1567 /* Move */ | |
1568 hb_glyph_info_t reph = info[start]; | 1576 hb_glyph_info_t reph = info[start]; |
1569 memmove (&info[start], &info[start + 1], (new_reph_pos - start) * sizeof (
info[0])); | 1577 memmove (&info[start], &info[start + 1], (new_reph_pos - start) * sizeof (
info[0])); |
1570 info[new_reph_pos] = reph; | 1578 info[new_reph_pos] = reph; |
| 1579 |
1571 if (start < base && base <= new_reph_pos) | 1580 if (start < base && base <= new_reph_pos) |
1572 base--; | 1581 base--; |
1573 } | 1582 } |
1574 } | 1583 } |
1575 | 1584 |
1576 | 1585 |
1577 /* o Reorder pre-base reordering consonants: | 1586 /* o Reorder pre-base reordering consonants: |
1578 * | 1587 * |
1579 * If a pre-base reordering consonant is found, reorder it according to | 1588 * If a pre-base reordering consonant is found, reorder it according to |
1580 * the following rules: | 1589 * the following rules: |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1633 | 1642 |
1634 if (new_pos > start && is_halant_or_coeng (info[new_pos - 1])) | 1643 if (new_pos > start && is_halant_or_coeng (info[new_pos - 1])) |
1635 { | 1644 { |
1636 /* -> If ZWJ or ZWNJ follow this halant, position is moved after it.
*/ | 1645 /* -> If ZWJ or ZWNJ follow this halant, position is moved after it.
*/ |
1637 if (new_pos < end && is_joiner (info[new_pos])) | 1646 if (new_pos < end && is_joiner (info[new_pos])) |
1638 new_pos++; | 1647 new_pos++; |
1639 } | 1648 } |
1640 | 1649 |
1641 { | 1650 { |
1642 unsigned int old_pos = i; | 1651 unsigned int old_pos = i; |
| 1652 |
1643 buffer->merge_clusters (new_pos, old_pos + 1); | 1653 buffer->merge_clusters (new_pos, old_pos + 1); |
1644 hb_glyph_info_t tmp = info[old_pos]; | 1654 hb_glyph_info_t tmp = info[old_pos]; |
1645 memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * s
izeof (info[0])); | 1655 memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * s
izeof (info[0])); |
1646 info[new_pos] = tmp; | 1656 info[new_pos] = tmp; |
| 1657 |
1647 if (new_pos <= base && base < old_pos) | 1658 if (new_pos <= base && base < old_pos) |
1648 base++; | 1659 base++; |
1649 } | 1660 } |
1650 } | 1661 } |
1651 | 1662 |
1652 break; | 1663 break; |
1653 } | 1664 } |
1654 } | 1665 } |
1655 | 1666 |
1656 | 1667 |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1823 data_create_indic, | 1834 data_create_indic, |
1824 data_destroy_indic, | 1835 data_destroy_indic, |
1825 NULL, /* preprocess_text */ | 1836 NULL, /* preprocess_text */ |
1826 HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, | 1837 HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, |
1827 decompose_indic, | 1838 decompose_indic, |
1828 compose_indic, | 1839 compose_indic, |
1829 setup_masks_indic, | 1840 setup_masks_indic, |
1830 HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, | 1841 HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, |
1831 false, /* fallback_position */ | 1842 false, /* fallback_position */ |
1832 }; | 1843 }; |
OLD | NEW |