aboutsummaryrefslogtreecommitdiff
path: root/src/libframe/frptofchar.c
blob: 58536ed9276858d71bce6ee88fd8830c3b2e0c18 (plain)
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
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <mouse.h>
#include <frame.h>

Point
_frptofcharptb(Frame *f, ulong p, Point pt, int bn)
{
	uchar *s;
	Frbox *b;
	int w, l;
	Rune r;

	for(b = &f->box[bn]; bn<f->nbox; bn++,b++){
		_frcklinewrap(f, &pt, b);
		if(p < (l=NRUNE(b))){
			if(b->nrune > 0)
				for(s=b->ptr; p>0; s+=w, p--){
					if((r = *s) < Runeself)
						w = 1;
					else
						w = chartorune(&r, (char*)s);
					pt.x += stringnwidth(f->font, (char*)s, 1);
					if(r==0 || pt.x>f->r.max.x)
						drawerror(f->display, "frptofchar");
				}
			break;
		}
		p -= l;
		_fradvance(f, &pt, b);
	}
	return pt;
}

Point
frptofchar(Frame *f, ulong p)
{
	return _frptofcharptb(f, p, f->r.min, 0);
}

Point
_frptofcharnb(Frame *f, ulong p, int nb)	/* doesn't do final _fradvance to next line */
{
	Point pt;
	int nbox;

	nbox = f->nbox;
	f->nbox = nb;
	pt = _frptofcharptb(f, p, f->r.min, 0);
	f->nbox = nbox;
	return pt;
}

static
Point
_frgrid(Frame *f, Point p)
{
	p.y -= f->r.min.y;
	p.y -= p.y%f->font->height;
	p.y += f->r.min.y;
	if(p.x > f->r.max.x)
		p.x = f->r.max.x;
	return p;
}

ulong
frcharofpt(Frame *f, Point pt)
{
	Point qt;
	int w, bn;
	uchar *s;
	Frbox *b;
	ulong p;
	Rune r;

	pt = _frgrid(f, pt);
	qt = f->r.min;
	for(b=f->box,bn=0,p=0; bn<f->nbox && qt.y<pt.y; bn++,b++){
		_frcklinewrap(f, &qt, b);
		if(qt.y >= pt.y)
			break;
		_fradvance(f, &qt, b);
		p += NRUNE(b);
	}
	for(; bn<f->nbox && qt.x<=pt.x; bn++,b++){
		_frcklinewrap(f, &qt, b);
		if(qt.y > pt.y)
			break;
		if(qt.x+b->wid > pt.x){
			if(b->nrune < 0)
				_fradvance(f, &qt, b);
			else{
				s = b->ptr;
				for(;;){
					if((r = *s) < Runeself)
						w = 1;
					else
						w = chartorune(&r, (char*)s);
					if(r == 0)
						drawerror(f->display, "end of string in frcharofpt");
					qt.x += stringnwidth(f->font, (char*)s, 1);
					s += w;
					if(qt.x > pt.x)
						break;
					p++;
				}
			}
		}else{
			p += NRUNE(b);
			_fradvance(f, &qt, b);
		}
	}
	return p;
}