1 /*
2 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
3 *
4 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5 *
6 * This file may be distributed under the terms of the Q Public License
7 * as defined by Trolltech AS of Norway and appearing in the file
8 * LICENSE.QPL included in the packaging of this file.
9 *
10 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/move.c,v 1.34 2011/05/16 16:21:58 william Exp $
19 */
20
21 #define _INCLUDE_FROM_MOVE_C_
22
23 #include "tgifdefs.h"
24
25 #include "arc.e"
26 #include "attr.e"
27 #include "choice.e"
28 #include "cmd.e"
29 #include "cursor.e"
30 #include "dialog.e"
31 #include "drawing.e"
32 #include "dup.e"
33 #include "exec.e"
34 #include "grid.e"
35 #include "mainloop.e"
36 #include "mark.e"
37 #include "move.e"
38 #include "msg.e"
39 #include "names.e"
40 #include "obj.e"
41 #include "oval.e"
42 #include "poly.e"
43 #include "raster.e"
44 #include "rcbox.e"
45 #include "rect.e"
46 #include "ruler.e"
47 #include "select.e"
48 #include "setup.e"
49 #include "spline.e"
50 #include "stretch.e"
51 #include "strtbl.e"
52
53 int oneMotionTimeout=200;
54 int minMoveInterval=0;
55
56 static
MovePoly(ObjPtr,Dx,Dy)57 void MovePoly(ObjPtr, Dx, Dy)
58 register struct ObjRec *ObjPtr;
59 register int Dx, Dy;
60 {
61 register int i;
62
63 for (i=0; i < ObjPtr->detail.p->n; i++) {
64 ObjPtr->detail.p->vlist[i].x += Dx;
65 ObjPtr->detail.p->vlist[i].y += Dy;
66 }
67 }
68
69 static
MovePolygon(ObjPtr,Dx,Dy)70 void MovePolygon(ObjPtr, Dx, Dy)
71 register struct ObjRec *ObjPtr;
72 register int Dx, Dy;
73 {
74 register int i;
75
76 for (i=0; i < ObjPtr->detail.g->n; i++) {
77 ObjPtr->detail.g->vlist[i].x += Dx;
78 ObjPtr->detail.g->vlist[i].y += Dy;
79 }
80 }
81
82 static
MoveArc(ObjPtr,Dx,Dy)83 void MoveArc(ObjPtr, Dx, Dy)
84 struct ObjRec *ObjPtr;
85 register int Dx, Dy;
86 {
87 register struct ArcRec *arc_ptr=ObjPtr->detail.a;
88
89 arc_ptr->xc += Dx; arc_ptr->yc += Dy;
90 arc_ptr->x1 += Dx; arc_ptr->y1 += Dy;
91 arc_ptr->x2 += Dx; arc_ptr->y2 += Dy;
92 arc_ptr->ltx += Dx; arc_ptr->lty += Dy;
93 }
94
MoveObj(ObjPtr,Dx,Dy)95 void MoveObj(ObjPtr, Dx, Dy)
96 struct ObjRec *ObjPtr;
97 int Dx, Dy;
98 {
99 struct ObjRec *ptr=NULL;
100 int saved_undoing_or_redoing=undoingOrRedoing;
101
102 ObjPtr->x += Dx;
103 ObjPtr->y += Dy;
104 ObjPtr->bbox.ltx += Dx;
105 ObjPtr->bbox.lty += Dy;
106 ObjPtr->bbox.rbx += Dx;
107 ObjPtr->bbox.rby += Dy;
108 ObjPtr->obbox.ltx += Dx;
109 ObjPtr->obbox.lty += Dy;
110 ObjPtr->obbox.rbx += Dx;
111 ObjPtr->obbox.rby += Dy;
112 MoveRotatedObjCache(ObjPtr, Dx, Dy);
113 switch (ObjPtr->type) {
114 case OBJ_POLY:
115 MoveAttrs(ObjPtr->fattr, Dx, Dy);
116 MovePoly(ObjPtr, Dx, Dy);
117 /* fake the undoingOrRedoing so that no */
118 /* actual auto-adjusting is done */
119 undoingOrRedoing = TRUE;
120 AdjObjSplineVs(ObjPtr);
121 undoingOrRedoing = saved_undoing_or_redoing;
122 break;
123 case OBJ_BOX:
124 MoveAttrs(ObjPtr->fattr, Dx, Dy);
125 break;
126 case OBJ_OVAL:
127 MoveAttrs(ObjPtr->fattr, Dx, Dy);
128 break;
129 case OBJ_TEXT:
130 ObjPtr->detail.t->baseline_y += Dy;
131 break;
132 case OBJ_POLYGON:
133 MoveAttrs(ObjPtr->fattr, Dx, Dy);
134 MovePolygon(ObjPtr, Dx, Dy);
135 AdjObjSplineVs(ObjPtr);
136 break;
137 case OBJ_ARC:
138 MoveAttrs(ObjPtr->fattr, Dx, Dy);
139 MoveArc(ObjPtr, Dx, Dy);
140 AdjObjSplineVs(ObjPtr);
141 break;
142 case OBJ_RCBOX:
143 MoveAttrs(ObjPtr->fattr, Dx, Dy);
144 break;
145 case OBJ_XBM:
146 MoveAttrs(ObjPtr->fattr, Dx, Dy);
147 break;
148 case OBJ_XPM:
149 MoveAttrs(ObjPtr->fattr, Dx, Dy);
150 break;
151 case OBJ_GROUP:
152 case OBJ_ICON:
153 case OBJ_SYM:
154 case OBJ_PIN:
155 MoveAttrs(ObjPtr->fattr, Dx, Dy);
156 for (ptr=ObjPtr->detail.r->first; ptr != NULL; ptr=ptr->next) {
157 MoveObj(ptr, Dx, Dy);
158 }
159 break;
160 }
161 }
162
MoveAllSelObjects(Dx,Dy)163 void MoveAllSelObjects(Dx, Dy)
164 register int Dx, Dy;
165 {
166 register struct SelRec *sel_ptr;
167
168 for (sel_ptr=topSel; sel_ptr != NULL; sel_ptr=sel_ptr->next) {
169 if (!sel_ptr->obj->locked) {
170 MoveObj(sel_ptr->obj, Dx, Dy);
171 }
172 }
173 if (numObjLocked != 0) Msg(TgLoadCachedString(CSTID_LOCKED_OBJS_NOT_MOVED));
174 }
175
176 static
MarkObjectsForMove()177 void MarkObjectsForMove()
178 {
179 register struct ObjRec *obj_ptr;
180 register struct SelRec *sel_ptr;
181
182 for (obj_ptr=botObj; obj_ptr != NULL; obj_ptr=obj_ptr->prev) {
183 obj_ptr->marked = FALSE;
184 }
185 for (sel_ptr=botSel; sel_ptr != NULL; sel_ptr=sel_ptr->prev) {
186 sel_ptr->obj->marked = TRUE;
187 }
188 }
189
190 static
EndPtInObjList(XOff,YOff,FirstObjPtr)191 int EndPtInObjList(XOff, YOff, FirstObjPtr)
192 int XOff, YOff;
193 struct ObjRec *FirstObjPtr;
194 /* XOff and YOff are screen offsets */
195 {
196 register struct ObjRec *obj_ptr;
197 register struct AttrRec *attr_ptr;
198 int found=FALSE, saved_fill=0, saved_trans_pat=FALSE;
199
200 for (obj_ptr=FirstObjPtr; obj_ptr != NULL; obj_ptr=obj_ptr->next) {
201 for (attr_ptr=obj_ptr->fattr; attr_ptr!=NULL; attr_ptr=attr_ptr->next) {
202 if (attr_ptr->shown &&
203 XOff >= OFFSET_X(attr_ptr->obj->bbox.ltx)-3 &&
204 YOff >= OFFSET_Y(attr_ptr->obj->bbox.lty)-3 &&
205 XOff <= OFFSET_X(attr_ptr->obj->bbox.rbx)+3 &&
206 YOff <= OFFSET_Y(attr_ptr->obj->bbox.rby)+3) {
207 return TRUE;
208 }
209 }
210 if (XOff >= OFFSET_X(obj_ptr->bbox.ltx)-3 &&
211 YOff >= OFFSET_Y(obj_ptr->bbox.lty)-3 &&
212 XOff <= OFFSET_X(obj_ptr->bbox.rbx)+3 &&
213 YOff <= OFFSET_Y(obj_ptr->bbox.rby)+3) {
214 switch (obj_ptr->type) {
215 case OBJ_TEXT: if (FindGoodText(XOff,YOff,obj_ptr)) return TRUE; break;
216 case OBJ_XBM: if (FindGoodXBm(XOff,YOff,obj_ptr)) return TRUE; break;
217 case OBJ_XPM: if (FindGoodXPm(XOff,YOff,obj_ptr)) return TRUE; break;
218 case OBJ_BOX:
219 saved_trans_pat = obj_ptr->trans_pat;
220 saved_fill = obj_ptr->detail.b->fill;
221 obj_ptr->detail.b->fill = SOLIDPAT;
222 found = FindGoodBox(XOff,YOff,obj_ptr);
223 obj_ptr->detail.b->fill = saved_fill;
224 obj_ptr->trans_pat = saved_trans_pat;
225 if (found) return TRUE;
226 break;
227 case OBJ_OVAL:
228 saved_trans_pat = obj_ptr->trans_pat;
229 saved_fill = obj_ptr->detail.o->fill;
230 obj_ptr->detail.o->fill = SOLIDPAT;
231 found = FindGoodOval(XOff,YOff,obj_ptr);
232 obj_ptr->detail.o->fill = saved_fill;
233 obj_ptr->trans_pat = saved_trans_pat;
234 if (found) return TRUE;
235 break;
236 case OBJ_POLY: if (FindGoodPoly(XOff,YOff,obj_ptr)) return TRUE; break;
237 case OBJ_POLYGON:
238 saved_trans_pat = obj_ptr->trans_pat;
239 saved_fill = obj_ptr->detail.g->fill;
240 obj_ptr->detail.g->fill = SOLIDPAT;
241 found = FindGoodPolygon(XOff,YOff,obj_ptr);
242 obj_ptr->detail.g->fill = saved_fill;
243 obj_ptr->trans_pat = saved_trans_pat;
244 if (found) return TRUE;
245 break;
246 case OBJ_ARC: if (FindGoodArc(XOff,YOff,obj_ptr)) return TRUE; break;
247 case OBJ_RCBOX:
248 saved_trans_pat = obj_ptr->trans_pat;
249 saved_fill = obj_ptr->detail.rcb->fill;
250 obj_ptr->detail.rcb->fill = SOLIDPAT;
251 found = FindGoodRCBox(XOff,YOff,obj_ptr);
252 obj_ptr->detail.rcb->fill = saved_fill;
253 obj_ptr->trans_pat = saved_trans_pat;
254 if (found) return TRUE;
255 break;
256
257 case OBJ_GROUP:
258 case OBJ_ICON:
259 case OBJ_SYM:
260 if (EndPtInObjList(XOff,YOff,obj_ptr->detail.r->first)) {
261 return TRUE;
262 }
263 break;
264 case OBJ_PIN:
265 if (EndPtInObjList(XOff,YOff,GetPinObj(obj_ptr)->detail.r->first)) {
266 return TRUE;
267 }
268 }
269 }
270 }
271 return FALSE;
272 }
273
EndPtInSelected(XOff,YOff)274 int EndPtInSelected(XOff, YOff)
275 int XOff, YOff;
276 /* XOff and YOff are screen offsets */
277 {
278 register struct SelRec *sel_ptr;
279 register struct ObjRec *obj_ptr;
280 register struct AttrRec *attr_ptr;
281 int found, saved_fill=0, saved_trans_pat=FALSE;
282
283 for (sel_ptr=topSel; sel_ptr != NULL; sel_ptr=sel_ptr->next) {
284 obj_ptr = sel_ptr->obj;
285 if (obj_ptr->locked) continue;
286
287 for (attr_ptr=obj_ptr->fattr; attr_ptr!=NULL; attr_ptr=attr_ptr->next) {
288 if (attr_ptr->shown &&
289 XOff >= OFFSET_X(attr_ptr->obj->bbox.ltx)-3 &&
290 YOff >= OFFSET_Y(attr_ptr->obj->bbox.lty)-3 &&
291 XOff <= OFFSET_X(attr_ptr->obj->bbox.rbx)+3 &&
292 YOff <= OFFSET_Y(attr_ptr->obj->bbox.rby)+3) {
293 return TRUE;
294 }
295 }
296 if (XOff >= OFFSET_X(obj_ptr->bbox.ltx)-3 &&
297 YOff >= OFFSET_Y(obj_ptr->bbox.lty)-3 &&
298 XOff <= OFFSET_X(obj_ptr->bbox.rbx)+3 &&
299 YOff <= OFFSET_Y(obj_ptr->bbox.rby)+3) {
300 switch (obj_ptr->type) {
301 case OBJ_TEXT: if (FindGoodText(XOff,YOff,obj_ptr)) return TRUE; break;
302 case OBJ_XBM: if (FindGoodXBm(XOff,YOff,obj_ptr)) return TRUE; break;
303 case OBJ_XPM: if (FindGoodXPm(XOff,YOff,obj_ptr)) return TRUE; break;
304 case OBJ_BOX:
305 saved_trans_pat = obj_ptr->trans_pat;
306 saved_fill = obj_ptr->detail.b->fill;
307 obj_ptr->detail.b->fill = SOLIDPAT;
308 found = FindGoodBox(XOff,YOff,obj_ptr);
309 obj_ptr->detail.b->fill = saved_fill;
310 obj_ptr->trans_pat = saved_trans_pat;
311 if (found) return TRUE;
312 break;
313 case OBJ_OVAL:
314 saved_trans_pat = obj_ptr->trans_pat;
315 saved_fill = obj_ptr->detail.o->fill;
316 obj_ptr->detail.o->fill = SOLIDPAT;
317 found = FindGoodOval(XOff,YOff,obj_ptr);
318 obj_ptr->detail.o->fill = saved_fill;
319 obj_ptr->trans_pat = saved_trans_pat;
320 if (found) return TRUE;
321 break;
322 case OBJ_POLY: if (FindGoodPoly(XOff,YOff,obj_ptr)) return TRUE; break;
323 case OBJ_POLYGON:
324 saved_trans_pat = obj_ptr->trans_pat;
325 saved_fill = obj_ptr->detail.g->fill;
326 obj_ptr->detail.g->fill = SOLIDPAT;
327 found = FindGoodPolygon(XOff,YOff,obj_ptr);
328 obj_ptr->detail.g->fill = saved_fill;
329 obj_ptr->trans_pat = saved_trans_pat;
330 if (found) return TRUE;
331 break;
332 case OBJ_ARC: if (FindGoodArc(XOff,YOff,obj_ptr)) return TRUE; break;
333 case OBJ_RCBOX:
334 saved_trans_pat = obj_ptr->trans_pat;
335 saved_fill = obj_ptr->detail.rcb->fill;
336 obj_ptr->detail.rcb->fill = SOLIDPAT;
337 found = FindGoodRCBox(XOff,YOff,obj_ptr);
338 obj_ptr->detail.rcb->fill = saved_fill;
339 obj_ptr->trans_pat = saved_trans_pat;
340 if (found) return TRUE;
341 break;
342
343 case OBJ_GROUP:
344 case OBJ_ICON:
345 case OBJ_SYM:
346 if (EndPtInObjList(XOff,YOff,obj_ptr->detail.r->first)) {
347 return TRUE;
348 }
349 break;
350 case OBJ_PIN:
351 if (EndPtInObjList(XOff,YOff,GetPinObj(obj_ptr)->detail.r->first)) {
352 return TRUE;
353 }
354 break;
355 }
356 }
357 }
358 return FALSE;
359 }
360
361 static
ConstrainedMoveAllSel(Dx,Dy,ltx,lty,rbx,rby)362 int ConstrainedMoveAllSel(Dx, Dy, ltx, lty, rbx, rby)
363 register int Dx, Dy;
364 int *ltx, *lty, *rbx, *rby;
365 {
366 struct ObjRec *obj_ptr=NULL;
367 int something_stretched=FALSE;
368
369 for (obj_ptr=botObj; obj_ptr != NULL; obj_ptr=obj_ptr->prev) {
370 if (!obj_ptr->marked && obj_ptr->type==OBJ_POLY && !obj_ptr->locked) {
371 struct PolyRec *poly_ptr=obj_ptr->detail.p;
372 IntPoint *v=obj_ptr->detail.p->vlist;
373 int num_pts=obj_ptr->detail.p->n;
374 int x_off=0, y_off=0, move_first=FALSE, move_last=FALSE;
375 int move_2nd=FALSE, move_2nd_to_last=FALSE;
376 int possibly_move_3rd=FALSE, possibly_move_3rd_to_last=FALSE;
377
378 if (obj_ptr->ctm == NULL) {
379 x_off = OFFSET_X(v[0].x); y_off = OFFSET_Y(v[0].y);
380 move_first = EndPtInSelected(x_off, y_off);
381 x_off = OFFSET_X(v[num_pts-1].x); y_off = OFFSET_Y(v[num_pts-1].y);
382 move_last = EndPtInSelected(x_off, y_off);
383 } else {
384 int tmp_x, tmp_y;
385
386 TransformPointThroughCTM(v[0].x-obj_ptr->x, v[0].y-obj_ptr->y,
387 obj_ptr->ctm, &tmp_x, &tmp_y);
388 tmp_x += obj_ptr->x;
389 tmp_y += obj_ptr->y;
390 x_off = OFFSET_X(tmp_x); y_off = OFFSET_Y(tmp_y);
391 move_first = EndPtInSelected(x_off, y_off);
392 TransformPointThroughCTM(v[num_pts-1].x-obj_ptr->x,
393 v[num_pts-1].y-obj_ptr->y, obj_ptr->ctm, &tmp_x, &tmp_y);
394 tmp_x += obj_ptr->x;
395 tmp_y += obj_ptr->y;
396 x_off = OFFSET_X(tmp_x); y_off = OFFSET_Y(tmp_y);
397 move_last = EndPtInSelected(x_off, y_off);
398 }
399 if (move_first && poly_ptr->curved == LT_STRUCT_SPLINE &&
400 v[0].x == v[1].x && v[0].y == v[1].y) {
401 move_2nd = TRUE;
402 if (num_pts > 4 &&
403 v[2].x == v[3].x && v[2].y == v[3].y &&
404 v[4].x == v[3].x && v[4].y == v[3].y) {
405 possibly_move_3rd = TRUE;
406 }
407 }
408 if (move_last && poly_ptr->curved == LT_STRUCT_SPLINE &&
409 v[num_pts-1].x == v[num_pts-2].x &&
410 v[num_pts-1].y == v[num_pts-2].y) {
411 move_2nd_to_last = TRUE;
412 if (num_pts > 4 &&
413 v[num_pts-3].x == v[num_pts-4].x &&
414 v[num_pts-3].y == v[num_pts-4].y &&
415 v[num_pts-5].x == v[num_pts-4].x &&
416 v[num_pts-5].y == v[num_pts-4].y) {
417 possibly_move_3rd_to_last = TRUE;
418 }
419 }
420 if (move_first || move_last) {
421 PrepareToReplaceAnObj(obj_ptr);
422
423 if (obj_ptr->ctm != NULL) {
424 /* Remove the transformations! */
425 int i;
426
427 for (i=0; i < num_pts; i++) {
428 int tmp_x, tmp_y;
429
430 TransformPointThroughCTM(v[i].x-obj_ptr->x, v[i].y-obj_ptr->y,
431 obj_ptr->ctm, &tmp_x, &tmp_y);
432 v[i].x = tmp_x+obj_ptr->x;
433 v[i].y = tmp_y+obj_ptr->y;
434 }
435 free(obj_ptr->ctm);
436 obj_ptr->ctm = NULL;
437 UpdPolyBBox(obj_ptr, num_pts, v);
438 }
439 if (something_stretched) {
440 if (obj_ptr->bbox.ltx < *ltx) *ltx = obj_ptr->bbox.ltx;
441 if (obj_ptr->bbox.lty < *lty) *lty = obj_ptr->bbox.lty;
442 if (obj_ptr->bbox.rbx > *rbx) *rbx = obj_ptr->bbox.rbx;
443 if (obj_ptr->bbox.rby > *rby) *rby = obj_ptr->bbox.rby;
444 } else {
445 *ltx = obj_ptr->bbox.ltx; *lty = obj_ptr->bbox.lty;
446 *rbx = obj_ptr->bbox.rbx; *rby = obj_ptr->bbox.rby;
447 }
448 something_stretched = TRUE;
449 if (move_first && move_last) {
450 MoveObj(obj_ptr, Dx, Dy);
451 } else {
452 int index=INVALID, seg_dx=0, seg_dy=0;
453 int cur_seg_dx=0, cur_seg_dy=0;
454
455 if (move_first) {
456 if (num_pts > 2) {
457 if (possibly_move_3rd) {
458 /* only for LT_STRUCT_SPLINE */
459 index = 3;
460 cur_seg_dx = v[index-3].x - v[index].x;
461 cur_seg_dy = v[index-3].y - v[index].y;
462 seg_dx = v[index].x - v[index+3].x;
463 seg_dy = v[index].y - v[index+3].y;
464 } else {
465 index = 1;
466 cur_seg_dx = v[index-1].x - v[index].x;
467 cur_seg_dy = v[index-1].y - v[index].y;
468 seg_dx = v[index].x - v[index+1].x;
469 seg_dy = v[index].y - v[index+1].y;
470 }
471 }
472 v[0].x += Dx; v[0].y += Dy;
473 if (move_2nd) {
474 v[1].x += Dx; v[1].y += Dy;
475 }
476 } else {
477 if (num_pts > 2) {
478 if (possibly_move_3rd_to_last) {
479 /* only for LT_STRUCT_SPLINE */
480 index = num_pts-4;
481 cur_seg_dx = v[index+3].x - v[index].x;
482 cur_seg_dy = v[index+3].y - v[index].y;
483 seg_dx = v[index].x - v[index-3].x;
484 seg_dy = v[index].y - v[index-3].y;
485 } else {
486 index = num_pts-2;
487 cur_seg_dx = v[index+1].x - v[index].x;
488 cur_seg_dy = v[index+1].y - v[index].y;
489 seg_dx = v[index].x - v[index-1].x;
490 seg_dy = v[index].y - v[index-1].y;
491 }
492 }
493 v[num_pts-1].x += Dx; v[num_pts-1].y += Dy;
494 if (move_2nd_to_last) {
495 v[num_pts-2].x += Dx; v[num_pts-2].y += Dy;
496 }
497 }
498 if (poly_ptr->curved == LT_STRUCT_SPLINE) {
499 if (possibly_move_3rd_to_last) {
500 if (cur_seg_dy==0 && cur_seg_dx!=0 &&
501 (seg_dy!=0 || (seg_dy==0 && Dx==0))) {
502 v[index-1].y += Dy;
503 v[index].y += Dy;
504 v[index+1].y += Dy;
505 } else if (cur_seg_dx==0 && cur_seg_dy!=0 &&
506 (seg_dx!=0 || (seg_dx==0 && Dy==0))) {
507 v[index-1].x += Dx;
508 v[index].x += Dx;
509 v[index+1].x += Dx;
510 }
511 }
512 } else {
513 if (num_pts>2 && cur_seg_dy==0 && cur_seg_dx!=0 &&
514 (seg_dy!=0 || (seg_dy==0 && Dx==0))) {
515 v[index].y += Dy;
516 } else if (num_pts>2 && cur_seg_dx==0 && cur_seg_dy!=0 &&
517 (seg_dx!=0 || (seg_dx==0 && Dy==0))) {
518 v[index].x += Dx;
519 }
520 }
521 }
522 AdjObjSplineVs(obj_ptr);
523 if (obj_ptr->detail.p->curved != LT_INTSPLINE) {
524 UpdPolyBBox(obj_ptr, num_pts, v);
525 } else {
526 UpdPolyBBox(obj_ptr, obj_ptr->detail.p->intn,
527 obj_ptr->detail.p->intvlist);
528 }
529 if (AutoCenterAttr(obj_ptr)) {
530 struct AttrRec *attr_ptr=obj_ptr->fattr;
531 int modified=FALSE;
532
533 for ( ; attr_ptr != NULL; attr_ptr=attr_ptr->next) {
534 if (attr_ptr->shown) {
535 struct BBRec bbox;
536
537 CenterObjInOBBox(attr_ptr->obj, obj_ptr->obbox,
538 &bbox);
539 if (bbox.ltx < *ltx) *ltx = bbox.ltx;
540 if (bbox.lty < *lty) *lty = bbox.lty;
541 if (bbox.rbx > *rbx) *rbx = bbox.rbx;
542 if (bbox.rby > *rby) *rby = bbox.rby;
543 modified = TRUE;
544 }
545 }
546 if (modified) AdjObjBBox(obj_ptr);
547 }
548 if (obj_ptr->bbox.ltx < *ltx) *ltx = obj_ptr->bbox.ltx;
549 if (obj_ptr->bbox.lty < *lty) *lty = obj_ptr->bbox.lty;
550 if (obj_ptr->bbox.rbx > *rbx) *rbx = obj_ptr->bbox.rbx;
551 if (obj_ptr->bbox.rby > *rby) *rby = obj_ptr->bbox.rby;
552 RecordReplaceAnObj(obj_ptr);
553 }
554 }
555 }
556 MoveAllSelObjects(Dx, Dy);
557 return something_stretched;
558 }
559
MoveAllSel(Dx,Dy)560 void MoveAllSel(Dx, Dy)
561 register int Dx, Dy;
562 {
563 int ltx=0, lty=0, rbx=0, rby=0;
564 struct SubCmdRec *sub_cmd=NULL;
565
566 sub_cmd = (struct SubCmdRec *)malloc(sizeof(struct SubCmdRec));
567 if (sub_cmd == NULL) FailAllocMessage();
568 memset(sub_cmd, 0, sizeof(struct SubCmdRec));
569 sub_cmd->detail.move.dx = Dx;
570 sub_cmd->detail.move.dy = Dy;
571
572 if (moveMode==CONST_MOVE && !justDupped) {
573 MarkObjectsForMove();
574
575 StartCompositeCmd();
576 PrepareToRecord(CMD_MOVE, topSel, botSel, numObjSelected);
577 RecordCmd(CMD_MOVE, sub_cmd, NULL, NULL, 0);
578 if (ConstrainedMoveAllSel(Dx, Dy, <x, <y, &rbx, &rby)) {
579 ltx = min(ltx,min(selLtX,selLtX+Dx));
580 lty = min(lty,min(selLtY,selLtY+Dy));
581 rbx = max(rbx,max(selRbX,selRbX+Dx));
582 rby = max(rby,max(selRbY,selRbY+Dy));
583 RedrawAnArea(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
584 rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1));
585 } else {
586 RedrawAreas(botObj, selLtX-GRID_ABS_SIZE(1),
587 selLtY-GRID_ABS_SIZE(1),
588 selRbX+GRID_ABS_SIZE(1), selRbY+GRID_ABS_SIZE(1),
589 selLtX-GRID_ABS_SIZE(1)+Dx, selLtY-GRID_ABS_SIZE(1)+Dy,
590 selRbX+GRID_ABS_SIZE(1)+Dx, selRbY+GRID_ABS_SIZE(1)+Dy);
591 }
592 EndCompositeCmd();
593 } else {
594 MoveAllSelObjects(Dx, Dy);
595 PrepareToRecord(CMD_MOVE, topSel, botSel, numObjSelected);
596 RecordCmd(CMD_MOVE, sub_cmd, NULL, NULL, 0);
597 RedrawAreas(botObj, selLtX-GRID_ABS_SIZE(1),
598 selLtY-GRID_ABS_SIZE(1),
599 selRbX+GRID_ABS_SIZE(1), selRbY+GRID_ABS_SIZE(1),
600 selLtX-GRID_ABS_SIZE(1)+Dx, selLtY-GRID_ABS_SIZE(1)+Dy,
601 selRbX+GRID_ABS_SIZE(1)+Dx, selRbY+GRID_ABS_SIZE(1)+Dy);
602 }
603 free(sub_cmd);
604 }
605
MoveAnObj(ObjPtr,TopOwner,Dx,Dy)606 void MoveAnObj(ObjPtr, TopOwner, Dx, Dy)
607 struct ObjRec *ObjPtr, *TopOwner;
608 int Dx, Dy;
609 /* This function is meant to be called from within an internal command */
610 {
611 if (execCurDepth <= 0) {
612 #ifdef _TGIF_DBG /* debug, do not translate */
613 TgAssert(FALSE,
614 "MoveAnObj() called not from an internal command!", NULL);
615 return;
616 #endif /* _TGIF_DBG */
617 }
618 if (ObjPtr == TopOwner) {
619 struct SelRec *saved_top_sel=topSel, *saved_bot_sel=botSel;
620 int ltx=ObjPtr->bbox.ltx, lty=ObjPtr->bbox.lty;
621 int rbx=ObjPtr->bbox.rbx, rby=ObjPtr->bbox.rby;
622 struct SubCmdRec *sub_cmd=NULL;
623
624 topSel = botSel = (struct SelRec *)malloc(sizeof(struct SelRec));
625 if (topSel == NULL) FailAllocMessage();
626 memset(topSel, 0, sizeof(struct SelRec));
627 topSel->next = topSel->prev = NULL;
628 topSel->obj = ObjPtr;
629 UpdSelBBox();
630
631 sub_cmd = (struct SubCmdRec *)malloc(sizeof(struct SubCmdRec));
632 if (sub_cmd == NULL) FailAllocMessage();
633 memset(sub_cmd, 0, sizeof(struct SubCmdRec));
634 sub_cmd->detail.move.dx = Dx;
635 sub_cmd->detail.move.dy = Dy;
636
637 MoveAllSelObjects(Dx, Dy);
638 PrepareToRecord(CMD_MOVE, topSel, botSel, numObjSelected);
639 RecordCmd(CMD_MOVE, sub_cmd, NULL, NULL, 0);
640 RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
641 rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1),
642 ltx-GRID_ABS_SIZE(1)+Dx, lty-GRID_ABS_SIZE(1)+Dy,
643 rbx+GRID_ABS_SIZE(1)+Dx, rby+GRID_ABS_SIZE(1)+Dy);
644
645 free(sub_cmd);
646
647 free(topSel);
648 topSel = saved_top_sel;
649 botSel = saved_bot_sel;
650 UpdSelBBox();
651 } else {
652 int ltx=TopOwner->bbox.ltx, lty=TopOwner->bbox.lty;
653 int rbx=TopOwner->bbox.rbx, rby=TopOwner->bbox.rby;
654
655 PrepareToReplaceAnObj(TopOwner);
656 MoveAttrs(ObjPtr->fattr, Dx, Dy);
657 MoveObj(ObjPtr, Dx, Dy);
658 if (ObjPtr->bbox.ltx < ltx) ltx = ObjPtr->bbox.ltx;
659 if (ObjPtr->bbox.lty < lty) lty = ObjPtr->bbox.lty;
660 if (ObjPtr->bbox.rbx > rbx) rbx = ObjPtr->bbox.rbx;
661 if (ObjPtr->bbox.rby > rby) rby = ObjPtr->bbox.rby;
662 while (ObjPtr != TopOwner) {
663 ObjPtr = ObjPtr->tmp_parent;
664 AdjObjBBox(ObjPtr);
665 if (ObjPtr->bbox.ltx < ltx) ltx = ObjPtr->bbox.ltx;
666 if (ObjPtr->bbox.lty < lty) lty = ObjPtr->bbox.lty;
667 if (ObjPtr->bbox.rbx > rbx) rbx = ObjPtr->bbox.rbx;
668 if (ObjPtr->bbox.rby > rby) rby = ObjPtr->bbox.rby;
669 }
670 RecordReplaceAnObj(TopOwner);
671 RedrawAnArea(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
672 rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1));
673 UpdSelBBox();
674 }
675 }
676
677 typedef struct tagRubberRec {
678 struct BBRec obbox;
679 XPoint *sv, *pv;
680 int sn;
681 int radius; /* for rcbox */
682
683 XPoint *v; /* for oval, poly or polygon */
684 int num_pts, curved, intn; /* for oval, poly or polygon */
685 IntPoint *cntrlv, *polyv; /* for poly or polygon */
686 char *smooth; /* for poly or polygon */
687
688 int ltx, lty, w, h, angle1, angle2, fill; /* for arc */
689 int saved_xc, saved_yc, saved_x1, saved_y1; /* for arc */
690 int saved_x2, saved_y2, saved_ltx, saved_lty; /* for arc */
691 int xc, yc, x1, y1, x2, y2; /* for arc */
692 } RubberInfo;
693
694 static
FreeRubberInfo(pInnerObj,pRubberInfo)695 void FreeRubberInfo(pInnerObj, pRubberInfo)
696 struct ObjRec *pInnerObj;
697 RubberInfo *pRubberInfo;
698 {
699 switch (pInnerObj->type) {
700 case OBJ_ARC:
701 if (pInnerObj->ctm != NULL) {
702 free(pRubberInfo->sv);
703 free(pRubberInfo->pv);
704 }
705 break;
706
707 case OBJ_RCBOX:
708 case OBJ_OVAL:
709 if (pInnerObj->ctm != NULL) {
710 free(pRubberInfo->sv);
711 free(pRubberInfo->pv);
712 }
713 break;
714
715 case OBJ_POLY:
716 case OBJ_POLYGON:
717 if (pRubberInfo->sv != NULL) free(pRubberInfo->sv);
718 if (pRubberInfo->polyv != NULL) free(pRubberInfo->polyv);
719 if (pRubberInfo->smooth != NULL) free(pRubberInfo->smooth);
720 if (pRubberInfo->curved == LT_INTSPLINE &&
721 pRubberInfo->cntrlv != NULL) {
722 free(pRubberInfo->cntrlv);
723 }
724 break;
725 }
726 }
727
728 static
SetRubberInfo(pInnerObj,pRubberInfo)729 void SetRubberInfo(pInnerObj, pRubberInfo)
730 struct ObjRec *pInnerObj;
731 RubberInfo *pRubberInfo;
732 {
733 int i=0, n=0;
734 IntPoint *vs=NULL;
735 char *smooth=NULL;
736 struct PolyRec *poly_ptr=NULL;
737 struct PolygonRec *polygon_ptr=NULL;
738
739 switch (pInnerObj->type) {
740 case OBJ_BOX:
741 case OBJ_XBM:
742 case OBJ_XPM:
743 case OBJ_TEXT:
744 if (pInnerObj->ctm == NULL) {
745 pRubberInfo->obbox.ltx = OFFSET_X(pInnerObj->obbox.ltx);
746 pRubberInfo->obbox.lty = OFFSET_Y(pInnerObj->obbox.lty);
747 pRubberInfo->obbox.rbx = OFFSET_X(pInnerObj->obbox.rbx);
748 pRubberInfo->obbox.rby = OFFSET_Y(pInnerObj->obbox.rby);
749 } else {
750 /* no need to do anything here, everything is computed */
751 }
752 break;
753 case OBJ_RCBOX:
754 if (pInnerObj->ctm == NULL) {
755 pRubberInfo->obbox.ltx = OFFSET_X(pInnerObj->obbox.ltx);
756 pRubberInfo->obbox.lty = OFFSET_Y(pInnerObj->obbox.lty);
757 pRubberInfo->obbox.rbx = OFFSET_X(pInnerObj->obbox.rbx);
758 pRubberInfo->obbox.rby = OFFSET_Y(pInnerObj->obbox.rby);
759 pRubberInfo->radius = pInnerObj->detail.rcb->radius;
760 } else {
761 pRubberInfo->sn = pInnerObj->detail.rcb->rotated_n;
762 pRubberInfo->sv = (XPoint*)malloc(pRubberInfo->sn*sizeof(XPoint));
763 pRubberInfo->pv = (XPoint*)malloc(pRubberInfo->sn*sizeof(XPoint));
764 if (pRubberInfo->sv == NULL || pRubberInfo->pv == NULL) {
765 FailAllocMessage();
766 }
767 for (i=0; i < pRubberInfo->sn; i++) {
768 pRubberInfo->pv[i].x = pInnerObj->detail.rcb->rotated_vlist[i].x;
769 pRubberInfo->pv[i].y = pInnerObj->detail.rcb->rotated_vlist[i].y;
770 }
771 }
772 break;
773 case OBJ_ARC:
774 if (pInnerObj->ctm == NULL) {
775 struct ObjRec *arc_obj_ptr=DupObj(pInnerObj);
776 struct ArcRec *arc_ptr=arc_obj_ptr->detail.a;
777
778 pRubberInfo->fill = arc_ptr->fill;
779 pRubberInfo->ltx = OFFSET_X(arc_ptr->ltx);
780 pRubberInfo->lty = OFFSET_Y(arc_ptr->lty);
781 pRubberInfo->w = OFFSET_X(arc_ptr->ltx+arc_ptr->w)-pRubberInfo->ltx;
782 pRubberInfo->h = OFFSET_Y(arc_ptr->lty+arc_ptr->h)-pRubberInfo->lty;
783 pRubberInfo->angle1 = arc_ptr->angle1;
784 pRubberInfo->angle2 = arc_ptr->angle2;
785 pRubberInfo->xc = OFFSET_X(arc_ptr->xc);
786 pRubberInfo->yc = OFFSET_Y(arc_ptr->yc);
787 pRubberInfo->x1 = OFFSET_X(arc_ptr->x1);
788 pRubberInfo->y1 = OFFSET_Y(arc_ptr->y1);
789 ArcRealX2Y2(arc_ptr, &pRubberInfo->x2, &pRubberInfo->y2);
790 pRubberInfo->x2 = OFFSET_X(pRubberInfo->x2);
791 pRubberInfo->y2 = OFFSET_Y(pRubberInfo->y2);
792 pRubberInfo->saved_xc = pRubberInfo->xc;
793 pRubberInfo->saved_yc = pRubberInfo->yc;
794 pRubberInfo->saved_x1 = pRubberInfo->x1;
795 pRubberInfo->saved_y1 = pRubberInfo->y1;
796 pRubberInfo->saved_x2 = pRubberInfo->x2;
797 pRubberInfo->saved_y2 = pRubberInfo->y2;
798 pRubberInfo->saved_ltx = pRubberInfo->ltx;
799 pRubberInfo->saved_lty = pRubberInfo->lty;
800
801 FreeArcObj(arc_obj_ptr);
802 } else {
803 pRubberInfo->sn = pInnerObj->detail.a->rotated_n;
804 pRubberInfo->sv = (XPoint*)malloc((pRubberInfo->sn+2)*sizeof(XPoint));
805 pRubberInfo->pv = (XPoint*)malloc((pRubberInfo->sn+2)*sizeof(XPoint));
806 if (pRubberInfo->sv == NULL || pRubberInfo->pv == NULL) {
807 FailAllocMessage();
808 }
809 for (i=0; i < pRubberInfo->sn+2; i++) {
810 pRubberInfo->pv[i].x = pInnerObj->detail.a->rotated_vlist[i].x;
811 pRubberInfo->pv[i].y = pInnerObj->detail.a->rotated_vlist[i].y;
812 }
813 }
814 break;
815 case OBJ_OVAL:
816 if (pInnerObj->ctm == NULL) {
817 pRubberInfo->num_pts = 13;
818 pRubberInfo->obbox.ltx = OFFSET_X(pInnerObj->obbox.ltx);
819 pRubberInfo->obbox.lty = OFFSET_Y(pInnerObj->obbox.lty);
820 pRubberInfo->obbox.rbx = OFFSET_X(pInnerObj->obbox.rbx);
821 pRubberInfo->obbox.rby = OFFSET_Y(pInnerObj->obbox.rby);
822 } else {
823 pRubberInfo->sn = pInnerObj->detail.o->rotated_n;
824 pRubberInfo->sv = (XPoint*)malloc(pRubberInfo->sn*sizeof(XPoint));
825 pRubberInfo->pv = (XPoint*)malloc(pRubberInfo->sn*sizeof(XPoint));
826 if (pRubberInfo->sv == NULL || pRubberInfo->pv == NULL) {
827 FailAllocMessage();
828 }
829 for (i=0; i < pRubberInfo->sn; i++) {
830 pRubberInfo->pv[i].x = pInnerObj->detail.o->rotated_vlist[i].x;
831 pRubberInfo->pv[i].y = pInnerObj->detail.o->rotated_vlist[i].y;
832 }
833 }
834 break;
835 case OBJ_POLY:
836 poly_ptr = pInnerObj->detail.p;
837 pRubberInfo->curved = poly_ptr->curved;
838 if (pRubberInfo->curved == LT_STRUCT_SPLINE) {
839 n = poly_ptr->ssn;
840 vs = poly_ptr->ssvlist;
841 smooth = poly_ptr->ssmooth;
842 } else {
843 n = poly_ptr->n;
844 vs = poly_ptr->vlist;
845 smooth = poly_ptr->smooth;
846 }
847 pRubberInfo->num_pts = n;
848 pRubberInfo->polyv =
849 (IntPoint*)malloc((pRubberInfo->num_pts+1)*sizeof(IntPoint));
850 if (pRubberInfo->polyv == NULL) FailAllocMessage();
851 if (pRubberInfo->curved != LT_INTSPLINE && smooth != NULL) {
852 pRubberInfo->smooth = (char*)malloc((n+1)*sizeof(char));
853 if (pRubberInfo->smooth == NULL) FailAllocMessage();
854 }
855 if (pInnerObj->ctm == NULL) {
856 for (i=0; i < pRubberInfo->num_pts; i++) {
857 pRubberInfo->polyv[i].x = vs[i].x;
858 pRubberInfo->polyv[i].y = vs[i].y;
859 if (pRubberInfo->smooth != NULL) {
860 pRubberInfo->smooth[i] = smooth[i];
861 }
862 }
863 } else {
864 for (i=0; i < pRubberInfo->num_pts; i++) {
865 int x=0, y=0;
866
867 TransformPointThroughCTM(vs[i].x-pInnerObj->x, vs[i].y-pInnerObj->y,
868 pInnerObj->ctm, &x, &y);
869 pRubberInfo->polyv[i].x = x+pInnerObj->x;
870 pRubberInfo->polyv[i].y = y+pInnerObj->y;
871 if (pRubberInfo->smooth != NULL) {
872 pRubberInfo->smooth[i] = smooth[i];
873 }
874 }
875 }
876 if (pRubberInfo->curved != LT_INTSPLINE) {
877 pRubberInfo->sv = MakeMultiSplinePolyVertex(pRubberInfo->curved,
878 &pRubberInfo->sn, pRubberInfo->smooth, drawOrigX, drawOrigY,
879 pRubberInfo->num_pts, pRubberInfo->polyv);
880 } else {
881 pRubberInfo->sv = MakeIntSplinePolyVertex(&pRubberInfo->sn,
882 &pRubberInfo->intn, &pRubberInfo->cntrlv, drawOrigX,
883 drawOrigY, pRubberInfo->num_pts, pRubberInfo->polyv);
884 }
885 break;
886 case OBJ_POLYGON:
887 polygon_ptr = pInnerObj->detail.g;
888 pRubberInfo->curved = polygon_ptr->curved;
889 if (pRubberInfo->curved == LT_STRUCT_SPLINE) {
890 n = polygon_ptr->ssn;
891 vs = polygon_ptr->ssvlist;
892 smooth = polygon_ptr->ssmooth;
893 } else {
894 n = polygon_ptr->n;
895 vs = polygon_ptr->vlist;
896 smooth = polygon_ptr->smooth;
897 }
898 pRubberInfo->num_pts = n;
899 pRubberInfo->polyv =
900 (IntPoint*)malloc((pRubberInfo->num_pts+1)*sizeof(IntPoint));
901 if (pRubberInfo->polyv == NULL) FailAllocMessage();
902 if (pRubberInfo->curved != LT_INTSPLINE && smooth != NULL) {
903 pRubberInfo->smooth =
904 (char*)malloc((pRubberInfo->num_pts+1)*sizeof(char));
905 if (pRubberInfo->smooth == NULL) FailAllocMessage();
906 }
907 if (pInnerObj->ctm == NULL) {
908 for (i=0; i < pRubberInfo->num_pts; i++) {
909 pRubberInfo->polyv[i].x = vs[i].x;
910 pRubberInfo->polyv[i].y = vs[i].y;
911 if (pRubberInfo->smooth != NULL) {
912 pRubberInfo->smooth[i] = smooth[i];
913 }
914 }
915 } else {
916 for (i=0; i < pRubberInfo->num_pts; i++) {
917 int x=0, y=0;
918
919 TransformPointThroughCTM(vs[i].x-pInnerObj->x, vs[i].y-pInnerObj->y,
920 pInnerObj->ctm, &x, &y);
921 pRubberInfo->polyv[i].x = x+pInnerObj->x;
922 pRubberInfo->polyv[i].y = y+pInnerObj->y;
923 if (pRubberInfo->smooth != NULL) {
924 pRubberInfo->smooth[i] = smooth[i];
925 }
926 }
927 }
928 if (pRubberInfo->curved != LT_INTSPLINE) {
929 pRubberInfo->sv = MakeMultiSplinePolygonVertex(pRubberInfo->curved,
930 &pRubberInfo->sn, pRubberInfo->smooth, drawOrigX, drawOrigY,
931 pRubberInfo->num_pts, pRubberInfo->polyv);
932 } else {
933 pRubberInfo->sv = MakeIntSplinePolygonVertex(&pRubberInfo->sn,
934 &pRubberInfo->intn, &pRubberInfo->cntrlv, drawOrigX,
935 drawOrigY, pRubberInfo->num_pts, pRubberInfo->polyv);
936 }
937 break;
938 case OBJ_GROUP:
939 case OBJ_ICON:
940 case OBJ_SYM:
941 case OBJ_PIN:
942 pRubberInfo->obbox.ltx = OFFSET_X(pInnerObj->obbox.ltx);
943 pRubberInfo->obbox.lty = OFFSET_Y(pInnerObj->obbox.lty);
944 pRubberInfo->obbox.rbx = OFFSET_X(pInnerObj->obbox.rbx);
945 pRubberInfo->obbox.rby = OFFSET_Y(pInnerObj->obbox.rby);
946 break;
947 }
948 }
949
950 static
DrawInnerRubberObj(pInnerObj,pRubberInfo,dx,dy)951 void DrawInnerRubberObj(pInnerObj, pRubberInfo, dx, dy)
952 struct ObjRec *pInnerObj;
953 RubberInfo *pRubberInfo;
954 int dx, dy;
955 {
956 int i=0;
957
958 switch (pInnerObj->type) {
959 case OBJ_BOX:
960 case OBJ_XBM:
961 case OBJ_XPM:
962 case OBJ_TEXT:
963 if (pInnerObj->ctm == NULL) {
964 SelBox(drawWindow, revDefaultGC,
965 pRubberInfo->obbox.ltx+dx, pRubberInfo->obbox.lty+dy,
966 pRubberInfo->obbox.rbx+dx, pRubberInfo->obbox.rby+dy);
967 } else {
968 XPoint obj_obbox_vs[5];
969
970 for (i=0; i < 5; i++) {
971 obj_obbox_vs[i].x = pInnerObj->rotated_obbox[i].x+dx;
972 obj_obbox_vs[i].y = pInnerObj->rotated_obbox[i].y+dy;
973 }
974 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
975 obj_obbox_vs, 5, CoordModeOrigin);
976 }
977 break;
978 case OBJ_RCBOX:
979 if (pInnerObj->ctm == NULL) {
980 SetRCBoxVertex(
981 pRubberInfo->obbox.ltx+dx, pRubberInfo->obbox.lty+dy,
982 pRubberInfo->obbox.rbx+dx, pRubberInfo->obbox.rby+dy,
983 pRubberInfo->radius);
984 MyRCBox(drawWindow, revDefaultGC,
985 pRubberInfo->obbox.ltx, pRubberInfo->obbox.lty,
986 pRubberInfo->obbox.rbx, pRubberInfo->obbox.rby,
987 pRubberInfo->radius);
988 } else {
989 for (i=0; i < pRubberInfo->sn; i++) {
990 pRubberInfo->sv[i].x = pRubberInfo->pv[i].x + dx;
991 pRubberInfo->sv[i].y = pRubberInfo->pv[i].y + dy;
992 }
993 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
994 pRubberInfo->sv, pRubberInfo->sn, CoordModeOrigin);
995 }
996 break;
997 case OBJ_ARC:
998 if (pInnerObj->ctm == NULL) {
999 if (!(pRubberInfo->fill == NONEPAT ||
1000 (pInnerObj->trans_pat && pRubberInfo->fill == BACKPAT))) {
1001 XDrawLine(mainDisplay, drawWindow, revDefaultGC,
1002 pRubberInfo->xc, pRubberInfo->yc,
1003 pRubberInfo->x1, pRubberInfo->y1);
1004 XDrawLine(mainDisplay, drawWindow, revDefaultGC,
1005 pRubberInfo->xc, pRubberInfo->yc,
1006 pRubberInfo->x2, pRubberInfo->y2);
1007 }
1008 XDrawArc(mainDisplay, drawWindow, revDefaultGC,
1009 pRubberInfo->ltx, pRubberInfo->lty,
1010 pRubberInfo->w, pRubberInfo->h,
1011 pRubberInfo->angle1, pRubberInfo->angle2);
1012 } else {
1013 for (i=0; i < pRubberInfo->sn+2; i++) {
1014 pRubberInfo->sv[i].x = pRubberInfo->pv[i].x + dx;
1015 pRubberInfo->sv[i].y = pRubberInfo->pv[i].y + dy;
1016 }
1017 if (!(pRubberInfo->fill == NONEPAT ||
1018 (pInnerObj->trans_pat && pRubberInfo->fill == BACKPAT))) {
1019 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
1020 pRubberInfo->sv, pRubberInfo->sn+2, CoordModeOrigin);
1021 } else {
1022 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
1023 pRubberInfo->sv, pRubberInfo->sn, CoordModeOrigin);
1024 }
1025 }
1026 break;
1027 case OBJ_OVAL:
1028 if (pInnerObj->ctm == NULL) {
1029 struct BBRec o_bbox;
1030
1031 o_bbox.ltx = pRubberInfo->obbox.ltx+dx;
1032 o_bbox.lty = pRubberInfo->obbox.lty+dy;
1033 o_bbox.rbx = pRubberInfo->obbox.rbx+dx;
1034 o_bbox.rby = pRubberInfo->obbox.rby+dy;
1035 MyOval(drawWindow, revDefaultGC, o_bbox);
1036 } else {
1037 for (i=0; i < pRubberInfo->sn; i++) {
1038 pRubberInfo->sv[i].x = pRubberInfo->pv[i].x + dx;
1039 pRubberInfo->sv[i].y = pRubberInfo->pv[i].y + dy;
1040 }
1041 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
1042 pRubberInfo->sv, pRubberInfo->sn, CoordModeOrigin);
1043 }
1044 break;
1045 case OBJ_POLY:
1046 case OBJ_POLYGON:
1047 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
1048 pRubberInfo->sv, pRubberInfo->sn, CoordModeOrigin);
1049 break;
1050 case OBJ_GROUP:
1051 case OBJ_ICON:
1052 case OBJ_SYM:
1053 case OBJ_PIN:
1054 SelBox(drawWindow, revDefaultGC,
1055 pRubberInfo->obbox.ltx+dx, pRubberInfo->obbox.lty+dy,
1056 pRubberInfo->obbox.rbx+dx, pRubberInfo->obbox.rby+dy);
1057 break;
1058 }
1059 }
1060
1061 static
UpdateInnerRubberObj(pInnerObj,pRubberInfo,dx,dy)1062 void UpdateInnerRubberObj(pInnerObj, pRubberInfo, dx, dy)
1063 struct ObjRec *pInnerObj;
1064 RubberInfo *pRubberInfo;
1065 int dx, dy;
1066 {
1067 int i=0, n=0;
1068 IntPoint *vs=NULL;
1069 struct PolyRec *poly_ptr=NULL;
1070 struct PolygonRec *polygon_ptr=NULL;
1071
1072 switch (pInnerObj->type) {
1073 case OBJ_ARC:
1074 if (pInnerObj->ctm == NULL) {
1075 pRubberInfo->xc = pRubberInfo->saved_xc+dx;
1076 pRubberInfo->yc = pRubberInfo->saved_yc+dy;
1077 pRubberInfo->x1 = pRubberInfo->saved_x1+dx;
1078 pRubberInfo->y1 = pRubberInfo->saved_y1+dy;
1079 pRubberInfo->x2 = pRubberInfo->saved_x2+dx;
1080 pRubberInfo->y2 = pRubberInfo->saved_y2+dy;
1081 pRubberInfo->ltx = pRubberInfo->saved_ltx+dx;
1082 pRubberInfo->lty = pRubberInfo->saved_lty+dy;
1083 }
1084 break;
1085 case OBJ_POLY:
1086 case OBJ_POLYGON:
1087 if (pRubberInfo->sv != NULL) {
1088 free(pRubberInfo->sv);
1089 pRubberInfo->sv = NULL;
1090 }
1091 switch (pInnerObj->type) {
1092 case OBJ_POLY:
1093 poly_ptr = pInnerObj->detail.p;
1094 if (poly_ptr->curved == LT_STRUCT_SPLINE) {
1095 n = poly_ptr->ssn;
1096 vs = poly_ptr->ssvlist;
1097 } else {
1098 n = poly_ptr->n;
1099 vs = poly_ptr->vlist;
1100 }
1101 if (pInnerObj->ctm == NULL) {
1102 for (i=0; i < pRubberInfo->num_pts; i++) {
1103 pRubberInfo->polyv[i].x = vs[i].x+ABS_SIZE(dx);
1104 pRubberInfo->polyv[i].y = vs[i].y+ABS_SIZE(dy);
1105 }
1106 } else {
1107 for (i=0; i < pRubberInfo->num_pts; i++) {
1108 int x=0, y=0;
1109
1110 TransformPointThroughCTM(vs[i].x-pInnerObj->x,
1111 vs[i].y-pInnerObj->y, pInnerObj->ctm, &x, &y);
1112 pRubberInfo->polyv[i].x = x+pInnerObj->x+ABS_SIZE(dx);
1113 pRubberInfo->polyv[i].y = y+pInnerObj->y+ABS_SIZE(dy);
1114 }
1115 }
1116 if (pRubberInfo->curved != LT_INTSPLINE) {
1117 pRubberInfo->sv = MakeMultiSplinePolyVertex(pRubberInfo->curved,
1118 &pRubberInfo->sn, pRubberInfo->smooth, drawOrigX,
1119 drawOrigY, pRubberInfo->num_pts, pRubberInfo->polyv);
1120 } else {
1121 free(pRubberInfo->cntrlv);
1122 pRubberInfo->sv = MakeIntSplinePolyVertex(&pRubberInfo->sn,
1123 &pRubberInfo->intn, &pRubberInfo->cntrlv, drawOrigX,
1124 drawOrigY, pRubberInfo->num_pts, pRubberInfo->polyv);
1125 }
1126 break;
1127 case OBJ_POLYGON:
1128 polygon_ptr = pInnerObj->detail.g;
1129 if (polygon_ptr->curved == LT_STRUCT_SPLINE) {
1130 n = polygon_ptr->ssn;
1131 vs = polygon_ptr->ssvlist;
1132 } else {
1133 n = polygon_ptr->n;
1134 vs = polygon_ptr->vlist;
1135 }
1136 if (pInnerObj->ctm == NULL) {
1137 for (i=0; i < pRubberInfo->num_pts; i++) {
1138 pRubberInfo->polyv[i].x = vs[i].x+ABS_SIZE(dx);
1139 pRubberInfo->polyv[i].y = vs[i].y+ABS_SIZE(dy);
1140 }
1141 } else {
1142 for (i=0; i < pRubberInfo->num_pts; i++) {
1143 int x=0, y=0;
1144
1145 TransformPointThroughCTM(vs[i].x-pInnerObj->x,
1146 vs[i].y-pInnerObj->y, pInnerObj->ctm, &x, &y);
1147 pRubberInfo->polyv[i].x = x+pInnerObj->x+ABS_SIZE(dx);
1148 pRubberInfo->polyv[i].y = y+pInnerObj->y+ABS_SIZE(dy);
1149 }
1150 }
1151 if (pRubberInfo->curved != LT_INTSPLINE) {
1152 pRubberInfo->sv = MakeMultiSplinePolygonVertex(pRubberInfo->curved,
1153 &pRubberInfo->sn, pRubberInfo->smooth, drawOrigX, drawOrigY,
1154 pRubberInfo->num_pts, pRubberInfo->polyv);
1155 } else {
1156 free(pRubberInfo->cntrlv);
1157 pRubberInfo->sv = MakeIntSplinePolygonVertex(&pRubberInfo->sn,
1158 &pRubberInfo->intn, &pRubberInfo->cntrlv, drawOrigX,
1159 drawOrigY, pRubberInfo->num_pts, pRubberInfo->polyv);
1160 }
1161 break;
1162 }
1163 break;
1164 }
1165 }
1166
1167 static
MoveSubObjEventCheck(ev,pn_move_sub_obj)1168 void MoveSubObjEventCheck(ev, pn_move_sub_obj)
1169 XEvent *ev;
1170 int *pn_move_sub_obj;
1171 {
1172 if (ev->type == MotionNotify) {
1173 *pn_move_sub_obj = (ev->xmotion.state & ControlMask) &&
1174 (!(ev->xmotion.state & ShiftMask));
1175 } else if (ev->type == KeyPress || ev->type == KeyRelease) {
1176 char s[80];
1177 KeySym key_sym;
1178
1179 XLookupString(&(ev->xkey), s, sizeof(s), &key_sym, NULL);
1180 if (key_sym == XK_Control_L || key_sym == XK_Control_R) {
1181 *pn_move_sub_obj = (ev->type == KeyPress);
1182 }
1183 }
1184 }
1185
MoveAnAttr(attr_ptr,attr_owner_obj,dx,dy)1186 void MoveAnAttr(attr_ptr, attr_owner_obj, dx, dy)
1187 struct AttrRec *attr_ptr;
1188 struct ObjRec *attr_owner_obj;
1189 int dx, dy;
1190 {
1191 struct ObjRec *text_obj_ptr=attr_ptr->obj;
1192 int ltx, lty, rbx, rby;
1193
1194 if (attr_owner_obj == NULL) {
1195 attr_owner_obj = GetTopOwner(attr_ptr->owner);
1196 }
1197 ltx = attr_owner_obj->bbox.ltx;
1198 lty = attr_owner_obj->bbox.lty;
1199 rbx = attr_owner_obj->bbox.rbx;
1200 rby = attr_owner_obj->bbox.rby;
1201 PrepareToReplaceAnObj(attr_owner_obj);
1202 MoveObj(text_obj_ptr, dx, dy);
1203 RecursivelyAdjObjBBox(attr_ptr->owner, attr_ptr->owner, attr_owner_obj);
1204 RecordReplaceAnObj(attr_owner_obj);
1205 RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
1206 rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1),
1207 attr_owner_obj->bbox.ltx-GRID_ABS_SIZE(1),
1208 attr_owner_obj->bbox.lty-GRID_ABS_SIZE(1),
1209 attr_owner_obj->bbox.rbx+GRID_ABS_SIZE(1),
1210 attr_owner_obj->bbox.rby+GRID_ABS_SIZE(1));
1211 SetFileModified(TRUE);
1212 }
1213
MoveSel(OrigX,OrigY,ObjPtr,down_button_ev)1214 void MoveSel(OrigX, OrigY, ObjPtr, down_button_ev)
1215 int OrigX, OrigY;
1216 struct ObjRec *ObjPtr;
1217 XButtonEvent *down_button_ev;
1218 {
1219 int sel_ltx=0, sel_lty=0, sel_rbx=0, sel_rby=0;
1220 int ruler_ltx=0, ruler_lty=0, ruler_rbx=0, ruler_rby=0;
1221 int moving=TRUE, dx=0, dy=0, grid_x=OrigX, grid_y=OrigY;
1222 int can_move_sub_obj=FALSE, move_sub_obj=FALSE, no_no_lock_sel=FALSE;
1223 char buf[80], x_buf[80], y_buf[80];
1224 XEvent ev;
1225 Time down_click_time=(Time)0;
1226 RubberInfo rubber_info;
1227
1228 if (down_button_ev != NULL) {
1229 down_click_time = down_button_ev->time;
1230 }
1231 if (numObjSelected == numObjLocked || ObjPtr->locked) {
1232 no_no_lock_sel = TRUE;
1233 }
1234 XFlush(mainDisplay);
1235 XSync(mainDisplay, False);
1236
1237 if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev) ||
1238 XCheckMaskEvent(mainDisplay, VisibilityChangeMask, &ev)) {
1239 ExposeEventHandler(&ev, TRUE);
1240 }
1241 if (ObjPtr->type == OBJ_TEXT && ObjPtr->detail.t->attr != NULL) {
1242 can_move_sub_obj = TRUE;
1243 SetStringStatus(TgLoadString(STID_HINT_CTL_MOVE_ATTR_ONLY));
1244 }
1245 if (!move_sub_obj && !no_no_lock_sel) {
1246 sel_ltx = OFFSET_X(selNoLockLtX)-1; sel_lty = OFFSET_Y(selNoLockLtY)-1;
1247 sel_rbx = OFFSET_X(selNoLockRbX)+1; sel_rby = OFFSET_Y(selNoLockRbY)+1;
1248 }
1249 ruler_ltx = OFFSET_X(selNoLockObjLtX); ruler_lty = OFFSET_Y(selNoLockObjLtY);
1250 ruler_rbx = OFFSET_X(selNoLockObjRbX); ruler_rby = OFFSET_Y(selNoLockObjRbY);
1251
1252 if (!move_sub_obj && !no_no_lock_sel) {
1253 SelBox(drawWindow, revDefaultGC, sel_ltx, sel_lty, sel_rbx, sel_rby);
1254 }
1255 PixelToMeasurementUnit(x_buf, 0);
1256 PixelToMeasurementUnit(y_buf, 0);
1257 if (VerboseMeasureTooltip()) {
1258 sprintf(buf, "dx=%s dy=%s", x_buf, y_buf);
1259 } else {
1260 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
1261 }
1262 StartShowMeasureCursor(OrigX, OrigY, buf, TRUE);
1263 BeginIntervalRulers(ruler_ltx, ruler_lty, ruler_rbx, ruler_rby);
1264
1265 memset(&rubber_info, 0, sizeof(RubberInfo));
1266 SetRubberInfo(ObjPtr, &rubber_info);
1267 DrawInnerRubberObj(ObjPtr, &rubber_info, 0, 0);
1268
1269 if (!debugNoPointerGrab) {
1270 XGrabPointer(mainDisplay, drawWindow, FALSE,
1271 PointerMotionMask | ButtonReleaseMask,
1272 GrabModeAsync, GrabModeAsync, None, moveCursor, CurrentTime);
1273 }
1274 dx = dy = 0;
1275
1276 while (moving) {
1277 XEvent input;
1278
1279 XNextEvent(mainDisplay, &input);
1280
1281 if (input.type == Expose || input.type == VisibilityNotify) {
1282 ExposeEventHandler(&input, TRUE);
1283 } else if (input.type == ButtonRelease) {
1284 Time release_time=input.xbutton.time;
1285
1286 XUngrabPointer(mainDisplay, CurrentTime);
1287 XSync(mainDisplay, False);
1288 moving = FALSE;
1289
1290 EndIntervalRulers(grid_x, grid_y);
1291 PixelToMeasurementUnit(x_buf, ABS_SIZE(dx));
1292 PixelToMeasurementUnit(y_buf, ABS_SIZE(dy));
1293 if (VerboseMeasureTooltip()) {
1294 sprintf(buf, "dx=%s dy=%s", x_buf, y_buf);
1295 } else {
1296 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
1297 }
1298 EndShowMeasureCursor(grid_x, grid_y, buf, TRUE);
1299 if (!move_sub_obj && !no_no_lock_sel) {
1300 SelBox(drawWindow, revDefaultGC, sel_ltx+dx, sel_lty+dy, sel_rbx+dx,
1301 sel_rby+dy);
1302 }
1303 DrawInnerRubberObj(ObjPtr, &rubber_info, dx, dy);
1304
1305 dx = grid_x - OrigX;
1306 dy = grid_y - OrigY;
1307
1308 if (oneMotionSelectMove && down_button_ev != NULL &&
1309 (release_time-down_click_time) < oneMotionTimeout) {
1310 dx = dy = 0;
1311 } else if (!oneMotionSelectMove && down_button_ev != NULL &&
1312 (release_time-down_click_time) < minMoveInterval) {
1313 dx = dy = 0;
1314 }
1315 } else if (input.type == MotionNotify || input.type == KeyPress ||
1316 input.type == KeyRelease) {
1317 int x=0, y=0, saved_move_sub_obj=move_sub_obj;
1318
1319 PixelToMeasurementUnit(x_buf, ABS_SIZE(dx));
1320 PixelToMeasurementUnit(y_buf, ABS_SIZE(dy));
1321 if (VerboseMeasureTooltip()) {
1322 sprintf(buf, "dx=%s dy=%s", x_buf, y_buf);
1323 } else {
1324 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
1325 }
1326 ShowMeasureCursor(grid_x, grid_y, buf, TRUE);
1327 if (input.type == KeyPress || input.type == KeyRelease) {
1328 x = grid_x;
1329 y = grid_y;
1330 } else {
1331 x = input.xmotion.x;
1332 y = input.xmotion.y;
1333 }
1334 if (shiftForDiagMouseMove && DiagEventCheck(&input)) {
1335 if (useRecentDupDistance && justDupped &&
1336 useRecentForDiagMouseMove) {
1337 DiagGridXY(OrigX-ZOOMED_SIZE(dupDx), OrigY-ZOOMED_SIZE(dupDy),
1338 &x, &y);
1339 } else {
1340 DiagGridXY(OrigX, OrigY, &x, &y);
1341 }
1342 } else if (can_move_sub_obj) {
1343 MoveSubObjEventCheck(&input, &move_sub_obj);
1344 }
1345 GridXY(x, y, &grid_x, &grid_y);
1346
1347 /* erase */
1348 DrawInnerRubberObj(ObjPtr, &rubber_info, dx, dy);
1349 if (!saved_move_sub_obj && !no_no_lock_sel) {
1350 SelBox(drawWindow, revDefaultGC, sel_ltx+dx, sel_lty+dy, sel_rbx+dx,
1351 sel_rby+dy);
1352 }
1353 dx = grid_x - OrigX;
1354 dy = grid_y - OrigY;
1355
1356 if ((dx != 0 || dy != 0) &&
1357 (numObjSelected == numObjLocked || ObjPtr->locked)) {
1358 XUngrabPointer(mainDisplay, CurrentTime);
1359 XSync(mainDisplay, False);
1360
1361 EndIntervalRulers(grid_x, grid_y);
1362 PixelToMeasurementUnit(x_buf, ABS_SIZE(dx));
1363 PixelToMeasurementUnit(y_buf, ABS_SIZE(dy));
1364 if (VerboseMeasureTooltip()) {
1365 sprintf(buf, "dx=%s dy=%s", x_buf, y_buf);
1366 } else {
1367 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
1368 }
1369 ShowMeasureCursor(grid_x, grid_y, buf, TRUE);
1370 EndShowMeasureCursor(grid_x, grid_y, buf, TRUE);
1371 if (!move_sub_obj && !no_no_lock_sel) {
1372 SelBox(drawWindow, revDefaultGC, sel_ltx+dx, sel_lty+dy,
1373 sel_rbx+dx, sel_rby+dy);
1374 }
1375 MsgBox(TgLoadString(STID_LOCKED_OBJS_CANT_BE_MOVED), TOOL_NAME,
1376 INFO_MB);
1377 return;
1378 }
1379 PixelToMeasurementUnit(x_buf, ABS_SIZE(dx));
1380 PixelToMeasurementUnit(y_buf, ABS_SIZE(dy));
1381 if (VerboseMeasureTooltip()) {
1382 sprintf(buf, "dx=%s dy=%s", x_buf, y_buf);
1383 } else {
1384 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
1385 }
1386 DrawIntervalRulers(ruler_ltx+dx, ruler_lty+dy, ruler_rbx+dx,
1387 ruler_rby+dy, buf);
1388 if (!move_sub_obj && !no_no_lock_sel) {
1389 SelBox(drawWindow, revDefaultGC, sel_ltx+dx, sel_lty+dy, sel_rbx+dx,
1390 sel_rby+dy);
1391 }
1392 ShowMeasureCursor(grid_x, grid_y, buf, TRUE);
1393
1394 UpdateInnerRubberObj(ObjPtr, &rubber_info, dx, dy);
1395 DrawInnerRubberObj(ObjPtr, &rubber_info, dx, dy);
1396
1397 while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &ev)) ;
1398 }
1399 }
1400 FreeRubberInfo(ObjPtr, &rubber_info);
1401
1402 if (dx != 0 || dy != 0) {
1403 if (numObjSelected == numObjLocked || ObjPtr->locked) {
1404 MsgBox(TgLoadString(STID_LOCKED_OBJS_CANT_BE_MOVED), TOOL_NAME,
1405 INFO_MB);
1406 return;
1407 }
1408 HighLightReverse();
1409 dx = ABS_SIZE(dx);
1410 dy = ABS_SIZE(dy);
1411 if (numObjSelected == numObjLocked) {
1412 HighLightForward();
1413 return;
1414 }
1415 if (can_move_sub_obj && move_sub_obj) {
1416 MoveAnAttr(ObjPtr->detail.t->attr, NULL, dx, dy);
1417 } else {
1418 MoveAllSel(dx, dy);
1419 }
1420 HighLightForward();
1421 UpdSelBBox();
1422 if (justDupped) {
1423 dupDx += dx;
1424 dupDy += dy;
1425 }
1426 SetFileModified(TRUE);
1427 }
1428 if (can_move_sub_obj) {
1429 ShowCurChoiceMouseStatus(curChoice, 0, FALSE);
1430 }
1431 }
1432
1433 static
IsSmoothForStructuredSpline(vlist_index,n,vlist)1434 int IsSmoothForStructuredSpline(vlist_index, n, vlist)
1435 int vlist_index, n;
1436 IntPoint *vlist;
1437 {
1438 int i=0, j=0, num_hinge_vs=(n+2)/3;
1439
1440 #ifdef _TGIF_DBG /* debug, do not translate */
1441 TgAssert((n+2)%3 == 0,
1442 "invalid n in IsSmoothForStructuredSpline()", NULL);
1443 #endif /* _TGIF_DBG */
1444 for (i=0, j=0; i < num_hinge_vs; i++, j+=3) {
1445 if (vlist_index > j+1) continue;
1446 if (i == 0) {
1447 if (vlist_index == j) {
1448 return FALSE;
1449 }
1450 return (vlist[0].x != vlist[1].x || vlist[0].y != vlist[1].y);
1451 } else if (i == num_hinge_vs-1) {
1452 if (vlist_index == j) {
1453 return FALSE;
1454 }
1455 return (vlist[n-1].x != vlist[n-2].x || vlist[n-1].y != vlist[n-2].y);
1456 } else {
1457 if (vlist_index == j) {
1458 return FALSE;
1459 }
1460 return (vlist[j-1].x != vlist[j].x || vlist[j-1].y != vlist[j].y);
1461 }
1462 }
1463 return FALSE;
1464 }
1465
FinishMoveVertexForStretchStructSpline(vsel_ptr,abs_dx,abs_dy,psssi)1466 void FinishMoveVertexForStretchStructSpline(vsel_ptr, abs_dx, abs_dy, psssi)
1467 struct VSelRec *vsel_ptr;
1468 int abs_dx, abs_dy;
1469 StretchStructuredSplineInfo *psssi;
1470 {
1471 struct ObjRec *obj_ptr=NULL;
1472 struct PolyRec *poly_ptr=NULL;
1473 struct PolygonRec *polygon_ptr=NULL;
1474 int was_smooth_point=(!psssi->hinge), vlist_index=0;
1475
1476 obj_ptr = vsel_ptr->obj;
1477 switch (obj_ptr->type) {
1478 case OBJ_POLY:
1479 poly_ptr = obj_ptr->detail.p;
1480 break;
1481 case OBJ_POLYGON:
1482 polygon_ptr = obj_ptr->detail.g;
1483 break;
1484 }
1485 if (was_smooth_point) {
1486 vlist_index = GetVlistIndexFromStretchStructuredSplineInfo(psssi,
1487 vsel_ptr->v_index[0]);
1488 }
1489 if (poly_ptr != NULL) {
1490 UpdateObjForStretchStructSpline(obj_ptr, poly_ptr->n,
1491 poly_ptr->vlist, abs_dx, abs_dy, psssi);
1492 if (was_smooth_point && !IsSmoothForStructuredSpline(vlist_index,
1493 poly_ptr->n, poly_ptr->vlist)) {
1494 if (!psssi->prev_valid) {
1495 /* first poly point */
1496 vsel_ptr->v_index[0] -= 1;
1497 } else if (!psssi->next_valid) {
1498 /* last poly point */
1499 /* merge with next point, so don't need to do anything */
1500 } else {
1501 if (!psssi->earlier_smooth_selected) {
1502 vsel_ptr->v_index[0] -= 2;
1503 } else {
1504 /* merge with next point, so don't need to do anything */
1505 }
1506 }
1507 SetIPTInfoForStretchPoly(vsel_ptr->v_index[0], poly_ptr->n,
1508 poly_ptr->vlist, psssi);
1509 }
1510 } else if (polygon_ptr != NULL) {
1511 UpdateObjForStretchStructSpline(obj_ptr, polygon_ptr->n,
1512 polygon_ptr->vlist, abs_dx, abs_dy, psssi);
1513 if (was_smooth_point && !IsSmoothForStructuredSpline(vlist_index,
1514 polygon_ptr->n, polygon_ptr->vlist)) {
1515 if (psssi->orig_hinge_index == 0 ||
1516 psssi->orig_hinge_index == polygon_ptr->n-1) {
1517 vsel_ptr->v_index[0] = 0;
1518 } else if (!psssi->earlier_smooth_selected) {
1519 if (vsel_ptr->v_index[0] == 1) {
1520 vsel_ptr->v_index[0] -= 1;
1521 } else {
1522 vsel_ptr->v_index[0] -= 2;
1523 }
1524 }
1525 SetIPTInfoForStretchPolygon(vsel_ptr->v_index[0], polygon_ptr->n,
1526 polygon_ptr->vlist, psssi);
1527 }
1528 }
1529 }
1530
MoveAllSelVs(abs_dx,abs_dy)1531 void MoveAllSelVs(abs_dx, abs_dy)
1532 int abs_dx, abs_dy;
1533 {
1534 int i;
1535 IntPoint *v=NULL;
1536 struct ObjRec *obj_ptr=NULL;
1537 struct VSelRec *vsel_ptr=NULL;
1538 int n=0, ltx=selLtX, lty=selLtY, rbx=selRbX, rby=selRbY;
1539
1540 StartCompositeCmd();
1541 for (vsel_ptr=botVSel; vsel_ptr != NULL; vsel_ptr=vsel_ptr->prev) {
1542 int auto_retracted_arrow=FALSE, curved=(-1);
1543 struct PolyRec *poly_ptr=NULL;
1544 struct PolygonRec *polygon_ptr=NULL;
1545 StretchStructuredSplineInfo *psssi=NULL;
1546
1547 obj_ptr = vsel_ptr->obj;
1548 switch (obj_ptr->type) {
1549 case OBJ_POLY:
1550 poly_ptr = obj_ptr->detail.p;
1551 curved = poly_ptr->curved;
1552 if (curved == LT_STRUCT_SPLINE) {
1553 v = poly_ptr->ssvlist;
1554 n = poly_ptr->ssn;
1555 psssi = (StretchStructuredSplineInfo*)(obj_ptr->userdata);
1556 if (psssi == NULL) {
1557 psssi = (StretchStructuredSplineInfo*)malloc(
1558 sizeof(StretchStructuredSplineInfo));
1559 if (psssi == NULL) FailAllocMessage();
1560 memset(psssi, 0, sizeof(StretchStructuredSplineInfo));
1561 obj_ptr->userdata = vsel_ptr->obj->userdata = psssi;
1562 SetIPTInfoForStretchPoly(vsel_ptr->v_index[0], poly_ptr->n,
1563 poly_ptr->vlist, psssi);
1564 }
1565 } else {
1566 v = poly_ptr->vlist;
1567 n = poly_ptr->n;
1568 }
1569 auto_retracted_arrow = AutoRetractedArrowAttr(obj_ptr, TRUE);
1570 break;
1571 case OBJ_POLYGON:
1572 polygon_ptr = obj_ptr->detail.g;
1573 curved = polygon_ptr->curved;
1574 if (curved == LT_STRUCT_SPLINE) {
1575 v = polygon_ptr->ssvlist;
1576 n = polygon_ptr->ssn;
1577 psssi = (StretchStructuredSplineInfo*)(obj_ptr->userdata);
1578 if (psssi == NULL) {
1579 psssi = (StretchStructuredSplineInfo*)malloc(
1580 sizeof(StretchStructuredSplineInfo));
1581 if (psssi == NULL) FailAllocMessage();
1582 memset(psssi, 0, sizeof(StretchStructuredSplineInfo));
1583 obj_ptr->userdata = vsel_ptr->obj->userdata = psssi;
1584 SetIPTInfoForStretchPolygon(vsel_ptr->v_index[0], polygon_ptr->n,
1585 polygon_ptr->vlist, psssi);
1586 }
1587 } else {
1588 v = polygon_ptr->vlist;
1589 n = polygon_ptr->n;
1590 }
1591 break;
1592 }
1593 PrepareToReplaceAnObj(obj_ptr);
1594 if (obj_ptr->ctm == NULL) {
1595 for (i=0; i < vsel_ptr->n; i++) {
1596 vsel_ptr->x[i] += abs_dx;
1597 vsel_ptr->y[i] += abs_dy;
1598 v[vsel_ptr->v_index[i]].x += abs_dx;
1599 v[vsel_ptr->v_index[i]].y += abs_dy;
1600 }
1601 } else {
1602 for (i=0; i < vsel_ptr->n; i++) {
1603 int x=0, y=0, x2=0, y2=0;
1604
1605 /*
1606 * vsel_ptr->x[i] += abs_dx;
1607 * vsel_ptr->y[i] += abs_dy;
1608 */
1609 ReverseTransformPointThroughCTM(vsel_ptr->x[i]+abs_dx-obj_ptr->x,
1610 vsel_ptr->y[i]+abs_dy-obj_ptr->y, obj_ptr->ctm, &x, &y);
1611 v[vsel_ptr->v_index[i]].x = x + obj_ptr->x;
1612 v[vsel_ptr->v_index[i]].y = y + obj_ptr->y;
1613 TransformPointThroughCTM(x, y, obj_ptr->ctm, &x2, &y2);
1614 vsel_ptr->x[i] = x2 + obj_ptr->x;
1615 vsel_ptr->y[i] = y2 + obj_ptr->y;
1616 }
1617 }
1618 if (curved == LT_STRUCT_SPLINE) {
1619 #ifdef _TGIF_DBG /* debug, do not translate */
1620 TgAssert(obj_ptr->userdata != NULL,
1621 "obj_ptr is NULL in MoveAllSelVs()", NULL);
1622 #endif /* _TGIF_DBG */
1623 FinishMoveVertexForStretchStructSpline(vsel_ptr, abs_dx, abs_dy,
1624 psssi);
1625 free(psssi);
1626 obj_ptr->userdata = NULL;
1627 }
1628 AdjObjSplineVs(obj_ptr);
1629 if (auto_retracted_arrow) {
1630 for (i=0; i < vsel_ptr->n; i++) {
1631 if (vsel_ptr->v_index[i] == 1) {
1632 vsel_ptr->x[i] = v[1].x;
1633 vsel_ptr->y[i] = v[1].y;
1634 }
1635 }
1636 }
1637 switch (obj_ptr->type) {
1638 case OBJ_POLY:
1639 if (obj_ptr->detail.p->curved != LT_INTSPLINE) {
1640 UpdPolyBBox(obj_ptr, n, v);
1641 } else {
1642 UpdPolyBBox(obj_ptr, obj_ptr->detail.p->intn,
1643 obj_ptr->detail.p->intvlist);
1644 }
1645 break;
1646 case OBJ_POLYGON:
1647 if (obj_ptr->detail.g->curved != LT_INTSPLINE) {
1648 UpdPolyBBox(obj_ptr, n, v);
1649 } else {
1650 UpdPolyBBox(obj_ptr, obj_ptr->detail.g->intn,
1651 obj_ptr->detail.g->intvlist);
1652 }
1653 break;
1654 }
1655 RecordReplaceAnObj(obj_ptr);
1656 }
1657 EndCompositeCmd();
1658 UpdSelBBox();
1659 RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
1660 rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1),
1661 selLtX-GRID_ABS_SIZE(1), selLtY-GRID_ABS_SIZE(1),
1662 selRbX+GRID_ABS_SIZE(1), selRbY+GRID_ABS_SIZE(1));
1663 }
1664
1665 static struct ObjRec *tmpTopObj=NULL, *tmpBotObj=NULL;
1666
1667 #define FORWARD 0
1668 #define REVERSE 1
1669
1670 static
EndMoveVsForStructuredSpline(obj_ptr,abs_dx,abs_dy)1671 void EndMoveVsForStructuredSpline(obj_ptr, abs_dx, abs_dy)
1672 struct ObjRec *obj_ptr;
1673 int abs_dx, abs_dy;
1674 {
1675 StretchStructuredSplineInfo *psssi=
1676 (StretchStructuredSplineInfo*)(obj_ptr->userdata);
1677
1678 if (psssi != NULL) {
1679 if (psssi->sv != NULL) {
1680 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
1681 psssi->sv, psssi->sn, CoordModeOrigin);
1682 free(psssi->sv);
1683 psssi->sv = NULL;
1684 }
1685 if (psssi->sv2 != NULL) {
1686 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
1687 psssi->sv2, psssi->sn2, CoordModeOrigin);
1688 free(psssi->sv2);
1689 psssi->sv2 = NULL;
1690 }
1691 EraseHighLightForStretchStructSpline(psssi, abs_dx, abs_dy, FALSE, TRUE);
1692 }
1693 }
1694
1695 static
EndMoveVs(abs_dx,abs_dy)1696 void EndMoveVs(abs_dx, abs_dy)
1697 int abs_dx, abs_dy;
1698 {
1699 int i=0;
1700 struct ObjRec *obj_ptr=NULL, *next_obj=NULL;
1701 struct PolyRec *poly_ptr=NULL;
1702 struct PolygonRec *polygon_ptr=NULL;
1703
1704 for (obj_ptr=tmpTopObj; obj_ptr != NULL; obj_ptr = next_obj) {
1705 next_obj = obj_ptr->next;
1706 switch (obj_ptr->type) {
1707 case OBJ_POLY:
1708 poly_ptr = obj_ptr->detail.p;
1709 if (poly_ptr->vlist != NULL) {
1710 free(poly_ptr->vlist);
1711 poly_ptr->vlist = NULL;
1712 }
1713 if (poly_ptr->svlist != NULL) {
1714 free(poly_ptr->svlist);
1715 poly_ptr->svlist = NULL;
1716 }
1717 if (poly_ptr->curved == LT_INTSPLINE &&
1718 poly_ptr->intvlist != NULL) {
1719 free(poly_ptr->intvlist);
1720 poly_ptr->intvlist = NULL;
1721 } else if (poly_ptr->curved == LT_STRUCT_SPLINE) {
1722 EndMoveVsForStructuredSpline(obj_ptr, 0, 0);
1723 for (i=0; i < poly_ptr->ssn; i++) {
1724 if (poly_ptr->ssmooth[i]) {
1725 MARKHO(drawWindow, revDefaultGC,
1726 OFFSET_X(poly_ptr->ssvlist[i].x),
1727 OFFSET_Y(poly_ptr->ssvlist[i].y));
1728 } else {
1729 MARKHR(drawWindow, revDefaultGC,
1730 OFFSET_X(poly_ptr->ssvlist[i].x),
1731 OFFSET_Y(poly_ptr->ssvlist[i].y));
1732 }
1733 }
1734 }
1735 free(poly_ptr);
1736 break;
1737 case OBJ_POLYGON:
1738 polygon_ptr = obj_ptr->detail.g;
1739 if (polygon_ptr->vlist != NULL) {
1740 free(polygon_ptr->vlist);
1741 polygon_ptr->vlist = NULL;
1742 }
1743 if (polygon_ptr->svlist != NULL) {
1744 free(polygon_ptr->svlist);
1745 polygon_ptr->svlist = NULL;
1746 }
1747 if (polygon_ptr->curved == LT_INTSPLINE &&
1748 polygon_ptr->intvlist != NULL) {
1749 free(polygon_ptr->intvlist);
1750 polygon_ptr->intvlist = NULL;
1751 } else if (polygon_ptr->curved == LT_STRUCT_SPLINE) {
1752 EndMoveVsForStructuredSpline(obj_ptr, 0, 0);
1753 for (i=0; i < polygon_ptr->ssn; i++) {
1754 if (polygon_ptr->ssmooth[i]) {
1755 MARKHO(drawWindow, revDefaultGC,
1756 OFFSET_X(polygon_ptr->ssvlist[i].x),
1757 OFFSET_Y(polygon_ptr->ssvlist[i].y));
1758 } else {
1759 MARKHR(drawWindow, revDefaultGC,
1760 OFFSET_X(polygon_ptr->ssvlist[i].x),
1761 OFFSET_Y(polygon_ptr->ssvlist[i].y));
1762 }
1763 }
1764 }
1765 free(polygon_ptr);
1766 break;
1767 }
1768 free(obj_ptr);
1769 }
1770 }
1771
1772 static
PrepareToMoveVs()1773 void PrepareToMoveVs()
1774 {
1775 struct VSelRec *vsel_ptr=NULL;
1776
1777 tmpTopObj = tmpBotObj = NULL;
1778 for (vsel_ptr=botVSel; vsel_ptr != NULL; vsel_ptr=vsel_ptr->prev) {
1779 struct ObjRec *obj_ptr=NULL;
1780 struct PolyRec *poly_ptr=NULL, *poly_copy=NULL;
1781 struct PolygonRec *polygon_ptr=NULL, *polygon_copy=NULL;
1782 XPoint *sv=NULL;
1783 IntPoint *polyv=NULL, *polyssv=NULL, *cntrlv=NULL;
1784 int i=0, num_pts=0, sn=0, curved=(-1), intn=0, ssn=0;
1785 char *smooth=NULL, *ssmooth=NULL;
1786 StretchStructuredSplineInfo *psssi=NULL;
1787
1788 obj_ptr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
1789 if (obj_ptr == NULL) FailAllocMessage();
1790 memset(obj_ptr, 0, sizeof(struct ObjRec));
1791 obj_ptr->prev = NULL;
1792 obj_ptr->next = tmpTopObj;
1793 obj_ptr->ctm = NULL;
1794 if (tmpTopObj == NULL) {
1795 tmpBotObj = obj_ptr;
1796 } else {
1797 tmpTopObj->prev = obj_ptr;
1798 }
1799 tmpTopObj = obj_ptr;
1800 obj_ptr->type = vsel_ptr->obj->type;
1801
1802 switch (vsel_ptr->obj->type) {
1803 case OBJ_POLY:
1804 poly_copy = (struct PolyRec *)malloc(sizeof(struct PolyRec));
1805 if (poly_copy == NULL) FailAllocMessage();
1806 memset(poly_copy, 0, sizeof(struct PolyRec));
1807 obj_ptr->detail.p = poly_copy;
1808
1809 poly_ptr = vsel_ptr->obj->detail.p;
1810 curved = poly_copy->curved = poly_ptr->curved;
1811 num_pts = poly_copy->n = poly_ptr->n;
1812 if (curved == LT_STRUCT_SPLINE) {
1813 ssn = poly_copy->ssn = poly_ptr->ssn;
1814 }
1815 polyv = (IntPoint*)malloc((num_pts+1)*sizeof(IntPoint));
1816 if (polyv == NULL) FailAllocMessage();
1817 if (curved == LT_STRUCT_SPLINE) {
1818 polyssv = (IntPoint*)malloc((ssn+2)*sizeof(IntPoint));
1819 if (polyssv == NULL) FailAllocMessage();
1820 }
1821 if (curved == LT_STRUCT_SPLINE || ((curved == LT_STRAIGHT ||
1822 curved == LT_SPLINE) && poly_ptr->smooth != NULL)) {
1823 if (poly_ptr->smooth != NULL) {
1824 smooth = (char*)malloc((num_pts+1)*sizeof(char));
1825 if (smooth == NULL) FailAllocMessage();
1826 }
1827 if (curved == LT_STRUCT_SPLINE) {
1828 ssmooth = (char*)malloc((ssn+2)*sizeof(char));
1829 if (ssmooth == NULL) FailAllocMessage();
1830 }
1831 }
1832 if (vsel_ptr->obj->ctm == NULL) {
1833 for (i=0; i < num_pts; i++) {
1834 polyv[i].x = poly_ptr->vlist[i].x;
1835 polyv[i].y = poly_ptr->vlist[i].y;
1836 if (smooth != NULL) smooth[i] = poly_ptr->smooth[i];
1837 }
1838 if (curved == LT_STRUCT_SPLINE) {
1839 for (i=0; i < ssn; i++) {
1840 polyssv[i].x = poly_ptr->ssvlist[i].x;
1841 polyssv[i].y = poly_ptr->ssvlist[i].y;
1842 if (ssmooth != NULL) ssmooth[i] = poly_ptr->ssmooth[i];
1843 }
1844 }
1845 } else {
1846 int x, y;
1847
1848 for (i=0; i < num_pts; i++) {
1849 TransformPointThroughCTM(
1850 poly_ptr->vlist[i].x-vsel_ptr->obj->x,
1851 poly_ptr->vlist[i].y-vsel_ptr->obj->y,
1852 vsel_ptr->obj->ctm, &x, &y);
1853 polyv[i].x = x+vsel_ptr->obj->x;
1854 polyv[i].y = y+vsel_ptr->obj->y;
1855 if (smooth != NULL) smooth[i] = poly_ptr->smooth[i];
1856 }
1857 if (curved == LT_STRUCT_SPLINE) {
1858 for (i=0; i < ssn; i++) {
1859 TransformPointThroughCTM(
1860 poly_ptr->ssvlist[i].x-vsel_ptr->obj->x,
1861 poly_ptr->ssvlist[i].y-vsel_ptr->obj->y,
1862 vsel_ptr->obj->ctm, &x, &y);
1863 polyssv[i].x = x+vsel_ptr->obj->x;
1864 polyssv[i].y = y+vsel_ptr->obj->y;
1865 if (ssmooth != NULL) ssmooth[i] = poly_ptr->ssmooth[i];
1866 }
1867 }
1868 }
1869 if (curved != LT_INTSPLINE) {
1870 if (curved == LT_STRUCT_SPLINE) {
1871 sv = MakeMultiSplinePolyVertex(curved, &sn, ssmooth,
1872 drawOrigX, drawOrigY, ssn, polyssv);
1873 poly_copy->ssvlist = polyssv;
1874 poly_copy->ssmooth = ssmooth;
1875 poly_copy->ssn = ssn;
1876 } else {
1877 sv = MakeMultiSplinePolyVertex(curved, &sn, smooth,
1878 drawOrigX, drawOrigY, num_pts, polyv);
1879 }
1880 } else {
1881 sv = MakeIntSplinePolyVertex(&sn, &intn, &cntrlv,
1882 drawOrigX, drawOrigY, num_pts, polyv);
1883 }
1884 poly_copy->vlist = polyv;
1885 poly_copy->smooth = smooth;
1886 poly_copy->svlist = sv;
1887 poly_copy->sn = sn;
1888
1889 if (curved == LT_STRUCT_SPLINE) {
1890 for (i=0; i < ssn; i++) {
1891 if (ssmooth[i]) {
1892 MARKHO(drawWindow, revDefaultGC, OFFSET_X(polyssv[i].x),
1893 OFFSET_Y(polyssv[i].y));
1894 } else {
1895 MARKHR(drawWindow, revDefaultGC, OFFSET_X(polyssv[i].x),
1896 OFFSET_Y(polyssv[i].y));
1897 }
1898 }
1899 }
1900 break;
1901 case OBJ_POLYGON:
1902 polygon_copy = (struct PolygonRec *)malloc(sizeof(struct PolygonRec));
1903 if (polygon_copy == NULL) FailAllocMessage();
1904 memset(polygon_copy, 0, sizeof(struct PolygonRec));
1905 obj_ptr->detail.g = polygon_copy;
1906
1907 polygon_ptr = vsel_ptr->obj->detail.g;
1908 curved = polygon_copy->curved = polygon_ptr->curved;
1909 num_pts = polygon_copy->n = polygon_ptr->n;
1910 if (curved == LT_STRUCT_SPLINE) {
1911 ssn = polygon_copy->ssn = polygon_ptr->ssn;
1912 }
1913 polyv = (IntPoint*)malloc((num_pts+1)*sizeof(IntPoint));
1914 if (polyv == NULL) FailAllocMessage();
1915 if (curved == LT_STRUCT_SPLINE) {
1916 polyssv = (IntPoint*)malloc((ssn+2)*sizeof(IntPoint));
1917 if (polyssv == NULL) FailAllocMessage();
1918 }
1919 if (curved == LT_STRUCT_SPLINE || ((curved == LT_STRAIGHT ||
1920 curved == LT_SPLINE) && polygon_ptr->smooth != NULL)) {
1921 if (polygon_ptr->smooth != NULL) {
1922 smooth = (char*)malloc((num_pts+1)*sizeof(char));
1923 if (smooth == NULL) FailAllocMessage();
1924 }
1925 if (curved == LT_STRUCT_SPLINE) {
1926 ssmooth = (char*)malloc((ssn+1)*sizeof(char));
1927 if (ssmooth == NULL) FailAllocMessage();
1928 }
1929 }
1930 if (vsel_ptr->obj->ctm == NULL) {
1931 for (i=0; i < num_pts; i++) {
1932 polyv[i].x = polygon_ptr->vlist[i].x;
1933 polyv[i].y = polygon_ptr->vlist[i].y;
1934 if (smooth != NULL) smooth[i] = polygon_ptr->smooth[i];
1935 }
1936 if (curved == LT_STRUCT_SPLINE) {
1937 for (i=0; i < ssn; i++) {
1938 polyssv[i].x = polygon_ptr->ssvlist[i].x;
1939 polyssv[i].y = polygon_ptr->ssvlist[i].y;
1940 if (ssmooth != NULL) ssmooth[i] = polygon_ptr->ssmooth[i];
1941 }
1942 }
1943 } else {
1944 int x, y;
1945
1946 for (i=0; i < num_pts; i++) {
1947 TransformPointThroughCTM(
1948 polygon_ptr->vlist[i].x-vsel_ptr->obj->x,
1949 polygon_ptr->vlist[i].y-vsel_ptr->obj->y,
1950 vsel_ptr->obj->ctm, &x, &y);
1951 polyv[i].x = x+vsel_ptr->obj->x;
1952 polyv[i].y = y+vsel_ptr->obj->y;
1953 if (smooth != NULL) smooth[i] = polygon_ptr->smooth[i];
1954 }
1955 if (curved == LT_STRUCT_SPLINE) {
1956 for (i=0; i < num_pts; i++) {
1957 TransformPointThroughCTM(
1958 polygon_ptr->ssvlist[i].x-vsel_ptr->obj->x,
1959 polygon_ptr->ssvlist[i].y-vsel_ptr->obj->y,
1960 vsel_ptr->obj->ctm, &x, &y);
1961 polyssv[i].x = x+vsel_ptr->obj->x;
1962 polyssv[i].y = y+vsel_ptr->obj->y;
1963 if (ssmooth != NULL) ssmooth[i] = polygon_ptr->ssmooth[i];
1964 }
1965 }
1966 }
1967 if (curved != LT_INTSPLINE) {
1968 if (curved == LT_STRUCT_SPLINE) {
1969 sv = MakeMultiSplinePolygonVertex(curved, &sn, ssmooth,
1970 drawOrigX, drawOrigY, ssn, polyssv);
1971 polygon_copy->ssvlist = polyssv;
1972 polygon_copy->ssmooth = ssmooth;
1973 polygon_copy->ssn = ssn;
1974 } else {
1975 sv = MakeMultiSplinePolygonVertex(curved, &sn, smooth,
1976 drawOrigX, drawOrigY, num_pts,polyv);
1977 }
1978 } else {
1979 sv = MakeIntSplinePolygonVertex(&sn, &intn, &cntrlv,
1980 drawOrigX, drawOrigY, num_pts,polyv);
1981 }
1982 polygon_copy->vlist = polyv;
1983 polygon_copy->smooth = smooth;
1984 polygon_copy->svlist = sv;
1985 polygon_copy->sn = sn;
1986
1987 if (curved == LT_STRUCT_SPLINE) {
1988 for (i=0; i < ssn; i++) {
1989 if (ssmooth[i]) {
1990 MARKHO(drawWindow, revDefaultGC, OFFSET_X(polyssv[i].x),
1991 OFFSET_Y(polyssv[i].y));
1992 } else {
1993 MARKHR(drawWindow, revDefaultGC, OFFSET_X(polyssv[i].x),
1994 OFFSET_Y(polyssv[i].y));
1995 }
1996 }
1997 }
1998 break;
1999 }
2000 if (curved == LT_STRUCT_SPLINE) {
2001 psssi = (StretchStructuredSplineInfo*)malloc(
2002 sizeof(StretchStructuredSplineInfo));
2003 if (psssi == NULL) FailAllocMessage();
2004 memset(psssi, 0, sizeof(StretchStructuredSplineInfo));
2005 #ifdef _TGIF_DBG /* debug, do not translate */
2006 TgAssert(obj_ptr->userdata == NULL,
2007 "obj_ptr is not NULL in PrepareToMoveVs()", NULL);
2008 #endif /* _TGIF_DBG */
2009 obj_ptr->userdata = vsel_ptr->obj->userdata = psssi;
2010 if (poly_ptr != NULL) {
2011 SetIPTInfoForStretchPoly(vsel_ptr->v_index[0], num_pts,
2012 polyv, psssi);
2013 } else if (polygon_ptr != NULL) {
2014 SetIPTInfoForStretchPolygon(vsel_ptr->v_index[0], num_pts,
2015 polyv, psssi);
2016 }
2017 SetVsAndVs2ForStretchStructSpline(psssi, 0, 0, &psssi->num_vs,
2018 psssi->vs, &psssi->num_vs2, psssi->vs2);
2019 FixUpSmoothAndSmooth2ForStretchStructSpline(psssi->num_vs,
2020 psssi->smooth, psssi->num_vs2, psssi->smooth2);
2021 if (psssi->prev_valid) {
2022 psssi->sv = MakeMultiSplinePolyVertex(LT_STRUCT_SPLINE,
2023 &psssi->sn, psssi->smooth, drawOrigX, drawOrigY,
2024 psssi->num_vs, psssi->vs);
2025 psssi->saved_sv = DupVs(&psssi->saved_sn, psssi->sv, psssi->sn);
2026 }
2027 if (psssi->next_valid) {
2028 psssi->sv2 = MakeMultiSplinePolyVertex(LT_STRUCT_SPLINE,
2029 &psssi->sn2, psssi->smooth2, drawOrigX, drawOrigY,
2030 psssi->num_vs2, psssi->vs2);
2031 psssi->saved_sv2 = DupVs(&psssi->saved_sn2, psssi->sv2, psssi->sn2);
2032 }
2033 EraseHighLightForStretchStructSpline(psssi, 0, 0, FALSE, TRUE);
2034 }
2035 }
2036 }
2037
2038 static
MarkVsForStructuredSplines(Dir,abs_dx,abs_dy)2039 void MarkVsForStructuredSplines(Dir, abs_dx, abs_dy)
2040 int Dir, abs_dx, abs_dy;
2041 {
2042 struct ObjRec *obj_ptr=NULL;
2043
2044 switch (Dir) {
2045 case FORWARD: obj_ptr = tmpBotObj; break;
2046 case REVERSE: obj_ptr = tmpTopObj; break;
2047 }
2048 while (obj_ptr != NULL) {
2049 StretchStructuredSplineInfo *psssi=
2050 (StretchStructuredSplineInfo*)(obj_ptr->userdata);
2051
2052 if (psssi != NULL) {
2053 switch (Dir) {
2054 case REVERSE:
2055 /* erase */
2056 if (psssi->sv != NULL) {
2057 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
2058 psssi->sv, psssi->sn, CoordModeOrigin);
2059 free(psssi->sv);
2060 psssi->sv = NULL;
2061 }
2062 if (psssi->sv2 != NULL) {
2063 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
2064 psssi->sv2, psssi->sn2, CoordModeOrigin);
2065 free(psssi->sv2);
2066 psssi->sv2 = NULL;
2067 }
2068 EraseHighLightForStretchStructSpline(psssi, abs_dx, abs_dy, TRUE,
2069 TRUE);
2070 break;
2071 case FORWARD:
2072 /* draw */
2073 SetVsAndVs2ForStretchStructSpline(psssi, abs_dx, abs_dy,
2074 &psssi->num_vs, psssi->vs, &psssi->num_vs2, psssi->vs2);
2075 FixUpSmoothAndSmooth2ForStretchStructSpline(psssi->num_vs,
2076 psssi->smooth, psssi->num_vs2,
2077 psssi->smooth2);
2078 if (psssi->prev_valid) {
2079 psssi->sv = MakeMultiSplinePolyVertex(LT_STRUCT_SPLINE,
2080 &psssi->sn, psssi->smooth, drawOrigX, drawOrigY,
2081 psssi->num_vs, psssi->vs);
2082 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
2083 psssi->sv, psssi->sn, CoordModeOrigin);
2084 }
2085 if (psssi->next_valid) {
2086 psssi->sv2 = MakeMultiSplinePolyVertex(LT_STRUCT_SPLINE,
2087 &psssi->sn2, psssi->smooth2, drawOrigX, drawOrigY,
2088 psssi->num_vs2, psssi->vs2);
2089 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
2090 psssi->sv2, psssi->sn2, CoordModeOrigin);
2091 }
2092 EraseHighLightForStretchStructSpline(psssi, abs_dx, abs_dy, TRUE,
2093 TRUE);
2094 break;
2095 }
2096 if (psssi->hinge) {
2097 MARKHR(drawWindow, revDefaultGC,
2098 OFFSET_X(psssi->ipt.hinge_pt.x+abs_dx),
2099 OFFSET_Y(psssi->ipt.hinge_pt.y+abs_dy));
2100 } else if (psssi->earlier_smooth_selected) {
2101 MARKHO(drawWindow, revDefaultGC,
2102 OFFSET_X(psssi->ipt.earlier_smooth_pt.x+abs_dx),
2103 OFFSET_Y(psssi->ipt.earlier_smooth_pt.y+abs_dy));
2104 } else {
2105 MARKHO(drawWindow, revDefaultGC,
2106 OFFSET_X(psssi->ipt.later_smooth_pt.x+abs_dx),
2107 OFFSET_Y(psssi->ipt.later_smooth_pt.y+abs_dy));
2108 }
2109 }
2110 switch (Dir) {
2111 case FORWARD: obj_ptr = obj_ptr->prev; break;
2112 case REVERSE: obj_ptr = obj_ptr->next; break;
2113 }
2114 }
2115 }
2116
2117 static
HighLightVs(Dir,abs_dx,abs_dy)2118 void HighLightVs(Dir, abs_dx, abs_dy)
2119 int Dir, abs_dx, abs_dy;
2120 {
2121 int i=0, n=0, curved=(-1);
2122 struct ObjRec *obj_ptr=NULL;
2123 IntPoint *v=NULL;
2124 char *smooth=NULL;
2125
2126 switch (Dir) {
2127 case FORWARD: obj_ptr = tmpBotObj; break;
2128 case REVERSE: obj_ptr = tmpTopObj; break;
2129 }
2130 while (obj_ptr != NULL) {
2131 switch (obj_ptr->type) {
2132 case OBJ_POLY:
2133 curved = obj_ptr->detail.p->curved;
2134 if (curved == LT_STRUCT_SPLINE) {
2135 n = obj_ptr->detail.p->ssn;
2136 v = obj_ptr->detail.p->ssvlist;
2137 smooth = obj_ptr->detail.p->ssmooth;
2138 } else {
2139 n = obj_ptr->detail.p->n;
2140 v = obj_ptr->detail.p->vlist;
2141 smooth = obj_ptr->detail.p->smooth;
2142 }
2143 if (curved != LT_INTSPLINE && smooth != NULL) {
2144 if (curved == LT_STRUCT_SPLINE) {
2145 /* nothing to do here */
2146 } else {
2147 for (i=0; i < n; i++) {
2148 if (smooth[i]) {
2149 MARKO(drawWindow, revDefaultGC, OFFSET_X(v[i].x),
2150 OFFSET_Y(v[i].y));
2151 } else {
2152 MARK(drawWindow, revDefaultGC, OFFSET_X(v[i].x),
2153 OFFSET_Y(v[i].y));
2154 }
2155 }
2156 }
2157 } else {
2158 for (i=0; i < n; i++) {
2159 MARK(drawWindow, revDefaultGC, OFFSET_X(v[i].x),
2160 OFFSET_Y(v[i].y));
2161 }
2162 }
2163 if (curved == LT_STRUCT_SPLINE) {
2164 /* nothing to do here */
2165 } else {
2166 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
2167 obj_ptr->detail.p->svlist, obj_ptr->detail.p->sn,
2168 CoordModeOrigin);
2169 }
2170 break;
2171 case OBJ_POLYGON:
2172 curved = obj_ptr->detail.g->curved;
2173 if (curved == LT_STRUCT_SPLINE) {
2174 n = obj_ptr->detail.g->ssn;
2175 v = obj_ptr->detail.g->ssvlist;
2176 smooth = obj_ptr->detail.g->ssmooth;
2177 } else {
2178 n = obj_ptr->detail.g->n;
2179 v = obj_ptr->detail.g->vlist;
2180 smooth = obj_ptr->detail.g->smooth;
2181 }
2182 if (obj_ptr->detail.g->curved != LT_INTSPLINE && smooth != NULL) {
2183 if (curved == LT_STRUCT_SPLINE) {
2184 /* nothing to do */
2185 } else {
2186 for (i=0; i < obj_ptr->detail.g->n-1; i++) {
2187 if (smooth[i]) {
2188 MARKO(drawWindow, revDefaultGC, OFFSET_X(v[i].x),
2189 OFFSET_Y(v[i].y));
2190 } else {
2191 MARK(drawWindow, revDefaultGC, OFFSET_X(v[i].x),
2192 OFFSET_Y(v[i].y));
2193 }
2194 }
2195 }
2196 } else {
2197 for (i=0; i < obj_ptr->detail.g->n-1; i++) {
2198 MARK(drawWindow, revDefaultGC, OFFSET_X(v[i].x),
2199 OFFSET_Y(v[i].y));
2200 }
2201 }
2202 if (curved == LT_STRUCT_SPLINE) {
2203 /* nothing to do here */
2204 } else {
2205 XDrawLines(mainDisplay, drawWindow, revDefaultGC,
2206 obj_ptr->detail.g->svlist, obj_ptr->detail.g->sn,
2207 CoordModeOrigin);
2208 }
2209 break;
2210 }
2211 switch (Dir) {
2212 case FORWARD: obj_ptr = obj_ptr->prev; break;
2213 case REVERSE: obj_ptr = obj_ptr->next; break;
2214 }
2215 }
2216 }
2217
2218 static
MarkVs(Dir,Dx,Dy)2219 void MarkVs(Dir, Dx, Dy)
2220 int Dir, Dx, Dy; /* Dx and Dy are screen offsets */
2221 {
2222 register int i, x, y;
2223 register struct VSelRec *vsel_ptr=NULL;
2224
2225 switch (Dir) {
2226 case FORWARD: vsel_ptr = botVSel; break;
2227 case REVERSE: vsel_ptr = topVSel; break;
2228 }
2229 while (vsel_ptr != NULL) {
2230 char *smooth=NULL;
2231 int curved=(-1);
2232
2233 switch (vsel_ptr->obj->type) {
2234 case OBJ_POLY:
2235 smooth = vsel_ptr->obj->detail.p->smooth;
2236 curved = vsel_ptr->obj->detail.p->curved;
2237 break;
2238 case OBJ_POLYGON:
2239 smooth = vsel_ptr->obj->detail.g->smooth;
2240 curved = vsel_ptr->obj->detail.g->curved;
2241 break;
2242 }
2243 for (i=0; i < vsel_ptr->n; i++) {
2244 if (!(vsel_ptr->obj->type==OBJ_POLYGON &&
2245 vsel_ptr->obj->detail.g->n-1==vsel_ptr->v_index[i])) {
2246 x = OFFSET_X(vsel_ptr->x[i])+Dx;
2247 y = OFFSET_Y(vsel_ptr->y[i])+Dy;
2248 if (curved == LT_STRUCT_SPLINE || ((curved == LT_STRAIGHT ||
2249 curved == LT_SPLINE) && smooth != NULL)) {
2250 if (curved == LT_STRUCT_SPLINE) {
2251 /* nothing to do here */
2252 } else {
2253 if (smooth[vsel_ptr->v_index[i]]) {
2254 if (curved == LT_STRUCT_SPLINE) {
2255 MARKHO(drawWindow, revDefaultGC, x, y);
2256 } else {
2257 MARKO(drawWindow, revDefaultGC, x, y);
2258 }
2259 } else {
2260 if (curved == LT_STRUCT_SPLINE) {
2261 MARKHR(drawWindow, revDefaultGC, x, y);
2262 } else {
2263 MARK(drawWindow, revDefaultGC, x, y);
2264 }
2265 }
2266 }
2267 } else {
2268 MARK(drawWindow, revDefaultGC, x, y);
2269 }
2270 MARKV(drawWindow, revDefaultGC, x, y);
2271 }
2272 }
2273 switch (Dir) {
2274 case FORWARD: vsel_ptr = vsel_ptr->prev; break;
2275 case REVERSE: vsel_ptr = vsel_ptr->next; break;
2276 }
2277 }
2278 }
2279
2280 static
GetSelectedVsBBox(pBBox)2281 void GetSelectedVsBBox(pBBox)
2282 struct BBRec *pBBox;
2283 {
2284 int found=FALSE, ltx=0, lty=0, rbx=0, rby=0;
2285 struct VSelRec *vsel_ptr=NULL;
2286
2287 vsel_ptr = botVSel;
2288 while (vsel_ptr != NULL) {
2289 int i=0;
2290
2291 for (i=0; i < vsel_ptr->n; i++) {
2292 if (!(vsel_ptr->obj->type==OBJ_POLYGON &&
2293 vsel_ptr->obj->detail.g->n-1==vsel_ptr->v_index[i])) {
2294 int x=OFFSET_X(vsel_ptr->x[i]);
2295 int y=OFFSET_Y(vsel_ptr->y[i]);
2296
2297 if (found) {
2298 if (x < ltx) ltx = x;
2299 if (x > rbx) rbx = x;
2300 if (y < lty) lty = y;
2301 if (y > rby) rby = y;
2302 } else {
2303 found = TRUE;
2304 ltx = rbx = x;
2305 lty = rby = y;
2306 }
2307 }
2308 }
2309 vsel_ptr = vsel_ptr->prev;
2310 }
2311 if (found) {
2312 pBBox->ltx = ltx; pBBox->lty = lty; pBBox->rbx = rbx; pBBox->rby = rby;
2313 }
2314 }
2315
MoveSelVs(OrigX,OrigY)2316 void MoveSelVs(OrigX, OrigY)
2317 int OrigX, OrigY;
2318 {
2319 int x=0, y=0, i=0;
2320 struct ObjRec *obj_ptr=NULL;
2321 struct VSelRec *vsel_ptr=NULL;
2322 struct PolyRec *poly_ptr=NULL;
2323 struct PolygonRec *polygon_ptr=NULL;
2324 IntPoint *pv=NULL;
2325 int moving=TRUE, dx=0, dy=0, num_pts=0, curved=FALSE;
2326 int grid_x=OrigX, grid_y=OrigY, abs_dx_from_orig=0, abs_dy_from_orig=0;
2327 int saved_grid_x=OrigX, saved_grid_y=OrigY;
2328 struct BBRec ruler_bbox;
2329 char buf[80], x_buf[80], y_buf[80];
2330 XEvent ev;
2331
2332 XFlush(mainDisplay);
2333 XSync(mainDisplay, False);
2334
2335 if (XCheckMaskEvent(mainDisplay, ExposureMask, &ev) ||
2336 XCheckMaskEvent(mainDisplay, VisibilityChangeMask, &ev)) {
2337 ExposeEventHandler(&ev, TRUE);
2338 }
2339 HighLightReverse();
2340
2341 PrepareToMoveVs();
2342 MarkVsForStructuredSplines(FORWARD, 0, 0);
2343 HighLightVs(FORWARD, 0, 0);
2344 MarkVs(FORWARD, 0, 0);
2345
2346 memset(&ruler_bbox, 0, sizeof(struct BBRec));
2347 GetSelectedVsBBox(&ruler_bbox);
2348
2349 PixelToMeasurementUnit(x_buf, 0);
2350 PixelToMeasurementUnit(y_buf, 0);
2351 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
2352 if (VerboseMeasureTooltip()) {
2353 sprintf(buf, "dx=%s dy=%s", x_buf, y_buf);
2354 } else {
2355 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
2356 }
2357 StartShowMeasureCursor(grid_x, grid_y, buf, TRUE);
2358 BeginIntervalRulers(ruler_bbox.ltx, ruler_bbox.lty, ruler_bbox.rbx,
2359 ruler_bbox.rby);
2360
2361 if (!debugNoPointerGrab) {
2362 XGrabPointer(mainDisplay, drawWindow, FALSE,
2363 PointerMotionMask | ButtonReleaseMask,
2364 GrabModeAsync, GrabModeAsync, None, moveCursor, CurrentTime);
2365 }
2366 while (moving) {
2367 XEvent input;
2368
2369 XNextEvent(mainDisplay, &input);
2370
2371 if (input.type == Expose || input.type == VisibilityNotify) {
2372 ExposeEventHandler(&input, TRUE);
2373 } else if (input.type == ButtonRelease) {
2374 XUngrabPointer(mainDisplay, CurrentTime);
2375 XSync(mainDisplay, False);
2376
2377 EndIntervalRulers(grid_x, grid_y);
2378 PixelToMeasurementUnit(x_buf, ABS_SIZE(grid_x-OrigX));
2379 PixelToMeasurementUnit(y_buf, ABS_SIZE(grid_y-OrigY));
2380 if (VerboseMeasureTooltip()) {
2381 sprintf(buf, "dx=%s dy=%s", x_buf, y_buf);
2382 } else {
2383 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
2384 }
2385 EndShowMeasureCursor(grid_x, grid_y, buf, TRUE);
2386 MarkRulers(grid_x, grid_y);
2387 moving = FALSE;
2388
2389 dx = grid_x - OrigX;
2390 dy = grid_y - OrigY;
2391
2392 MarkVs(REVERSE, dx, dy);
2393 MarkVsForStructuredSplines(REVERSE, ABS_SIZE(dx), ABS_SIZE(dy));
2394 HighLightVs(REVERSE, ABS_SIZE(dx), ABS_SIZE(dy));
2395 EndMoveVs(ABS_SIZE(dx), ABS_SIZE(dy));
2396
2397 if (dx != 0 || dy != 0) {
2398 MoveAllSelVs(ABS_SIZE(dx), ABS_SIZE(dy));
2399 HighLightForward();
2400 SetFileModified(TRUE);
2401 } else {
2402 HighLightForward();
2403 }
2404 } else if (input.type == MotionNotify || input.type == KeyPress ||
2405 input.type == KeyRelease) {
2406 PixelToMeasurementUnit(x_buf, ABS_SIZE(grid_x-OrigX));
2407 PixelToMeasurementUnit(y_buf, ABS_SIZE(grid_y-OrigY));
2408 if (VerboseMeasureTooltip()) {
2409 sprintf(buf, "dx=%s dy=%s", x_buf, y_buf);
2410 } else {
2411 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
2412 }
2413 ShowMeasureCursor(grid_x, grid_y, buf, TRUE);
2414 /* erase */
2415 MarkVs(REVERSE, grid_x-OrigX, grid_y-OrigY);
2416 MarkVsForStructuredSplines(REVERSE, ABS_SIZE(grid_x-OrigX),
2417 ABS_SIZE(grid_y-OrigY));
2418 HighLightVs(REVERSE, ABS_SIZE(grid_x-OrigX), ABS_SIZE(grid_x-OrigX));
2419
2420 if (input.type == KeyPress || input.type == KeyRelease) {
2421 x = saved_grid_x;
2422 y = saved_grid_y;
2423 } else {
2424 x = input.xmotion.x;
2425 y = input.xmotion.y;
2426 }
2427 if (shiftForDiagMouseMove && DiagEventCheck(&input)) {
2428 if (useRecentDupDistance && justDupped &&
2429 useRecentForDiagMouseMove) {
2430 DiagGridXY(OrigX-ZOOMED_SIZE(dupDx), OrigY-ZOOMED_SIZE(dupDy),
2431 &x, &y);
2432 } else {
2433 DiagGridXY(OrigX, OrigY, &x, &y);
2434 }
2435 }
2436 GridXY(x, y, &grid_x, &grid_y);
2437
2438 dx = grid_x - saved_grid_x;
2439 dy = grid_y - saved_grid_y;
2440
2441 saved_grid_x = grid_x;
2442 saved_grid_y = grid_y;
2443
2444 abs_dx_from_orig = ABS_SIZE(grid_x-OrigX);
2445 abs_dy_from_orig = ABS_SIZE(grid_y-OrigY);
2446
2447 for (vsel_ptr=botVSel, obj_ptr=tmpBotObj; vsel_ptr != NULL;
2448 vsel_ptr=vsel_ptr->prev, obj_ptr=obj_ptr->prev) {
2449 switch (obj_ptr->type) {
2450 case OBJ_POLY:
2451 poly_ptr = obj_ptr->detail.p;
2452 curved = poly_ptr->curved;
2453 num_pts = poly_ptr->n;
2454 pv = poly_ptr->vlist;
2455 for (i=0; i < vsel_ptr->n; i++) {
2456 pv[vsel_ptr->v_index[i]].x += ABS_SIZE(dx);
2457 pv[vsel_ptr->v_index[i]].y += ABS_SIZE(dy);
2458 }
2459 if (poly_ptr->svlist != NULL) {
2460 free(poly_ptr->svlist);
2461 poly_ptr->svlist = NULL;
2462 }
2463 switch (curved) {
2464 case LT_STRAIGHT:
2465 case LT_SPLINE:
2466 poly_ptr->svlist = MakeMultiSplinePolyVertex(
2467 curved, &(poly_ptr->sn), poly_ptr->smooth,
2468 drawOrigX, drawOrigY, num_pts, pv);
2469 break;
2470 case LT_STRUCT_SPLINE:
2471 /* nothing to do here */
2472 break;
2473 case LT_INTSPLINE:
2474 if (poly_ptr->intvlist != NULL) {
2475 free(poly_ptr->intvlist);
2476 poly_ptr->intvlist = NULL;
2477 }
2478 poly_ptr->svlist = MakeIntSplinePolyVertex(
2479 &(poly_ptr->sn), &(poly_ptr->intn),
2480 &(poly_ptr->intvlist), drawOrigX, drawOrigY,
2481 num_pts, pv);
2482 break;
2483 }
2484 break;
2485 case OBJ_POLYGON:
2486 polygon_ptr = obj_ptr->detail.g;
2487 curved = polygon_ptr->curved;
2488 num_pts = polygon_ptr->n;
2489 pv = polygon_ptr->vlist;
2490 for (i=0; i < vsel_ptr->n; i++) {
2491 pv[vsel_ptr->v_index[i]].x += ABS_SIZE(dx);
2492 pv[vsel_ptr->v_index[i]].y += ABS_SIZE(dy);
2493 }
2494 if (polygon_ptr->svlist != NULL) {
2495 free(polygon_ptr->svlist);
2496 polygon_ptr->svlist = NULL;
2497 }
2498 switch (curved) {
2499 case LT_STRAIGHT:
2500 case LT_SPLINE:
2501 polygon_ptr->svlist =
2502 MakeMultiSplinePolygonVertex(curved,
2503 &(polygon_ptr->sn), polygon_ptr->smooth,
2504 drawOrigX, drawOrigY, num_pts, pv);
2505 break;
2506 case LT_STRUCT_SPLINE:
2507 /* nothing to do here */
2508 break;
2509 case LT_INTSPLINE:
2510 if (polygon_ptr->intvlist != NULL) {
2511 free(polygon_ptr->intvlist);
2512 polygon_ptr->intvlist = NULL;
2513 }
2514 polygon_ptr->svlist =
2515 MakeIntSplinePolygonVertex(&(polygon_ptr->sn),
2516 &(polygon_ptr->intn), &(polygon_ptr->intvlist),
2517 drawOrigX, drawOrigY, num_pts, pv);
2518 break;
2519 }
2520 break;
2521 }
2522 }
2523 /* draw */
2524 MarkVsForStructuredSplines(FORWARD, abs_dx_from_orig,
2525 abs_dy_from_orig);
2526 HighLightVs(FORWARD, abs_dx_from_orig, abs_dy_from_orig);
2527 MarkVs(FORWARD, grid_x-OrigX, grid_y-OrigY);
2528 PixelToMeasurementUnit(x_buf, abs_dx_from_orig);
2529 PixelToMeasurementUnit(y_buf, abs_dy_from_orig);
2530 if (VerboseMeasureTooltip()) {
2531 sprintf(buf, "dx=%s dy=%s", x_buf, y_buf);
2532 } else {
2533 sprintf(buf, "dx=%s\ndy=%s", x_buf, y_buf);
2534 }
2535 DrawIntervalRulers(ruler_bbox.ltx+abs_dx_from_orig,
2536 ruler_bbox.lty+abs_dy_from_orig, ruler_bbox.rbx+abs_dx_from_orig,
2537 ruler_bbox.rby+abs_dy_from_orig, buf);
2538 ShowMeasureCursor(grid_x, grid_y, buf, TRUE);
2539 while (XCheckMaskEvent(mainDisplay, PointerMotionMask, &ev)) ;
2540 }
2541 }
2542 }
2543