src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

width.go (1631B)


      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 }