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/dup.c,v 1.13 2011/05/16 16:21:57 william Exp $
19 */
20
21 #define _INCLUDE_FROM_DUP_C_
22
23 #include "tgifdefs.h"
24
25 #include "attr.e"
26 #include "auxtext.e"
27 #include "choice.e"
28 #include "cmd.e"
29 #include "drawing.e"
30 #include "dup.e"
31 #include "file.e"
32 #include "grid.e"
33 #include "mark.e"
34 #include "move.e"
35 #include "msg.e"
36 #include "obj.e"
37 #include "page.e"
38 #include "raster.e"
39 #include "select.e"
40 #include "setup.e"
41 #include "text.e"
42 #include "util.e"
43 #include "xbitmap.e"
44 #include "xpixmap.e"
45
46 int justDupped = FALSE;
47 int useRecentDupDistance = TRUE;
48 int dupDx = INVALID, dupDy = INVALID;
49
CopyObjId(FromObjPtr,ToObjPtr)50 void CopyObjId(FromObjPtr, ToObjPtr)
51 struct ObjRec *FromObjPtr, *ToObjPtr;
52 {
53 register struct ObjRec *from_obj_ptr, *to_obj_ptr;
54 register struct AttrRec *from_attr_ptr, *to_attr_ptr;
55
56 ToObjPtr->id = FromObjPtr->id;
57 if (FromObjPtr->creator_full_id != NULL) {
58 UtilFree(ToObjPtr->creator_full_id);
59 ToObjPtr->creator_full_id = UtilStrDup(FromObjPtr->creator_full_id);
60 if (ToObjPtr->creator_full_id == NULL) FailAllocMessage();
61 }
62 switch (FromObjPtr->type) {
63 case OBJ_SYM:
64 case OBJ_GROUP:
65 case OBJ_ICON:
66 case OBJ_PIN:
67 from_obj_ptr = FromObjPtr->detail.r->first;
68 to_obj_ptr = ToObjPtr->detail.r->first;
69 for ( ; from_obj_ptr!=NULL; from_obj_ptr=from_obj_ptr->next,
70 to_obj_ptr=to_obj_ptr->next) {
71 CopyObjId(from_obj_ptr, to_obj_ptr);
72 }
73 break;
74 }
75 from_attr_ptr = FromObjPtr->fattr;
76 to_attr_ptr = ToObjPtr->fattr;
77 for ( ; from_attr_ptr!=NULL; from_attr_ptr=from_attr_ptr->next,
78 to_attr_ptr=to_attr_ptr->next) {
79 CopyObjId(from_attr_ptr->obj, to_attr_ptr->obj);
80 }
81 }
82
CopyObjLocks(FromObjPtr,ToObjPtr)83 void CopyObjLocks(FromObjPtr, ToObjPtr)
84 struct ObjRec *FromObjPtr, *ToObjPtr;
85 {
86 register struct ObjRec *from_obj_ptr, *to_obj_ptr;
87 register struct AttrRec *from_attr_ptr, *to_attr_ptr;
88
89 ToObjPtr->locked = FromObjPtr->locked;
90 switch (FromObjPtr->type) {
91 case OBJ_SYM:
92 case OBJ_GROUP:
93 case OBJ_ICON:
94 case OBJ_PIN:
95 from_obj_ptr = FromObjPtr->detail.r->first;
96 to_obj_ptr = ToObjPtr->detail.r->first;
97 for ( ; from_obj_ptr!=NULL; from_obj_ptr=from_obj_ptr->next,
98 to_obj_ptr=to_obj_ptr->next) {
99 CopyObjLocks(from_obj_ptr, to_obj_ptr);
100 }
101 break;
102 }
103 from_attr_ptr = FromObjPtr->fattr;
104 to_attr_ptr = ToObjPtr->fattr;
105 for ( ; from_attr_ptr!=NULL; from_attr_ptr=from_attr_ptr->next,
106 to_attr_ptr=to_attr_ptr->next) {
107 CopyObjLocks(from_attr_ptr->obj, to_attr_ptr->obj);
108 }
109 }
110
UnlockAnObj(ObjPtr)111 void UnlockAnObj(ObjPtr)
112 struct ObjRec *ObjPtr;
113 {
114 register struct ObjRec *obj_ptr;
115 register struct AttrRec *attr_ptr;
116
117 ObjPtr->locked = FALSE;
118 switch (ObjPtr->type) {
119 case OBJ_SYM:
120 case OBJ_GROUP:
121 case OBJ_ICON:
122 case OBJ_PIN:
123 for (obj_ptr=ObjPtr->detail.r->first; obj_ptr!=NULL;
124 obj_ptr=obj_ptr->next) {
125 UnlockAnObj(obj_ptr);
126 }
127 }
128 for (attr_ptr=ObjPtr->fattr; attr_ptr!=NULL; attr_ptr=attr_ptr->next) {
129 attr_ptr->obj->locked = FALSE;
130 }
131 }
132
DupObjXfrmMtrx(FromObjPtr,ToObjPtr)133 void DupObjXfrmMtrx(FromObjPtr, ToObjPtr)
134 register struct ObjRec *FromObjPtr, *ToObjPtr;
135 {
136 ToObjPtr->ctm = NULL;
137 if (FromObjPtr->ctm == NULL) return;
138 ToObjPtr->ctm = (struct XfrmMtrxRec *)malloc(sizeof(struct XfrmMtrxRec));
139 if (ToObjPtr->ctm == NULL) FailAllocMessage();
140 memcpy(ToObjPtr->ctm, FromObjPtr->ctm, sizeof(struct XfrmMtrxRec));
141 memcpy(&ToObjPtr->orig_obbox,&FromObjPtr->orig_obbox,sizeof(struct BBRec));
142 }
143
DupObjBasics(FromObjPtr,ToObjPtr)144 void DupObjBasics(FromObjPtr, ToObjPtr)
145 register struct ObjRec *FromObjPtr, *ToObjPtr;
146 {
147 ToObjPtr->next = ToObjPtr->prev = NULL;
148 ToObjPtr->x = FromObjPtr->x;
149 ToObjPtr->y = FromObjPtr->y;
150 ToObjPtr->color = FromObjPtr->color;
151 ToObjPtr->bg_color = FromObjPtr->bg_color;
152 memcpy(ToObjPtr->color_str, FromObjPtr->color_str,
153 sizeof(ToObjPtr->color_str));
154 memcpy(ToObjPtr->bg_color_str, FromObjPtr->bg_color_str,
155 sizeof(ToObjPtr->bg_color_str));
156 ToObjPtr->id = objId++;
157 ToObjPtr->dirty = FALSE;
158 ToObjPtr->rotation = FromObjPtr->rotation;
159 ToObjPtr->type = FromObjPtr->type;
160 ToObjPtr->bbox.ltx = FromObjPtr->bbox.ltx;
161 ToObjPtr->bbox.lty = FromObjPtr->bbox.lty;
162 ToObjPtr->bbox.rbx = FromObjPtr->bbox.rbx;
163 ToObjPtr->bbox.rby = FromObjPtr->bbox.rby;
164 ToObjPtr->obbox.ltx = FromObjPtr->obbox.ltx;
165 ToObjPtr->obbox.lty = FromObjPtr->obbox.lty;
166 ToObjPtr->obbox.rbx = FromObjPtr->obbox.rbx;
167 ToObjPtr->obbox.rby = FromObjPtr->obbox.rby;
168 ToObjPtr->locked = FALSE;
169 ToObjPtr->invisible = FromObjPtr->invisible;
170 ToObjPtr->trans_pat = FromObjPtr->trans_pat;
171
172 memcpy(&ToObjPtr->orig_obbox, &FromObjPtr->orig_obbox,
173 sizeof(struct BBRec));
174 memcpy(ToObjPtr->rotated_obbox, FromObjPtr->rotated_obbox,
175 5*sizeof(XPoint));
176 DupObjXfrmMtrx(FromObjPtr, ToObjPtr);
177 }
178
DupPolyObj(PolyPtr,ObjPtr)179 void DupPolyObj(PolyPtr, ObjPtr)
180 struct PolyRec *PolyPtr;
181 struct ObjRec *ObjPtr;
182 {
183 register int i, num_pts;
184 register struct PolyRec *poly_ptr;
185 register XPoint *sv;
186 register IntPoint *pv;
187
188 poly_ptr = (struct PolyRec *)malloc(sizeof(struct PolyRec));
189 if (poly_ptr == NULL) FailAllocMessage();
190 memset(poly_ptr, 0, sizeof(struct PolyRec));
191 num_pts = poly_ptr->n = PolyPtr->n;
192 pv = (IntPoint*)malloc((num_pts+1)*sizeof(IntPoint));
193 if (pv == NULL) FailAllocMessage();
194 if (PolyPtr->smooth != NULL) {
195 poly_ptr->smooth = (char*)malloc((num_pts+1)*sizeof(char));
196 if (poly_ptr->smooth == NULL) FailAllocMessage();
197 } else {
198 poly_ptr->smooth = NULL;
199 }
200 for (i=0; i < num_pts; i++) {
201 pv[i].x = PolyPtr->vlist[i].x;
202 pv[i].y = PolyPtr->vlist[i].y;
203 if (PolyPtr->smooth != NULL && poly_ptr->smooth != NULL) {
204 poly_ptr->smooth[i] = PolyPtr->smooth[i];
205 }
206 }
207 poly_ptr->vlist = pv;
208 poly_ptr->style = PolyPtr->style;
209 poly_ptr->width = PolyPtr->width;
210 poly_ptr->aw = PolyPtr->aw;
211 poly_ptr->ah = PolyPtr->ah;
212 strcpy(poly_ptr->width_spec, PolyPtr->width_spec);
213 strcpy(poly_ptr->aw_spec, PolyPtr->aw_spec);
214 strcpy(poly_ptr->ah_spec, PolyPtr->ah_spec);
215 poly_ptr->pen = PolyPtr->pen;
216 poly_ptr->fill = PolyPtr->fill;
217 poly_ptr->curved = PolyPtr->curved;
218 if (PolyPtr->sn != 0 && PolyPtr->svlist != NULL) {
219 poly_ptr->sn = num_pts = PolyPtr->sn;
220 sv = (XPoint*)malloc((num_pts+1)*sizeof(XPoint));
221 if (sv == NULL) FailAllocMessage();
222 for (i=0; i < num_pts; i++) {
223 sv[i].x = PolyPtr->svlist[i].x;
224 sv[i].y = PolyPtr->svlist[i].y;
225 }
226 poly_ptr->svlist = sv;
227 } else {
228 poly_ptr->sn = 0;
229 poly_ptr->svlist = NULL;
230 }
231 if (PolyPtr->ssn != 0 && PolyPtr->ssvlist != NULL) {
232 poly_ptr->ssn = num_pts = PolyPtr->ssn;
233 pv = (IntPoint*)malloc((num_pts+1)*sizeof(IntPoint));
234 if (pv == NULL) FailAllocMessage();
235 for (i=0; i < num_pts; i++) {
236 pv[i].x = PolyPtr->ssvlist[i].x;
237 pv[i].y = PolyPtr->ssvlist[i].y;
238 }
239 poly_ptr->ssvlist = pv;
240 } else {
241 poly_ptr->ssn = 0;
242 poly_ptr->ssvlist = NULL;
243 }
244 if (PolyPtr->ssmooth != NULL && PolyPtr->ssvlist != NULL) {
245 num_pts = PolyPtr->ssn;
246 poly_ptr->ssmooth = (char*)malloc((num_pts+1)*sizeof(char));
247 if (poly_ptr->ssmooth == NULL) FailAllocMessage();
248 memcpy(poly_ptr->ssmooth, PolyPtr->ssmooth, num_pts*sizeof(char));
249 poly_ptr->ssmooth[num_pts] = FALSE;
250 } else {
251 poly_ptr->ssmooth = NULL;
252 }
253 if (PolyPtr->curved == LT_INTSPLINE && PolyPtr->intn != 0 &&
254 PolyPtr->intvlist != NULL) {
255 poly_ptr->intn = num_pts = PolyPtr->intn;
256 pv = (IntPoint*)malloc((num_pts+1)*sizeof(IntPoint));
257 if (pv == NULL) FailAllocMessage();
258 for (i=0; i < num_pts; i++) {
259 pv[i].x = PolyPtr->intvlist[i].x;
260 pv[i].y = PolyPtr->intvlist[i].y;
261 }
262 poly_ptr->intvlist = pv;
263 } else {
264 poly_ptr->intn = 0;
265 poly_ptr->intvlist = NULL;
266 }
267 poly_ptr->dash = PolyPtr->dash;
268 if (ObjPtr->ctm != NULL && PolyPtr->rotated_n != 0 &&
269 PolyPtr->rotated_vlist != NULL) {
270 poly_ptr->rotated_n = num_pts = PolyPtr->rotated_n;
271 sv = (XPoint*)malloc((num_pts+1)*sizeof(XPoint));
272 if (sv == NULL) FailAllocMessage();
273 for (i=0; i < num_pts; i++) {
274 sv[i].x = PolyPtr->rotated_vlist[i].x;
275 sv[i].y = PolyPtr->rotated_vlist[i].y;
276 }
277 poly_ptr->rotated_vlist = sv;
278 } else {
279 poly_ptr->rotated_n = 0;
280 poly_ptr->rotated_vlist = NULL;
281 }
282 /*
283 * Need to check for pins.
284 * Need to handle the case where connection objects need to be dupped!
285 */
286 poly_ptr->start_conn = poly_ptr->end_conn = NULL;
287
288 ObjPtr->detail.p = poly_ptr;
289 }
290
DupPolygonObj(PolygonPtr,ObjPtr)291 void DupPolygonObj(PolygonPtr, ObjPtr)
292 struct PolygonRec *PolygonPtr;
293 struct ObjRec *ObjPtr;
294 {
295 register int i, num_pts;
296 register struct PolygonRec *polygon_ptr;
297 XPoint *sv;
298 IntPoint *pv;
299
300 polygon_ptr = (struct PolygonRec *)malloc(sizeof(struct PolygonRec));
301 if (polygon_ptr == NULL) FailAllocMessage();
302 memset(polygon_ptr, 0, sizeof(struct PolygonRec));
303 num_pts = polygon_ptr->n = PolygonPtr->n;
304 pv = (IntPoint*)malloc((num_pts+1)*sizeof(IntPoint));
305 if (pv == NULL) FailAllocMessage();
306 if (PolygonPtr->smooth != NULL) {
307 polygon_ptr->smooth = (char*)malloc((num_pts+1)*sizeof(char));
308 if (polygon_ptr->smooth == NULL) FailAllocMessage();
309 } else {
310 polygon_ptr->smooth = NULL;
311 }
312 for (i=0; i < num_pts; i++) {
313 pv[i].x = PolygonPtr->vlist[i].x;
314 pv[i].y = PolygonPtr->vlist[i].y;
315 if (PolygonPtr->smooth != NULL && polygon_ptr->smooth != NULL) {
316 polygon_ptr->smooth[i] = PolygonPtr->smooth[i];
317 }
318 }
319 polygon_ptr->vlist = pv;
320 polygon_ptr->fill = PolygonPtr->fill;
321 polygon_ptr->width = PolygonPtr->width;
322 strcpy(polygon_ptr->width_spec, PolygonPtr->width_spec);
323 polygon_ptr->pen = PolygonPtr->pen;
324 polygon_ptr->curved = PolygonPtr->curved;
325 if (PolygonPtr->sn != 0 && PolygonPtr->svlist != NULL) {
326 polygon_ptr->sn = num_pts = PolygonPtr->sn;
327 sv = (XPoint*)malloc((num_pts+1)*sizeof(XPoint));
328 if (sv == NULL) FailAllocMessage();
329 for (i=0; i < num_pts; i++) {
330 sv[i].x = PolygonPtr->svlist[i].x;
331 sv[i].y = PolygonPtr->svlist[i].y;
332 }
333 polygon_ptr->svlist = sv;
334 } else {
335 polygon_ptr->sn = 0;
336 polygon_ptr->svlist = NULL;
337 }
338 if (PolygonPtr->ssn != 0 && PolygonPtr->ssvlist != NULL) {
339 polygon_ptr->ssn = num_pts = PolygonPtr->ssn;
340 pv = (IntPoint*)malloc((num_pts+1)*sizeof(IntPoint));
341 if (pv == NULL) FailAllocMessage();
342 for (i=0; i < num_pts; i++) {
343 pv[i].x = PolygonPtr->ssvlist[i].x;
344 pv[i].y = PolygonPtr->ssvlist[i].y;
345 }
346 polygon_ptr->ssvlist = pv;
347 } else {
348 polygon_ptr->ssn = 0;
349 polygon_ptr->ssvlist = NULL;
350 }
351 if (PolygonPtr->ssmooth != NULL && PolygonPtr->ssvlist != NULL) {
352 num_pts = PolygonPtr->ssn;
353 polygon_ptr->ssmooth = (char*)malloc((num_pts+1)*sizeof(char));
354 if (polygon_ptr->ssmooth == NULL) FailAllocMessage();
355 memcpy(polygon_ptr->ssmooth, PolygonPtr->ssmooth, num_pts*sizeof(char));
356 polygon_ptr->ssmooth[num_pts] = FALSE;
357 } else {
358 polygon_ptr->ssmooth = NULL;
359 }
360 if (PolygonPtr->curved == LT_INTSPLINE && PolygonPtr->intn != 0 &&
361 PolygonPtr->intvlist != NULL) {
362 polygon_ptr->intn = num_pts = PolygonPtr->intn;
363 pv = (IntPoint*)malloc((num_pts+1)*sizeof(IntPoint));
364 if (pv == NULL) FailAllocMessage();
365 for (i=0; i < num_pts; i++) {
366 pv[i].x = PolygonPtr->intvlist[i].x;
367 pv[i].y = PolygonPtr->intvlist[i].y;
368 }
369 polygon_ptr->intvlist = pv;
370 } else {
371 polygon_ptr->intn = 0;
372 polygon_ptr->intvlist = NULL;
373 }
374 polygon_ptr->dash = PolygonPtr->dash;
375 if (ObjPtr->ctm != NULL && PolygonPtr->rotated_n != 0 &&
376 PolygonPtr->rotated_vlist != NULL) {
377 polygon_ptr->rotated_n = num_pts = PolygonPtr->rotated_n;
378 sv = (XPoint*)malloc((num_pts+1)*sizeof(XPoint));
379 if (sv == NULL) FailAllocMessage();
380 for (i=0; i < num_pts; i++) {
381 sv[i].x = PolygonPtr->rotated_vlist[i].x;
382 sv[i].y = PolygonPtr->rotated_vlist[i].y;
383 }
384 polygon_ptr->rotated_vlist = sv;
385 } else {
386 polygon_ptr->rotated_n = 0;
387 polygon_ptr->rotated_vlist = NULL;
388 }
389
390 ObjPtr->detail.g = polygon_ptr;
391 }
392
DupOvalObj(OvalPtr,ObjPtr)393 void DupOvalObj(OvalPtr, ObjPtr)
394 struct OvalRec *OvalPtr;
395 struct ObjRec *ObjPtr;
396 {
397 register struct OvalRec *oval_ptr;
398
399 oval_ptr = (struct OvalRec *)malloc(sizeof(struct OvalRec));
400 if (oval_ptr == NULL) FailAllocMessage();
401 memset(oval_ptr, 0, sizeof(struct OvalRec));
402 oval_ptr->fill = OvalPtr->fill;
403 oval_ptr->width = OvalPtr->width;
404 strcpy(oval_ptr->width_spec, OvalPtr->width_spec);
405 oval_ptr->pen = OvalPtr->pen;
406 oval_ptr->dash = OvalPtr->dash;
407 if (ObjPtr->ctm != NULL && OvalPtr->rotated_n != 0 &&
408 OvalPtr->rotated_vlist != NULL) {
409 int i, num_pts;
410 XPoint *v;
411
412 oval_ptr->rotated_n = num_pts = OvalPtr->rotated_n;
413 v = (XPoint*)malloc((num_pts+1)*sizeof(XPoint));
414 if (v == NULL) FailAllocMessage();
415 for (i=0; i < num_pts; i++) {
416 v[i].x = OvalPtr->rotated_vlist[i].x;
417 v[i].y = OvalPtr->rotated_vlist[i].y;
418 }
419 oval_ptr->rotated_vlist = v;
420 } else {
421 oval_ptr->rotated_n = 0;
422 oval_ptr->rotated_vlist = NULL;
423 }
424
425 ObjPtr->detail.o = oval_ptr;
426 }
427
DupBoxObj(BoxPtr,ObjPtr)428 void DupBoxObj(BoxPtr, ObjPtr)
429 struct BoxRec *BoxPtr;
430 struct ObjRec *ObjPtr;
431 {
432 register struct BoxRec *box_ptr;
433
434 box_ptr = (struct BoxRec *)malloc(sizeof(struct BoxRec));
435 if (box_ptr == NULL) FailAllocMessage();
436 memset(box_ptr, 0, sizeof(struct BoxRec));
437 box_ptr->fill = BoxPtr->fill;
438 box_ptr->width = BoxPtr->width;
439 strcpy(box_ptr->width_spec, BoxPtr->width_spec);
440 box_ptr->pen = BoxPtr->pen;
441 box_ptr->dash = BoxPtr->dash;
442
443 ObjPtr->detail.b = box_ptr;
444 }
445
DupRCBoxObj(RCBoxPtr,ObjPtr)446 void DupRCBoxObj(RCBoxPtr, ObjPtr)
447 struct RCBoxRec *RCBoxPtr;
448 struct ObjRec *ObjPtr;
449 {
450 register struct RCBoxRec *rcbox_ptr;
451
452 rcbox_ptr = (struct RCBoxRec *)malloc(sizeof(struct RCBoxRec));
453 if (rcbox_ptr == NULL) FailAllocMessage();
454 memset(rcbox_ptr, 0, sizeof(struct RCBoxRec));
455 rcbox_ptr->fill = RCBoxPtr->fill;
456 rcbox_ptr->width = RCBoxPtr->width;
457 strcpy(rcbox_ptr->width_spec, RCBoxPtr->width_spec);
458 rcbox_ptr->pen = RCBoxPtr->pen;
459 rcbox_ptr->dash = RCBoxPtr->dash;
460 rcbox_ptr->radius = RCBoxPtr->radius;
461 if (ObjPtr->ctm != NULL && RCBoxPtr->rotated_n != 0 &&
462 RCBoxPtr->rotated_vlist != NULL) {
463 int i, num_pts;
464 XPoint *v;
465
466 rcbox_ptr->rotated_n = num_pts = RCBoxPtr->rotated_n;
467 v = (XPoint*)malloc((num_pts+1)*sizeof(XPoint));
468 if (v == NULL) FailAllocMessage();
469 for (i=0; i < num_pts; i++) {
470 v[i].x = RCBoxPtr->rotated_vlist[i].x;
471 v[i].y = RCBoxPtr->rotated_vlist[i].y;
472 }
473 rcbox_ptr->rotated_vlist = v;
474 } else {
475 rcbox_ptr->rotated_n = 0;
476 rcbox_ptr->rotated_vlist = NULL;
477 }
478
479 ObjPtr->detail.rcb = rcbox_ptr;
480 }
481
DupArcObj(ArcPtr,ObjPtr)482 void DupArcObj(ArcPtr, ObjPtr)
483 struct ArcRec *ArcPtr;
484 struct ObjRec *ObjPtr;
485 {
486 register struct ArcRec *arc_ptr;
487
488 arc_ptr = (struct ArcRec *)malloc(sizeof(struct ArcRec));
489 if (arc_ptr == NULL) FailAllocMessage();
490 memset(arc_ptr, 0, sizeof(struct ArcRec));
491 arc_ptr->fill = ArcPtr->fill;
492 arc_ptr->width = ArcPtr->width;
493 arc_ptr->aw = ArcPtr->aw;
494 arc_ptr->ah = ArcPtr->ah;
495 strcpy(arc_ptr->width_spec, ArcPtr->width_spec);
496 strcpy(arc_ptr->aw_spec, ArcPtr->aw_spec);
497 strcpy(arc_ptr->ah_spec, ArcPtr->ah_spec);
498 arc_ptr->pen = ArcPtr->pen;
499 arc_ptr->dash = ArcPtr->dash;
500 arc_ptr->style = ArcPtr->style;
501
502 arc_ptr->xc = ArcPtr->xc; arc_ptr->yc = ArcPtr->yc;
503 arc_ptr->x1 = ArcPtr->x1; arc_ptr->y1 = ArcPtr->y1;
504 arc_ptr->x2 = ArcPtr->x2; arc_ptr->y2 = ArcPtr->y2;
505 arc_ptr->dir = ArcPtr->dir;
506 arc_ptr->ltx = ArcPtr->ltx; arc_ptr->lty = ArcPtr->lty;
507 arc_ptr->w = ArcPtr->w; arc_ptr->h = ArcPtr->h;
508 arc_ptr->angle1 = ArcPtr->angle1; arc_ptr->angle2 = ArcPtr->angle2;
509 arc_ptr->a_angle1 = ArcPtr->a_angle1; arc_ptr->a_angle2 = ArcPtr->a_angle2;
510 if (ObjPtr->ctm != NULL && ArcPtr->rotated_n != 0 &&
511 ArcPtr->rotated_vlist != NULL) {
512 int i, num_pts;
513 XPoint *v;
514
515 arc_ptr->rotated_n = num_pts = ArcPtr->rotated_n;
516 v = (XPoint*)malloc((num_pts+2)*sizeof(XPoint));
517 if (v == NULL) FailAllocMessage();
518 for (i=0; i < num_pts+2; i++) {
519 v[i].x = ArcPtr->rotated_vlist[i].x;
520 v[i].y = ArcPtr->rotated_vlist[i].y;
521 }
522 arc_ptr->rotated_vlist = v;
523 } else {
524 arc_ptr->rotated_n = 0;
525 arc_ptr->rotated_vlist = NULL;
526 }
527
528 ObjPtr->detail.a = arc_ptr;
529 }
530
DupXBmObj(XBmPtr,ObjPtr)531 void DupXBmObj(XBmPtr, ObjPtr)
532 struct XBmRec *XBmPtr;
533 struct ObjRec *ObjPtr;
534 {
535 register struct XBmRec *xbm_ptr;
536 register int i;
537 Pixmap bitmap, cached_bitmap;
538 int w, h, image_w, image_h;
539
540 xbm_ptr = (struct XBmRec *)malloc(sizeof(struct XBmRec));
541 if (xbm_ptr == NULL) FailAllocMessage();
542 memset(xbm_ptr, 0, sizeof(struct XBmRec));
543 ObjPtr->detail.xbm = xbm_ptr;
544
545 xbm_ptr->image = NULL;
546 xbm_ptr->data = NULL;
547 xbm_ptr->fill = XBmPtr->fill;
548 xbm_ptr->image_w = image_w = XBmPtr->image_w;
549 xbm_ptr->image_h = image_h = XBmPtr->image_h;
550 xbm_ptr->flip = XBmPtr->flip;
551 xbm_ptr->cached_zoom = XBmPtr->cached_zoom;
552 xbm_ptr->cached_zoomed = XBmPtr->cached_zoomed;
553 xbm_ptr->cached_flip = XBmPtr->cached_flip;
554 xbm_ptr->cached_w = XBmPtr->cached_w;
555 xbm_ptr->cached_h = XBmPtr->cached_h;
556
557 xbm_ptr->eps_w = XBmPtr->eps_w;
558 xbm_ptr->eps_h = XBmPtr->eps_h;
559
560 xbm_ptr->bitmap = None;
561 xbm_ptr->cached_bitmap = None;
562
563 *xbm_ptr->write_date = '\0';
564 xbm_ptr->save_epsf = XBmPtr->save_epsf;
565 xbm_ptr->real_type = XBmPtr->real_type;
566
567 if (ObjPtr->ctm != NULL) {
568 memcpy(&xbm_ptr->cached_ctm, &XBmPtr->cached_ctm,
569 sizeof(struct XfrmMtrxRec));
570 }
571 if (XBmPtr->real_type==XBM_XBM || (XBmPtr->real_type==XBM_EPS &&
572 XBmPtr->bitmap!=None)) {
573 bitmap = XCreatePixmap(mainDisplay, mainWindow, image_w, image_h, 1);
574 if (bitmap == None) {
575 FailAllocBitmapMessage(image_w, image_h);
576 return;
577 }
578 XCopyArea(mainDisplay, XBmPtr->bitmap, bitmap, xbmGC, 0, 0,
579 image_w, image_h, 0, 0);
580 xbm_ptr->bitmap = bitmap;
581 if (XBmPtr->cached_bitmap != None) {
582 w = ZOOMED_SIZE(ObjPtr->obbox.rbx - ObjPtr->obbox.ltx);
583 h = ZOOMED_SIZE(ObjPtr->obbox.rby - ObjPtr->obbox.lty);
584
585 cached_bitmap = XCreatePixmap(mainDisplay, mainWindow, w, h, 1);
586 if (cached_bitmap == None) {
587 FailAllocBitmapMessage(w, h);
588 return;
589 }
590 XCopyArea(mainDisplay, XBmPtr->cached_bitmap, cached_bitmap, xbmGC,
591 0, 0, w, h, 0, 0);
592 xbm_ptr->cached_bitmap = cached_bitmap;
593 }
594 }
595 if (XBmPtr->real_type == XBM_EPS) {
596 int len=strlen(XBmPtr->filename);
597 int num_epsf_lines=XBmPtr->num_epsf_lines;
598
599 xbm_ptr->llx = XBmPtr->llx; xbm_ptr->lly = XBmPtr->lly;
600 xbm_ptr->urx = XBmPtr->urx; xbm_ptr->ury = XBmPtr->ury;
601 xbm_ptr->filename = (char*)malloc((len+1)*sizeof(char));
602 if (xbm_ptr->filename == NULL) FailAllocMessage();
603 strcpy(xbm_ptr->filename, XBmPtr->filename);
604 strcpy(xbm_ptr->write_date, XBmPtr->write_date);
605 if (num_epsf_lines > 0) {
606 xbm_ptr->num_epsf_lines = num_epsf_lines;
607 xbm_ptr->epsflines = (char**)malloc(num_epsf_lines*sizeof(char*));
608 if (xbm_ptr->epsflines == NULL) FailAllocMessage();
609 for (i=0; i < num_epsf_lines; i++) {
610 len = strlen(XBmPtr->epsflines[i]);
611 xbm_ptr->epsflines[i] = (char*)malloc((len+1)*sizeof(char));
612 if (xbm_ptr->epsflines[i] == NULL) FailAllocMessage();
613 strcpy(xbm_ptr->epsflines[i], XBmPtr->epsflines[i]);
614 }
615 }
616 }
617 }
618
DupXPmObj(XPmPtr,ObjPtr)619 void DupXPmObj(XPmPtr, ObjPtr)
620 struct XPmRec *XPmPtr;
621 struct ObjRec *ObjPtr;
622 {
623 register struct XPmRec *xpm_ptr=NULL;
624 Pixmap pixmap=None, bitmap=None, cached_pixmap=None, cached_bitmap=None;
625 int w=0, h=0, ncolors=0, image_w=0, image_h=0;
626
627 xpm_ptr = (struct XPmRec *)malloc(sizeof(struct XPmRec));
628 if (xpm_ptr == NULL) FailAllocMessage();
629 memset(xpm_ptr, 0, sizeof(struct XPmRec));
630 ObjPtr->detail.xpm = xpm_ptr;
631
632 xpm_ptr->image = NULL;
633 xpm_ptr->bitmap_image = NULL;
634 xpm_ptr->data = NULL;
635 xpm_ptr->fill = XPmPtr->fill;
636 xpm_ptr->image_w = image_w = XPmPtr->image_w;
637 xpm_ptr->image_h = image_h = XPmPtr->image_h;
638 xpm_ptr->flip = XPmPtr->flip;
639 xpm_ptr->cached_zoom = XPmPtr->cached_zoom;
640 xpm_ptr->cached_zoomed = XPmPtr->cached_zoomed;
641 xpm_ptr->cached_flip = XPmPtr->cached_flip;
642 xpm_ptr->cached_w = XPmPtr->cached_w;
643 xpm_ptr->cached_h = XPmPtr->cached_h;
644 xpm_ptr->cached_color = (-1);
645
646 xpm_ptr->pixmap = None;
647 xpm_ptr->bitmap = None;
648 xpm_ptr->cached_pixmap = None;
649 xpm_ptr->cached_bitmap = None;
650 xpm_ptr->clip_mask = None;
651
652 xpm_ptr->real_type = XPmPtr->real_type;
653 xpm_ptr->linked_jpeg = FALSE;
654 xpm_ptr->filename = NULL;
655
656 if (xpm_ptr->real_type == XPM_JPEG) {
657 xpm_ptr->linked_jpeg = XPmPtr->linked_jpeg;
658 if (XPmPtr->filename != NULL) {
659 xpm_ptr->filename = UtilStrDup(XPmPtr->filename);
660 if (xpm_ptr->filename == NULL) FailAllocMessage();
661 }
662 } else if (xpm_ptr->real_type == PPM_TRUE) {
663 xpm_ptr->ppm_data_compress = XPmPtr->ppm_data_compress;
664 if (xpm_ptr->ppm_data_compress == PPM_JPEG_COMPRESS ||
665 xpm_ptr->ppm_data_compress == PPM_DATA_DEFLATED) {
666 xpm_ptr->ppm_mask_size = XPmPtr->ppm_mask_size;
667 if (xpm_ptr->ppm_mask_size > 0) {
668 xpm_ptr->ppm_mask_data = (char*)malloc(xpm_ptr->ppm_mask_size);
669 if (xpm_ptr->ppm_mask_data == NULL) FailAllocMessage();
670 memcpy(xpm_ptr->ppm_mask_data, XPmPtr->ppm_mask_data,
671 xpm_ptr->ppm_mask_size);
672 }
673 xpm_ptr->ppm_data_size = XPmPtr->ppm_data_size;
674 xpm_ptr->ppm_data = (char*)malloc(xpm_ptr->ppm_data_size);
675 if (xpm_ptr->ppm_data == NULL) FailAllocMessage();
676 memcpy(xpm_ptr->ppm_data, XPmPtr->ppm_data, xpm_ptr->ppm_data_size);
677 xpm_ptr->has_transparent_color = XPmPtr->has_transparent_color;
678 memcpy(xpm_ptr->transparent_color, XPmPtr->transparent_color,
679 sizeof(xpm_ptr->transparent_color));
680 }
681 }
682 if (ObjPtr->ctm != NULL) {
683 memcpy(&xpm_ptr->cached_ctm, &XPmPtr->cached_ctm,
684 sizeof(struct XfrmMtrxRec));
685 }
686 pixmap = XCreatePixmap(mainDisplay,mainWindow,image_w,image_h,mainDepth);
687 if (pixmap == None) {
688 FailAllocPixmapMessage(image_w, image_h);
689 return;
690 }
691 XCopyArea(mainDisplay,XPmPtr->pixmap,pixmap,xpmGC,0,0,image_w,image_h,0,0);
692 xpm_ptr->pixmap = pixmap;
693
694 bitmap = XCreatePixmap(mainDisplay,mainWindow,image_w,image_h,1);
695 if (bitmap == None) {
696 FailAllocBitmapMessage(image_w, image_h);
697 return;
698 }
699 XCopyArea(mainDisplay,XPmPtr->bitmap,bitmap,xbmGC,0,0,image_w,image_h,0,0);
700 xpm_ptr->bitmap = bitmap;
701
702 w = ZOOMED_SIZE(ObjPtr->obbox.rbx - ObjPtr->obbox.ltx);
703 h = ZOOMED_SIZE(ObjPtr->obbox.rby - ObjPtr->obbox.lty);
704
705 if (XPmPtr->cached_pixmap != None) {
706 cached_pixmap = XCreatePixmap(mainDisplay, mainWindow, w, h, mainDepth);
707 if (cached_pixmap == None) {
708 FailAllocPixmapMessage(w, h);
709 return;
710 }
711 XCopyArea(mainDisplay, XPmPtr->cached_pixmap, cached_pixmap, xpmGC, 0, 0,
712 w, h, 0, 0);
713 xpm_ptr->cached_pixmap = cached_pixmap;
714 }
715 if (XPmPtr->cached_bitmap != None) {
716 cached_bitmap = XCreatePixmap(mainDisplay, mainWindow, w, h, 1);
717 if (cached_bitmap == None) {
718 FailAllocBitmapMessage(w, h);
719 return;
720 }
721 XCopyArea(mainDisplay, XPmPtr->cached_bitmap, cached_bitmap, xbmGC, 0, 0,
722 w, h, 0, 0);
723 xpm_ptr->cached_bitmap = cached_bitmap;
724 }
725 ncolors = xpm_ptr->ncolors = XPmPtr->ncolors;
726
727 if (xpm_ptr->real_type != PPM_TRUE) {
728 int i=0, *pixels=NULL, chars_per_pixel=0;
729 char *color_char=NULL, **color_str=NULL;
730
731 chars_per_pixel = xpm_ptr->chars_per_pixel = XPmPtr->chars_per_pixel;
732 xpm_ptr->first_pixel_is_bg = XPmPtr->first_pixel_is_bg;
733
734 color_char = xpm_ptr->color_char =
735 (char*)malloc(ncolors*chars_per_pixel*sizeof(char));
736 color_str = xpm_ptr->color_str = (char**)malloc(ncolors*sizeof(char*));
737 pixels = xpm_ptr->pixels = (int*)malloc(ncolors*sizeof(int));
738 if (color_char==NULL || color_str==NULL || pixels==NULL) {
739 FailAllocMessage();
740 }
741 for (i=0; i < ncolors; i++) {
742 int j=0, len=0;
743
744 for (j=0; j < chars_per_pixel; j++) {
745 color_char[i*chars_per_pixel+j] =
746 XPmPtr->color_char[i*chars_per_pixel+j];
747 }
748 pixels[i] = XPmPtr->pixels[i];
749
750 len = strlen(XPmPtr->color_str[i]);
751 color_str[i] = (char*)malloc((len+1)*sizeof(char));
752 if (color_str[i] == NULL) FailAllocMessage();
753 strcpy(color_str[i], XPmPtr->color_str[i]);
754 }
755 }
756 xpm_ptr->red = xpm_ptr->green = xpm_ptr->blue = NULL;
757 if (ObjPtr->ctm != NULL && XPmPtr->clip_mask != None) {
758 w = ZOOMED_SIZE(ObjPtr->obbox.rbx - ObjPtr->obbox.ltx);
759 h = ZOOMED_SIZE(ObjPtr->obbox.rby - ObjPtr->obbox.lty);
760
761 pixmap = XCreatePixmap(mainDisplay, mainWindow, w, h, 1);
762 if (pixmap == None) {
763 FailAllocBitmapMessage(w, h);
764 return;
765 }
766 XCopyArea(mainDisplay, XPmPtr->clip_mask, pixmap, xbmGC, 0, 0,
767 w, h, 0, 0);
768 xpm_ptr->clip_mask = pixmap;
769 }
770 }
771
DupStrSeg(pToStrBlock,pFromStrSeg)772 void DupStrSeg(pToStrBlock, pFromStrSeg)
773 StrBlockInfo *pToStrBlock;
774 StrSegInfo *pFromStrSeg;
775 /* pToStrBlock->type is either SB_SIMPLE or SB_SUPSUB_CENTER */
776 /* pToStrBlock->seg is the newly created string segment */
777 {
778 StrSegInfo *str_seg=(StrSegInfo*)malloc(sizeof(StrSegInfo));
779
780 if (str_seg == NULL) FailAllocMessage();
781 memcpy(str_seg, pFromStrSeg, sizeof(StrSegInfo));
782 if (PRTGIF && pFromStrSeg->font_name != NULL &&
783 *pFromStrSeg->font_name != '\0') {
784 /*
785 * this should never happen anyway (because DupStrSeg() is never called
786 * in PRTGIF)
787 */
788 str_seg->font_name = UtilStrDup(pFromStrSeg->font_name);
789 if (str_seg->font_name == NULL) FailAllocMessage();
790 }
791 str_seg->dyn_str.s = NULL;
792 str_seg->dyn_str.sz = 0;
793 DynStrCpy(&str_seg->dyn_str, &pFromStrSeg->dyn_str);
794 str_seg->owner = pToStrBlock;
795 pToStrBlock->seg = str_seg;
796 }
797
DupStrBlock(pStrBlock,pMiniLineOwner,ppFirstStrBlock,ppLastStrBlock)798 void DupStrBlock(pStrBlock, pMiniLineOwner, ppFirstStrBlock, ppLastStrBlock)
799 StrBlockInfo *pStrBlock, **ppFirstStrBlock, **ppLastStrBlock;
800 MiniLineInfo *pMiniLineOwner;
801 {
802 StrBlockInfo *str_block=(StrBlockInfo*)malloc(sizeof(StrBlockInfo));
803
804 if (str_block == NULL) FailAllocMessage();
805 memcpy(str_block, pStrBlock, sizeof(StrBlockInfo));
806 str_block->seg = NULL;
807 str_block->sup = str_block->sub = NULL;
808 str_block->owner_mini_line = pMiniLineOwner;
809 str_block->next = NULL;
810 str_block->prev = (*ppLastStrBlock);
811 if ((*ppLastStrBlock) == NULL) {
812 (*ppFirstStrBlock) = str_block;
813 } else {
814 (*ppLastStrBlock)->next = str_block;
815 }
816 (*ppLastStrBlock) = str_block;
817 switch (pStrBlock->type) {
818 case SB_SIMPLE:
819 DupStrSeg(str_block, pStrBlock->seg);
820 break;
821 case SB_CHAR_SPACE: break;
822
823 case SB_SUPSUB_LEFT:
824 case SB_SUPSUB_CENTER:
825 case SB_SUPSUB_RIGHT:
826 if (pStrBlock->sup != NULL) {
827 DupMiniLines(pStrBlock->sup, str_block, &str_block->sup);
828 }
829 if (pStrBlock->sub != NULL) {
830 DupMiniLines(pStrBlock->sub, str_block, &str_block->sub);
831 }
832 if (pStrBlock->type == SB_SUPSUB_CENTER) {
833 DupStrSeg(str_block, pStrBlock->seg);
834 }
835 break;
836 }
837 }
838
DupMiniLine(pMiniLine,pOwnerMiniLines,pOwnerBlock,ppFirstMiniLine,ppLastMiniLine)839 void DupMiniLine(pMiniLine, pOwnerMiniLines, pOwnerBlock, ppFirstMiniLine,
840 ppLastMiniLine)
841 MiniLineInfo *pMiniLine, **ppFirstMiniLine, **ppLastMiniLine;
842 MiniLinesInfo *pOwnerMiniLines;
843 StrBlockInfo *pOwnerBlock;
844 {
845 MiniLineInfo *new_mini_line=(MiniLineInfo*)malloc(sizeof(MiniLineInfo));
846 StrBlockInfo *pStrBlock=NULL;
847
848 if (new_mini_line == NULL) FailAllocMessage();
849 memcpy(new_mini_line, pMiniLine, sizeof(MiniLineInfo));
850 new_mini_line->first_block = new_mini_line->last_block = NULL;
851 new_mini_line->owner_minilines = pOwnerMiniLines;
852 new_mini_line->next = NULL;
853 new_mini_line->prev = (*ppLastMiniLine);
854 if ((*ppLastMiniLine) == NULL) {
855 (*ppFirstMiniLine) = new_mini_line;
856 } else {
857 (*ppLastMiniLine)->next = new_mini_line;
858 }
859 (*ppLastMiniLine) = new_mini_line;
860 for (pStrBlock=pMiniLine->first_block; pStrBlock != NULL;
861 pStrBlock=pStrBlock->next) {
862 DupStrBlock(pStrBlock, new_mini_line, &new_mini_line->first_block,
863 &new_mini_line->last_block);
864 }
865 }
866
DupMiniLines(minilines,pOwnerBlock,ppMinilines)867 void DupMiniLines(minilines, pOwnerBlock, ppMinilines)
868 MiniLinesInfo *minilines, **ppMinilines;
869 StrBlockInfo *pOwnerBlock;
870 {
871 MiniLinesInfo *new_minilines=(MiniLinesInfo*)malloc(sizeof(MiniLinesInfo));
872 MiniLineInfo *pMiniLine=NULL, *pFirstMiniLine=NULL, *pLastMiniLine=NULL;
873
874 if (new_minilines == NULL) FailAllocMessage();
875 memcpy(new_minilines, minilines, sizeof(MiniLinesInfo));
876 new_minilines->first = new_minilines->last = NULL;
877 new_minilines->owner_block = pOwnerBlock;
878 for (pMiniLine=minilines->first; pMiniLine != NULL;
879 pMiniLine=pMiniLine->next) {
880 DupMiniLine(pMiniLine, new_minilines, pOwnerBlock, &pFirstMiniLine,
881 &pLastMiniLine);
882 }
883 new_minilines->first = pFirstMiniLine;
884 new_minilines->last = pLastMiniLine;
885
886 if (ppMinilines != NULL) {
887 *ppMinilines = new_minilines;
888 }
889 }
890
DupTextObj(TextPtr,FromObjPtr,ToObjPtr)891 void DupTextObj(TextPtr, FromObjPtr, ToObjPtr)
892 struct TextRec *TextPtr;
893 struct ObjRec *FromObjPtr, *ToObjPtr;
894 {
895 struct TextRec *text_ptr=NULL;
896 MiniLinesInfo *minilines=NULL;
897 MiniLineInfo *pMiniLine=NULL;
898
899 text_ptr = (struct TextRec *)malloc(sizeof(struct TextRec));
900 if (text_ptr == NULL) FailAllocMessage();
901 memcpy(text_ptr, TextPtr, sizeof(struct TextRec));
902
903 text_ptr->attr = NULL;
904 text_ptr->cached_bitmap = None;
905 text_ptr->cached_pixmap = None;
906 text_ptr->cached_bg_bitmap = None;
907
908 ToObjPtr->detail.t = text_ptr;
909
910 if (TextPtr->cached_bitmap != None) {
911 int w=ZOOMED_SIZE(FromObjPtr->bbox.rbx - FromObjPtr->bbox.ltx - 2);
912 int h=ZOOMED_SIZE(FromObjPtr->bbox.rby - FromObjPtr->bbox.lty - 2);
913
914 if (w == 0) w = 1;
915 if (h == 0) h = 1;
916 text_ptr->cached_bitmap = XCreatePixmap(mainDisplay,mainWindow,w,h,1);
917 if (text_ptr->cached_bitmap == None) {
918 FailAllocBitmapMessage(w, h);
919 return;
920 }
921 XCopyArea(mainDisplay, TextPtr->cached_bitmap, text_ptr->cached_bitmap,
922 rotateGC, 0, 0, w, h, 0, 0);
923 }
924 if (TextPtr->cached_bg_bitmap != None) {
925 int w=ZOOMED_SIZE(FromObjPtr->bbox.rbx - FromObjPtr->bbox.ltx - 2);
926 int h=ZOOMED_SIZE(FromObjPtr->bbox.rby - FromObjPtr->bbox.lty - 2);
927
928 if (w == 0) w = 1;
929 if (h == 0) h = 1;
930 text_ptr->cached_bg_bitmap = XCreatePixmap(mainDisplay,mainWindow,w,h,1);
931 if (text_ptr->cached_bg_bitmap == None) {
932 FailAllocBitmapMessage(w, h);
933 return;
934 }
935 XCopyArea(mainDisplay, TextPtr->cached_bg_bitmap,
936 text_ptr->cached_bg_bitmap, rotateGC, 0, 0, w, h, 0, 0);
937 }
938 if (TextPtr->cached_pixmap != None) {
939 int w=ZOOMED_SIZE(FromObjPtr->bbox.rbx - FromObjPtr->bbox.ltx - 2);
940 int h=ZOOMED_SIZE(FromObjPtr->bbox.rby - FromObjPtr->bbox.lty - 2);
941
942 if (w == 0) w = 1;
943 if (h == 0) h = 1;
944 text_ptr->cached_pixmap = XCreatePixmap(mainDisplay, mainWindow, w, h,
945 mainDepth);
946 if (text_ptr->cached_pixmap == None) {
947 FailAllocBitmapMessage(w, h);
948 return;
949 }
950 XCopyArea(mainDisplay, TextPtr->cached_pixmap, text_ptr->cached_pixmap,
951 xpmGC, 0, 0, w, h, 0, 0);
952 }
953 DupMiniLines(&FromObjPtr->detail.t->minilines, NULL, &minilines);
954 memcpy(&text_ptr->minilines, minilines, sizeof(MiniLinesInfo));
955 free(minilines);
956 minilines = (&text_ptr->minilines);
957 for (pMiniLine=minilines->first; pMiniLine != NULL;
958 pMiniLine=pMiniLine->next) {
959 pMiniLine->owner_minilines = minilines;
960 }
961 }
962
DupConnection(FromConnPtr,ToConnPtr)963 void DupConnection(FromConnPtr, ToConnPtr)
964 struct ConnRec *FromConnPtr, *ToConnPtr;
965 {
966 }
967
DupGroupObj(GroupPtr,ObjPtr)968 void DupGroupObj(GroupPtr, ObjPtr)
969 struct GroupRec *GroupPtr;
970 struct ObjRec *ObjPtr;
971 {
972 register struct GroupRec *group_ptr;
973 struct ObjRec *top_obj;
974 struct ObjRec *from_obj_ptr, *to_obj_ptr;
975
976 group_ptr = (struct GroupRec *)malloc(sizeof(struct GroupRec));
977 if (group_ptr == NULL) FailAllocMessage();
978 memset(group_ptr, 0, sizeof(struct GroupRec));
979 top_obj = NULL;
980 from_obj_ptr = GroupPtr->last;
981 for ( ; from_obj_ptr != NULL; from_obj_ptr=from_obj_ptr->prev) {
982 to_obj_ptr = DupObj(from_obj_ptr);
983 to_obj_ptr->next = top_obj;
984 if (top_obj == NULL) {
985 group_ptr->last = to_obj_ptr;
986 } else {
987 top_obj->prev = to_obj_ptr;
988 }
989 top_obj = to_obj_ptr;
990 }
991 top_obj->prev = NULL;
992 group_ptr->first = top_obj;
993
994 ObjPtr->detail.r = group_ptr;
995 }
996
DupObj(ObjPtr)997 struct ObjRec *DupObj(ObjPtr)
998 struct ObjRec *ObjPtr;
999 {
1000 struct ObjRec *obj_ptr;
1001
1002 obj_ptr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
1003 if (obj_ptr == NULL) FailAllocMessage();
1004 memset(obj_ptr, 0, sizeof(struct ObjRec));
1005 DupObjBasics(ObjPtr, obj_ptr);
1006
1007 switch (ObjPtr->type) {
1008 case OBJ_POLY:
1009 DupPolyObj(ObjPtr->detail.p, obj_ptr);
1010 DupAttrs(ObjPtr, obj_ptr);
1011 break;
1012 case OBJ_BOX:
1013 DupBoxObj(ObjPtr->detail.b, obj_ptr);
1014 DupAttrs(ObjPtr, obj_ptr);
1015 break;
1016 case OBJ_OVAL:
1017 DupOvalObj(ObjPtr->detail.o, obj_ptr);
1018 DupAttrs(ObjPtr, obj_ptr);
1019 break;
1020 case OBJ_TEXT: DupTextObj(ObjPtr->detail.t, ObjPtr, obj_ptr); break;
1021 case OBJ_POLYGON:
1022 DupPolygonObj(ObjPtr->detail.g, obj_ptr);
1023 DupAttrs(ObjPtr, obj_ptr);
1024 break;
1025 case OBJ_ARC:
1026 DupArcObj(ObjPtr->detail.a, obj_ptr);
1027 DupAttrs(ObjPtr, obj_ptr);
1028 break;
1029 case OBJ_RCBOX:
1030 DupRCBoxObj(ObjPtr->detail.rcb, obj_ptr);
1031 DupAttrs(ObjPtr, obj_ptr);
1032 break;
1033 case OBJ_XBM:
1034 DupXBmObj(ObjPtr->detail.xbm, obj_ptr);
1035 DupAttrs(ObjPtr, obj_ptr);
1036 break;
1037 case OBJ_XPM:
1038 DupXPmObj(ObjPtr->detail.xpm, obj_ptr);
1039 DupAttrs(ObjPtr, obj_ptr);
1040 break;
1041 case OBJ_SYM:
1042 case OBJ_GROUP:
1043 case OBJ_ICON:
1044 case OBJ_PIN:
1045 DupGroupObj(ObjPtr->detail.r, obj_ptr);
1046 DupAttrs(ObjPtr, obj_ptr);
1047 if (obj_ptr->type == OBJ_ICON || obj_ptr->type == OBJ_PIN) {
1048 strcpy(obj_ptr->detail.r->s, ObjPtr->detail.r->s);
1049 obj_ptr->detail.r->rotate = ObjPtr->detail.r->rotate;
1050 obj_ptr->detail.r->flip = ObjPtr->detail.r->flip;
1051 obj_ptr->detail.r->deck_index = (-1);
1052 /*
1053 * Need to check for pins.
1054 * Need to handle the case where connection objects need to be dupped!
1055 */
1056 obj_ptr->detail.r->pin_connected = 0;
1057 obj_ptr->detail.r->first_conn = obj_ptr->detail.r->last_conn = NULL;
1058 }
1059 break;
1060 }
1061 return obj_ptr;
1062 }
1063
DupSelObj()1064 void DupSelObj()
1065 {
1066 struct SelRec *sel_ptr, *sel_ptr1;
1067 struct ObjRec *obj_ptr, *top_obj, *bot_obj;
1068 int dx=0, dy=0;
1069
1070 if (topSel==NULL || curChoice==VERTEXMODE) return;
1071 /*
1072 * Need to check for pins.
1073 * Need to handle the case where connection objects need to be dupped!
1074 */
1075 top_obj = bot_obj = NULL;
1076 for (sel_ptr=botSel; sel_ptr != NULL; sel_ptr=sel_ptr->prev) {
1077 obj_ptr = DupObj(sel_ptr->obj);
1078 obj_ptr->next = top_obj;
1079 if (top_obj == NULL) {
1080 bot_obj = obj_ptr;
1081 } else {
1082 top_obj->prev = obj_ptr;
1083 }
1084 top_obj = obj_ptr;
1085 }
1086 top_obj->prev = NULL;
1087
1088 HighLightReverse();
1089
1090 sel_ptr = botSel;
1091 sel_ptr1 = sel_ptr->prev;
1092 for (obj_ptr=bot_obj; sel_ptr1 != NULL; obj_ptr=obj_ptr->prev) {
1093 sel_ptr->obj = obj_ptr;
1094 sel_ptr = sel_ptr1;
1095 sel_ptr1 = sel_ptr1->prev;
1096 }
1097 sel_ptr->obj = obj_ptr;
1098
1099 bot_obj->next = topObj;
1100 topObj->prev = bot_obj;
1101 curPage->top = topObj = top_obj;
1102
1103 if (justDupped && useRecentDupDistance) {
1104 dx = dupDx;
1105 dy = dupDy;
1106 } else {
1107 switch (gridSystem) {
1108 case ENGLISH_GRID:
1109 if (snapOn) {
1110 dupDx = dupDy = dx = dy = GRID_ABS_SIZE(xyEnglishGrid);
1111 } else {
1112 dupDx = dupDy = dx = dy = GRID_ABS_SIZE(DEFAULT_ENGLISH_GRID);
1113 }
1114 break;
1115 case METRIC_GRID:
1116 if (snapOn) {
1117 dupDx = dupDy = dx = dy = GRID_ABS_SIZE(xyMetricGrid);
1118 } else {
1119 dupDx = dupDy = dx = dy = GRID_ABS_SIZE(DEFAULT_METRIC_GRID);
1120 }
1121 break;
1122 }
1123 justDupped = TRUE;
1124 }
1125
1126 MoveAllSelObjects(dx, dy);
1127 PrepareToRecord(CMD_NEW, NULL, NULL, 0);
1128 RecordCmd(CMD_NEW, NULL, topSel, botSel, numObjSelected);
1129 UpdSelBBox();
1130 RedrawAnArea(botObj, selLtX-(GRID_ABS_SIZE(1)), selLtY-(GRID_ABS_SIZE(1)),
1131 selRbX+(GRID_ABS_SIZE(1)), selRbY+(GRID_ABS_SIZE(1)));
1132 HighLightForward();
1133 SetFileModified(TRUE);
1134 }
1135
DupTheseObjects(TopSel,BotSel,NewTopSel,NewBotSel)1136 void DupTheseObjects(TopSel, BotSel, NewTopSel, NewBotSel)
1137 struct SelRec *TopSel, *BotSel, **NewTopSel, **NewBotSel;
1138 {
1139 struct SelRec *sel_ptr, *new_sel_ptr;
1140 struct ObjRec *obj_ptr, *top_obj;
1141
1142 *NewTopSel = *NewBotSel = NULL;
1143 if (TopSel == NULL) return;
1144
1145 top_obj = NULL;
1146 for (sel_ptr=BotSel; sel_ptr != NULL; sel_ptr=sel_ptr->prev) {
1147 obj_ptr = DupObj(sel_ptr->obj);
1148 AdjObjSplineVs(obj_ptr);
1149 obj_ptr->next = top_obj;
1150 new_sel_ptr = (struct SelRec *)malloc(sizeof(struct SelRec));
1151 if (new_sel_ptr == NULL) FailAllocMessage();
1152 new_sel_ptr->next = *NewTopSel;
1153 new_sel_ptr->obj = obj_ptr;
1154 if (top_obj == NULL) {
1155 *NewBotSel = new_sel_ptr;
1156 } else {
1157 top_obj->prev = obj_ptr;
1158 (*NewTopSel)->prev = new_sel_ptr;
1159 }
1160 top_obj = obj_ptr;
1161 *NewTopSel = new_sel_ptr;
1162 }
1163 top_obj->prev = NULL;
1164 (*NewTopSel)->prev = NULL;
1165 }
1166
JustDupSelObj(NewTopSel,NewBotSel)1167 void JustDupSelObj(NewTopSel, NewBotSel)
1168 struct SelRec **NewTopSel, **NewBotSel;
1169 {
1170 DupTheseObjects(topSel, botSel, NewTopSel, NewBotSel);
1171 }
1172