diff options
Diffstat (limited to 'libtk')
| -rw-r--r-- | libtk/image.c | 18 | ||||
| -rw-r--r-- | libtk/label.c | 22 | ||||
| -rw-r--r-- | libtk/label.h | 2 | ||||
| -rw-r--r-- | libtk/utils.c | 196 |
4 files changed, 169 insertions, 69 deletions
diff --git a/libtk/image.c b/libtk/image.c index 3b256eb3..cfd5f150 100644 --- a/libtk/image.c +++ b/libtk/image.c @@ -227,7 +227,6 @@ tkimage(TkTop *t, char *arg, char **ret) TkImg *tkim; char *fmt, *e, *buf, *cmd; - /* Note - could actually allocate buf and cmd in one buffer - DBK */ buf = mallocz(Tkmaxitem, 0); if(buf == nil) return TkNomem; @@ -318,14 +317,14 @@ tkimgput(TkImg *tki) } TkImg* -tkauximage(TkTop *t, char* s, uchar* bytes, int nbytes, int chans, Rectangle r, int repl) +tkauximage(TkTop *t, char* s, TkMemimage *m, int repl) { TkName *name; TkCtxt *c; TkImg *tki; Display *d; Image *i; - int locked; + int locked, nbytes; tki = tkname2img(t, s); if (tki != nil) { @@ -336,7 +335,7 @@ tkauximage(TkTop *t, char* s, uchar* bytes, int nbytes, int chans, Rectangle r, name = tkmkname(s); if (name == nil) return nil; - tki = mallocz(sizeof(*tki), 0); + tki = mallocz(sizeof(*tki), 1); if (tki == nil) goto err; tki->env = tkdefaultenv(t); @@ -346,15 +345,16 @@ tkauximage(TkTop *t, char* s, uchar* bytes, int nbytes, int chans, Rectangle r, c = t->ctxt; d = c->display; + nbytes = bytesperline(m->r, chantodepth(m->chans))*Dy(m->r); locked = lockdisplay(d); - i = allocimage(d, r, chans, repl, DTransparent); + i = allocimage(d, m->r, m->chans, repl, DTransparent); if (i != nil) { - if (loadimage(i, r, bytes, nbytes) != nbytes) { + if (loadimage(i, m->r, m->data, nbytes) != nbytes) { freeimage(i); i = nil; } if (repl) - replclipr(i, 1, huger); + replclipr(i, 1, huger); /* TO DO: doesn't allocimage do this? */ } if (locked) unlockdisplay(d); @@ -363,8 +363,8 @@ tkauximage(TkTop *t, char* s, uchar* bytes, int nbytes, int chans, Rectangle r, tki->top = t; tki->ref = 2; /* t->imgs ref and the ref we are returning */ tki->type = 0; /* bitmap */ - tki->w = Dx(r); - tki->h = Dy(r); + tki->w = Dx(m->r); + tki->h = Dy(m->r); tki->img = i; tki->name = name; tki->link = t->imgs; diff --git a/libtk/label.c b/libtk/label.c index 79d6344a..63355266 100644 --- a/libtk/label.c +++ b/libtk/label.c @@ -128,19 +128,15 @@ tksizelabel(Tk *tk) if(tkl->img != nil) { w = tkl->img->w + 2*Bitpadx; h = tkl->img->h + 2*Bitpady; - } - else - if(tkl->bitmap != nil) { + } else if(tkl->bitmap != nil) { w = Dx(tkl->bitmap->r) + 2*Bitpadx; h = Dy(tkl->bitmap->r) + 2*Bitpady; - } - else - if(tkl->text != nil) { + } else if(tkl->text != nil) { p = tkstringsize(tk, tkl->text); w = p.x + 2*Textpadx; h = p.y + 2*Textpady; if(tkl->ul != -1 && tkl->ul > strlen(tkl->text)) - tkl->ul = -1; + tkl->ul = strlen(tkl->text); /* underline all */ tkl->textheight = p.y; } @@ -232,11 +228,7 @@ tktriangle(Point u, Image *i, TkEnv *e) p[1].y = u.y + CheckButton; p[2].x = u.x; p[2].y = u.y; - fillpoly(i, p, 3, ~0, tkgc(e, TkCbackgnddark), p[0]); - for(j = 0; j < 3; j++) - p[j].y -= 2; - - fillpoly(i, p, 3, ~0, tkgc(e, TkCbackgndlght), p[0]); + fillpoly(i, p, 3, ~0, tkgc(e, TkCforegnd), p[0]); } /* @@ -297,14 +289,12 @@ tkdrawlabel(Tk *tk, Point orig) dy = tk->act.height - tkl->h - tk->ipad.y; if((tkl->anchor & (Tknorth|Tksouth)) == 0) p.y += dy/2; - else - if(tkl->anchor & Tksouth) + else if(tkl->anchor & Tksouth) p.y += dy; if((tkl->anchor & (Tkeast|Tkwest)) == 0) p.x += dx/2; - else - if(tkl->anchor & Tkeast) + else if(tkl->anchor & Tkeast) p.x += dx; switch(tk->type) { diff --git a/libtk/label.h b/libtk/label.h index da820c39..6541a10b 100644 --- a/libtk/label.h +++ b/libtk/label.h @@ -54,8 +54,6 @@ extern TkOption tkradopts[]; extern TkOption tkcbopts[]; /* label.c */ -extern char* tklabelsaverelief(Tk*, char*, char**); -extern char* tklabelrestorerelief(Tk*, char*, char**); extern void tksizelabel(Tk*); extern char* tkdrawlabel(Tk*, Point); extern void tkfreelabel(Tk*); diff --git a/libtk/utils.c b/libtk/utils.c index 635bef9a..00dd9d90 100644 --- a/libtk/utils.c +++ b/libtk/utils.c @@ -2,6 +2,14 @@ #include "draw.h" #include "tk.h" +struct TkCol +{ + ulong rgba1; + ulong rgba3; /* if mixed, otherwise DNotacolor */ + Image* i; + TkCol* forw; +}; + extern void rptwakeup(void*, void*); extern void* rptproc(char*, int, void*, int (*)(void*), int (*)(void*,int), void (*)(void*)); @@ -119,6 +127,48 @@ tkrgbavals(ulong rgba, int *R, int *G, int *B, int *A) } } +static int +tkcachecol(TkCtxt *c, Image *i, ulong one, ulong three) +{ + TkCol *cc; + + cc = malloc(sizeof(*cc)); + if(cc == nil) + return 0; + cc->rgba1 = one; + cc->rgba3 = three; + cc->i = i; + cc->forw = c->chead; + c->chead = cc; + c->ncol++; + /* we'll do LRU management at some point */ + if(c->ncol > TkColcachesize){ + static int warn; + if(warn == 0){ + warn = 1; + print("tk: %d colours cached\n", TkColcachesize); + } + } + return 1; +} + +static Image* +tkfindcol(TkCtxt *c, ulong one, ulong three) +{ + TkCol *cc, **l; + + for(l = &c->chead; (cc = *l) != nil; l = &cc->forw) + if(cc->rgba1 == one && cc->rgba3 == three){ + /* move it up in the list */ + *l = cc->forw; + cc->forw = c->chead; + c->chead = cc; + /* we assume it will be used right away and not stored */ + return cc->i; + } + return nil; +} + void tkfreecolcache(TkCtxt *c) { @@ -136,27 +186,40 @@ tkfreecolcache(TkCtxt *c) } Image* +tkcolormix(TkCtxt *c, ulong one, ulong three) +{ + Image *i; + Display *d; + + i = tkfindcol(c, one, three); + if(i != nil) + return i; + d = c->display; + i = allocimagemix(d, one, three); + if(i == nil) + return d->black; + if(!tkcachecol(c, i, one, three)){ + freeimage(i); + return d->black; + } + return i; +} + +Image* tkcolor(TkCtxt *c, ulong pix) { Image *i; - TkCol *cc, **l; Display *d; Rectangle r; - for(l = &c->chead; (cc = *l) != nil; l = &cc->forw) - if(cc->rgba == pix){ - /* move it up in the list */ - *l = cc->forw; - cc->forw = c->chead; - c->chead = cc; - /* we assume it will be used right away and not stored */ - return cc->i; - } d = c->display; if(pix == DWhite) return d->white; if(pix == DBlack) return d->black; + i = tkfindcol(c, pix, DNotacolor); + if(i != nil) + return i; r.min = ZP; r.max.x = 1; r.max.y = 1; @@ -166,24 +229,65 @@ tkcolor(TkCtxt *c, ulong pix) i = allocimage(d, r, RGBA32, 1, pix); if(i == nil) return d->black; - cc = malloc(sizeof(*cc)); - if(cc == nil){ + if(!tkcachecol(c, i, pix, DNotacolor)) { freeimage(i); return d->black; } - cc->rgba = pix; - cc->i = i; - cc->forw = c->chead; - c->chead = cc; - c->ncol++; - /* we'll do LRU management at some point */ - if(c->ncol > TkColcachesize){ - static int warn; - if(warn == 0){ - warn = 1; - print("tk: %d colours cached\n", TkColcachesize); - } - } + return i; +} + +Image* +tkgradient(TkCtxt *c, Rectangle r, int dir, ulong pix0, ulong pix1) +{ + Display *d; + Image *i; + uchar *b, *p, *e; + int c0[3], c1[3], delta[3], a, j, x, y, n, locked; + Rectangle s; + + d = c->display; + y = Dy(r); + x = Dx(r); + if(x <= 0 || y <= 0) + return d->black; + /* TO DO: diagonal */ + s = r; + if(dir == Tkhorizontal){ + n = x; + r.max.y = r.min.y+1; + }else{ + n = y; + r.max.x = r.min.x+1; + } + b = mallocz(3*n, 0); + if(b == nil) + return d->black; + locked = lockdisplay(d); + i = allocimage(d, r, RGB24, 1, DNofill); + if(i == nil) + goto Ret; + tkrgbavals(pix0, &c0[2], &c0[1], &c0[0], &a); + tkrgbavals(pix1, &c1[2], &c1[1], &c1[0], &a); + for(j = 0; j < 3; j++){ + c0[j] <<= 12; + c1[j] <<= 12; + delta[j] = ((c1[j]-c0[j])+(1<<11))/n; + } + e = b+3*n; + for(p = b; p < e; p += 3) { + p[0] = c0[0]>>12; + p[1] = c0[1]>>12; + p[2] = c0[2]>>12; + c0[0] += delta[0]; + c0[1] += delta[1]; + c0[2] += delta[2]; + } + loadimage(i, r, b, 3*n); + replclipr(i, 1, s); +Ret: + if(locked) + unlockdisplay(d); + free(b); return i; } @@ -816,7 +920,20 @@ tkstringsize(Tk *tk, char *text) return p; } -static char* +static void +tkulall(Image *i, Point o, Image *col, Font *f, char *text) +{ + Rectangle r; + + r.max = stringsize(f, text); + r.max = addpt(r.max, o); + r.min.x = o.x; + r.min.y = r.max.y - 1; + r.max.y += 1; + draw(i, r, col, nil, ZP); +} + +static void tkul(Image *i, Point o, Image *col, int ul, Font *f, char *text) { char c, *v; @@ -833,8 +950,6 @@ tkul(Image *i, Point o, Image *col, int ul, Font *f, char *text) r.min.y = r.max.y - 1; r.max.y += 2; draw(i, r, col, nil, ZP); - - return nil; } char* @@ -880,14 +995,13 @@ tkdrawstring(Tk *tk, Image *i, Point o, char *text, int ul, Image *col, int j) if(ul >= 0) { n = strlen(text); if(ul < n) { - char *r; - - r = tkul(i, o, col, ul, e->font, text); - if(r != nil) - return r; + tkul(i, o, col, ul, e->font, text); ul = -1; - } - ul -= n; + } else if(ul == n) { + tkulall(i, o, col, e->font, text); + ul = -1; + } else + ul -= n; } o.y += e->font->height; if(q == nil) @@ -1216,14 +1330,12 @@ tkanchorpoint(Rectangle r, Point size, int anchor) dy = Dy(r) - size.y; if((anchor & (Tknorth|Tksouth)) == 0) p.y += dy/2; - else - if(anchor & Tksouth) + else if(anchor & Tksouth) p.y += dy; if((anchor & (Tkeast|Tkwest)) == 0) p.x += dx/2; - else - if(anchor & Tkeast) + else if(anchor & Tkeast) p.x += dx; return p; } @@ -1779,12 +1891,12 @@ tkinsidepoly(Point *poly, int np, int winding, Point p) hit = 0; j = np - 1; - for (i = 0; i < np; j = i++) { + for(i = 0; i < np; j = i++) { pi = poly[i]; pj = poly[j]; - if ((pi.y <= p.y && p.y < pj.y || pj.y <= p.y && p.y < pi.y) && + if((pi.y <= p.y && p.y < pj.y || pj.y <= p.y && p.y < pi.y) && p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x) { - if (winding == 1 || pi.y > p.y) + if(winding == 1 || pi.y > p.y) hit++; else hit--; |
