xref: /plan9/sys/src/libframe/frptofchar.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3*7dd7cddfSDavid du Colombier #include <draw.h>
4*7dd7cddfSDavid du Colombier #include <thread.h>
5*7dd7cddfSDavid du Colombier #include <mouse.h>
63e12c5d1SDavid du Colombier #include <frame.h>
73e12c5d1SDavid du Colombier 
83e12c5d1SDavid du Colombier Point
_frptofcharptb(Frame * f,ulong p,Point pt,int bn)93e12c5d1SDavid du Colombier _frptofcharptb(Frame *f, ulong p, Point pt, int bn)
103e12c5d1SDavid du Colombier {
113e12c5d1SDavid du Colombier 	uchar *s;
123e12c5d1SDavid du Colombier 	Frbox *b;
133e12c5d1SDavid du Colombier 	int w, l;
143e12c5d1SDavid du Colombier 	Rune r;
153e12c5d1SDavid du Colombier 
163e12c5d1SDavid du Colombier 	for(b = &f->box[bn]; bn<f->nbox; bn++,b++){
173e12c5d1SDavid du Colombier 		_frcklinewrap(f, &pt, b);
183e12c5d1SDavid du Colombier 		if(p < (l=NRUNE(b))){
193e12c5d1SDavid du Colombier 			if(b->nrune > 0)
203e12c5d1SDavid du Colombier 				for(s=b->ptr; p>0; s+=w, p--){
213e12c5d1SDavid du Colombier 					if((r = *s) < Runeself)
223e12c5d1SDavid du Colombier 						w = 1;
233e12c5d1SDavid du Colombier 					else
243e12c5d1SDavid du Colombier 						w = chartorune(&r, (char*)s);
25*7dd7cddfSDavid du Colombier 					pt.x += stringnwidth(f->font, (char*)s, 1);
263e12c5d1SDavid du Colombier 					if(r==0 || pt.x>f->r.max.x)
27*7dd7cddfSDavid du Colombier 						drawerror(f->display, "frptofchar");
283e12c5d1SDavid du Colombier 				}
293e12c5d1SDavid du Colombier 			break;
303e12c5d1SDavid du Colombier 		}
313e12c5d1SDavid du Colombier 		p -= l;
323e12c5d1SDavid du Colombier 		_fradvance(f, &pt, b);
333e12c5d1SDavid du Colombier 	}
343e12c5d1SDavid du Colombier 	return pt;
353e12c5d1SDavid du Colombier }
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier Point
frptofchar(Frame * f,ulong p)383e12c5d1SDavid du Colombier frptofchar(Frame *f, ulong p)
393e12c5d1SDavid du Colombier {
40*7dd7cddfSDavid du Colombier 	return _frptofcharptb(f, p, f->r.min, 0);
413e12c5d1SDavid du Colombier }
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier Point
_frptofcharnb(Frame * f,ulong p,int nb)443e12c5d1SDavid du Colombier _frptofcharnb(Frame *f, ulong p, int nb)	/* doesn't do final _fradvance to next line */
453e12c5d1SDavid du Colombier {
463e12c5d1SDavid du Colombier 	Point pt;
473e12c5d1SDavid du Colombier 	int nbox;
483e12c5d1SDavid du Colombier 
493e12c5d1SDavid du Colombier 	nbox = f->nbox;
503e12c5d1SDavid du Colombier 	f->nbox = nb;
51*7dd7cddfSDavid du Colombier 	pt = _frptofcharptb(f, p, f->r.min, 0);
523e12c5d1SDavid du Colombier 	f->nbox = nbox;
533e12c5d1SDavid du Colombier 	return pt;
543e12c5d1SDavid du Colombier }
553e12c5d1SDavid du Colombier 
563e12c5d1SDavid du Colombier static
573e12c5d1SDavid du Colombier Point
_frgrid(Frame * f,Point p)583e12c5d1SDavid du Colombier _frgrid(Frame *f, Point p)
593e12c5d1SDavid du Colombier {
603e12c5d1SDavid du Colombier 	p.y -= f->r.min.y;
613e12c5d1SDavid du Colombier 	p.y -= p.y%f->font->height;
623e12c5d1SDavid du Colombier 	p.y += f->r.min.y;
633e12c5d1SDavid du Colombier 	if(p.x > f->r.max.x)
643e12c5d1SDavid du Colombier 		p.x = f->r.max.x;
653e12c5d1SDavid du Colombier 	return p;
663e12c5d1SDavid du Colombier }
673e12c5d1SDavid du Colombier 
683e12c5d1SDavid du Colombier ulong
frcharofpt(Frame * f,Point pt)693e12c5d1SDavid du Colombier frcharofpt(Frame *f, Point pt)
703e12c5d1SDavid du Colombier {
713e12c5d1SDavid du Colombier 	Point qt;
723e12c5d1SDavid du Colombier 	int w, bn;
733e12c5d1SDavid du Colombier 	uchar *s;
743e12c5d1SDavid du Colombier 	Frbox *b;
753e12c5d1SDavid du Colombier 	ulong p;
763e12c5d1SDavid du Colombier 	Rune r;
773e12c5d1SDavid du Colombier 
783e12c5d1SDavid du Colombier 	pt = _frgrid(f, pt);
79*7dd7cddfSDavid du Colombier 	qt = f->r.min;
803e12c5d1SDavid du Colombier 	for(b=f->box,bn=0,p=0; bn<f->nbox && qt.y<pt.y; bn++,b++){
813e12c5d1SDavid du Colombier 		_frcklinewrap(f, &qt, b);
823e12c5d1SDavid du Colombier 		if(qt.y >= pt.y)
833e12c5d1SDavid du Colombier 			break;
843e12c5d1SDavid du Colombier 		_fradvance(f, &qt, b);
853e12c5d1SDavid du Colombier 		p += NRUNE(b);
863e12c5d1SDavid du Colombier 	}
873e12c5d1SDavid du Colombier 	for(; bn<f->nbox && qt.x<=pt.x; bn++,b++){
883e12c5d1SDavid du Colombier 		_frcklinewrap(f, &qt, b);
893e12c5d1SDavid du Colombier 		if(qt.y > pt.y)
903e12c5d1SDavid du Colombier 			break;
913e12c5d1SDavid du Colombier 		if(qt.x+b->wid > pt.x){
923e12c5d1SDavid du Colombier 			if(b->nrune < 0)
933e12c5d1SDavid du Colombier 				_fradvance(f, &qt, b);
943e12c5d1SDavid du Colombier 			else{
953e12c5d1SDavid du Colombier 				s = b->ptr;
963e12c5d1SDavid du Colombier 				for(;;){
973e12c5d1SDavid du Colombier 					if((r = *s) < Runeself)
983e12c5d1SDavid du Colombier 						w = 1;
993e12c5d1SDavid du Colombier 					else
1003e12c5d1SDavid du Colombier 						w = chartorune(&r, (char*)s);
1013e12c5d1SDavid du Colombier 					if(r == 0)
102*7dd7cddfSDavid du Colombier 						drawerror(f->display, "end of string in frcharofpt");
103*7dd7cddfSDavid du Colombier 					qt.x += stringnwidth(f->font, (char*)s, 1);
1043e12c5d1SDavid du Colombier 					s += w;
1053e12c5d1SDavid du Colombier 					if(qt.x > pt.x)
1063e12c5d1SDavid du Colombier 						break;
1073e12c5d1SDavid du Colombier 					p++;
1083e12c5d1SDavid du Colombier 				}
1093e12c5d1SDavid du Colombier 			}
1103e12c5d1SDavid du Colombier 		}else{
1113e12c5d1SDavid du Colombier 			p += NRUNE(b);
1123e12c5d1SDavid du Colombier 			_fradvance(f, &qt, b);
1133e12c5d1SDavid du Colombier 		}
1143e12c5d1SDavid du Colombier 	}
1153e12c5d1SDavid du Colombier 	return p;
1163e12c5d1SDavid du Colombier }
117