2022-09-13 13:44:44 +00:00
|
|
|
package uniseg
|
|
|
|
|
2024-01-30 16:47:01 +00:00
|
|
|
// EastAsianAmbiguousWidth specifies the monospace width for East Asian
|
|
|
|
// characters classified as Ambiguous. The default is 1 but some rare fonts
|
|
|
|
// render them with a width of 2.
|
|
|
|
var EastAsianAmbiguousWidth = 1
|
|
|
|
|
2022-09-13 13:44:44 +00:00
|
|
|
// runeWidth returns the monospace width for the given rune. The provided
|
|
|
|
// grapheme property is a value mapped by the [graphemeCodePoints] table.
|
|
|
|
//
|
|
|
|
// Every rune has a width of 1, except for runes with the following properties
|
|
|
|
// (evaluated in this order):
|
|
|
|
//
|
|
|
|
// - Control, CR, LF, Extend, ZWJ: Width of 0
|
|
|
|
// - \u2e3a, TWO-EM DASH: Width of 3
|
|
|
|
// - \u2e3b, THREE-EM DASH: Width of 4
|
|
|
|
// - East-Asian width Fullwidth and Wide: Width of 2 (Ambiguous and Neutral
|
|
|
|
// have a width of 1)
|
|
|
|
// - Regional Indicator: Width of 2
|
|
|
|
// - Extended Pictographic: Width of 2, unless Emoji Presentation is "No".
|
|
|
|
func runeWidth(r rune, graphemeProperty int) int {
|
|
|
|
switch graphemeProperty {
|
|
|
|
case prControl, prCR, prLF, prExtend, prZWJ:
|
|
|
|
return 0
|
|
|
|
case prRegionalIndicator:
|
|
|
|
return 2
|
|
|
|
case prExtendedPictographic:
|
|
|
|
if property(emojiPresentation, r) == prEmojiPresentation {
|
|
|
|
return 2
|
|
|
|
}
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
switch r {
|
|
|
|
case 0x2e3a:
|
|
|
|
return 3
|
|
|
|
case 0x2e3b:
|
|
|
|
return 4
|
|
|
|
}
|
|
|
|
|
2024-01-30 16:47:01 +00:00
|
|
|
switch propertyEastAsianWidth(r) {
|
2022-09-13 13:44:44 +00:00
|
|
|
case prW, prF:
|
|
|
|
return 2
|
2024-01-30 16:47:01 +00:00
|
|
|
case prA:
|
|
|
|
return EastAsianAmbiguousWidth
|
2022-09-13 13:44:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// StringWidth returns the monospace width for the given string, that is, the
|
|
|
|
// number of same-size cells to be occupied by the string.
|
|
|
|
func StringWidth(s string) (width int) {
|
|
|
|
state := -1
|
|
|
|
for len(s) > 0 {
|
|
|
|
var w int
|
|
|
|
_, s, w, state = FirstGraphemeClusterInString(s, state)
|
|
|
|
width += w
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|