1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <mouse.h>
6 #include <frame.h>
7
8 Point
_frptofcharptb(Frame * f,ulong p,Point pt,int bn)9 _frptofcharptb(Frame *f, ulong p, Point pt, int bn)
10 {
11 uchar *s;
12 Frbox *b;
13 int w, l;
14 Rune r;
15
16 for(b = &f->box[bn]; bn<f->nbox; bn++,b++){
17 _frcklinewrap(f, &pt, b);
18 if(p < (l=NRUNE(b))){
19 if(b->nrune > 0)
20 for(s=b->ptr; p>0; s+=w, p--){
21 if((r = *s) < Runeself)
22 w = 1;
23 else
24 w = chartorune(&r, (char*)s);
25 pt.x += stringnwidth(f->font, (char*)s, 1);
26 if(r==0 || pt.x>f->r.max.x)
27 drawerror(f->display, "frptofchar");
28 }
29 break;
30 }
31 p -= l;
32 _fradvance(f, &pt, b);
33 }
34 return pt;
35 }
36
37 Point
frptofchar(Frame * f,ulong p)38 frptofchar(Frame *f, ulong p)
39 {
40 return _frptofcharptb(f, p, f->r.min, 0);
41 }
42
43 Point
_frptofcharnb(Frame * f,ulong p,int nb)44 _frptofcharnb(Frame *f, ulong p, int nb) /* doesn't do final _fradvance to next line */
45 {
46 Point pt;
47 int nbox;
48
49 nbox = f->nbox;
50 f->nbox = nb;
51 pt = _frptofcharptb(f, p, f->r.min, 0);
52 f->nbox = nbox;
53 return pt;
54 }
55
56 static
57 Point
_frgrid(Frame * f,Point p)58 _frgrid(Frame *f, Point p)
59 {
60 p.y -= f->r.min.y;
61 p.y -= p.y%f->font->height;
62 p.y += f->r.min.y;
63 if(p.x > f->r.max.x)
64 p.x = f->r.max.x;
65 return p;
66 }
67
68 ulong
frcharofpt(Frame * f,Point pt)69 frcharofpt(Frame *f, Point pt)
70 {
71 Point qt;
72 int w, bn;
73 uchar *s;
74 Frbox *b;
75 ulong p;
76 Rune r;
77
78 pt = _frgrid(f, pt);
79 qt = f->r.min;
80 for(b=f->box,bn=0,p=0; bn<f->nbox && qt.y<pt.y; bn++,b++){
81 _frcklinewrap(f, &qt, b);
82 if(qt.y >= pt.y)
83 break;
84 _fradvance(f, &qt, b);
85 p += NRUNE(b);
86 }
87 for(; bn<f->nbox && qt.x<=pt.x; bn++,b++){
88 _frcklinewrap(f, &qt, b);
89 if(qt.y > pt.y)
90 break;
91 if(qt.x+b->wid > pt.x){
92 if(b->nrune < 0)
93 _fradvance(f, &qt, b);
94 else{
95 s = b->ptr;
96 for(;;){
97 if((r = *s) < Runeself)
98 w = 1;
99 else
100 w = chartorune(&r, (char*)s);
101 if(r == 0)
102 drawerror(f->display, "end of string in frcharofpt");
103 qt.x += stringnwidth(f->font, (char*)s, 1);
104 s += w;
105 if(qt.x > pt.x)
106 break;
107 p++;
108 }
109 }
110 }else{
111 p += NRUNE(b);
112 _fradvance(f, &qt, b);
113 }
114 }
115 return p;
116 }
117