1*37da2899SCharles.Forsyth #include <lib9.h>
2*37da2899SCharles.Forsyth #include <kernel.h>
3*37da2899SCharles.Forsyth #include "draw.h"
4*37da2899SCharles.Forsyth #include "tk.h"
5*37da2899SCharles.Forsyth #include "canvs.h"
6*37da2899SCharles.Forsyth
7*37da2899SCharles.Forsyth #define O(t, e) ((long)(&((t*)0)->e))
8*37da2899SCharles.Forsyth
9*37da2899SCharles.Forsyth /* Rectangle Options (+ means implemented)
10*37da2899SCharles.Forsyth +fill
11*37da2899SCharles.Forsyth +outline
12*37da2899SCharles.Forsyth +stipple
13*37da2899SCharles.Forsyth +tags
14*37da2899SCharles.Forsyth +width
15*37da2899SCharles.Forsyth */
16*37da2899SCharles.Forsyth
17*37da2899SCharles.Forsyth typedef struct TkCrect TkCrect;
18*37da2899SCharles.Forsyth struct TkCrect
19*37da2899SCharles.Forsyth {
20*37da2899SCharles.Forsyth int width;
21*37da2899SCharles.Forsyth Image* stipple;
22*37da2899SCharles.Forsyth };
23*37da2899SCharles.Forsyth
24*37da2899SCharles.Forsyth static
25*37da2899SCharles.Forsyth TkOption rectopts[] =
26*37da2899SCharles.Forsyth {
27*37da2899SCharles.Forsyth "width", OPTnnfrac, O(TkCrect, width), nil,
28*37da2899SCharles.Forsyth "stipple", OPTbmap, O(TkCrect, stipple), nil,
29*37da2899SCharles.Forsyth nil
30*37da2899SCharles.Forsyth };
31*37da2899SCharles.Forsyth
32*37da2899SCharles.Forsyth static
33*37da2899SCharles.Forsyth TkOption itemopts[] =
34*37da2899SCharles.Forsyth {
35*37da2899SCharles.Forsyth "tags", OPTctag, O(TkCitem, tags), nil,
36*37da2899SCharles.Forsyth "fill", OPTcolr, O(TkCitem, env), IAUX(TkCfill),
37*37da2899SCharles.Forsyth "outline", OPTcolr, O(TkCitem, env), IAUX(TkCforegnd),
38*37da2899SCharles.Forsyth nil
39*37da2899SCharles.Forsyth };
40*37da2899SCharles.Forsyth
41*37da2899SCharles.Forsyth void
tkcvsrectsize(TkCitem * i)42*37da2899SCharles.Forsyth tkcvsrectsize(TkCitem *i)
43*37da2899SCharles.Forsyth {
44*37da2899SCharles.Forsyth TkCrect *r;
45*37da2899SCharles.Forsyth int w;
46*37da2899SCharles.Forsyth
47*37da2899SCharles.Forsyth r = TKobj(TkCrect, i);
48*37da2899SCharles.Forsyth w = TKF2I(r->width)*2;
49*37da2899SCharles.Forsyth
50*37da2899SCharles.Forsyth i->p.bb = bbnil;
51*37da2899SCharles.Forsyth tkpolybound(i->p.drawpt, i->p.npoint, &i->p.bb);
52*37da2899SCharles.Forsyth i->p.bb = insetrect(i->p.bb, -w);
53*37da2899SCharles.Forsyth }
54*37da2899SCharles.Forsyth
55*37da2899SCharles.Forsyth static void
tkmkstipple(Image * stipple)56*37da2899SCharles.Forsyth tkmkstipple(Image *stipple)
57*37da2899SCharles.Forsyth {
58*37da2899SCharles.Forsyth int locked;
59*37da2899SCharles.Forsyth if (stipple != nil && !stipple->repl) {
60*37da2899SCharles.Forsyth locked = lockdisplay(stipple->display);
61*37da2899SCharles.Forsyth replclipr(stipple, 1, huger);
62*37da2899SCharles.Forsyth if (locked)
63*37da2899SCharles.Forsyth unlockdisplay(stipple->display);
64*37da2899SCharles.Forsyth }
65*37da2899SCharles.Forsyth }
66*37da2899SCharles.Forsyth
67*37da2899SCharles.Forsyth char*
tkcvsrectcreat(Tk * tk,char * arg,char ** val)68*37da2899SCharles.Forsyth tkcvsrectcreat(Tk* tk, char *arg, char **val)
69*37da2899SCharles.Forsyth {
70*37da2899SCharles.Forsyth char *e;
71*37da2899SCharles.Forsyth TkCrect *r;
72*37da2899SCharles.Forsyth TkCitem *i;
73*37da2899SCharles.Forsyth TkCanvas *c;
74*37da2899SCharles.Forsyth TkOptab tko[3];
75*37da2899SCharles.Forsyth
76*37da2899SCharles.Forsyth c = TKobj(TkCanvas, tk);
77*37da2899SCharles.Forsyth
78*37da2899SCharles.Forsyth i = tkcnewitem(tk, TkCVrect, sizeof(TkCitem)+sizeof(TkCrect));
79*37da2899SCharles.Forsyth if(i == nil)
80*37da2899SCharles.Forsyth return TkNomem;
81*37da2899SCharles.Forsyth
82*37da2899SCharles.Forsyth r = TKobj(TkCrect, i);
83*37da2899SCharles.Forsyth r->width = TKI2F(1);
84*37da2899SCharles.Forsyth
85*37da2899SCharles.Forsyth e = tkparsepts(tk->env->top, &i->p, &arg, 0);
86*37da2899SCharles.Forsyth if(e != nil) {
87*37da2899SCharles.Forsyth tkcvsfreeitem(i);
88*37da2899SCharles.Forsyth return e;
89*37da2899SCharles.Forsyth }
90*37da2899SCharles.Forsyth if(i->p.npoint != 2) {
91*37da2899SCharles.Forsyth tkcvsfreeitem(i);
92*37da2899SCharles.Forsyth return TkFewpt;
93*37da2899SCharles.Forsyth }
94*37da2899SCharles.Forsyth
95*37da2899SCharles.Forsyth tko[0].ptr = r;
96*37da2899SCharles.Forsyth tko[0].optab = rectopts;
97*37da2899SCharles.Forsyth tko[1].ptr = i;
98*37da2899SCharles.Forsyth tko[1].optab = itemopts;
99*37da2899SCharles.Forsyth tko[2].ptr = nil;
100*37da2899SCharles.Forsyth e = tkparse(tk->env->top, arg, tko, nil);
101*37da2899SCharles.Forsyth if(e != nil) {
102*37da2899SCharles.Forsyth tkcvsfreeitem(i);
103*37da2899SCharles.Forsyth return e;
104*37da2899SCharles.Forsyth }
105*37da2899SCharles.Forsyth tkmkstipple(r->stipple);
106*37da2899SCharles.Forsyth e = tkcaddtag(tk, i, 1);
107*37da2899SCharles.Forsyth if(e != nil) {
108*37da2899SCharles.Forsyth tkcvsfreeitem(i);
109*37da2899SCharles.Forsyth return e;
110*37da2899SCharles.Forsyth }
111*37da2899SCharles.Forsyth
112*37da2899SCharles.Forsyth tkcvsrectsize(i);
113*37da2899SCharles.Forsyth e = tkvalue(val, "%d", i->id);
114*37da2899SCharles.Forsyth if(e != nil) {
115*37da2899SCharles.Forsyth tkcvsfreeitem(i);
116*37da2899SCharles.Forsyth return e;
117*37da2899SCharles.Forsyth }
118*37da2899SCharles.Forsyth tkcvsappend(c, i);
119*37da2899SCharles.Forsyth
120*37da2899SCharles.Forsyth tkbbmax(&c->update, &i->p.bb);
121*37da2899SCharles.Forsyth tkcvssetdirty(tk);
122*37da2899SCharles.Forsyth return nil;
123*37da2899SCharles.Forsyth }
124*37da2899SCharles.Forsyth
125*37da2899SCharles.Forsyth char*
tkcvsrectcget(TkCitem * i,char * arg,char ** val)126*37da2899SCharles.Forsyth tkcvsrectcget(TkCitem *i, char *arg, char **val)
127*37da2899SCharles.Forsyth {
128*37da2899SCharles.Forsyth TkOptab tko[3];
129*37da2899SCharles.Forsyth TkCrect *r = TKobj(TkCrect, i);
130*37da2899SCharles.Forsyth
131*37da2899SCharles.Forsyth tko[0].ptr = r;
132*37da2899SCharles.Forsyth tko[0].optab = rectopts;
133*37da2899SCharles.Forsyth tko[1].ptr = i;
134*37da2899SCharles.Forsyth tko[1].optab = itemopts;
135*37da2899SCharles.Forsyth tko[2].ptr = nil;
136*37da2899SCharles.Forsyth
137*37da2899SCharles.Forsyth return tkgencget(tko, arg, val, i->env->top);
138*37da2899SCharles.Forsyth }
139*37da2899SCharles.Forsyth
140*37da2899SCharles.Forsyth char*
tkcvsrectconf(Tk * tk,TkCitem * i,char * arg)141*37da2899SCharles.Forsyth tkcvsrectconf(Tk *tk, TkCitem *i, char *arg)
142*37da2899SCharles.Forsyth {
143*37da2899SCharles.Forsyth char *e;
144*37da2899SCharles.Forsyth TkOptab tko[3];
145*37da2899SCharles.Forsyth TkCrect *r = TKobj(TkCrect, i);
146*37da2899SCharles.Forsyth
147*37da2899SCharles.Forsyth tko[0].ptr = r;
148*37da2899SCharles.Forsyth tko[0].optab = rectopts;
149*37da2899SCharles.Forsyth tko[1].ptr = i;
150*37da2899SCharles.Forsyth tko[1].optab = itemopts;
151*37da2899SCharles.Forsyth tko[2].ptr = nil;
152*37da2899SCharles.Forsyth
153*37da2899SCharles.Forsyth e = tkparse(tk->env->top, arg, tko, nil);
154*37da2899SCharles.Forsyth tkcvsrectsize(i);
155*37da2899SCharles.Forsyth tkmkstipple(r->stipple);
156*37da2899SCharles.Forsyth return e;
157*37da2899SCharles.Forsyth }
158*37da2899SCharles.Forsyth
159*37da2899SCharles.Forsyth void
tkcvsrectfree(TkCitem * i)160*37da2899SCharles.Forsyth tkcvsrectfree(TkCitem *i)
161*37da2899SCharles.Forsyth {
162*37da2899SCharles.Forsyth TkCrect *r;
163*37da2899SCharles.Forsyth
164*37da2899SCharles.Forsyth r = TKobj(TkCrect, i);
165*37da2899SCharles.Forsyth if(r->stipple)
166*37da2899SCharles.Forsyth freeimage(r->stipple);
167*37da2899SCharles.Forsyth }
168*37da2899SCharles.Forsyth
169*37da2899SCharles.Forsyth void
tkcvsrectdraw(Image * img,TkCitem * i,TkEnv * pe)170*37da2899SCharles.Forsyth tkcvsrectdraw(Image *img, TkCitem *i, TkEnv *pe)
171*37da2899SCharles.Forsyth {
172*37da2899SCharles.Forsyth int lw, rw;
173*37da2899SCharles.Forsyth TkEnv *e;
174*37da2899SCharles.Forsyth TkCrect *r;
175*37da2899SCharles.Forsyth Rectangle d, rr;
176*37da2899SCharles.Forsyth Point tr, bl;
177*37da2899SCharles.Forsyth Image *pen;
178*37da2899SCharles.Forsyth
179*37da2899SCharles.Forsyth USED(pe);
180*37da2899SCharles.Forsyth
181*37da2899SCharles.Forsyth d.min = i->p.drawpt[0];
182*37da2899SCharles.Forsyth d.max = i->p.drawpt[1];
183*37da2899SCharles.Forsyth
184*37da2899SCharles.Forsyth e = i->env;
185*37da2899SCharles.Forsyth r = TKobj(TkCrect, i);
186*37da2899SCharles.Forsyth
187*37da2899SCharles.Forsyth pen = nil;
188*37da2899SCharles.Forsyth if((e->set & (1<<TkCfill)))
189*37da2899SCharles.Forsyth pen = tkgc(e, TkCfill);
190*37da2899SCharles.Forsyth
191*37da2899SCharles.Forsyth if(pen != nil)
192*37da2899SCharles.Forsyth draw(img, d, pen, r->stipple, d.min);
193*37da2899SCharles.Forsyth
194*37da2899SCharles.Forsyth tr.x = d.max.x;
195*37da2899SCharles.Forsyth tr.y = d.min.y;
196*37da2899SCharles.Forsyth bl.x = d.min.x;
197*37da2899SCharles.Forsyth bl.y = d.max.y;
198*37da2899SCharles.Forsyth
199*37da2899SCharles.Forsyth rw = (TKF2I(r->width) + 1)/2;
200*37da2899SCharles.Forsyth if(rw <= 0)
201*37da2899SCharles.Forsyth return;
202*37da2899SCharles.Forsyth lw = (TKF2I(r->width))/2;
203*37da2899SCharles.Forsyth
204*37da2899SCharles.Forsyth pen = tkgc(e, TkCforegnd);
205*37da2899SCharles.Forsyth if(pen != nil) {
206*37da2899SCharles.Forsyth /* horizontal lines first */
207*37da2899SCharles.Forsyth rr.min.x = d.min.x - lw;
208*37da2899SCharles.Forsyth rr.max.x = d.max.x + rw;
209*37da2899SCharles.Forsyth rr.min.y = d.min.y - lw;
210*37da2899SCharles.Forsyth rr.max.y = d.min.y + rw;
211*37da2899SCharles.Forsyth draw(img, rr, pen, nil, rr.min);
212*37da2899SCharles.Forsyth rr.min.y += Dy(d);
213*37da2899SCharles.Forsyth rr.max.y += Dy(d);
214*37da2899SCharles.Forsyth draw(img, rr, pen, nil, rr.min);
215*37da2899SCharles.Forsyth /* now the vertical */
216*37da2899SCharles.Forsyth /* horizontal lines first */
217*37da2899SCharles.Forsyth rr.min.x = d.min.x - lw;
218*37da2899SCharles.Forsyth rr.max.x = d.min.x + rw;
219*37da2899SCharles.Forsyth rr.min.y = d.min.y + rw;
220*37da2899SCharles.Forsyth rr.max.y = d.max.y - lw;
221*37da2899SCharles.Forsyth draw(img, rr, pen, nil, rr.min);
222*37da2899SCharles.Forsyth rr.min.x += Dx(d);
223*37da2899SCharles.Forsyth rr.max.x += Dx(d);
224*37da2899SCharles.Forsyth draw(img, rr, pen, nil, rr.min);
225*37da2899SCharles.Forsyth }
226*37da2899SCharles.Forsyth }
227*37da2899SCharles.Forsyth
228*37da2899SCharles.Forsyth char*
tkcvsrectcoord(TkCitem * i,char * arg,int x,int y)229*37da2899SCharles.Forsyth tkcvsrectcoord(TkCitem *i, char *arg, int x, int y)
230*37da2899SCharles.Forsyth {
231*37da2899SCharles.Forsyth char *e;
232*37da2899SCharles.Forsyth TkCpoints p;
233*37da2899SCharles.Forsyth
234*37da2899SCharles.Forsyth if(arg == nil) {
235*37da2899SCharles.Forsyth tkxlatepts(i->p.parampt, i->p.npoint, x, y);
236*37da2899SCharles.Forsyth tkxlatepts(i->p.drawpt, i->p.npoint, TKF2I(x), TKF2I(y));
237*37da2899SCharles.Forsyth i->p.bb = rectaddpt(i->p.bb, Pt(TKF2I(x), TKF2I(y)));
238*37da2899SCharles.Forsyth }
239*37da2899SCharles.Forsyth else {
240*37da2899SCharles.Forsyth e = tkparsepts(i->env->top, &p, &arg, 0);
241*37da2899SCharles.Forsyth if(e != nil)
242*37da2899SCharles.Forsyth return e;
243*37da2899SCharles.Forsyth if(p.npoint != 2) {
244*37da2899SCharles.Forsyth tkfreepoint(&p);
245*37da2899SCharles.Forsyth return TkFewpt;
246*37da2899SCharles.Forsyth }
247*37da2899SCharles.Forsyth tkfreepoint(&i->p);
248*37da2899SCharles.Forsyth i->p = p;
249*37da2899SCharles.Forsyth tkcvsrectsize(i);
250*37da2899SCharles.Forsyth }
251*37da2899SCharles.Forsyth return nil;
252*37da2899SCharles.Forsyth }
253