plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

frptofchar.c (1975B)


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