#include #include #include #include #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) return nr; } drawerror(f->display, "_frcanfit can't"); return 0; } 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; }