xref: /plan9/sys/src/libframe/frutil.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 int
_frcanfit(Frame * f,Point pt,Frbox * b)93e12c5d1SDavid du Colombier _frcanfit(Frame *f, Point pt, Frbox *b)
103e12c5d1SDavid du Colombier {
113e12c5d1SDavid du Colombier 	int left, w, nr;
123e12c5d1SDavid du Colombier 	uchar *p;
133e12c5d1SDavid du Colombier 	Rune r;
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier 	left = f->r.max.x-pt.x;
163e12c5d1SDavid du Colombier 	if(b->nrune < 0)
173e12c5d1SDavid du Colombier 		return b->minwid <= left;
183e12c5d1SDavid du Colombier 	if(left >= b->wid)
193e12c5d1SDavid du Colombier 		return b->nrune;
203e12c5d1SDavid du Colombier 	for(nr=0,p=b->ptr; *p; p+=w,nr++){
213e12c5d1SDavid du Colombier 		r = *p;
223e12c5d1SDavid du Colombier 		if(r < Runeself)
233e12c5d1SDavid du Colombier 			w = 1;
243e12c5d1SDavid du Colombier 		else
253e12c5d1SDavid du Colombier 			w = chartorune(&r, (char*)p);
26*7dd7cddfSDavid du Colombier 		left -= stringnwidth(f->font, (char*)p, 1);
273e12c5d1SDavid du Colombier 		if(left < 0)
283e12c5d1SDavid du Colombier 			return nr;
293e12c5d1SDavid du Colombier 	}
30*7dd7cddfSDavid du Colombier 	drawerror(f->display, "_frcanfit can't");
313e12c5d1SDavid du Colombier 	return 0;
323e12c5d1SDavid du Colombier }
333e12c5d1SDavid du Colombier 
343e12c5d1SDavid du Colombier void
_frcklinewrap(Frame * f,Point * p,Frbox * b)353e12c5d1SDavid du Colombier _frcklinewrap(Frame *f, Point *p, Frbox *b)
363e12c5d1SDavid du Colombier {
373e12c5d1SDavid du Colombier 	if((b->nrune<0? b->minwid : b->wid) > f->r.max.x-p->x){
38*7dd7cddfSDavid du Colombier 		p->x = f->r.min.x;
393e12c5d1SDavid du Colombier 		p->y += f->font->height;
403e12c5d1SDavid du Colombier 	}
413e12c5d1SDavid du Colombier }
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier void
_frcklinewrap0(Frame * f,Point * p,Frbox * b)443e12c5d1SDavid du Colombier _frcklinewrap0(Frame *f, Point *p, Frbox *b)
453e12c5d1SDavid du Colombier {
463e12c5d1SDavid du Colombier 	if(_frcanfit(f, *p, b) == 0){
47*7dd7cddfSDavid du Colombier 		p->x = f->r.min.x;
483e12c5d1SDavid du Colombier 		p->y += f->font->height;
493e12c5d1SDavid du Colombier 	}
503e12c5d1SDavid du Colombier }
513e12c5d1SDavid du Colombier 
523e12c5d1SDavid du Colombier void
_fradvance(Frame * f,Point * p,Frbox * b)533e12c5d1SDavid du Colombier _fradvance(Frame *f, Point *p, Frbox *b)
543e12c5d1SDavid du Colombier {
553e12c5d1SDavid du Colombier 	if(b->nrune<0 && b->bc=='\n'){
56*7dd7cddfSDavid du Colombier 		p->x = f->r.min.x;
573e12c5d1SDavid du Colombier 		p->y += f->font->height;
583e12c5d1SDavid du Colombier 	}else
593e12c5d1SDavid du Colombier 		p->x += b->wid;
603e12c5d1SDavid du Colombier }
613e12c5d1SDavid du Colombier 
623e12c5d1SDavid du Colombier int
_frnewwid(Frame * f,Point pt,Frbox * b)633e12c5d1SDavid du Colombier _frnewwid(Frame *f, Point pt, Frbox *b)
643e12c5d1SDavid du Colombier {
65*7dd7cddfSDavid du Colombier 	b->wid = _frnewwid0(f, pt, b);
66*7dd7cddfSDavid du Colombier 	return b->wid;
67*7dd7cddfSDavid du Colombier }
68*7dd7cddfSDavid du Colombier 
69*7dd7cddfSDavid du Colombier int
_frnewwid0(Frame * f,Point pt,Frbox * b)70*7dd7cddfSDavid du Colombier _frnewwid0(Frame *f, Point pt, Frbox *b)
71*7dd7cddfSDavid du Colombier {
723e12c5d1SDavid du Colombier 	int c, x;
733e12c5d1SDavid du Colombier 
743e12c5d1SDavid du Colombier 	c = f->r.max.x;
753e12c5d1SDavid du Colombier 	x = pt.x;
76*7dd7cddfSDavid du Colombier 	if(b->nrune>=0 || b->bc!='\t')
773e12c5d1SDavid du Colombier 		return b->wid;
783e12c5d1SDavid du Colombier 	if(x+b->minwid > c)
79*7dd7cddfSDavid du Colombier 		x = pt.x = f->r.min.x;
803e12c5d1SDavid du Colombier 	x += f->maxtab;
81*7dd7cddfSDavid du Colombier 	x -= (x-f->r.min.x)%f->maxtab;
823e12c5d1SDavid du Colombier 	if(x-pt.x<b->minwid || x>c)
833e12c5d1SDavid du Colombier 		x = pt.x+b->minwid;
84*7dd7cddfSDavid du Colombier 	return x-pt.x;
853e12c5d1SDavid du Colombier }
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier void
_frclean(Frame * f,Point pt,int n0,int n1)883e12c5d1SDavid du Colombier _frclean(Frame *f, Point pt, int n0, int n1)	/* look for mergeable boxes */
893e12c5d1SDavid du Colombier {
903e12c5d1SDavid du Colombier 	Frbox *b;
913e12c5d1SDavid du Colombier 	int nb, c;
923e12c5d1SDavid du Colombier 
933e12c5d1SDavid du Colombier 	c = f->r.max.x;
943e12c5d1SDavid du Colombier 	for(nb=n0; nb<n1-1; nb++){
953e12c5d1SDavid du Colombier 		b = &f->box[nb];
963e12c5d1SDavid du Colombier 		_frcklinewrap(f, &pt, b);
973e12c5d1SDavid du Colombier 		while(b[0].nrune>=0 && nb<n1-1 && b[1].nrune>=0 && pt.x+b[0].wid+b[1].wid<c){
983e12c5d1SDavid du Colombier 			_frmergebox(f, nb);
993e12c5d1SDavid du Colombier 			n1--;
1003e12c5d1SDavid du Colombier 			b = &f->box[nb];
1013e12c5d1SDavid du Colombier 		}
1023e12c5d1SDavid du Colombier 		_fradvance(f, &pt, &f->box[nb]);
1033e12c5d1SDavid du Colombier 	}
1043e12c5d1SDavid du Colombier 	for(; nb<f->nbox; nb++){
1053e12c5d1SDavid du Colombier 		b = &f->box[nb];
1063e12c5d1SDavid du Colombier 		_frcklinewrap(f, &pt, b);
1073e12c5d1SDavid du Colombier 		_fradvance(f, &pt, &f->box[nb]);
1083e12c5d1SDavid du Colombier 	}
1093e12c5d1SDavid du Colombier 	f->lastlinefull = 0;
1103e12c5d1SDavid du Colombier 	if(pt.y >= f->r.max.y)
1113e12c5d1SDavid du Colombier 		f->lastlinefull = 1;
1123e12c5d1SDavid du Colombier }
113