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