ref: ea993877a96cd535199d0cd437e49f8d616615d9
dir: /sys/src/libframe/frutil.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <thread.h> #include <mouse.h> #include <frame.h> int _frcanfit(Frame *f, Point pt, Frbox *b) { int left, w, nr; uchar *p; Rune r; left = f->r.max.x-pt.x; if(b->nrune < 0) return b->minwid <= left; if(left >= b->wid) return b->nrune; for(nr=0,p=b->ptr; *p; p+=w,nr++){ r = *p; if(r < Runeself) w = 1; else w = chartorune(&r, (char*)p); left -= stringnwidth(f->font, (char*)p, 1); if(left < 0) break; } return nr; } void _frcklinewrap(Frame *f, Point *p, Frbox *b) { if((b->nrune<0? b->minwid : b->wid) > f->r.max.x-p->x){ p->x = f->r.min.x; p->y += f->font->height; } } void _frcklinewrap0(Frame *f, Point *p, Frbox *b) { if(_frcanfit(f, *p, b) == 0){ p->x = f->r.min.x; p->y += f->font->height; } } void _fradvance(Frame *f, Point *p, Frbox *b) { if(b->nrune<0 && b->bc=='\n'){ p->x = f->r.min.x; p->y += f->font->height; }else p->x += b->wid; } int _frnewwid(Frame *f, Point pt, Frbox *b) { b->wid = _frnewwid0(f, pt, b); return b->wid; } int _frnewwid0(Frame *f, Point pt, Frbox *b) { int c, x; c = f->r.max.x; x = pt.x; if(b->nrune>=0 || b->bc!='\t') return b->wid; if(x+b->minwid > c) x = pt.x = f->r.min.x; x += f->maxtab; x -= (x-f->r.min.x)%f->maxtab; if(x-pt.x<b->minwid || x>c) x = pt.x+b->minwid; return x-pt.x; } void _frclean(Frame *f, Point pt, int n0, int n1) /* look for mergeable boxes */ { Frbox *b; int nb, c; c = f->r.max.x; for(nb=n0; nb<n1-1; nb++){ b = &f->box[nb]; _frcklinewrap(f, &pt, b); while(b[0].nrune>=0 && nb<n1-1 && b[1].nrune>=0 && pt.x+b[0].wid+b[1].wid<c){ _frmergebox(f, nb); n1--; b = &f->box[nb]; } _fradvance(f, &pt, &f->box[nb]); } for(; nb<f->nbox; nb++){ b = &f->box[nb]; _frcklinewrap(f, &pt, b); _fradvance(f, &pt, &f->box[nb]); } f->lastlinefull = 0; if(pt.y >= f->r.max.y) f->lastlinefull = 1; }