diff options
author | rsc <devnull@localhost> | 2003-09-30 17:47:43 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2003-09-30 17:47:43 +0000 |
commit | b822e0d8035e1c80b86d974e63bd10936a96ed2d (patch) | |
tree | e213ab32233fa820bc9ce8a043b8b44173377f4b /src/libframe/frdraw.c | |
parent | b5990708483a1fa452b3d4b6ed2bfa998deeeb39 (diff) | |
download | plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.tar.gz plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.tar.bz2 plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.zip |
Initial revision
Diffstat (limited to 'src/libframe/frdraw.c')
-rw-r--r-- | src/libframe/frdraw.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/libframe/frdraw.c b/src/libframe/frdraw.c new file mode 100644 index 00000000..29c3daff --- /dev/null +++ b/src/libframe/frdraw.c @@ -0,0 +1,176 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <mouse.h> +#include <frame.h> + +void +_frredraw(Frame *f, Point pt) +{ + Frbox *b; + int nb; + /* static int x; */ + + for(nb=0,b=f->box; nb<f->nbox; nb++, b++){ + _frcklinewrap(f, &pt, b); + if(b->nrune >= 0){ + string(f->b, pt, f->cols[TEXT], ZP, f->font, (char *)b->ptr); + } + pt.x += b->wid; + } +} + +static int +nbytes(char *s0, int nr) +{ + char *s; + Rune r; + + s = s0; + while(--nr >= 0) + s += chartorune(&r, s); + return s-s0; +} + +void +frdrawsel(Frame *f, Point pt, ulong p0, ulong p1, int issel) +{ + Image *back, *text; + + if(f->ticked) + frtick(f, frptofchar(f, f->p0), 0); + + if(p0 == p1){ + frtick(f, pt, issel); + return; + } + + if(issel){ + back = f->cols[HIGH]; + text = f->cols[HTEXT]; + }else{ + back = f->cols[BACK]; + text = f->cols[TEXT]; + } + + frdrawsel0(f, pt, p0, p1, back, text); +} + +void +frdrawsel0(Frame *f, Point pt, ulong p0, ulong p1, Image *back, Image *text) +{ + Frbox *b; + int nb, nr, w, x, trim; + Point qt; + uint p; + char *ptr; + + p = 0; + b = f->box; + trim = 0; + for(nb=0; nb<f->nbox && p<p1; nb++){ + nr = b->nrune; + if(nr < 0) + nr = 1; + if(p+nr <= p0) + goto Continue; + if(p >= p0){ + qt = pt; + _frcklinewrap(f, &pt, b); + if(pt.y > qt.y) + draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt); + } + ptr = (char*)b->ptr; + if(p < p0){ /* beginning of region: advance into box */ + ptr += nbytes(ptr, p0-p); + nr -= (p0-p); + p = p0; + } + trim = 0; + if(p+nr > p1){ /* end of region: trim box */ + nr -= (p+nr)-p1; + trim = 1; + } + if(b->nrune<0 || nr==b->nrune) + w = b->wid; + else + w = stringnwidth(f->font, ptr, nr); + x = pt.x+w; + if(x > f->r.max.x) + x = f->r.max.x; + draw(f->b, Rect(pt.x, pt.y, x, pt.y+f->font->height), back, nil, pt); + if(b->nrune >= 0) + stringn(f->b, pt, text, ZP, f->font, ptr, nr); + pt.x += w; + Continue: + b++; + p += nr; + } + /* if this is end of last plain text box on wrapped line, fill to end of line */ + if(p1>p0 && b>f->box && b<f->box+f->nbox && b[-1].nrune>0 && !trim){ + qt = pt; + _frcklinewrap(f, &pt, b); + if(pt.y > qt.y) + draw(f->b, Rect(qt.x, qt.y, f->r.max.x, pt.y), back, nil, qt); + } +} + +void +frtick(Frame *f, Point pt, int ticked) +{ + Rectangle r; + + if(f->ticked==ticked || f->tick==0 || !ptinrect(pt, f->r)) + return; + pt.x--; /* looks best just left of where requested */ + r = Rect(pt.x, pt.y, pt.x+FRTICKW, pt.y+f->font->height); + if(ticked){ + draw(f->tickback, f->tickback->r, f->b, nil, pt); + draw(f->b, r, f->tick, nil, ZP); + }else + draw(f->b, r, f->tickback, nil, ZP); + f->ticked = ticked; +} + +Point +_frdraw(Frame *f, Point pt) +{ + Frbox *b; + int nb, n; + + for(b=f->box,nb=0; nb<f->nbox; nb++, b++){ + _frcklinewrap0(f, &pt, b); + if(pt.y == f->r.max.y){ + f->nchars -= _frstrlen(f, nb); + _frdelbox(f, nb, f->nbox-1); + break; + } + if(b->nrune > 0){ + n = _frcanfit(f, pt, b); + if(n == 0) + drawerror(f->display, "draw: _frcanfit==0"); + if(n != b->nrune){ + _frsplitbox(f, nb, n); + b = &f->box[nb]; + } + pt.x += b->wid; + }else{ + if(b->bc == '\n'){ + pt.x = f->r.min.x; + pt.y+=f->font->height; + }else + pt.x += _frnewwid(f, pt, b); + } + } + return pt; +} + +int +_frstrlen(Frame *f, int nb) +{ + int n; + + for(n=0; nb<f->nbox; nb++) + n += NRUNE(&f->box[nb]); + return n; +} |