summaryrefslogtreecommitdiff
path: root/libtk
diff options
context:
space:
mode:
Diffstat (limited to 'libtk')
-rw-r--r--libtk/image.c18
-rw-r--r--libtk/label.c22
-rw-r--r--libtk/label.h2
-rw-r--r--libtk/utils.c196
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--;