xref: /inferno-os/libtk/crect.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
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