/* * 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. Load more
/* * 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; int min(int a, int b) { if(a < b) return a; return b; } int max(int a, int b) { if(a > b) return a; return b; } void cvttorunes(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; } void bytetorunestr(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; } void error(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; } int runestreq(Runestr a, Runestr b) { return runeeq(a.r, a.nr, b.r, b.nr); } int runeeq(Rune *s1, uint n1, Rune *s2, uint n2) { if(n1 != n2) return FALSE; return memcmp(s1, s2, n1*sizeof(Rune)) == 0; } void closerunestr(Runestr *rs) { rs->nr = 0; if(rs->r) free(rs->r); rs->r = nil; } void copyrunestr(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; } int isalnum(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; } int istextfield(Item *i) { Formfield *ff; ff = ((Iformfield *)i)->formfield; if(ff->ftype==Ftext || ff->ftype==Ftextarea || ff->ftype==Fpassword) return TRUE; return FALSE; } int forceitem(Item *i) { if(i->state&IFwrap && i->tag!=Iruletag && i->tag!=Itabletag) return FALSE; return TRUE; } int dimwidth(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; } void frdims(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; } void rect3d(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); } void ellipse3d(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); } void colarray(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]; void initfontpaths(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, };