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