| Abhay Kumar | a61c522 | 2025-11-10 07:32:50 +0000 | [diff] [blame] | 1 | package uniseg |
| 2 | |
| 3 | // EastAsianAmbiguousWidth specifies the monospace width for East Asian |
| 4 | // characters classified as Ambiguous. The default is 1 but some rare fonts |
| 5 | // render them with a width of 2. |
| 6 | var EastAsianAmbiguousWidth = 1 |
| 7 | |
| 8 | // runeWidth returns the monospace width for the given rune. The provided |
| 9 | // grapheme property is a value mapped by the [graphemeCodePoints] table. |
| 10 | // |
| 11 | // Every rune has a width of 1, except for runes with the following properties |
| 12 | // (evaluated in this order): |
| 13 | // |
| 14 | // - Control, CR, LF, Extend, ZWJ: Width of 0 |
| 15 | // - \u2e3a, TWO-EM DASH: Width of 3 |
| 16 | // - \u2e3b, THREE-EM DASH: Width of 4 |
| 17 | // - East-Asian width Fullwidth and Wide: Width of 2 (Ambiguous and Neutral |
| 18 | // have a width of 1) |
| 19 | // - Regional Indicator: Width of 2 |
| 20 | // - Extended Pictographic: Width of 2, unless Emoji Presentation is "No". |
| 21 | func runeWidth(r rune, graphemeProperty int) int { |
| 22 | switch graphemeProperty { |
| 23 | case prControl, prCR, prLF, prExtend, prZWJ: |
| 24 | return 0 |
| 25 | case prRegionalIndicator: |
| 26 | return 2 |
| 27 | case prExtendedPictographic: |
| 28 | if property(emojiPresentation, r) == prEmojiPresentation { |
| 29 | return 2 |
| 30 | } |
| 31 | return 1 |
| 32 | } |
| 33 | |
| 34 | switch r { |
| 35 | case 0x2e3a: |
| 36 | return 3 |
| 37 | case 0x2e3b: |
| 38 | return 4 |
| 39 | } |
| 40 | |
| 41 | switch propertyEastAsianWidth(r) { |
| 42 | case prW, prF: |
| 43 | return 2 |
| 44 | case prA: |
| 45 | return EastAsianAmbiguousWidth |
| 46 | } |
| 47 | |
| 48 | return 1 |
| 49 | } |
| 50 | |
| 51 | // StringWidth returns the monospace width for the given string, that is, the |
| 52 | // number of same-size cells to be occupied by the string. |
| 53 | func StringWidth(s string) (width int) { |
| 54 | state := -1 |
| 55 | for len(s) > 0 { |
| 56 | var w int |
| 57 | _, s, w, state = FirstGraphemeClusterInString(s, state) |
| 58 | width += w |
| 59 | } |
| 60 | return |
| 61 | } |