-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathptofchar.go
118 lines (105 loc) · 2.27 KB
/
ptofchar.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
package frame
import (
"image"
"log"
"unicode/utf8"
)
// ptofcharptb returns the point of run p based on the current box state.
// NB: it is possible that a different rune at p would give a different
// result. Consequently, the result of this function will not say where a
// new rune at position p should be positioned, only where the current
// rune at p is positioned.
func (f *frameimpl) ptofcharptb(p int, pt image.Point, bn int) image.Point {
var w int
var r rune
for _, b := range f.box[bn:] {
pt = f.cklinewrap(pt, b)
l := nrune(b)
if p < l {
if b.Nrune > 0 {
for s := 0; s < len(b.Ptr) && p > 0; s += w {
p--
r, w = utf8.DecodeRune(b.Ptr[s:])
pt.X += f.font.BytesWidth(b.Ptr[s : s+w])
if r == 0 || pt.X > f.rect.Max.X {
log.Panicf("frptofchar: r=%v pt.X=%v f.rect.Max.X=%v\n", r, pt.X, f.rect.Max.X)
}
}
}
break
}
p -= l
pt = f.advance(pt, b)
}
return pt
}
func (f *frameimpl) Ptofchar(p int) image.Point {
f.lk.Lock()
defer f.lk.Unlock()
return f.ptofcharptb(p, f.rect.Min, 0)
}
func (f *frameimpl) ptofcharnb(p int, _ int) image.Point {
pt := f.ptofcharptb(p, f.rect.Min, 0)
return pt
}
func (f *frameimpl) grid(p image.Point) image.Point {
p.Y -= f.rect.Min.Y
p.Y -= p.Y % f.defaultfontheight
p.Y += f.rect.Min.Y
if p.X > f.rect.Max.X {
p.X = f.rect.Max.X
}
return p
}
func (f *frameimpl) Charofpt(pt image.Point) int {
f.lk.Lock()
defer f.lk.Unlock()
return f.charofptimpl(pt)
}
func (f *frameimpl) charofptimpl(pt image.Point) int {
var w, bn int
var p int
pt = f.grid(pt)
qt := f.rect.Min
for bn = 0; bn < len(f.box) && qt.Y < pt.Y; bn++ {
b := f.box[bn]
qt = f.cklinewrap(qt, b)
if qt.Y >= pt.Y {
break
}
qt = f.advance(qt, b)
p += nrune(b)
}
var r rune
for _, b := range f.box[bn:] {
if qt.X > pt.X {
break
}
qt = f.cklinewrap(qt, b)
if qt.Y > pt.Y {
break
}
if qt.X+b.Wid > pt.X {
if b.Nrune < 0 {
qt = f.advance(qt, b)
} else {
s := 0
for ; s < len(b.Ptr); s += w {
r, w = utf8.DecodeRune(b.Ptr[s:])
if r == 0 {
panic("end of string in frcharofpt")
}
qt.X += f.font.BytesWidth(b.Ptr[s : s+w])
if qt.X > pt.X {
break
}
p++
}
}
} else {
p += nrune(b)
qt = f.advance(qt, b)
}
}
return p
}