Commit Diff


commit - b5990708483a1fa452b3d4b6ed2bfa998deeeb39
commit + b822e0d8035e1c80b86d974e63bd10936a96ed2d
blob - /dev/null
blob + 5d99bb5b727e39e7d26a7eca7558fa870c6adb58 (mode 755)
Binary files /dev/null and src/libdraw/test differ
blob - /dev/null
blob + 4cc55140af1e2dc409ac87c58e77def43cd97e2b (mode 644)
Binary files /dev/null and src/libdraw/test.core differ
blob - /dev/null
blob + 81b73e983741d8711fa2a338c6368103409be0c3 (mode 644)
--- /dev/null
+++ 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
blob - /dev/null
blob + f7d29ece6a7f64f8410f81bc9f5a400f23d8ab8f (mode 644)
--- /dev/null
+++ 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
blob - /dev/null
blob + d25930119c793488f4f66dbeb8c7d14767a12671 (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + 29c3daff242b3c1715acd86b76890bf4a3ae3960 (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + bb99a25ab4d41b82f60096fe078cf4374b5fa108 (mode 644)
--- /dev/null
+++ src/libframe/mkfile
@@ -0,0 +1 @@
+<../libutf/mkfile