1*37da2899SCharles.Forsyth #include "lib9.h"
2*37da2899SCharles.Forsyth #include "draw.h"
3*37da2899SCharles.Forsyth #include "tk.h"
4*37da2899SCharles.Forsyth #include "canvs.h"
5*37da2899SCharles.Forsyth
6*37da2899SCharles.Forsyth #define O(t, e) ((long)(&((t*)0)->e))
7*37da2899SCharles.Forsyth
8*37da2899SCharles.Forsyth /* Line Options (+ means implemented)
9*37da2899SCharles.Forsyth +arrow
10*37da2899SCharles.Forsyth +arrowshape
11*37da2899SCharles.Forsyth +capstyle
12*37da2899SCharles.Forsyth +fill
13*37da2899SCharles.Forsyth joinstyle
14*37da2899SCharles.Forsyth +smooth
15*37da2899SCharles.Forsyth +splinesteps
16*37da2899SCharles.Forsyth +stipple
17*37da2899SCharles.Forsyth +tags
18*37da2899SCharles.Forsyth +width
19*37da2899SCharles.Forsyth */
20*37da2899SCharles.Forsyth
21*37da2899SCharles.Forsyth static
22*37da2899SCharles.Forsyth TkStab tklines[] =
23*37da2899SCharles.Forsyth {
24*37da2899SCharles.Forsyth "none", 0,
25*37da2899SCharles.Forsyth "first", TkCarrowf,
26*37da2899SCharles.Forsyth "last", TkCarrowl,
27*37da2899SCharles.Forsyth "both", TkCarrowf|TkCarrowl,
28*37da2899SCharles.Forsyth nil
29*37da2899SCharles.Forsyth };
30*37da2899SCharles.Forsyth
31*37da2899SCharles.Forsyth static
32*37da2899SCharles.Forsyth TkStab tkcapstyle[] =
33*37da2899SCharles.Forsyth {
34*37da2899SCharles.Forsyth "butt", Endsquare,
35*37da2899SCharles.Forsyth "projecting", Endsquare,
36*37da2899SCharles.Forsyth "round", Enddisc,
37*37da2899SCharles.Forsyth nil
38*37da2899SCharles.Forsyth };
39*37da2899SCharles.Forsyth
40*37da2899SCharles.Forsyth static
41*37da2899SCharles.Forsyth TkOption lineopts[] =
42*37da2899SCharles.Forsyth {
43*37da2899SCharles.Forsyth "arrow", OPTstab, O(TkCline, arrow), tklines,
44*37da2899SCharles.Forsyth "arrowshape", OPTfrac, O(TkCline, shape[0]), IAUX(3),
45*37da2899SCharles.Forsyth "width", OPTnnfrac, O(TkCline, width), nil,
46*37da2899SCharles.Forsyth "stipple", OPTbmap, O(TkCline, stipple), nil,
47*37da2899SCharles.Forsyth "smooth", OPTstab, O(TkCline, smooth), tkbool,
48*37da2899SCharles.Forsyth "splinesteps", OPTdist, O(TkCline, steps), nil,
49*37da2899SCharles.Forsyth "capstyle", OPTstab, O(TkCline, capstyle), tkcapstyle,
50*37da2899SCharles.Forsyth nil
51*37da2899SCharles.Forsyth };
52*37da2899SCharles.Forsyth
53*37da2899SCharles.Forsyth static
54*37da2899SCharles.Forsyth TkOption itemopts[] =
55*37da2899SCharles.Forsyth {
56*37da2899SCharles.Forsyth "tags", OPTctag, O(TkCitem, tags), nil,
57*37da2899SCharles.Forsyth "fill", OPTcolr, O(TkCitem, env), IAUX(TkCforegnd),
58*37da2899SCharles.Forsyth nil
59*37da2899SCharles.Forsyth };
60*37da2899SCharles.Forsyth
61*37da2899SCharles.Forsyth void
tkcvslinesize(TkCitem * i)62*37da2899SCharles.Forsyth tkcvslinesize(TkCitem *i)
63*37da2899SCharles.Forsyth {
64*37da2899SCharles.Forsyth TkCline *l;
65*37da2899SCharles.Forsyth int j, w, as, shape[3], arrow;
66*37da2899SCharles.Forsyth
67*37da2899SCharles.Forsyth l = TKobj(TkCline, i);
68*37da2899SCharles.Forsyth w = TKF2I(l->width);
69*37da2899SCharles.Forsyth
70*37da2899SCharles.Forsyth i->p.bb = bbnil;
71*37da2899SCharles.Forsyth tkpolybound(i->p.drawpt, i->p.npoint, &i->p.bb);
72*37da2899SCharles.Forsyth
73*37da2899SCharles.Forsyth l->arrowf = l->capstyle;
74*37da2899SCharles.Forsyth l->arrowl = l->capstyle;
75*37da2899SCharles.Forsyth if(l->arrow != 0) {
76*37da2899SCharles.Forsyth as = w/3;
77*37da2899SCharles.Forsyth if(as < 1)
78*37da2899SCharles.Forsyth as = 1;
79*37da2899SCharles.Forsyth for(j = 0; j < 3; j++) {
80*37da2899SCharles.Forsyth shape[j] = l->shape[j];
81*37da2899SCharles.Forsyth if(shape[j] == 0)
82*37da2899SCharles.Forsyth shape[j] = as * cvslshape[j];
83*37da2899SCharles.Forsyth }
84*37da2899SCharles.Forsyth arrow = ARROW(TKF2I(shape[0]), TKF2I(shape[1]), TKF2I(shape[2]));
85*37da2899SCharles.Forsyth if(l->arrow & TkCarrowf)
86*37da2899SCharles.Forsyth l->arrowf = arrow;
87*37da2899SCharles.Forsyth if(l->arrow & TkCarrowl)
88*37da2899SCharles.Forsyth l->arrowl = arrow;
89*37da2899SCharles.Forsyth w += shape[2];
90*37da2899SCharles.Forsyth }
91*37da2899SCharles.Forsyth
92*37da2899SCharles.Forsyth i->p.bb = insetrect(i->p.bb, -w);
93*37da2899SCharles.Forsyth }
94*37da2899SCharles.Forsyth
95*37da2899SCharles.Forsyth char*
tkcvslinecreat(Tk * tk,char * arg,char ** val)96*37da2899SCharles.Forsyth tkcvslinecreat(Tk* tk, char *arg, char **val)
97*37da2899SCharles.Forsyth {
98*37da2899SCharles.Forsyth char *e;
99*37da2899SCharles.Forsyth TkCline *l;
100*37da2899SCharles.Forsyth TkCitem *i;
101*37da2899SCharles.Forsyth TkCanvas *c;
102*37da2899SCharles.Forsyth TkOptab tko[3];
103*37da2899SCharles.Forsyth
104*37da2899SCharles.Forsyth c = TKobj(TkCanvas, tk);
105*37da2899SCharles.Forsyth
106*37da2899SCharles.Forsyth i = tkcnewitem(tk, TkCVline, sizeof(TkCitem)+sizeof(TkCline));
107*37da2899SCharles.Forsyth if(i == nil)
108*37da2899SCharles.Forsyth return TkNomem;
109*37da2899SCharles.Forsyth
110*37da2899SCharles.Forsyth l = TKobj(TkCline, i);
111*37da2899SCharles.Forsyth l->width = TKI2F(1);
112*37da2899SCharles.Forsyth
113*37da2899SCharles.Forsyth e = tkparsepts(tk->env->top, &i->p, &arg, 0);
114*37da2899SCharles.Forsyth if(e != nil) {
115*37da2899SCharles.Forsyth tkcvsfreeitem(i);
116*37da2899SCharles.Forsyth return e;
117*37da2899SCharles.Forsyth }
118*37da2899SCharles.Forsyth
119*37da2899SCharles.Forsyth tko[0].ptr = l;
120*37da2899SCharles.Forsyth tko[0].optab = lineopts;
121*37da2899SCharles.Forsyth tko[1].ptr = i;
122*37da2899SCharles.Forsyth tko[1].optab = itemopts;
123*37da2899SCharles.Forsyth tko[2].ptr = nil;
124*37da2899SCharles.Forsyth e = tkparse(tk->env->top, arg, tko, nil);
125*37da2899SCharles.Forsyth if(e != nil) {
126*37da2899SCharles.Forsyth tkcvsfreeitem(i);
127*37da2899SCharles.Forsyth return e;
128*37da2899SCharles.Forsyth }
129*37da2899SCharles.Forsyth tkmkpen(&l->pen, i->env, l->stipple);
130*37da2899SCharles.Forsyth
131*37da2899SCharles.Forsyth e = tkcaddtag(tk, i, 1);
132*37da2899SCharles.Forsyth if(e != nil) {
133*37da2899SCharles.Forsyth tkcvsfreeitem(i);
134*37da2899SCharles.Forsyth return e;
135*37da2899SCharles.Forsyth }
136*37da2899SCharles.Forsyth
137*37da2899SCharles.Forsyth tkcvslinesize(i);
138*37da2899SCharles.Forsyth e = tkvalue(val, "%d", i->id);
139*37da2899SCharles.Forsyth if(e != nil) {
140*37da2899SCharles.Forsyth tkcvsfreeitem(i);
141*37da2899SCharles.Forsyth return e;
142*37da2899SCharles.Forsyth }
143*37da2899SCharles.Forsyth tkcvsappend(c, i);
144*37da2899SCharles.Forsyth
145*37da2899SCharles.Forsyth tkbbmax(&c->update, &i->p.bb);
146*37da2899SCharles.Forsyth tkcvssetdirty(tk);
147*37da2899SCharles.Forsyth return nil;
148*37da2899SCharles.Forsyth }
149*37da2899SCharles.Forsyth
150*37da2899SCharles.Forsyth char*
tkcvslinecget(TkCitem * i,char * arg,char ** val)151*37da2899SCharles.Forsyth tkcvslinecget(TkCitem *i, char *arg, char **val)
152*37da2899SCharles.Forsyth {
153*37da2899SCharles.Forsyth TkOptab tko[3];
154*37da2899SCharles.Forsyth TkCline *l = TKobj(TkCline, i);
155*37da2899SCharles.Forsyth
156*37da2899SCharles.Forsyth tko[0].ptr = l;
157*37da2899SCharles.Forsyth tko[0].optab = lineopts;
158*37da2899SCharles.Forsyth tko[1].ptr = i;
159*37da2899SCharles.Forsyth tko[1].optab = itemopts;
160*37da2899SCharles.Forsyth tko[2].ptr = nil;
161*37da2899SCharles.Forsyth
162*37da2899SCharles.Forsyth return tkgencget(tko, arg, val, i->env->top);
163*37da2899SCharles.Forsyth }
164*37da2899SCharles.Forsyth
165*37da2899SCharles.Forsyth char*
tkcvslineconf(Tk * tk,TkCitem * i,char * arg)166*37da2899SCharles.Forsyth tkcvslineconf(Tk *tk, TkCitem *i, char *arg)
167*37da2899SCharles.Forsyth {
168*37da2899SCharles.Forsyth char *e;
169*37da2899SCharles.Forsyth TkOptab tko[3];
170*37da2899SCharles.Forsyth TkCline *l = TKobj(TkCline, i);
171*37da2899SCharles.Forsyth
172*37da2899SCharles.Forsyth tko[0].ptr = l;
173*37da2899SCharles.Forsyth tko[0].optab = lineopts;
174*37da2899SCharles.Forsyth tko[1].ptr = i;
175*37da2899SCharles.Forsyth tko[1].optab = itemopts;
176*37da2899SCharles.Forsyth tko[2].ptr = nil;
177*37da2899SCharles.Forsyth
178*37da2899SCharles.Forsyth e = tkparse(tk->env->top, arg, tko, nil);
179*37da2899SCharles.Forsyth
180*37da2899SCharles.Forsyth tkmkpen(&l->pen, i->env, l->stipple);
181*37da2899SCharles.Forsyth tkcvslinesize(i);
182*37da2899SCharles.Forsyth
183*37da2899SCharles.Forsyth return e;
184*37da2899SCharles.Forsyth }
185*37da2899SCharles.Forsyth
186*37da2899SCharles.Forsyth void
tkcvslinefree(TkCitem * i)187*37da2899SCharles.Forsyth tkcvslinefree(TkCitem *i)
188*37da2899SCharles.Forsyth {
189*37da2899SCharles.Forsyth TkCline *l;
190*37da2899SCharles.Forsyth
191*37da2899SCharles.Forsyth l = TKobj(TkCline, i);
192*37da2899SCharles.Forsyth if(l->stipple)
193*37da2899SCharles.Forsyth freeimage(l->stipple);
194*37da2899SCharles.Forsyth if(l->pen)
195*37da2899SCharles.Forsyth freeimage(l->pen);
196*37da2899SCharles.Forsyth }
197*37da2899SCharles.Forsyth
198*37da2899SCharles.Forsyth void
tkcvslinedraw(Image * img,TkCitem * i,TkEnv * pe)199*37da2899SCharles.Forsyth tkcvslinedraw(Image *img, TkCitem *i, TkEnv *pe)
200*37da2899SCharles.Forsyth {
201*37da2899SCharles.Forsyth int w;
202*37da2899SCharles.Forsyth Point *p;
203*37da2899SCharles.Forsyth TkCline *l;
204*37da2899SCharles.Forsyth Image *pen;
205*37da2899SCharles.Forsyth
206*37da2899SCharles.Forsyth USED(pe);
207*37da2899SCharles.Forsyth
208*37da2899SCharles.Forsyth l = TKobj(TkCline, i);
209*37da2899SCharles.Forsyth
210*37da2899SCharles.Forsyth pen = l->pen;
211*37da2899SCharles.Forsyth if(pen == nil)
212*37da2899SCharles.Forsyth pen = tkgc(i->env, TkCforegnd);
213*37da2899SCharles.Forsyth
214*37da2899SCharles.Forsyth w = TKF2I(l->width)/2;
215*37da2899SCharles.Forsyth if(w < 0)
216*37da2899SCharles.Forsyth return;
217*37da2899SCharles.Forsyth
218*37da2899SCharles.Forsyth p = i->p.drawpt;
219*37da2899SCharles.Forsyth if(l->smooth == BoolT && i->p.npoint >= 3)
220*37da2899SCharles.Forsyth bezspline(img, p, i->p.npoint, l->arrowf, l->arrowl, w, pen, p[0]);
221*37da2899SCharles.Forsyth else
222*37da2899SCharles.Forsyth poly(img, p, i->p.npoint, l->arrowf, l->arrowl, w, pen, p[0]);
223*37da2899SCharles.Forsyth }
224*37da2899SCharles.Forsyth
225*37da2899SCharles.Forsyth char*
tkcvslinecoord(TkCitem * i,char * arg,int x,int y)226*37da2899SCharles.Forsyth tkcvslinecoord(TkCitem *i, char *arg, int x, int y)
227*37da2899SCharles.Forsyth {
228*37da2899SCharles.Forsyth char *e;
229*37da2899SCharles.Forsyth TkCpoints p;
230*37da2899SCharles.Forsyth
231*37da2899SCharles.Forsyth if(arg == nil) {
232*37da2899SCharles.Forsyth tkxlatepts(i->p.parampt, i->p.npoint, x, y);
233*37da2899SCharles.Forsyth tkxlatepts(i->p.drawpt, i->p.npoint, TKF2I(x), TKF2I(y));
234*37da2899SCharles.Forsyth i->p.bb = rectaddpt(i->p.bb, Pt(TKF2I(x), TKF2I(y)));
235*37da2899SCharles.Forsyth }
236*37da2899SCharles.Forsyth else {
237*37da2899SCharles.Forsyth e = tkparsepts(i->env->top, &p, &arg, 0);
238*37da2899SCharles.Forsyth if(e != nil)
239*37da2899SCharles.Forsyth return e;
240*37da2899SCharles.Forsyth if(p.npoint < 2) {
241*37da2899SCharles.Forsyth tkfreepoint(&p);
242*37da2899SCharles.Forsyth return TkFewpt;
243*37da2899SCharles.Forsyth }
244*37da2899SCharles.Forsyth tkfreepoint(&i->p);
245*37da2899SCharles.Forsyth i->p = p;
246*37da2899SCharles.Forsyth tkcvslinesize(i);
247*37da2899SCharles.Forsyth }
248*37da2899SCharles.Forsyth return nil;
249*37da2899SCharles.Forsyth }
250*37da2899SCharles.Forsyth
251*37da2899SCharles.Forsyth int
tkcvslinehit(TkCitem * i,Point p)252*37da2899SCharles.Forsyth tkcvslinehit(TkCitem *i, Point p)
253*37da2899SCharles.Forsyth {
254*37da2899SCharles.Forsyth TkCline *l;
255*37da2899SCharles.Forsyth int w, np, r;
256*37da2899SCharles.Forsyth Point *pp;
257*37da2899SCharles.Forsyth
258*37da2899SCharles.Forsyth l = TKobj(TkCline, i);
259*37da2899SCharles.Forsyth w =TKF2I(l->width) + 2; /* 2 for slop */
260*37da2899SCharles.Forsyth
261*37da2899SCharles.Forsyth if (l->smooth == BoolT) {
262*37da2899SCharles.Forsyth np = getbezsplinepts(i->p.drawpt, i->p.npoint, &pp);
263*37da2899SCharles.Forsyth r = tklinehit(pp, np, w, p);
264*37da2899SCharles.Forsyth free(pp);
265*37da2899SCharles.Forsyth } else
266*37da2899SCharles.Forsyth r = tklinehit(i->p.drawpt, i->p.npoint, w, p);
267*37da2899SCharles.Forsyth return r;
268*37da2899SCharles.Forsyth }
269