|
|
1.1 root 1: /*
2: %Z% %M% version %I% %Q%of %H% %T%
3: Last Delta: %G% %U% to %P%
4: */
5:
6: #include "cip.h"
7:
8: extern Rectangle brushes[];
9:
10: Point
11: track(p,offset,b,th)
12: Point p,offset; int b;
13: register struct thing *th;
14: {
15: Point t, ot, r;
16:
17: if ( b != ARC ) {
18: p = add(p,offset);
19: ot = p;
20: }
21: else {
22: ot = add(p,offset);
23: }
24: if (th != TNULL || b==BOX || b==LINE || b==REVLINE || b==ARC) {
25: do {
26: t = MOUSE_XY;
27: if ((t.x!=ot.x)||(t.y!=ot.y)) {
28: cursinhibit();
29: switch (b) {
30: case BOX: {
31: r = near(t,th,offset);
32: if (r.x != 0) {
33: t = r;
34: }
35: else {
36: r=near(Pt(p.x,t.y),th,offset);
37: if (r.x!=0) {
38: t.y = r.y;
39: }
40: else {
41: r=near(Pt(t.x,p.y),th,offset);
42: if (r.x != 0) {
43: t.x = r.x;
44: }
45: }
46: }
47: xbox (canon (p, ot));
48: xbox (canon (p, t));
49: break;
50: }
51: case ARC: {
52: th->type = ARC;
53: th->otherValues.arc.start = p;
54: th->otherValues.arc.end = sub( ot,offset );
55: th->origin=computeArcOrigin( p, sub( ot,offset ));
56: if (!eqpt(th->otherValues.arc.start,
57: th->otherValues.arc.end)) {
58: draw(th,offset);
59: }
60: th->otherValues.arc.end = sub( t,offset );
61: th->origin=computeArcOrigin( p,sub( t,offset ));
62: draw(th,offset);
63: break;
64: }
65: case REVLINE:
66: case LINE: {
67: r=near(t,th,offset);
68: if (r.x!=0) {
69: t=r;
70: }
71: else {
72: if (abs(p.x-t.x)<nearlyStraight) {
73: t.x=p.x;
74: }
75: else {
76: if (abs(p.y-t.y)<nearlyStraight) {
77: t.y=p.y;
78: }
79: }
80: }
81: if (b== LINE) { /* See note 1 */
82: xsegment(p,ot);
83: xsegment(p,t);
84: }
85: else {
86: xsegment(ot,p);
87: xsegment(t,p);
88: }
89: break;
90: }
91: case GROWCIRCLE: {
92: draw(th,offset);
93: th->otherValues.radius=distance(add(th->origin,offset),t);
94: draw(th,offset);
95: break;
96: }
97: case MOVE: {
98: r=near(t,th,offset);
99: if (r.x != 0) {
100: t=r;
101: }
102: draw(th,offset);
103: th->origin = sub(t,offset);
104: draw(th,offset);
105: break;
106: }
107: case GROWEHT: {
108: draw(th,offset);
109: th->otherValues.ellipse.ht =
110: abs(th->origin.y-t.y+offset.y)<<1;
111: draw(th,offset);
112: break;
113: }
114: case GROWEWID: {
115: draw(th,offset);
116: th->otherValues.ellipse.wid =
117: abs(th->origin.x-t.x+offset.x)<<1;
118: draw(th,offset);
119: break;
120: }
121: case ELLIPSE: {
122: draw(th,offset);
123: th->otherValues.ellipse.wid =
124: (abs(th->origin.x-t.x+offset.x))<<1;
125: th->otherValues.ellipse.ht =
126: abs(th->origin.y-t.y+offset.y)<<1;
127: draw(th,offset);
128: break;
129: }
130: }
131: ot = t;
132: cursallow();
133: }
134: jnap(2);
135: } while (button2());
136: }
137: if ( b == ARC ) {
138: draw(th,offset);
139: }
140: cursinhibit();
141: switch (b) {
142: case BOX: {
143: xbox (canon (p, ot));
144: break;
145: }
146: /* case REVLINE: /* REVLINE not needed, used only with splines */
147: case LINE: {
148: /* Don't draw line if tracking a spline */
149: if (th->type != SPLINE) {
150: xsegment(p,ot);
151: }
152: break;
153: }
154: }
155: cursallow();
156: return(sub(t,offset));
157: }
158: /* NOTE 1: */
159: /* Lines drawn and undrawn using XOR mode must always be drawn in the */
160: /* same direction. This is because the last point on the line is not */
161: /* drawn. The same line drawn twice, but in opposite directions */
162: /* will leave two points on the screen. So, because of this when */
163: /* the tracking routine is tracking a spline from p[2] to p[1] the */
164: /* line must be drawn in the opposite direction (from p[1] to p[2]). */
165: /* Therefore, the need for the REVLINE value. */
166:
167: Point
168: track2(offset,o1, o2, p)
169: Point offset, o1, o2, p;
170: {
171: Point op;
172:
173: o1 = add(offset,o1);
174: o2 = add(offset,o2);
175: op = add(offset,p);
176: do {
177: p = MOUSE_XY;
178: cursinhibit();
179: if ((p.x!=op.x)||(p.y!=op.y)) {
180: xsegment(o1,op);
181: xsegment(op,o2);
182: xsegment(o1,p);
183: xsegment(p,o2);
184: }
185: op = p;
186: cursallow();
187: jnap(2);
188: } while (button2());
189: cursinhibit ();
190: cursallow ();
191: return(sub(p,offset));
192: }
193:
194: Rectangle
195: moveBox(p,r,h,offset)
196: Point p, offset;
197: Rectangle r;
198: register struct thing *h;
199: {
200: Rectangle or; Point dor, dc; Point op, q;
201:
202: or = r;
203: dor= sub(or.origin,p);
204: dc = sub(or.corner,p);
205: op = add(p,offset);
206: do {
207: p = MOUSE_XY;
208: r.origin = add(or.origin,sub(p,op));
209: q = near(add(r.origin,offset),h,offset);
210: if (q.x!=0) {
211: p = sub(q,dor);
212: }
213: else {
214: r.corner = add(or.corner,sub(p,op));
215: q = near(add(r.corner,offset),h,offset);
216: if (q.x!=0) {
217: p = sub(q,dc);
218: }
219: }
220: r.origin = add(or.origin,sub(p,op));
221: r.corner = add(or.corner,sub(p,op));
222: cursinhibit();
223: xbox(raddp(or,offset));
224: xbox(raddp (r, offset));
225: op = p;
226: or = r;
227: cursallow();
228: jnap(2);
229: } while (button2());
230: return(r);
231: }
232:
233: arcOrigin(t,offset)
234: register struct thing *t;
235: Point offset;
236: {
237: Point oc, c, c1, c2, s, e, om, m, org, mid;
238:
239: s = add(offset,t->otherValues.arc.start);
240: e = add(offset,t->otherValues.arc.end);
241: org = add(offset,t->origin);
242: mid = sub(org,div(add(s,e),2));
243: oc = org;
244: om = oc;
245: do {
246: cursinhibit();
247: m = MOUSE_XY;
248: if (distance(m,om)>2) {
249: c1.x = m.x;
250: c1.y = muldiv(mid.y, c1.x-org.x, mid.x) + org.y;
251: c2.y = m.y;
252: c2.x = muldiv(c2.y-org.y, mid.x,mid.y) + org.x;
253: c = (distance(oc,c1)<distance(c,c2))?c1:c2;
254: eraseAndDrawArc(oc,e,s,c,e,s);
255: oc = c;
256: om = m;
257: t->origin = sub(c,offset);
258: }
259: cursallow();
260: jnap(2);
261: } while (button2());
262: }
263:
264: arcStart(t,offset)
265: register struct thing *t;
266: Point offset;
267: {
268: Point oc, s, e, os;
269:
270: os = add(offset,t->otherValues.arc.start);
271: e = add(offset,t->otherValues.arc.end);
272: oc = add(offset,t->origin);
273: do {
274: cursinhibit();
275: s = MOUSE_XY;
276: if (distance(s,os)>2) {
277: eraseAndDrawArc(oc,e,os,oc,e,s);
278: os = s;
279: t->otherValues.arc.start=sub(s,offset);
280: }
281: cursallow();
282: jnap(2);
283: } while (button2());
284: }
285:
286: arcEnd(t,offset)
287: register struct thing *t;
288: Point offset;
289: {
290: Point oc, s, e, oe;
291:
292: s = add(offset,t->otherValues.arc.start);
293: oe = add(offset,t->otherValues.arc.end);
294: oc = add(offset,t->origin);
295: do {
296: cursinhibit();
297: e = MOUSE_XY;
298: if (distance(e,oe)>2) {
299: eraseAndDrawArc(oc,oe,s,oc,e,s);
300: oe = e;
301: t->otherValues.arc.end=sub(e,offset);
302: }
303: cursallow();
304: jnap(2);
305: } while (button2());
306: }
307:
308: eraseAndDrawArc(oc,oe,os,c,e,s)
309: Point oc, oe, os, c, e, s;
310: {
311: xarc(oc,os,oe);
312: xsegment(oc,os);
313: xsegment(oc,oe);
314: xarc(c,s,e);
315: xsegment(c,s);
316: xsegment(c,e);
317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.