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 | |
parent | b5990708483a1fa452b3d4b6ed2bfa998deeeb39 (diff) | |
download | plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.tar.gz plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.tar.bz2 plan9port-b822e0d8035e1c80b86d974e63bd10936a96ed2d.zip |
Initial revision
Diffstat (limited to 'src/libframe')
-rw-r--r-- | src/libframe/Makefile | 92 | ||||
-rw-r--r-- | src/libframe/Makefile.MID | 21 | ||||
-rw-r--r-- | src/libframe/frbox.c | 156 | ||||
-rw-r--r-- | src/libframe/frdraw.c | 176 | ||||
-rw-r--r-- | src/libframe/mkfile | 1 |
5 files changed, 446 insertions, 0 deletions
diff --git a/src/libframe/Makefile b/src/libframe/Makefile new file mode 100644 index 00000000..81b73e98 --- /dev/null +++ b/src/libframe/Makefile @@ -0,0 +1,92 @@ + +# this works in gnu make +SYSNAME:=${shell uname} +OBJTYPE:=${shell uname -m | sed 's;i.86;386;; s;/.*;;; s; ;;g'} + +# this works in bsd make +SYSNAME!=uname +OBJTYPE!=uname -m | sed 's;i.86;386;; s;/.*;;; s; ;;g' + +# the gnu rules will mess up bsd but not vice versa, +# hence the gnu rules come first. + +include Make.$(SYSNAME)-$(OBJTYPE) + +PREFIX=/usr/local + +NUKEFILES= + +TGZFILES= + +LIB=libframe.a +VERSION=2.0 +PORTPLACE=devel/libframe +NAME=libdraw + +OFILES=\ + frbox.$O\ + frdelete.$O\ + frdraw.$O\ + frinit.$O\ + frinsert.$O\ + frptofchar.$O\ + frselect.$O\ + frstr.$O\ + frutil.$O\ + +all: $(LIB) + +install: $(LIB) + install -c -m 0644 $(LIB) $(PREFIX)/lib/$(LIB) + install -c -m 0644 frame.h $(PREFIX)/include/frame.h +$(LIB): $(OFILES) + $(AR) $(ARFLAGS) $(LIB) $(OFILES) + +NUKEFILES+=$(LIB) +.c.$O: + $(CC) $(CFLAGS) -I/usr/X11R6/include -I$(PREFIX)/include $*.c + +%.$O: %.c + $(CC) $(CFLAGS) -I/usr/X11R6/include -I$(PREFIX)/include $*.c + + +$(OFILES): $(HFILES) + +tgz: + rm -rf $(NAME)-$(VERSION) + mkdir $(NAME)-$(VERSION) + cp Makefile Make.* README LICENSE NOTICE *.[ch137] rpm.spec bundle.ports $(TGZFILES) $(NAME)-$(VERSION) + tar cf - $(NAME)-$(VERSION) | gzip >$(NAME)-$(VERSION).tgz + rm -rf $(NAME)-$(VERSION) + +clean: + rm -f $(OFILES) $(LIB) + +nuke: + rm -f $(OFILES) *.tgz *.rpm $(NUKEFILES) + +rpm: + make tgz + cp $(NAME)-$(VERSION).tgz /usr/src/RPM/SOURCES + rpm -ba rpm.spec + cp /usr/src/RPM/SRPMS/$(NAME)-$(VERSION)-1.src.rpm . + cp /usr/src/RPM/RPMS/i586/$(NAME)-$(VERSION)-1.i586.rpm . + scp *.rpm rsc@amsterdam.lcs.mit.edu:public_html/software + +PORTDIR=/usr/ports/$(PORTPLACE) + +ports: + make tgz + rm -rf $(PORTDIR) + mkdir $(PORTDIR) + cp $(NAME)-$(VERSION).tgz /usr/ports/distfiles + cat bundle.ports | (cd $(PORTDIR) && awk '$$1=="---" && $$3=="---" { ofile=$$2; next} {if(ofile) print >ofile}') + (cd $(PORTDIR); make makesum) + (cd $(PORTDIR); make) + (cd $(PORTDIR); /usr/local/bin/portlint) + rm -rf $(PORTDIR)/work + shar `find $(PORTDIR)` > ports.shar + (cd $(PORTDIR); tar cf - *) | gzip >$(NAME)-$(VERSION)-ports.tgz + scp *.tgz rsc@amsterdam.lcs.mit.edu:public_html/software + +.phony: all clean nuke install tgz rpm ports diff --git a/src/libframe/Makefile.MID b/src/libframe/Makefile.MID new file mode 100644 index 00000000..f7d29ece --- /dev/null +++ b/src/libframe/Makefile.MID @@ -0,0 +1,21 @@ +LIB=libframe.a +VERSION=2.0 +PORTPLACE=devel/libframe +NAME=libdraw + +OFILES=\ + frbox.$O\ + frdelete.$O\ + frdraw.$O\ + frinit.$O\ + frinsert.$O\ + frptofchar.$O\ + frselect.$O\ + frstr.$O\ + frutil.$O\ + +all: $(LIB) + +install: $(LIB) + install -c -m 0644 $(LIB) $(PREFIX)/lib/$(LIB) + install -c -m 0644 frame.h $(PREFIX)/include/frame.h diff --git a/src/libframe/frbox.c b/src/libframe/frbox.c new file mode 100644 index 00000000..d2593011 --- /dev/null +++ b/src/libframe/frbox.c @@ -0,0 +1,156 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <mouse.h> +#include <frame.h> + +#define SLOP 25 + +void +_fraddbox(Frame *f, int bn, int n) /* add n boxes after bn, shift the rest up, + * box[bn+n]==box[bn] */ +{ + int i; + + if(bn > f->nbox) + drawerror(f->display, "_fraddbox"); + if(f->nbox+n > f->nalloc) + _frgrowbox(f, n+SLOP); + for(i=f->nbox; --i>=bn; ) + f->box[i+n] = f->box[i]; + f->nbox+=n; +} + +void +_frclosebox(Frame *f, int n0, int n1) /* inclusive */ +{ + int i; + + if(n0>=f->nbox || n1>=f->nbox || n1<n0) + drawerror(f->display, "_frclosebox"); + n1++; + for(i=n1; i<f->nbox; i++) + f->box[i-(n1-n0)] = f->box[i]; + f->nbox -= n1-n0; +} + +void +_frdelbox(Frame *f, int n0, int n1) /* inclusive */ +{ + if(n0>=f->nbox || n1>=f->nbox || n1<n0) + drawerror(f->display, "_frdelbox"); + _frfreebox(f, n0, n1); + _frclosebox(f, n0, n1); +} + +void +_frfreebox(Frame *f, int n0, int n1) /* inclusive */ +{ + int i; + + if(n1<n0) + return; + if(n0>=f->nbox || n1>=f->nbox) + drawerror(f->display, "_frfreebox"); + n1++; + for(i=n0; i<n1; i++) + if(f->box[i].nrune >= 0) + free(f->box[i].ptr); +} + +void +_frgrowbox(Frame *f, int delta) +{ + f->nalloc += delta; + f->box = realloc(f->box, f->nalloc*sizeof(Frbox)); + if(f->box == 0) + drawerror(f->display, "_frgrowbox"); +} + +static +void +dupbox(Frame *f, int bn) +{ + uchar *p; + + if(f->box[bn].nrune < 0) + drawerror(f->display, "dupbox"); + _fraddbox(f, bn, 1); + if(f->box[bn].nrune >= 0){ + p = _frallocstr(f, NBYTE(&f->box[bn])+1); + strcpy((char*)p, (char*)f->box[bn].ptr); + f->box[bn+1].ptr = p; + } +} + +static +uchar* +runeindex(uchar *p, int n) +{ + int i, w; + Rune rune; + + for(i=0; i<n; i++,p+=w) + if(*p < Runeself) + w = 1; + else{ + w = chartorune(&rune, (char*)p); + USED(rune); + } + return p; +} + +static +void +truncatebox(Frame *f, Frbox *b, int n) /* drop last n chars; no allocation done */ +{ + if(b->nrune<0 || b->nrune<n) + drawerror(f->display, "truncatebox"); + b->nrune -= n; + runeindex(b->ptr, b->nrune)[0] = 0; + b->wid = stringwidth(f->font, (char *)b->ptr); +} + +static +void +chopbox(Frame *f, Frbox *b, int n) /* drop first n chars; no allocation done */ +{ + if(b->nrune<0 || b->nrune<n) + drawerror(f->display, "chopbox"); + strcpy((char*)b->ptr, (char*)runeindex(b->ptr, n)); + b->nrune -= n; + b->wid = stringwidth(f->font, (char *)b->ptr); +} + +void +_frsplitbox(Frame *f, int bn, int n) +{ + dupbox(f, bn); + truncatebox(f, &f->box[bn], f->box[bn].nrune-n); + chopbox(f, &f->box[bn+1], n); +} + +void +_frmergebox(Frame *f, int bn) /* merge bn and bn+1 */ +{ + Frbox *b; + + b = &f->box[bn]; + _frinsure(f, bn, NBYTE(&b[0])+NBYTE(&b[1])+1); + strcpy((char*)runeindex(b[0].ptr, b[0].nrune), (char*)b[1].ptr); + b[0].wid += b[1].wid; + b[0].nrune += b[1].nrune; + _frdelbox(f, bn+1, bn+1); +} + +int +_frfindbox(Frame *f, int bn, ulong p, ulong q) /* find box containing q and put q on a box boundary */ +{ + Frbox *b; + + for(b = &f->box[bn]; bn<f->nbox && p+NRUNE(b)<=q; bn++, b++) + p += NRUNE(b); + if(p != q) + _frsplitbox(f, bn++, (int)(q-p)); + return bn; +} 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; +} diff --git a/src/libframe/mkfile b/src/libframe/mkfile new file mode 100644 index 00000000..bb99a25a --- /dev/null +++ b/src/libframe/mkfile @@ -0,0 +1 @@ +<../libutf/mkfile |