forked from gnolang/gno
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmisc.go
155 lines (142 loc) · 2.8 KB
/
misc.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package logos
import (
"strings"
"unicode"
"github.com/gdamore/tcell/v2"
runewidth "github.com/mattn/go-runewidth"
)
// splits a string into lines by newline.
func splitLines(s string) (ss []string) {
return strings.Split(s, "\n")
}
// splits a string according to unicode spaces.
func splitSpaces(s string) (ss []string) {
buf := []rune{}
for _, r := range s {
if unicode.IsSpace(r) {
// continue
if len(buf) > 0 {
ss = append(ss, string(buf))
buf = nil
}
} else {
buf = append(buf, r)
}
}
if len(buf) > 0 {
ss = append(ss, string(buf))
// buf = nil
}
return ss
}
func toRunes(s string) []rune {
runes := make([]rune, 0, len(s))
for _, r := range s {
runes = append(runes, r)
}
return runes
}
// gets the terminal display width of a string.
// must be compatible with nextCharacter().
// NOTE: must be kept in sync with nextCharacter(); see tests.
func widthOf(s string) (l int) {
zwj := false // zero width joiner '\u200d'.
for _, r := range s {
if r == '\u200d' {
zwj = true
continue
}
if zwj {
zwj = false
continue
}
switch runewidth.RuneWidth(r) {
case 0:
if isCombining(r) {
// combining characters have no length.
} else {
l++ // show a blank instead, weird.
}
case 1:
l++
case 2:
l += 2
default:
panic("should not happen")
}
}
return l
}
// given runes of a valid utf8 string,
// return a string that represents
// the next single character (with any modifiers).
// w: width of character. n: number of runes read
func nextCharacter(rz []rune) (s string, w int, n int) {
for n = 0; n < len(rz); n++ {
r := rz[n]
if r == '\u200d' {
// special case: zero width joins.
s = s + string(r)
if n+1 < len(rz) {
s = s + string(rz[n+1])
n++
continue
} else {
// just continue, return invalid string s.
n++
return
}
} else if 0 < len(s) {
return
} else {
// append r to s and inc w.
rw := runewidth.RuneWidth(r)
s = s + string(r)
if rw == 0 {
if isCombining(r) {
// no width
} else {
w += 1
}
} else {
w += rw
}
}
}
return
}
//----------------------------------------
func AbsCoord(elem Elem) (crd Coord) {
for elem != nil {
crd = crd.Add(elem.GetCoord())
elem = elem.GetParent()
}
return
}
var randColors []Color = []Color{
tcell.ColorAliceBlue,
tcell.ColorAntiqueWhite,
tcell.ColorAquaMarine,
tcell.ColorAzure,
tcell.ColorBeige,
tcell.ColorBisque,
tcell.ColorBlanchedAlmond,
tcell.ColorBlueViolet,
tcell.ColorBrown,
tcell.ColorBurlyWood,
}
var rctr = 0
func RandColor() Color {
rctr++
return randColors[rctr%len(randColors)]
}
func IsInBounds(x, y int, origin Coord, size Size) bool {
if x < origin.X || y < origin.Y {
return false
}
if origin.X+size.Width <= x ||
origin.Y+size.Height <= y {
return false
}
return true
}