1302 lines · 21.2 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <bio.h>#include <draw.h>#include <memdraw.h>#include <thread.h>#include <cursor.h>#include <mouse.h>#include <keyboard.h>#include <frame.h>#include <plumb.h>#include <html.h>#include <regexp.h>#include "dat.h"#include "fns.h" static	Point		prevmouse;static	Window	*mousew; intmin(int a, int b){	if(a < b)		return a;	return b;} intmax(int a, int b){	if(a > b)		return a;	return b;} voidcvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls){	uchar *q;	Rune *s;	int j, w; 	/*	 * Always guaranteed that n bytes may be interpreted	 * without worrying about partial runes.  This may mean	 * reading up to UTFmax-1 more bytes than n; the caller	 * knows this.  If n is a firm limit, the caller should	 * set p[n] = 0.	 */	q = (uchar*)p;	s = r;	for(j=0; j<n; j+=w){		if(*q < Runeself){			w = 1;			*s = *q++;		}else{			w = chartorune(s, (char*)q);			q += w;		}		if(*s)			s++;		else if(nulls)			*nulls = TRUE;	}	*nb = (char*)q-p;	*nr = s-r;} voidbytetorunestr(char *s, Runestr *rs){	Rune *r;	int nb, nr; 	nb = strlen(s);	r = runemalloc(nb+1);	cvttorunes(s, nb, r, &nb, &nr, nil);	r[nr] = '\0';	rs->nr = nr;	rs->r = r;} voiderror(char *s){	fprint(2, "abaco: %s: %r\n", s);//	abort();	threadexitsall(s);} void*emalloc(ulong n){	void *p; 	p = malloc(n);	if(p == nil)		error("malloc failed");	setmalloctag(p, getcallerpc(&n));	memset(p, 0, n);	return p;} void*erealloc(void *p, ulong n){	p = realloc(p, n);	if(p == nil)		error("realloc failed");	setmalloctag(p, getcallerpc(&n));	return p;} Rune*erunestrdup(Rune *r){	void *p; 	if(r == nil)		return nil;	p = runestrdup(r);	if(p == nil)		error("runestrdup failed");	setmalloctag(p, getcallerpc(&r));	return p;} char*estrdup(char *s){	char *t; 	t = strdup(s);	if(t == nil)		error("strdup failed");	setmalloctag(t, getcallerpc(&s));	return t;} intrunestreq(Runestr a, Runestr b){	return runeeq(a.r, a.nr, b.r, b.nr);} intruneeq(Rune *s1, uint n1, Rune *s2, uint n2){	if(n1 != n2)		return FALSE;	return memcmp(s1, s2, n1*sizeof(Rune)) == 0;} voidcloserunestr(Runestr *rs){ 	rs->nr = 0;	if(rs->r)		free(rs->r);	rs->r = nil;} voidcopyrunestr(Runestr *a, Runestr *b){	closerunestr(a);	a->r = runemalloc(b->nr+1);	runemove(a->r, b->r, b->nr);	a->r[b->nr] = 0;	a->nr = b->nr;} intisalnum(Rune c){	/*	 * Hard to get absolutely right.  Use what we know about ASCII	 * and assume anything above the Latin control characters is	 * potentially an alphanumeric.	 */	if(c <= ' ')		return FALSE;	if(0x7F<=c && c<=0xA0)		return FALSE;	if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))		return FALSE;	return TRUE;} Rune*skipbl(Rune *r, int n, int *np){	while(n>0 && (*r==' ' || *r=='\t' || *r=='\n')){		--n;		r++;	}	*np = n;	return r;} Rune*findbl(Rune *r, int n, int *np){	while(n>0 && *r!=' ' && *r!='\t' && *r!='\n'){		--n;		r++;	}	*np = n;	return r;} intistextfield(Item *i){	Formfield *ff; 	ff = ((Iformfield *)i)->formfield;	if(ff->ftype==Ftext || ff->ftype==Ftextarea || ff->ftype==Fpassword)		return TRUE; 	return FALSE;} intforceitem(Item *i){	if(i->state&IFwrap && i->tag!=Iruletag && i->tag!=Itabletag)		return FALSE; 	return TRUE;} intdimwidth(Dimen d, int w){	int s, k; 	k = dimenkind(d);	if(k == Dnone)		return w;	s = dimenspec(d);	if(k == Dpixels)		 w = s;	else if(k==Dpercent && s<100)		w = s*w/100; 	return w;} voidfrdims(Dimen *d, int n, int t, int **ret){	int totpix, totpcnt, totrel;	double spix, spcnt, relu, vd;	int tt, trest, totpixrel, minrelu, i;	int *x, *spec, *kind; 	if(n == 1){		*ret = x = emalloc(sizeof(int));		x[0] = t;		return;	}	totpix = totpcnt = totrel = 0;	spec = emalloc(n*sizeof(int));	kind = emalloc(n*sizeof(int));	for(i=0; i<n; i++){		spec[i] = dimenspec(d[i]);		if(spec[i] < 0)			spec[i] = 0;		kind[i] = dimenkind(d[i]);		switch(kind[i]){		case Dpixels:			totpix += spec[i];			break;		case Dpercent:			totpcnt += spec[i];			break;		case Drelative:			totrel += spec[i];			break;		case Dnone:			totrel++;			break;		}	}	spix = spcnt = 1.0;	minrelu = 0;	if(totrel > 0)		minrelu = Scrollsize+Scrollgap;	relu = (double)minrelu;	tt = totpix + t*totpcnt/100 + totrel*minrelu;	if(tt < t){		if(totrel == 0){			if(totpcnt != 0)				spcnt = (double)((t-totpix)*100)/(double)(t*totpcnt);			else				spix = (double)t/(double)totpix;		}else			relu += (double)(t-tt)/(double)totrel;	}else{		totpixrel = totpix + totrel*minrelu;		if(totpixrel < t)			spcnt = (double)((t-totpixrel)*100)/(double)(t*totpcnt);		else{			trest = t - totrel*minrelu;			if(trest > 0)				spcnt = (double)trest/(double)(totpix + (t*totpcnt/100));			else{				spcnt = (double)t/(double)tt;				relu = 0.0;			}			spix = spcnt;		}	}	x = emalloc(n * sizeof(int));	tt = 0;	for(i=0; i<n-1; i++){		vd = (double)spec[i];		switch(kind[i]){		case Dpixels:			vd = vd*spix;			break;		case Dpercent:			vd = vd*(double)t*spcnt/100.0;			break;		case Drelative:			vd = vd*relu;			break;		case Dnone:			vd = relu;			break;		}		x[i] = (int)(vd+.5);		tt += x[i];	}	x[n - 1] = t - tt;	*ret = x;	free(spec);	free(kind);} Image *getbg(Page *p){	Docinfo *d;	Cimage *ci;	Image *bg; 	d = p->doc;	if(d->backgrounditem){		if(d->backgrounditem->aux){			ci = d->backgrounditem->aux;			if(ci->mi)				getimage(ci, d->backgrounditem->altrep);			bg = ci->i;		}else			bg = display->white;	}else		bg = getcolor(d->background.color); 	return bg;} Rune *getbase(Page *p){	if(p->doc)		return p->doc->base;	if(p->url->act.r)		return p->url->act.r;	return p->url->src.r;} Image *eallocimage(Display *d, Rectangle r, ulong chan, int repl, int col){	Image *i; 	i = allocimage(d, r, chan, repl, col);	if(i == nil)		error("allocimage failed");	return i;} voidrect3d(Image *im, Rectangle r, int i, Image **c, Point sp){	Point p[6]; 	if(i < 0){		r = insetrect(r, i);		sp = addpt(sp, Pt(i,i));		i = -i;	}	draw(im, Rect(r.min.x+i, r.min.y+i, r.max.x-i, r.max.y-i), c[2], nil, sp);	p[0] = r.min;	p[1] = Pt(r.min.x, r.max.y);	p[2] = Pt(r.min.x+i, r.max.y-i);	p[3] = Pt(r.min.x+i, r.min.y+i);	p[4] = Pt(r.max.x-i, r.min.y+i);	p[5] = Pt(r.max.x, r.min.y);	fillpoly(im, p, 6, 0, c[0], sp);	p[0] = r.max;	p[1] = Pt(r.min.x, r.max.y);	p[2] = Pt(r.min.x+i, r.max.y-i);	p[3] = Pt(r.max.x-i, r.max.y-i);	p[4] = Pt(r.max.x-i, r.min.y+i);	p[5] = Pt(r.max.x, r.min.y);	fillpoly(im, p, 6, 0, c[1], sp);} voidellipse3d(Image *im, Point p, int rad, int i, Image **c, Point sp){	fillarc(im, p, rad, rad, c[0], sp, 45, 180);	fillarc(im, p, rad, rad, c[1], sp,  45, -180);	fillellipse(im, p, rad-i, rad-i, c[2], sp);} voidcolarray(Image **c, Image *c0, Image *c1, Image *c2, int checked){	if(checked){		c[0] = c0;		c[1] = c1;	}else{		c[0] = c1;		c[1] = c0;	}	c[2] = c2;} static char *deffontpaths[] = {#include "fonts.h"}; static char *fontpaths[NumFnt];static Font *fonts[NumFnt]; voidinitfontpaths(void){	Biobufhdr *bp;	char buf[128];	int i; 	/* we don't care if getenv(2) fails */	snprint(buf, sizeof(buf)-1, "%s/lib/abaco.fonts", getenv("home"));	if((bp=Bopen(buf, OREAD)) == nil)		goto Default; 	for(i=0; i<NumFnt; i++)		if((fontpaths[i]=Brdstr(bp, '\n', 1)) == nil)			goto Error; 	Bterm(bp);	return;Error:	fprint(2, "abaco: not enough fontpaths in '%s'\n", buf);	Bterm(bp);	for(i--; i>=0; i--)		free(fontpaths[i]);Default:	for(i=0; i<NumFnt; i++)		fontpaths[i] = deffontpaths[i];} Font *getfont(int i){	if(fonts[i] == nil){		fonts[i] = openfont(display, fontpaths[i]);		if(fonts[i] == nil)			error("can't open font file");	}	return fonts[i];} typedef struct Color Color; struct Color {	int	rgb;	Image	*i;	Color	*next;}; enum {	NHASH = 19,}; 

Lines 1–500 of 1302.