xref: /plan9-contrib/sys/src/libframe/frutil.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <libg.h>
4 #include <frame.h>
5 
6 int
7 _frcanfit(Frame *f, Point pt, Frbox *b)
8 {
9 	int left, w, nr;
10 	uchar *p;
11 	Rune r;
12 
13 	left = f->r.max.x-pt.x;
14 	if(b->nrune < 0)
15 		return b->minwid <= left;
16 	if(left >= b->wid)
17 		return b->nrune;
18 	for(nr=0,p=b->ptr; *p; p+=w,nr++){
19 		r = *p;
20 		if(r < Runeself)
21 			w = 1;
22 		else
23 			w = chartorune(&r, (char*)p);
24 		left -= charwidth(f->font, r);
25 		if(left < 0)
26 			return nr;
27 	}
28 	berror("_frcanfit can't");
29 	return 0;
30 }
31 
32 void
33 _frcklinewrap(Frame *f, Point *p, Frbox *b)
34 {
35 	if((b->nrune<0? b->minwid : b->wid) > f->r.max.x-p->x){
36 		p->x = f->left;
37 		p->y += f->font->height;
38 	}
39 }
40 
41 void
42 _frcklinewrap0(Frame *f, Point *p, Frbox *b)
43 {
44 	if(_frcanfit(f, *p, b) == 0){
45 		p->x = f->left;
46 		p->y += f->font->height;
47 	}
48 }
49 
50 void
51 _fradvance(Frame *f, Point *p, Frbox *b)
52 {
53 	if(b->nrune<0 && b->bc=='\n'){
54 		p->x = f->left;
55 		p->y += f->font->height;
56 	}else
57 		p->x += b->wid;
58 }
59 
60 int
61 _frnewwid(Frame *f, Point pt, Frbox *b)
62 {
63 	int c, x;
64 
65 	c = f->r.max.x;
66 	x = pt.x;
67 	if(b->nrune >= 0)
68 		return b->wid;
69 	if(b->bc == '\t'){
70 		if(x+b->minwid > c)
71 			x = pt.x = f->left;
72 		x += f->maxtab;
73 		x -= (x-f->left)%f->maxtab;
74 		if(x-pt.x<b->minwid || x>c)
75 			x = pt.x+b->minwid;
76 		b->wid = x-pt.x;
77 	}
78 	return b->wid;
79 }
80 
81 void
82 _frclean(Frame *f, Point pt, int n0, int n1)	/* look for mergeable boxes */
83 {
84 	Frbox *b;
85 	int nb, c;
86 
87 	c = f->r.max.x;
88 	for(nb=n0; nb<n1-1; nb++){
89 		b = &f->box[nb];
90 		_frcklinewrap(f, &pt, b);
91 		while(b[0].nrune>=0 && nb<n1-1 && b[1].nrune>=0 && pt.x+b[0].wid+b[1].wid<c){
92 			_frmergebox(f, nb);
93 			n1--;
94 			b = &f->box[nb];
95 		}
96 		_fradvance(f, &pt, &f->box[nb]);
97 	}
98 	for(; nb<f->nbox; nb++){
99 		b = &f->box[nb];
100 		_frcklinewrap(f, &pt, b);
101 		_fradvance(f, &pt, &f->box[nb]);
102 	}
103 	f->lastlinefull = 0;
104 	if(pt.y >= f->r.max.y)
105 		f->lastlinefull = 1;
106 }
107