-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
width.go
92 lines (84 loc) · 2.68 KB
/
width.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package uniseg
// runeWidth returns the monospace width for the given rune. The provided
// grapheme property is a value mapped by the [graphemeCodePoints] table.
// runeWidth calculates the width of a given rune based on its grapheme property and the current parser settings.
func runeWidth(p *Parser, r rune, graphemeProperty property) int {
// Check the grapheme property of the rune.
switch graphemeProperty {
case prControl, prCR, prLF, prExtend, prZWJ:
// If the property is a control character, carriage return, line feed, extend character, or zero-width joiner, return a width of 0.
return 0
case prRegionalIndicator:
// If the property is a regional indicator, return a width of 2.
return 2
case prExtendedPictographic:
if emojiPresentation.search(r) == prEmojiPresentation {
// If only the WideEmoji setting is true and the rune has an emoji presentation property, return a width of 2.
return 2
}
if p.EastAsianWidth {
return p.runeWidthAE(r, graphemeProperty)
}
// Otherwise, return a width of 1.
return 1
}
// Check for specific runes that have a fixed width.
switch r {
case '\u2e3a': // TWO-EM DASH: Width of 3
return 3
case '\u2e3b': // THREE-EM DASH: Width of 4
return 4
}
return p.runeWidthAE(r, graphemeProperty)
}
func (p *Parser) runeWidthAE(r rune, graphemeProperty property) int {
if p.EastAsianWidth && p.WideEmoji {
if graphemeProperty == prExtendedPictographic {
return 2
}
if emoji.search(r) == prEmoji {
return 2
}
}
// Check the East Asian Width property of the rune.
switch eastAsianWidth.search(r) {
case eawprW, eawprF:
// If the property is Wide or Fullwidth, return a width of 2.
return 2
case eawprA:
if p.EastAsianWidth {
// If the EastAsianWidth setting is true, return a width of 2.
return 2
} else {
// Otherwise, return a width of 1.
return 1
}
case eawprNa, eawprH, eawprN:
// If the property is Neutral, Halfwidth, or Narrow, return a width of 1.
return 1
}
// If the property is not recognized, return a width of 1.
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) {
var state GraphemeBreakState
for len(s) > 0 {
var w int
_, s, w, state = DefaultParser.FirstGraphemeClusterInString(s, state)
width += w
}
return
}
// StringWidth returns the monospace width for the given string, that is, the
// number of same-size cells to be occupied by the string.
func (p *Parser) StringWidth(s string) (width int) {
var state GraphemeBreakState
for len(s) > 0 {
var w int
_, s, w, state = p.FirstGraphemeClusterInString(s, state)
width += w
}
return
}