1 #include "lib9.h"
2 #include "draw.h"
3 #include "tk.h"
4 #include "canvs.h"
5
6 #define O(t, e) ((long)(&((t*)0)->e))
7
8 /* Bitmap Options (+ means implemented)
9 +anchor
10 +bitmap
11 */
12
13 typedef struct TkCbits TkCbits;
14 struct TkCbits
15 {
16 int anchor;
17 Point anchorp;
18 Image* bitmap;
19 };
20
21 static
22 TkOption bitopts[] =
23 {
24 "anchor", OPTstab, O(TkCbits, anchor), tkanchor,
25 "bitmap", OPTbmap, O(TkCbits, bitmap), nil,
26 nil
27 };
28
29 static
30 TkOption itemopts[] =
31 {
32 "tags", OPTctag, O(TkCitem, tags), nil,
33 "background", OPTcolr, O(TkCitem, env), IAUX(TkCbackgnd),
34 "foreground", OPTcolr, O(TkCitem, env), IAUX(TkCforegnd),
35 nil
36 };
37
38 void
tkcvsbitsize(TkCitem * i)39 tkcvsbitsize(TkCitem *i)
40 {
41 Point o;
42 int dx, dy;
43 TkCbits *b;
44
45 b = TKobj(TkCbits, i);
46 i->p.bb = bbnil;
47 if(b->bitmap == nil)
48 return;
49
50 dx = Dx(b->bitmap->r);
51 dy = Dy(b->bitmap->r);
52
53 o = tkcvsanchor(i->p.drawpt[0], dx, dy, b->anchor);
54
55 i->p.bb.min.x = o.x;
56 i->p.bb.min.y = o.y;
57 i->p.bb.max.x = o.x + dx;
58 i->p.bb.max.y = o.y + dy;
59 b->anchorp = subpt(o, i->p.drawpt[0]);
60 }
61
62 char*
tkcvsbitcreat(Tk * tk,char * arg,char ** val)63 tkcvsbitcreat(Tk* tk, char *arg, char **val)
64 {
65 char *e;
66 TkCbits *b;
67 TkCitem *i;
68 TkCanvas *c;
69 TkOptab tko[3];
70
71 c = TKobj(TkCanvas, tk);
72
73 i = tkcnewitem(tk, TkCVbitmap, sizeof(TkCitem)+sizeof(TkCbits));
74 if(i == nil)
75 return TkNomem;
76
77 b = TKobj(TkCbits, i);
78
79 e = tkparsepts(tk->env->top, &i->p, &arg, 0);
80 if(e != nil) {
81 tkcvsfreeitem(i);
82 return e;
83 }
84 if(i->p.npoint != 1) {
85 tkcvsfreeitem(i);
86 return TkFewpt;
87 }
88
89 tko[0].ptr = b;
90 tko[0].optab = bitopts;
91 tko[1].ptr = i;
92 tko[1].optab = itemopts;
93 tko[2].ptr = nil;
94 e = tkparse(tk->env->top, arg, tko, nil);
95 if(e != nil) {
96 tkcvsfreeitem(i);
97 return e;
98 }
99
100 e = tkcaddtag(tk, i, 1);
101 if(e != nil) {
102 tkcvsfreeitem(i);
103 return e;
104 }
105
106 tkcvsbitsize(i);
107 tkcvsappend(c, i);
108
109 tkbbmax(&c->update, &i->p.bb);
110 tkcvssetdirty(tk);
111 return tkvalue(val, "%d", i->id);
112 }
113
114 char*
tkcvsbitcget(TkCitem * i,char * arg,char ** val)115 tkcvsbitcget(TkCitem *i, char *arg, char **val)
116 {
117 TkOptab tko[3];
118 TkCbits *b = TKobj(TkCbits, i);
119
120 tko[0].ptr = b;
121 tko[0].optab = bitopts;
122 tko[1].ptr = i;
123 tko[1].optab = itemopts;
124 tko[2].ptr = nil;
125
126 return tkgencget(tko, arg, val, i->env->top);
127 }
128
129 char*
tkcvsbitconf(Tk * tk,TkCitem * i,char * arg)130 tkcvsbitconf(Tk *tk, TkCitem *i, char *arg)
131 {
132 char *e;
133 TkOptab tko[3];
134 TkCbits *b = TKobj(TkCbits, i);
135
136 tko[0].ptr = b;
137 tko[0].optab = bitopts;
138 tko[1].ptr = i;
139 tko[1].optab = itemopts;
140 tko[2].ptr = nil;
141
142 e = tkparse(tk->env->top, arg, tko, nil);
143 tkcvsbitsize(i);
144 return e;
145 }
146
147 void
tkcvsbitfree(TkCitem * i)148 tkcvsbitfree(TkCitem *i)
149 {
150 TkCbits *b;
151
152 b = TKobj(TkCbits, i);
153 if(b->bitmap)
154 freeimage(b->bitmap);
155 }
156
157 void
tkcvsbitdraw(Image * img,TkCitem * i,TkEnv * pe)158 tkcvsbitdraw(Image *img, TkCitem *i, TkEnv *pe)
159 {
160 TkEnv *e;
161 TkCbits *b;
162 Rectangle r;
163 Image *bi;
164
165 USED(pe);
166
167 e = i->env;
168 b = TKobj(TkCbits, i);
169
170 bi = b->bitmap;
171 if(bi == nil)
172 return;
173
174 r.min = addpt(b->anchorp, i->p.drawpt[0]);
175 r.max = r.min;
176 r.max.x += Dx(bi->r);
177 r.max.y += Dy(bi->r);
178
179 if(bi->depth != 1) {
180 draw(img, r, bi, nil, ZP);
181 return;
182 }
183 gendraw(img, r, tkgc(e, TkCbackgnd), r.min, nil, ZP);
184 draw(img, r, tkgc(e, TkCforegnd), bi, ZP);
185 }
186
187 char*
tkcvsbitcoord(TkCitem * i,char * arg,int x,int y)188 tkcvsbitcoord(TkCitem *i, char *arg, int x, int y)
189 {
190 char *e;
191 TkCpoints p;
192
193 if(arg == nil) {
194 tkxlatepts(i->p.parampt, i->p.npoint, x, y);
195 tkxlatepts(i->p.drawpt, i->p.npoint, TKF2I(x), TKF2I(y));
196 i->p.bb = rectaddpt(i->p.bb, Pt(TKF2I(x), TKF2I(y)));
197 }
198 else {
199 e = tkparsepts(i->env->top, &p, &arg, 0);
200 if(e != nil)
201 return e;
202 if(p.npoint != 1) {
203 tkfreepoint(&p);
204 return TkFewpt;
205 }
206 tkfreepoint(&i->p);
207 i->p = p;
208 tkcvsbitsize(i);
209 }
210 return nil;
211 }
212