~ubuntu-branches/ubuntu/precise/xcircuit/precise

« back to all changes in this revision

Viewing changes to files.c

  • Committer: Bazaar Package Importer
  • Author(s): David Z Maze
  • Date: 2003-08-24 09:08:10 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20030824090810-5d6ptk9msqsbsnqv
Tags: 3.1.19-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
#include <stdio.h>
7
7
#include <stdlib.h>
8
8
#include <string.h>
9
 
#if defined(DARWIN)
10
 
#include <sys/malloc.h>
11
 
#else
12
 
#include <malloc.h>
13
 
#endif
14
9
#include <time.h>
15
10
#include <pwd.h>
16
11
#include <ctype.h>
19
14
#include <unistd.h>
20
15
#include <X11/Intrinsic.h>
21
16
#include <X11/StringDefs.h>
22
 
#include <Xw/TextEdit.h>   /* for XwTextCopyBuffer() */
 
17
 
 
18
#ifdef TCL_WRAPPER 
 
19
#include <tk.h>
 
20
#else
 
21
#include "Xw/TextEdit.h"   /* for XwTextCopyBuffer() */
 
22
#endif
23
23
 
24
24
/*------------------------------------------------------------------------*/
25
25
/* Local includes                                                         */
56
56
/* External Variable definitions                                          */
57
57
/*------------------------------------------------------------------------*/
58
58
 
 
59
#ifdef TCL_WRAPPER
 
60
extern Tcl_Interp *xcinterp;
 
61
#endif
 
62
 
59
63
extern char _STR2[250], _STR[150];
60
64
extern Globaldata xobjs;
61
65
extern Clientdata areastruct;
69
73
extern int *appcolors;
70
74
extern int number_colors;
71
75
extern colorindex *colorlist;
72
 
extern objectpair *pushlist;
73
76
 
74
77
/*------------------------------------------------------*/
75
78
/* Global variable definitions                          */
157
160
      if (mode != SAVE) {
158
161
         for (genobj = localdata->plist; genobj < localdata->plist
159
162
                + localdata->parts; genobj++)
160
 
            /* (*genobj == NULL) only if this is a library page */
161
 
            /* and the "special instances" have been deleted    */
162
 
            /* just before calling reset().                     */
 
163
 
 
164
            /* (*genobj == NULL) only on library pages          */
 
165
            /* where the instances are kept in the library      */
 
166
            /* definition, and are only referenced on the page. */
 
167
 
163
168
            if (*genobj != NULL)
164
169
               free_single(genobj);
165
170
      }
174
179
 
175
180
/*---------------------------------------------------------*/
176
181
 
177
 
void topreset()
 
182
void pagereset(short rpage)
178
183
{
179
 
   short rpage;
180
 
 
181
184
   /* free alloc'd filename */
182
185
 
183
 
   if (xobjs.pagelist[areastruct.page]->filename != NULL)
184
 
      free(xobjs.pagelist[areastruct.page]->filename);
185
 
 
186
 
   if (xobjs.pagelist[areastruct.page]->background.name != NULL)
187
 
      free(xobjs.pagelist[areastruct.page]->background.name);
188
 
 
189
 
   rpage = areastruct.page;
190
 
 
191
 
   if (areastruct.selects > 0) {
192
 
      free(areastruct.selectlist);
193
 
      areastruct.selects = 0;
194
 
   }
 
186
   if (xobjs.pagelist[rpage]->filename != NULL)
 
187
      free(xobjs.pagelist[rpage]->filename);
 
188
 
 
189
   if (xobjs.pagelist[rpage]->background.name != NULL)
 
190
      free(xobjs.pagelist[rpage]->background.name);
 
191
 
 
192
   destroyselects();
195
193
 
196
194
   /* New pages pick up their properties from page 0, which can be changed */
197
195
   /* from the .xcircuitrc file on startup (or loaded from a script).      */
204
202
   xobjs.pagelist[rpage]->pmode = xobjs.pagelist[0]->pmode;
205
203
   xobjs.pagelist[rpage]->outscale = xobjs.pagelist[0]->outscale;
206
204
   xobjs.pagelist[rpage]->filename = (char *)malloc
207
 
                ((1 + strlen(xobjs.pagelist[rpage]->pageobj->name)) * sizeof(char));
 
205
                ((1 + strlen(xobjs.pagelist[rpage]->pageinst->thisobject->name))
 
206
                * sizeof(char));
208
207
   xobjs.pagelist[rpage]->background.name = (char *)NULL;
209
208
 
210
 
   strcpy(xobjs.pagelist[rpage]->filename, xobjs.pagelist[rpage]->pageobj->name);
 
209
   strcpy(xobjs.pagelist[rpage]->filename,
 
210
                xobjs.pagelist[rpage]->pageinst->thisobject->name);
211
211
   xobjs.pagelist[rpage]->drawingscale.x = xobjs.pagelist[0]->drawingscale.x;
212
212
   xobjs.pagelist[rpage]->drawingscale.y = xobjs.pagelist[0]->drawingscale.y;
213
213
   xobjs.pagelist[rpage]->gridspace = xobjs.pagelist[0]->gridspace;
239
239
   localdata->viewscale = 0.5;
240
240
   localdata->pcorner.x = -areastruct.width;
241
241
   localdata->pcorner.y = -areastruct.height; 
242
 
   localdata->width = 0;
243
 
   localdata->height = 0;
244
 
   localdata->lowerleft.x = 0;
245
 
   localdata->lowerleft.y = 0;
 
242
   localdata->bbox.width = 0;
 
243
   localdata->bbox.height = 0;
 
244
   localdata->bbox.lowerleft.x = 0;
 
245
   localdata->bbox.lowerleft.y = 0;
246
246
 
247
247
#ifdef SCHEMA
 
248
   localdata->highlight.netid = 0;
 
249
   localdata->highlight.thisinst = NULL;
248
250
   localdata->schemtype = SCHEMATIC;
249
251
   localdata->symschem = NULL;
250
252
   localdata->netlist = NULL;
253
255
   localdata->valid = False;
254
256
   localdata->traversed = False;
255
257
   localdata->devname = NULL;
256
 
 
257
 
   localdata->width2 = 0;
258
 
   localdata->height2 = 0;
259
 
   localdata->lleft2.x = 0;
260
 
   localdata->lleft2.y = 0;
261
258
#endif
262
259
}
263
260
 
556
553
/* Load a PostScript or Python (interpreter script) file */
557
554
/*-------------------------------------------------------*/
558
555
 
559
 
void getfile(Widget button, void *mode, caddr_t nulldata)
 
556
void getfile(xcWidget button, pointertype mode, caddr_t nulldata)
560
557
{
561
558
   buttonsave *savebutton;
562
559
   static void ((*runprog[LOAD_MODES])()) =
565
562
        {"load", "import", "render", "execute", "recover"};
566
563
   char *promptstr = NULL;
567
564
 
568
 
   if (is_page(objectdata) == -1) {
 
565
   if (is_page(topobject) == -1) {
569
566
      Wprintf("Can only read file into top-level page!");
570
567
      return;
571
568
   }
574
571
      return;
575
572
   }
576
573
   savebutton = (buttonsave *)malloc(sizeof(buttonsave));
577
 
   getgeneric(savebutton, button, getfile, mode);
 
574
   getgeneric(savebutton, button, getfile, (void *)mode);
578
575
   if ((int)mode == RECOVER) {
579
576
      char *cfile = getcrashfilename();
580
577
      promptstr = (char *)malloc(18 + ((cfile == NULL) ? 9 : strlen(cfile)));
601
598
/* Tilde ('~') expansion in file name (stored in _STR)          */
602
599
/*--------------------------------------------------------------*/
603
600
 
604
 
Boolean tilde_expand(char *filename)
 
601
Boolean xc_tilde_expand(char *filename)
605
602
{
606
603
   struct passwd *passwd;
607
604
   char *username = NULL, *expanded, *sptr;
671
668
      else
672
669
         ilib = createlibrary();
673
670
      loadlibrary(ilib);
674
 
      if (ilib == tlib) zoomview(NULL, NULL, NULL);
 
671
      /* if (ilib == tlib) zoomview(NULL, NULL, NULL); */
675
672
   }
676
673
   if (lflag)
677
674
      lflag = False;
678
675
   else
679
676
      ilib = createlibrary();
680
677
   loadlibrary(ilib);
681
 
   if (ilib == tlib) zoomview(NULL, NULL, NULL);
 
678
   /* if (ilib == tlib) zoomview(NULL, NULL, NULL); */
682
679
}
683
680
 
684
681
/*------------------------------------------------------*/
688
685
 
689
686
void loadulib()
690
687
{
691
 
   loadglib(False, (short)0, (short)is_library(objectdata) + LIBRARY);
 
688
   loadglib(False, (short)0, (short)is_library(topobject) + LIBRARY);
692
689
}
693
690
 
694
691
/*-----------------------------------------------------------*/
703
700
 
704
701
   /* Flag whether current page is a library page or not */
705
702
 
706
 
   if ((tlib = is_library(objectdata)) < 0) {
 
703
   if ((tlib = is_library(topobject)) < 0) {
707
704
      ilib = LIBRARY;
708
705
      lflag = False;
709
706
   }
715
712
 
716
713
/*---------------------------------------------------------*/
717
714
 
718
 
void getlib(Widget button, caddr_t clientdata, caddr_t nulldata)
 
715
void getlib(xcWidget button, caddr_t clientdata, caddr_t nulldata)
719
716
{
720
717
   buttonsave *savebutton = (buttonsave *)malloc(sizeof(buttonsave));
721
718
   getgeneric(savebutton, button, getlib, NULL);
725
722
 
726
723
/*---------------------------------------------------------*/
727
724
 
728
 
void getuserlib(Widget button, caddr_t clientdata, caddr_t nulldata)
 
725
void getuserlib(xcWidget button, caddr_t clientdata, caddr_t nulldata)
729
726
{
730
727
   buttonsave *savebutton = (buttonsave *)malloc(sizeof(buttonsave));
731
728
   getgeneric(savebutton, button, getuserlib, NULL);
826
823
   FILE *ps;
827
824
   char inname[150], temp[150], keyword[30], percentc;
828
825
 
829
 
   tilde_expand(_STR);
 
826
   xc_tilde_expand(_STR);
830
827
   sscanf(_STR, "%149s", inname);
831
828
 
832
829
   ps = fopen(inname, "r");
856
853
               ps = fopen(inname, "r");
857
854
            }
858
855
            if (ps == NULL && mode == FONTLIB) {
859
 
               /* printf("looking in %s/fonts\n", tmp_s); */
 
856
               /* Fprintf(stdout, "looking in %s/fonts\n", tmp_s); */
860
857
               sprintf(inname, "%s/fonts/%s", tmp_s, _STR);
861
858
               ps = fopen(inname, "r");
862
859
               if (ps == NULL) {
863
860
                  sprintf(inname, "%s/fonts/%s.lps", tmp_s, _STR);
864
861
                  ps = fopen(inname, "r");
865
862
               }
866
 
               if (ps == NULL) printf("not found there.\n");
 
863
               if (ps == NULL)
 
864
                  Fprintf(stdout, "%s not found, still trying. . .\n", inname);
867
865
            }
868
866
         }
869
867
 
877
875
               ps = fopen(inname, "r");
878
876
            }
879
877
            if (ps == NULL && mode == FONTLIB) {
880
 
               /* printf("looking in %s/fonts\n", BUILTINS_DIR); */
 
878
               /* Fprintf(stdout, "looking in %s/fonts\n", BUILTINS_DIR); */
881
879
               sprintf(inname, "%s/fonts/%s", BUILTINS_DIR, _STR);
882
880
               ps = fopen(inname, "r");
883
881
               if (ps == NULL) {
884
882
                  sprintf(inname, "%s/fonts/%s.lps", BUILTINS_DIR, _STR);
885
883
                  ps = fopen(inname, "r");
886
884
               }
887
 
               if (ps == NULL) printf("not found there.\n");
 
885
               if (ps == NULL) Fprintf(stdout, "%s not found.\n", inname);
888
886
            }
889
887
            if (ps == NULL) {
890
888
               Wprintf("No library file found.");
918
916
               /* Don't write terminating newline to the object's name string */
919
917
               if ((nptr = strchr(cptr + 2, '\n')) != NULL) *nptr = '\0';
920
918
               if (xobjs.userlibs[mode - LIBRARY].number == 0) {
921
 
                  sprintf(xobjs.libtop[mode]->name, "Library: %.79s", cptr + 2);
 
919
                  sprintf(xobjs.libtop[mode]->thisobject->name,
 
920
                                "Library: %.79s", cptr + 2);
922
921
                  renamelib(mode);
923
922
               }
924
923
            }
934
933
         else if (!strcmp(keyword, "XCircuitLib")) break;
935
934
      }
936
935
   }
937
 
   objectread(ps, objectdata, 0, 0, mode, temp, DEFAULTCOLOR);
 
936
   objectread(ps, topobject, 0, 0, mode, temp, DEFAULTCOLOR);
938
937
   cleanupaliases(mode);
939
938
 
940
939
   if (mode != FONTLIB) composelib(mode);
941
940
 
942
 
   /* printf("Loaded library %s\n", inname); */
 
941
   /* Fprintf(stdout, "Loaded library %s\n", inname); */
943
942
   sprintf(_STR, "Loaded library %s", inname);
944
943
   Wprintf(_STR);
945
944
 
958
957
      /* find next undefined page */
959
958
 
960
959
      while(areastruct.page < xobjs.pages &&
961
 
           xobjs.pagelist[areastruct.page]->pageobj != NULL) areastruct.page++;
 
960
           xobjs.pagelist[areastruct.page]->pageinst != NULL) areastruct.page++;
962
961
      changepage(areastruct.page);
963
962
   }
964
963
   loadfile(0);
966
965
   /* Display the first page loaded */
967
966
 
968
967
   newpage(firstpage);
969
 
   zoomview(NULL, NULL, NULL);
970
968
 
971
969
#ifdef SCHEMA
972
970
   setsymschem();
981
979
{
982
980
   while (nextfilename()) loadfile(1);
983
981
   loadfile(1);
984
 
   zoomview(NULL, NULL, NULL);
985
982
}
986
983
 
987
984
/*--------------------------------------------------------------*/
1002
999
 
1003
1000
/*--------------------------------------------------------------*/
1004
1001
/* Load an xcircuit file into xcircuit                          */
 
1002
/*                                                              */
 
1003
/*    mode = 0 is a "load" function.  Behavior:  load on        */
 
1004
/*      current page if empty.  Otherwise, load on first empty  */
 
1005
/*      page found.  If no empty pages exist, create a new page */
 
1006
/*      and load there.                                         */
 
1007
/*    mode = 1 is an "import" function.  Behavior:  add         */
 
1008
/*      contents of file to the current page.                   */
1005
1009
/*--------------------------------------------------------------*/
1006
1010
 
1007
1011
void loadfile(short mode)
1022
1026
 
1023
1027
   /* Do tilde expansion on filename */
1024
1028
 
1025
 
   tilde_expand(_STR);
 
1029
   xc_tilde_expand(_STR);
1026
1030
 
1027
1031
#ifdef LGF
1028
1032
   /* quick check for .lgf or .lfo file */
1082
1086
         }
1083
1087
#endif
1084
1088
 
1085
 
         if (objectdata->parts == 0 && (mode == 0)) {
 
1089
         if (topobject->parts == 0 && (mode == 0)) {
1086
1090
 
1087
1091
            /* Check for file extension, and remove if "ps". */
1088
1092
 
1096
1100
            /* for the object name, but the full path for the filename. */
1097
1101
 
1098
1102
            if ((pdchar = strrchr(_STR, '/')) != NULL)
1099
 
               sprintf(objectdata->name, "%s", pdchar + 1);
 
1103
               sprintf(topobject->name, "%s", pdchar + 1);
1100
1104
            else
1101
 
               sprintf(objectdata->name, "%s", _STR);
 
1105
               sprintf(topobject->name, "%s", _STR);
1102
1106
 
1103
1107
            renamepage(areastruct.page);
1104
 
            printname(objectdata);
 
1108
            printname(topobject);
1105
1109
            Wprintf("Starting new drawing");
1106
1110
         }
1107
1111
         else {
1173
1177
      /* read out-of-page library definitions */
1174
1178
 
1175
1179
      if (strstr(temp, "%%Page:") == NULL && strstr(temp, "offsets") == NULL)
1176
 
         objectread(ps, objectdata, 0, 0, USERLIB, temp, DEFAULTCOLOR);
 
1180
         objectread(ps, topobject, 0, 0, USERLIB, temp, DEFAULTCOLOR);
1177
1181
 
1178
1182
      if (strstr(temp, "%%Page:") != NULL)
1179
1183
         sscanf(temp + 8, "%99s", pagestr);
1185
1189
         /* find next undefined page */
1186
1190
 
1187
1191
         while(areastruct.page < xobjs.pages &&
1188
 
                xobjs.pagelist[areastruct.page]->pageobj != NULL) areastruct.page++;
 
1192
                xobjs.pagelist[areastruct.page]->pageinst != NULL) areastruct.page++;
1189
1193
         changepage(areastruct.page);
1190
1194
      }
1191
1195
 
1200
1204
      /* good so far;  let's clear out the old data structure */
1201
1205
 
1202
1206
      if (mode == 0) {
1203
 
 
1204
 
         reset(objectdata, NORMAL);
1205
 
         topreset();
 
1207
         reset(topobject, NORMAL);
 
1208
         pagereset(areastruct.page);
1206
1209
         xobjs.pagelist[areastruct.page]->pmode = temppmode;
1207
1210
         if (temppmode == 1) {
1208
1211
            xobjs.pagelist[areastruct.page]->pagesize.x = pagesize.x;
1209
1212
            xobjs.pagelist[areastruct.page]->pagesize.y = pagesize.y;
1210
1213
         }
1211
1214
      }
 
1215
#ifdef SCHEMA
 
1216
      else topobject->valid = False;
 
1217
#endif
1212
1218
 
1213
1219
      /* read to the "scale" line, picking up inch/cm type, drawing */
1214
1220
      /* scale, and grid/snapspace along the way                    */
1229
1235
#ifdef SCHEMA
1230
1236
         else if (strstr(temp, "is_symbol") != NULL) {
1231
1237
            sscanf(temp, "%*c %49s", teststr);
1232
 
            checkschem(objectdata, teststr);
 
1238
            checkschem(topobject, teststr);
1233
1239
         }
1234
1240
#endif
1235
1241
         else if (strstr(temp, "gridspace"))
1289
1295
         }
1290
1296
      }
1291
1297
 
1292
 
      objectread(ps, objectdata, offx, offy, LIBRARY, temp, DEFAULTCOLOR);
 
1298
      objectread(ps, topobject, offx, offy, LIBRARY, temp, DEFAULTCOLOR);
1293
1299
 
1294
1300
      /* skip to next page boundary or file trailer */
1295
1301
 
1332
1338
 
1333
1339
         sprintf(tpstr, "%d", page + 1);
1334
1340
         if (!strcmp(pagestr, tpstr))
1335
 
            sprintf(objectdata->name, "%.79s", rootptr);
 
1341
            sprintf(topobject->name, "%.79s", rootptr);
1336
1342
         else
1337
 
            sprintf(objectdata->name, "%.79s", pagestr);
 
1343
            sprintf(topobject->name, "%.79s", pagestr);
1338
1344
 
1339
1345
         renamepage(areastruct.page);
1340
1346
      }
1341
1347
 
1342
1348
      /* set object position to fit to window separately for each page */
1343
 
      centerview(objectdata);
 
1349
      calcbbox(areastruct.topinstance);
 
1350
      centerview(areastruct.topinstance);
1344
1351
   }
1345
1352
 
1346
1353
   /* Crash file recovery: read any out-of-page library definitions tacked */
1347
1354
   /* onto the end of the file into the user library.                      */
1348
 
   objectread(ps, objectdata, 0, 0, USERLIB, temp, DEFAULTCOLOR);
 
1355
   objectread(ps, topobject, 0, 0, USERLIB, temp, DEFAULTCOLOR);
1349
1356
   cleanupaliases(USERLIB);
1350
1357
 
1351
1358
   sprintf(_STR, "Loaded file: %s (%d page%s)", inname, multipage,
1424
1431
         case FONT_NAME:
1425
1432
            if (curfont == curpart->data.font) {
1426
1433
               /* Font change is redundant:  remove it */
1427
 
               curpart = deletestring(curpart, strhead, NORMINST);
 
1434
               curpart = deletestring(curpart, strhead, areastruct.topinstance);
1428
1435
            }
1429
1436
            else {
1430
1437
               curfont = curpart->data.font;
1435
1442
            /* Old style font scale is always written absolute, not relative.   */
1436
1443
            /* Changes in scale were not allowed, so just get rid of them.      */
1437
1444
            if (version < 2.25)
1438
 
               curpart = deletestring(curpart, strhead, NORMINST);
 
1445
               curpart = deletestring(curpart, strhead, areastruct.topinstance);
1439
1446
            break;
1440
1447
 
1441
1448
         /* A font change may occur inside a parameter, so any font     */
1651
1658
            /* the number of parameters and parameter type.             */
1652
1659
 
1653
1660
            if (localdata->num_params < paramno) {
1654
 
               fprintf(stderr, "readlabel() error:  Parameter %d exceeds declared "
 
1661
               Fprintf(stderr, "readlabel() error:  Parameter %d exceeds declared "
1655
1662
                    "number of parameters (%d)!\n", paramno, localdata->num_params);
1656
 
               deletestring(newpart, strhead, NORMINST);
 
1663
               deletestring(newpart, strhead, areastruct.topinstance);
1657
1664
            }
1658
1665
            else if ((localdata->params[paramno - 1])->type != XC_STRING) {
1659
 
               fprintf(stderr, "readlabel() error:  Parameter %d is not a string "
 
1666
               Fprintf(stderr, "readlabel() error:  Parameter %d is not a string "
1660
1667
                        "but was called as one!\n", paramno);
1661
 
               deletestring(newpart, strhead, NORMINST);
 
1668
               deletestring(newpart, strhead, areastruct.topinstance);
1662
1669
            }
1663
1670
 
1664
 
            /* printf("Parameter %d called from object %s\n", paramno,  */
1665
 
            /*          localdata->name);                               */
 
1671
            /* Fprintf(stdout, "Parameter %d called from object %s\n",  */
 
1672
            /* paramno, localdata->name);                               */
1666
1673
         }
1667
1674
         endptr = segptr + 1;
1668
 
         while (!isspace(*endptr)) endptr++;
 
1675
         while (!isspace(*endptr) && (*endptr != '\0')) endptr++;
1669
1676
      }
1670
1677
      segptr = endptr;
1671
1678
   }
1719
1726
            newinst->params[i] = NULL;
1720
1727
         else {
1721
1728
            newinst->params[i] = (oparamptr)malloc(sizeof(oparam));
 
1729
 
 
1730
            /* Fill in "which" entry from the object default */
 
1731
            newinst->params[i]->which = libobj->params[i]->which;
 
1732
 
1722
1733
            if (*arrayptr == '(' || *arrayptr == '{') { 
1723
1734
               char *substrend, csave;
1724
1735
               stringpart *endpart;
1726
1737
               /* type XC_STRING */
1727
1738
 
1728
1739
               newinst->params[i]->type = XC_STRING;
 
1740
               newinst->params[i]->which = P_SUBSTRING;
1729
1741
               newinst->params[i]->parameter.string = NULL;
1730
1742
               substrend = find_match(arrayptr);
1731
1743
               csave = *(++substrend);
1751
1763
 
1752
1764
               oparamptr ops;
1753
1765
               if (newinst->thisobject->params == NULL)
1754
 
                  printf("Error: parameter list does not exist!\n");
 
1766
                  Fprintf(stdout, "Error: parameter list does not exist!\n");
1755
1767
               else {
1756
1768
                  ops = newinst->thisobject->params[i];
1757
1769
                  if (ops == NULL)
1758
 
                     printf("Error: parameter does not exist!\n");
 
1770
                     Fprintf(stdout, "Error: parameter does not exist!\n");
1759
1771
                  else {
1760
1772
                     newinst->params[i]->type = ops->type;
1761
1773
                     if (ops->type == XC_FLOAT) {
1762
1774
                        sscanf(arrayptr, "%f",
1763
1775
                                &(newinst->params[i]->parameter.fvalue));
1764
 
                        /* printf("Object %s called with parameter "
 
1776
                        /* Fprintf(stdout, "Object %s called with parameter "
1765
1777
                                "%d value %3.2f\n", newinst->thisobject->name,
1766
1778
                                i + 1, newinst->params[i]->parameter.fvalue); */
1767
1779
                     }
1768
1780
                     else if (ops->type == XC_INT) {
1769
1781
                        sscanf(arrayptr, "%d",
1770
1782
                                &(newinst->params[i]->parameter.ivalue));
1771
 
                        /* printf("Object %s called with parameter "
 
1783
                        /* Fprintf(stdout, "Object %s called with parameter "
1772
1784
                                "%d value %d\n", newinst->thisobject->name,
1773
1785
                                i + 1, newinst->params[i]->parameter.ivalue); */
1774
1786
                     }
1775
1787
                     else
1776
 
                        printf("Error: unknown parameter type!\n");
 
1788
                        Fprintf(stderr, "Error: unknown parameter type!\n");
1777
1789
                  }
1778
1790
               }
1779
1791
               arrayptr = advancetoken(arrayptr);
1781
1793
         }
1782
1794
      }
1783
1795
   }
 
1796
 
 
1797
   /* Calculate the unique bounding box for the instance */
 
1798
 
 
1799
   if (libobj->num_params != 0) {
 
1800
      opsubstitute(libobj, newinst);
 
1801
      calcbboxinst(newinst);
 
1802
   }
1784
1803
}
1785
1804
 
1786
1805
/*--------------------------------------------------------------*/
1828
1847
            }
1829
1848
            else {
1830
1849
               *hvalue = 0; /* okay; will get filled in later */
1831
 
               fprintf(stderr, "Error:  parameter has no default?");
 
1850
               Fprintf(stderr, "Error:  parameter has no default?");
1832
1851
            }
1833
1852
         }
1834
1853
         else 
1885
1904
               *fvalue = ops->parameter.fvalue;
1886
1905
            }
1887
1906
            else
1888
 
               printf("Error: no parameter defined!\n");
 
1907
               Fprintf(stderr, "Error: no parameter defined!\n");
1889
1908
         }
1890
1909
         else 
1891
1910
            Wprintf("Error in reading parameter point substitution");
1899
1918
}
1900
1919
 
1901
1920
/*--------------------------------------------------------------*/
 
1921
/* Create a new instance of an object in the library's list of  */
 
1922
/* instances.  This instance will be used on the library page   */
 
1923
/* when doing "composelib()".                                   */
 
1924
/*--------------------------------------------------------------*/
 
1925
 
 
1926
objinstptr addtoinstlist(int libnum, objectptr libobj, Boolean virtual)
 
1927
{
 
1928
   objinstptr newinst = (objinstptr) malloc(sizeof(objinst));
 
1929
   liblistptr spec = (liblistptr) malloc(sizeof(liblist));
 
1930
   liblistptr srch;
 
1931
 
 
1932
   newinst->type = OBJECT;
 
1933
   objectdefaults(newinst, libobj, 0, 0);
 
1934
 
 
1935
   spec->virtual = (u_char)virtual;
 
1936
   spec->thisinst = newinst;
 
1937
   spec->next = NULL;
 
1938
 
 
1939
   /* Add to end, so that duplicate, parameterized instances    */
 
1940
   /* always come after the original instance with the default  */
 
1941
   /* parameters.                                               */
 
1942
 
 
1943
   if ((srch = xobjs.userlibs[libnum].instlist) == NULL)
 
1944
      xobjs.userlibs[libnum].instlist = spec;
 
1945
   else {
 
1946
      while (srch->next != NULL) srch = srch->next;
 
1947
      srch->next = spec;
 
1948
   }
 
1949
 
 
1950
   /* Calculate the instance-specific bounding box */
 
1951
   calcbboxinst(newinst);
 
1952
 
 
1953
   return newinst;
 
1954
}
 
1955
 
 
1956
/*--------------------------------------------------------------*/
1902
1957
/* Continuation Line --- add memory to "buffer" as necessary.   */
1903
1958
/* Add a space character to the current text in "buffer" and    */
1904
1959
/* return a pointer to the new end-of-text.                     */
1931
1986
   objectptr    *libobj;
1932
1987
   int curcolor = ccolor;
1933
1988
   int i, j, k;
 
1989
   objinstptr *newinst, newobjinst;
1934
1990
 
1935
1991
   /* path-handling variables */
1936
1992
   pathptr *newpath;
1964
2020
            strncpy(retstr, buffer, 150);
1965
2021
            retstr[149] = '\0';
1966
2022
            free(buffer);
1967
 
            calcbbox(localdata);
1968
2023
            return False;  /* end of page */
1969
2024
         }
1970
2025
 
2375
2430
               for (; *lineptr != ' '; lineptr--);
2376
2431
            }
2377
2432
            if ((strchr(lineptr, '.') != NULL) && (version < 2.25)) {
2378
 
               fprintf(stderr, "Error:  File version claims to be %2.1f,"
 
2433
               Fprintf(stderr, "Error:  File version claims to be %2.1f,"
2379
2434
                        " but has version %2.1f labels\n", version, PROG_VERSION);
2380
 
               fprintf(stderr, "Attempting to resolve problem by updating version.\n");
 
2435
               Fprintf(stderr, "Attempting to resolve problem by updating version.\n");
2381
2436
               version = PROG_VERSION;
2382
2437
               for (; *lineptr == ' '; lineptr--);
2383
2438
               for (; *lineptr != ' '; lineptr--);
2412
2467
            (*newlabel)->pin = False;
2413
2468
            if (strcmp(keyword, "label")) {     /* all the schematic types */
2414
2469
               /* enable schematic capture if it is not already on. */
2415
 
               if (!areastruct.schemon) doxschema(NULL, NULL, NULL);
 
2470
               if (!areastruct.schemon) doxschema(NULL, 0, NULL);
2416
2471
               if (!strcmp(keyword, "pinlabel"))
2417
2472
                  (*newlabel)->pin = LOCAL;
2418
2473
               else if (!strcmp(keyword, "pinglobal"))
2421
2476
                  localdata->schemtype = FUNDAMENTAL;
2422
2477
                  (*newlabel)->pin = INFO;
2423
2478
                  if (curcolor == DEFAULTCOLOR)
2424
 
                     (*newlabel)->color = AUXCOLOR;
 
2479
                     (*newlabel)->color = INFOLABELCOLOR;
2425
2480
               }
2426
2481
            }
2427
2482
#endif
2442
2497
               }
2443
2498
               else {
2444
2499
                  (*newlabel)->scale = firstscale->data.scale;
2445
 
                  deletestring(firstscale, &((*newlabel)->string), NORMINST);
 
2500
                  deletestring(firstscale, &((*newlabel)->string),
 
2501
                                areastruct.topinstance);
2446
2502
               }
2447
2503
            }
2448
2504
 
2449
2505
            firstfont = (*newlabel)->string;
2450
2506
            if (firstfont->type != FONT_NAME) {
2451
2507
               if (tmpfont == -1) {
2452
 
                  fprintf(stderr, "Error:  Label with no font designator?\n");
 
2508
                  Fprintf(stderr, "Error:  Label with no font designator?\n");
2453
2509
                  tmpfont = 0;
2454
2510
               }
2455
2511
               firstfont = makesegment(&((*newlabel)->string), (*newlabel)->string);  
2491
2547
         }
2492
2548
#endif
2493
2549
 
2494
 
         /* read bounding box */
 
2550
         /* read bounding box (font files only) */
2495
2551
 
2496
2552
         else if (!strcmp(keyword, "bbox")) {
2497
2553
            for (lineptr = buffer; *lineptr == ' '; lineptr++);
2501
2557
               *retstr = '\0';
2502
2558
               return True;
2503
2559
            }
2504
 
#ifdef SCHEMA
2505
 
            sscanf(++lineptr, "%hd %hd %hd %hd", &localdata->lleft2.x, 
2506
 
               &localdata->lleft2.y, &localdata->width2, &localdata->height2);
2507
 
            if (mode == FONTLIB) {
2508
 
               localdata->lowerleft.x = localdata->lleft2.x;
2509
 
               localdata->lowerleft.y = localdata->lleft2.y;
2510
 
               localdata->width = localdata->width2;
2511
 
               localdata->height = localdata->height2;
2512
 
            }
2513
 
#else
2514
 
            sscanf(++lineptr, "%hd %hd %hd %hd", &localdata->lowerleft.x, 
2515
 
               &localdata->lowerleft.y, &localdata->width, &localdata->height);
2516
 
#endif
 
2560
            sscanf(++lineptr, "%hd %hd %hd %hd",
 
2561
                &localdata->bbox.lowerleft.x, &localdata->bbox.lowerleft.y,
 
2562
                &localdata->bbox.width, &localdata->bbox.height);
2517
2563
         }
2518
2564
 
2519
2565
         /* read "hidden" attribute */
2525
2571
         /* read "libinst" special instance of a library part */
2526
2572
 
2527
2573
         else if (!strcmp(keyword, "libinst")) {
2528
 
            objinstptr *newinst;
2529
2574
 
2530
2575
            /* Read backwards from keyword to find name of object instanced. */
2531
2576
 
2534
2579
            sscanf(++lineptr, "%79s", keyword);
2535
2580
 
2536
2581
            /* Find the library containing the object, add a record to its */
2537
 
            /* speclist list, and create a new instance and add it to the  */
 
2582
            /* instlist list, and create a new instance and add it to the  */
2538
2583
            /* record.                                                     */
2539
2584
 
2540
2585
            for (i = 0; i < xobjs.numlibs; i++) {
2541
2586
               for (j = 0; j < xobjs.userlibs[i].number; j++) {
2542
2587
                  libobj = xobjs.userlibs[i].library + j;
2543
2588
                  if (!strcmp(keyword, (*libobj)->name)) {
2544
 
                     objectpairptr spec = (objectpairptr)
2545
 
                                malloc(sizeof(objectpair));
2546
 
                     NEW_OBJINST(newinst, localdata);
2547
 
                     objectdefaults(*newinst, *libobj, 0, 0);
2548
 
                     spec->thisobject = *libobj;
2549
 
                     spec->thisinst = *newinst;
2550
 
                     spec->nextpair = xobjs.userlibs[i].speclist;
2551
 
                     xobjs.userlibs[i].speclist = spec;
2552
 
                     readparams(*newinst, *libobj, buffer);
 
2589
                     newobjinst = addtoinstlist(i, *libobj, TRUE);
 
2590
                     lineptr = buffer;
 
2591
                     while (isspace(*lineptr)) lineptr++;
 
2592
 
 
2593
                     /* May declare instanced scale and rotation first */
 
2594
                     if (*lineptr != '[') {
 
2595
                        lineptr = varfscan(localdata, lineptr,
 
2596
                                        &newobjinst->scale,
 
2597
                                        (genericptr)newobjinst, P_SCALE);
 
2598
                        lineptr = varscan(localdata, lineptr,
 
2599
                                        &newobjinst->rotation,
 
2600
                                        (genericptr)newobjinst, P_ROTATION);
 
2601
                     }
 
2602
                     readparams(newobjinst, *libobj, lineptr);
2553
2603
                     break;
2554
2604
                  }
2555
2605
               }
2560
2610
         /* read objects */
2561
2611
 
2562
2612
         else if (!strcmp(keyword, "{")) {  /* This is an object definition */
2563
 
            objectpairptr newdef, redef = NULL;
 
2613
            objlistptr newdef, redef = NULL;
2564
2614
            objectptr *newobject;
2565
2615
            objectptr *curlib = (mode == FONTLIB) ?
2566
2616
                xobjs.fontlib.library : xobjs.userlibs[mode - LIBRARY].library;
2591
2641
                    xobjs.fontlib.number; libobj++) {
2592
2642
                  /* This font character may be a redefinition of another */
2593
2643
                  if (!objnamecmp(keyword, (*libobj)->name)) {
2594
 
                     newdef = (objectpairptr) malloc(sizeof(objectpair));
 
2644
                     newdef = (objlistptr) malloc(sizeof(objlist));
2595
2645
                     newdef->thisobject = *libobj;
2596
 
                     newdef->nextpair = redef;
 
2646
                     newdef->next = redef;
2597
2647
                     redef = newdef;
2598
2648
                  }
2599
2649
               }
2604
2654
                     libobj = xobjs.userlibs[i].library + j;
2605
2655
                     /* This object may be a redefinition of another object */
2606
2656
                     if (!objnamecmp(keyword, (*libobj)->name)) {
2607
 
                        newdef = (objectpairptr) malloc(sizeof(objectpair));
 
2657
                        newdef = (objlistptr) malloc(sizeof(objlist));
2608
2658
                        newdef->thisobject = *libobj;
2609
 
                        newdef->nextpair = redef;
 
2659
                        newdef->next = redef;
2610
2660
                        redef = newdef;
2611
2661
                     }
2612
2662
                  }
2634
2684
            /* rename the original one.                         */
2635
2685
 
2636
2686
            else if (redef != NULL) {
2637
 
               for (newdef = redef; newdef != NULL; newdef = newdef->nextpair) {
 
2687
               for (newdef = redef; newdef != NULL; newdef = newdef->next) {
2638
2688
 
2639
2689
                  /* must make sure that default parameter values are */
2640
2690
                  /* plugged into the original object.             */
2668
2718
                     break;
2669
2719
                  }
2670
2720
               }
2671
 
               for (; (newdef = redef->nextpair); redef = newdef)
 
2721
               for (; (newdef = redef->next); redef = newdef)
2672
2722
                  free(redef);
2673
2723
               free(redef);
2674
2724
               redef = NULL;
2675
2725
            }
 
2726
 
 
2727
            /* Add an instance of the object to the library's instance list */
 
2728
 
 
2729
            if ((mode != FONTLIB) && (newobject != NULL)) {
 
2730
               objinstptr libinst;
 
2731
 
 
2732
               libinst = addtoinstlist(mode - LIBRARY, *newobject, FALSE);
 
2733
               calcbboxvalues(libinst, (genericptr *)NULL);
 
2734
 
 
2735
               /* Center the view of the object in its instance */
 
2736
               centerview(libinst);
 
2737
            }
2676
2738
         }
2677
2739
         else if (!strcmp(keyword, "def")) {
2678
2740
            strncpy(retstr, buffer, 150);
2679
2741
            retstr[149] = '\0';
2680
2742
            free (buffer);
2681
 
            if (mode != FONTLIB) {
2682
 
               calcbboxvalues(localdata, (u_char)1, (genericptr *)NULL);
2683
 
               centerview(localdata);
2684
 
            }
2685
2743
            return False; /* end of object def or end of object library */
2686
2744
         }
2687
2745
 
2717
2775
         else if (!strcmp(keyword, "beginparm")) { /* parameterized object */
2718
2776
            short tmpnum, i;
2719
2777
            for (--keyptr; *keyptr == ' '; keyptr--);
2720
 
            for (; *keyptr != ' '; keyptr--);
 
2778
            for (; isdigit(*keyptr) && (keyptr >= buffer); keyptr--);
2721
2779
            sscanf(keyptr, "%hd", &tmpnum);
2722
2780
            lineptr = buffer;
2723
2781
            while (isspace(*lineptr)) lineptr++;
2748
2806
                     newpart->type = PARAM_END;
2749
2807
 
2750
2808
                     ops->type = (u_char)XC_STRING;
2751
 
                     /* printf("Parameter %d to object %s defaults to string \"%s\"\n",
2752
 
                                i + 1, localdata->name, ops->parameter.string); */
 
2809
                     ops->which = P_SUBSTRING;
 
2810
                     /* Fprintf(stdout, "Parameter %d to object %s defaults "
 
2811
                                "to string \"%s\"\n", i + 1, localdata->name,
 
2812
                                ops->parameter.string); */
2753
2813
                     *linetmp = csave;
2754
2814
                     lineptr = linetmp;
2755
2815
                     while (isspace(*lineptr)) lineptr++;
2757
2817
                  else {        /* type is assumed to be XC_FLOAT */
2758
2818
                     ops->type = (u_char)XC_FLOAT;
2759
2819
                     sscanf(lineptr, "%f", &ops->parameter.fvalue);
2760
 
                     /* printf("Parameter %d to object %s defaults to value %3.2f\n",
2761
 
                                i + 1, localdata->name, ops->parameter.fvalue); */
 
2820
                     /* Fprintf(stdout, "Parameter %d to object %s defaults to "
 
2821
                                "value %3.2f\n", i + 1, localdata->name,
 
2822
                                ops->parameter.fvalue); */
2762
2823
                     lineptr = advancetoken(lineptr);
2763
2824
                  }
2764
2825
               }
2767
2828
#ifdef SCHEMA
2768
2829
         else if (!strcmp(keyword, "trivial")) {
2769
2830
            localdata->schemtype = TRIVIAL;
2770
 
            if (!areastruct.schemon) doxschema(NULL, NULL, NULL);
 
2831
            if (!areastruct.schemon) doxschema(NULL, 0, NULL);
2771
2832
         }
2772
2833
#endif
2773
2834
         else if (!strcmp(keyword, "begingate")) {
2781
2842
         else if (!strcmp(keyword, "endgate"));    /* also ignore */
2782
2843
         else if (!strcmp(keyword, "xyarray"));    /* ignore for now */
2783
2844
         else {
2784
 
            objinstptr *newinst;
2785
2845
            char *tmpptr;
2786
2846
            Boolean found = False;
2787
2847
 
2841
2901
                     (*newinst)->params = NULL;
2842
2902
                     (*newinst)->num_params = 0;
2843
2903
                     (*newinst)->passed = NULL;
 
2904
                     (*newinst)->bbox.lowerleft.x = (*libobj)->bbox.lowerleft.x;
 
2905
                     (*newinst)->bbox.lowerleft.y = (*libobj)->bbox.lowerleft.y;
 
2906
                     (*newinst)->bbox.width = (*libobj)->bbox.width;
 
2907
                     (*newinst)->bbox.height = (*libobj)->bbox.height;
 
2908
#ifdef SCHEMA
 
2909
                     (*newinst)->schembbox = NULL;
 
2910
#endif
2844
2911
 
2845
2912
                     lineptr = varfscan(localdata, buffer, &(*newinst)->scale,
2846
2913
                                (genericptr)*newinst, P_SCALE);
2865
2932
                     while ((*newinst)->rotation > 360) (*newinst)->rotation -= 360;
2866
2933
                     while ((*newinst)->rotation < 0) (*newinst)->rotation += 360;
2867
2934
 
 
2935
                     calcbboxinst(*newinst);
 
2936
 
2868
2937
                     /* Does this instance contain parameters? */
2869
 
 
2870
2938
                     readparams(*newinst, *libobj, buffer);
2871
 
 
2872
2939
                     break;
 
2940
 
2873
2941
                  } /* if !strcmp */
2874
2942
               } /* for j loop */
2875
2943
               if (found) break;
2889
2957
/* Save a PostScript file */
2890
2958
/*------------------------*/
2891
2959
 
2892
 
void setfile(Widget button, Widget fnamewidget, caddr_t clientdata) 
 
2960
#ifdef TCL_WRAPPER
 
2961
 
 
2962
void setfile(char *filename, int mode)
 
2963
{
 
2964
   /* see if name has been changed in the buffer */
 
2965
 
 
2966
   if (strcmp(xobjs.pagelist[areastruct.page]->filename, filename)) {
 
2967
      Wprintf("Changing name of edit file.");
 
2968
      free(xobjs.pagelist[areastruct.page]->filename);
 
2969
      xobjs.pagelist[areastruct.page]->filename = strdup(filename);
 
2970
   }
 
2971
 
 
2972
   if (strstr(xobjs.pagelist[areastruct.page]->filename, "Page ") != NULL) {
 
2973
      Wprintf("Warning: Enter a new name.");
 
2974
      if (beeper) XBell(dpy, 100);
 
2975
   }
 
2976
   else {
 
2977
      savefile(mode); 
 
2978
      if (beeper) XBell(dpy, 100);
 
2979
   }
 
2980
}
 
2981
 
 
2982
#else  /* !TCL_WRAPPER */
 
2983
 
 
2984
void setfile(xcWidget button, xcWidget fnamewidget, caddr_t clientdata) 
2893
2985
{
2894
2986
   /* see if name has been changed in the buffer */
2895
2987
 
2906
2998
   else {
2907
2999
 
2908
3000
      Arg wargs[1];
2909
 
      Widget db, di;
 
3001
      xcWidget db, di;
2910
3002
 
2911
 
      savefile(objectdata, CURRENT_PAGE); 
 
3003
      savefile(CURRENT_PAGE); 
2912
3004
 
2913
3005
      /* Change "close" button to read "done" */
2914
3006
 
2915
 
      di = XtParent(button);
 
3007
      di = xcParent(button);
2916
3008
      db = XtNameToWidget(di, "Close");
2917
3009
      XtSetArg(wargs[0], XtNlabel, "  Done  ");
2918
3010
      XtSetValues(db, wargs, 1);
2920
3012
   }
2921
3013
}
2922
3014
 
 
3015
#endif  /* TCL_WRAPPER */
 
3016
 
2923
3017
/*--------------------------------------------------------------*/
2924
3018
/* Update number of changes for an object and initiate a temp   */
2925
3019
/* file save if total number of unsaved changes exceeds 20.     */
2927
3021
 
2928
3022
void incr_changes(objectptr thisobj)
2929
3023
{
 
3024
   /* It is assumed that empty pages are meant to be that way */
 
3025
   /* and are not to be saved, so changes are marked as zero. */
 
3026
 
 
3027
   if (thisobj->parts == 0) {
 
3028
      thisobj->changes = 0;
 
3029
      return;
 
3030
   }
 
3031
 
2930
3032
   thisobj->changes++;
2931
3033
   xobjs.new_changes++;
2932
3034
 
2933
3035
   if (xobjs.new_changes > MAXCHANGES) {
 
3036
#ifdef TCL_WRAPPER
 
3037
      savetemp(NULL);
 
3038
#else
2934
3039
      savetemp(NULL, NULL);
 
3040
#endif
2935
3041
      xobjs.new_changes = 0;    /* reset the count */
2936
3042
   }
2937
3043
}
2940
3046
/* tempfile save                                                */
2941
3047
/*--------------------------------------------------------------*/
2942
3048
 
2943
 
XtTimerCallbackProc savetemp(Widget w, XtIntervalId *id)
 
3049
#ifdef TCL_WRAPPER
 
3050
 
 
3051
xcTimeOutProc savetemp(caddr_t clientdata)
 
3052
{
 
3053
   if (xobjs.timeout_id == NULL) {      /* Not called by timeout callback */
 
3054
      xcRemoveTimeOut(xobjs.timeout_id);
 
3055
   }
 
3056
   xobjs.timeout_id = NULL;
 
3057
 
 
3058
#else
 
3059
 
 
3060
xcTimeOutProc savetemp(caddr_t clientdata, xcIntervalId *id)
2944
3061
{
2945
3062
   if (id == NULL)      /* Not called by timeout callback */
2946
 
      XtRemoveTimeOut(xobjs.timeout_id);
 
3063
      xcRemoveTimeOut(xobjs.timeout_id);
 
3064
 
 
3065
#endif
2947
3066
 
2948
3067
   /* First see if there are any unsaved changes in the file.   */
2949
3068
   /* If not, then just reset the counter and continue.         */
2958
3077
 
2959
3078
         fd = mkstemp(template);
2960
3079
         if (fd == -1) {
2961
 
            fprintf(stderr, "Error generating file for savetemp\n");
 
3080
            Fprintf(stderr, "Error generating file for savetemp\n");
2962
3081
            free(template);
2963
3082
            return NULL;
2964
3083
         } 
2966
3085
         xobjs.tempfile = strdup(template);
2967
3086
         free(template);
2968
3087
      }
2969
 
      savefile(objectdata, ALL_PAGES);
 
3088
      savefile(ALL_PAGES);
2970
3089
   }
2971
3090
 
2972
 
   xobjs.timeout_id = XtAppAddTimeOut(app, (u_long)60000 *
2973
 
        xobjs.save_interval, (XtTimerCallbackProc)savetemp, NULL);
 
3091
   xobjs.timeout_id = xcAddTimeOut(app, (u_long)60000 *
 
3092
        xobjs.save_interval, (xcTimeOutProc)savetemp, NULL);
2974
3093
   return NULL;
2975
3094
}
2976
3095
 
2986
3105
      (*(wroteobjs + i))->changes = 0;
2987
3106
}
2988
3107
 
2989
 
/*--------------------------------------------------------------*/
 
3108
/*---------------------------------------------------------------*/
 
3109
/* Save indicated library.  If libno is 0, save current page if  */
 
3110
/* the current page is a library.  If not, save the user library */
 
3111
/*---------------------------------------------------------------*/
2990
3112
 
2991
 
void savelib(Widget button, caddr_t clientdata, caddr_t nulldata)
 
3113
void savelibpopup(xcWidget button, pointertype libno, caddr_t nulldata)
2992
3114
{
2993
 
   buttonsave *savebutton = (buttonsave *)malloc(sizeof(buttonsave));
2994
 
   int ilib;
 
3115
   char *bconf;
 
3116
   buttonsave *savebutton;
 
3117
   int ilib = (int)libno;
2995
3118
 
2996
 
   if ((ilib = is_library(objectdata)) < 0) ilib = xobjs.numlibs - 1;
 
3119
   if (ilib == 0) ilib = is_library(topobject);
 
3120
   if (ilib < 0) ilib = xobjs.numlibs - 1;
 
3121
   if ((ilib = is_library(topobject)) < 0) ilib = xobjs.numlibs - 1;
2997
3122
 
2998
3123
   if (xobjs.userlibs[ilib].number == 0) {
2999
 
      Wprintf("No user objects to save.");
 
3124
      Wprintf("No objects in library to save.");
3000
3125
      return;
3001
3126
   }
3002
 
   getgeneric(savebutton, button, savelib, (void *)ilib);
 
3127
 
 
3128
#ifndef TCL_WRAPPER
 
3129
   savebutton = (buttonsave *)malloc(sizeof(buttonsave));
 
3130
   getgeneric(savebutton, button, savelibpopup, (void *)ilib);
3003
3131
   popupprompt(button, "Enter name for library:", "\0", savelibrary,
3004
3132
        savebutton, NULL);
 
3133
#endif
3005
3134
}
3006
3135
 
3007
3136
/*---------------------------------------------------------*/
3008
3137
 
3009
 
void savelibrary(Widget w, int ilib)
 
3138
void savelibrary(xcWidget w, int ilib)
3010
3139
{
3011
3140
   FILE *ps;
3012
3141
   char outname[150], *outptr;
3013
3142
   objectptr *wroteobjs, *libptr;
3014
 
   objectpairptr spec;
 
3143
   liblistptr spec;
3015
3144
   short written = 0;
3016
3145
   char *uname = NULL;
3017
3146
   char *hostname = NULL;
3020
3149
   sscanf(_STR2, "%249s", outname);
3021
3150
   if ((outptr = strrchr(outname, '/')) == NULL) outptr = outname;
3022
3151
   if (strchr(outptr, '.') == NULL) sprintf(outname, "%s.lps", _STR2);
3023
 
   tilde_expand(outname);
 
3152
   xc_tilde_expand(outname);
3024
3153
 
3025
3154
   ps = fopen(outname, "w");
3026
3155
   if (ps == NULL) {
3054
3183
 
3055
3184
   wroteobjs = (objectptr *) malloc (sizeof(objectptr));
3056
3185
 
3057
 
   /* write all of the object definitions used, bottom up */
3058
 
 
3059
 
   for (libptr = xobjs.userlibs[ilib].library; libptr < xobjs.userlibs[ilib].library + 
3060
 
        xobjs.userlibs[ilib].number; libptr++)
3061
 
      printobjects(ps, *libptr, 0.0, 0.0, 0.0, 0, 0, &wroteobjs, &written, DEFAULTCOLOR);
3062
 
 
3063
 
   /* note the virtual object copies and their parameters */
3064
 
 
3065
 
   for (spec = xobjs.userlibs[ilib].speclist; spec != NULL; spec =
3066
 
                spec->nextpair) {
3067
 
      printparams(ps, spec->thisinst, 0);
3068
 
      fprintf(ps, "/%s libinst\n", spec->thisobject->name);
 
3186
   /* write all of the object definitions used, bottom up, with virtual instances */
 
3187
   /* in the correct placement.                                                   */
 
3188
 
 
3189
   for (spec = xobjs.userlibs[ilib].instlist; spec != NULL; spec = spec->next) {
 
3190
      if (!spec->virtual) {
 
3191
         printobjects(ps, spec->thisinst->thisobject, 0.0, 0.0, 0.0, 0, 0,
 
3192
                        &wroteobjs, &written, DEFAULTCOLOR);
 
3193
      }
 
3194
      else {
 
3195
         if ((spec->thisinst->scale != 1.0) || (spec->thisinst->rotation != 0)) {
 
3196
            fprintf(ps, "%3.2f %d ", spec->thisinst->scale,
 
3197
                                spec->thisinst->rotation);
 
3198
         }
 
3199
         printparams(ps, spec->thisinst, 0);
 
3200
         fprintf(ps, "/%s libinst\n", spec->thisinst->thisobject->name);
 
3201
         if ((spec->next != NULL) && (!(spec->next->virtual)))
 
3202
            fprintf(ps, "\n");
 
3203
      }
3069
3204
   }
3070
3205
 
3071
3206
   setassaved(wroteobjs, written);
3111
3246
/* Main file saving routine                                             */
3112
3247
/*----------------------------------------------------------------------*/
3113
3248
 
3114
 
void savefile(objectptr localdata, short mode) 
 
3249
void savefile(short mode) 
3115
3250
{
3116
3251
   FILE *ps, *pro;
3117
3252
   char outname[150], temp[150], prologue[150], *fname, *fptr;
3118
 
   short written = 0, fontsused[256], i, page, curpage, multipage, savepage, stcount;
3119
 
   objectptr *wroteobjs, writepage, *mpages;
3120
 
   int *mpageno, findex;
 
3253
   short written = 0, fontsused[256], i, page, curpage, multipage;
 
3254
   short savepage, stcount, *pagelist;
 
3255
   objectptr *wroteobjs;
 
3256
   objinstptr writepage;
 
3257
   int findex;
3121
3258
   float psscale, psnorm;
3122
3259
   float xmargin = 72.0, ymargin = 72.0;
3123
 
   int bboxx, bboxy;
 
3260
   int bboxx, bboxy, width, height;
3124
3261
   time_t tdate;
 
3262
   char *tmp_s;
3125
3263
 
3126
 
   if (mode == CURRENT_PAGE)
 
3264
   if (mode != ALL_PAGES)
3127
3265
      fname = xobjs.pagelist[areastruct.page]->filename;
3128
3266
   else {
3129
3267
      /* doubly-protected backup: protect against errors during file write */
3133
3271
   }
3134
3272
 
3135
3273
   if ((fptr = strrchr(fname, '/')) == NULL) fptr = fname;
3136
 
   if ((mode == CURRENT_PAGE) && (strchr(fptr, '.') == NULL))
 
3274
   if ((mode != ALL_PAGES) && (strchr(fptr, '.') == NULL))
3137
3275
      sprintf(outname, "%s.ps", fname);
3138
3276
   else sprintf(outname, "%s", fname);
3139
3277
 
3140
 
   tilde_expand(outname);
 
3278
   xc_tilde_expand(outname);
3141
3279
 
3142
3280
   ps = fopen(outname, "w");
3143
3281
   if (ps == NULL) {
3147
3285
 
3148
3286
   /* calculate the bounding box of the drawing */
3149
3287
 
 
3288
#ifdef SCHEMA
 
3289
   width = toplevelwidth(areastruct.topinstance);
 
3290
   height = toplevelheight(areastruct.topinstance);
 
3291
#else
 
3292
   width = topobject->bbox.width;
 
3293
   height = topobject->bbox.height;
 
3294
#endif
 
3295
 
3150
3296
   /* find margins */
3151
3297
 
3152
3298
   psscale = getpsscale(xobjs.pagelist[areastruct.page]->outscale, areastruct.page);
3153
3299
   if (xobjs.pagelist[areastruct.page]->pmode & 1) {
3154
3300
      if (xobjs.pagelist[areastruct.page]->orient == 90) {
3155
3301
         xmargin = (xobjs.pagelist[areastruct.page]->pagesize.x -
3156
 
                ((float)localdata->height * psscale)) / 2;
 
3302
                ((float)height * psscale)) / 2;
3157
3303
         ymargin = (xobjs.pagelist[areastruct.page]->pagesize.y -
3158
 
                ((float)localdata->width * psscale)) / 2;
 
3304
                ((float)width * psscale)) / 2;
3159
3305
      }
3160
3306
      else {
3161
3307
         xmargin = (xobjs.pagelist[areastruct.page]->pagesize.x -
3162
 
                ((float)localdata->width * psscale)) / 2;
 
3308
                ((float)width * psscale)) / 2;
3163
3309
         ymargin = (xobjs.pagelist[areastruct.page]->pagesize.y -
3164
 
                ((float)localdata->height * psscale)) / 2;
 
3310
                ((float)height * psscale)) / 2;
3165
3311
      }
3166
3312
   }
3167
3313
 
3170
3316
   /* circuit and give them the same filename, so that they will be saved */
3171
3317
   /* together as a set.                                                  */
3172
3318
 
3173
 
   if (areastruct.schemon) {
 
3319
   if ((areastruct.schemon) && (mode != NO_SUBCIRCUITS)) {
3174
3320
      Wprintf("Gathering all subcircuits. . .");
3175
 
      if (findsubschems(areastruct.page, objectdata, 0) == -1)
3176
 
         Wprintf("Error:  Check for recursion in circuit!");
 
3321
      collectsubschems(areastruct.page);
3177
3322
   }
3178
3323
#endif
3179
3324
 
3180
 
   /* check for multiple-page output: get the number of pages */
 
3325
   /* Check for multiple-page output: get the number of pages;  */
 
3326
   /* ignore empty pages.                                       */
3181
3327
 
3182
3328
   multipage = 0;
3183
 
   mpages = (objectptr *) malloc (sizeof(objectptr));
3184
 
   mpageno = (int *) malloc (sizeof(int));
3185
3329
   savepage = areastruct.page;
3186
3330
 
3187
 
   for (page = 0; page < xobjs.pages; page++) {
3188
 
      writepage = xobjs.pagelist[page]->pageobj;
3189
 
      if (writepage != NULL)
3190
 
         if ((mode == ALL_PAGES) || (!strcmp(xobjs.pagelist[page]->filename,
3191
 
                        xobjs.pagelist[areastruct.page]->filename))) {
3192
 
            multipage++;
3193
 
            mpages = (objectptr *)realloc(mpages, multipage * sizeof(objectptr));
3194
 
            mpageno = (int *)realloc(mpageno, multipage * sizeof(int));
3195
 
            mpages[multipage - 1] = writepage;
3196
 
            mpageno[multipage - 1] = page;
3197
 
         }
3198
 
   }
 
3331
   if (mode == NO_SUBCIRCUITS)
 
3332
      pagelist = pagetotals(areastruct.page, INDEPENDENT);
 
3333
   else if (mode == ALL_PAGES)
 
3334
      pagelist = pagetotals(areastruct.page, ALL_PAGES);
 
3335
   else
 
3336
      pagelist = pagetotals(areastruct.page, TOTAL_PAGES);
 
3337
 
 
3338
   for (page = 0; page < xobjs.pages; page++)
 
3339
      if (pagelist[page] > 0)
 
3340
          multipage++;
 
3341
 
3199
3342
   if (multipage == 0) {
3200
3343
      Wprintf("Panic:  could not find this page in page list!");
3201
 
      free (mpages);
3202
 
      free (mpageno);
 
3344
      free (pagelist);
3203
3345
      fclose(ps);
3204
3346
      return;
3205
3347
   }
3216
3358
   tdate = time(NULL);
3217
3359
   fprintf(ps, "%%%%CreationDate: %s", asctime(localtime(&tdate)));
3218
3360
   fprintf(ps, "%%%%Pages: %d\n", multipage);
 
3361
 
3219
3362
   if (xobjs.pagelist[areastruct.page]->orient == 90) {
3220
 
      bboxx = (int)((float)localdata->height * psscale) + (int)xmargin + 4;
3221
 
      bboxy = (int)((float)localdata->width * psscale) + (int)ymargin + 4;
 
3363
      bboxx = (int)((float)height * psscale) + (int)xmargin + 4;
 
3364
      bboxy = (int)((float)width * psscale) + (int)ymargin + 4;
3222
3365
   }
3223
3366
   else {
3224
 
      bboxx = (int)((float)localdata->width * psscale) + (int)xmargin + 4;
3225
 
      bboxy = (int)((float)localdata->height * psscale) + (int)ymargin + 4;
 
3367
      bboxx = (int)((float)width * psscale) + (int)xmargin + 4;
 
3368
      bboxy = (int)((float)height * psscale) + (int)ymargin + 4;
3226
3369
   }
3227
3370
   /* in order to reconstruct the page size, it is necessary that the   */
3228
3371
   /* bounding box extent + margin = page size.  This of course assumes */
3242
3385
   /* find all of the fonts used in this document */
3243
3386
   /* log all fonts which are native PostScript   */
3244
3387
 
3245
 
   for (page = 0; page < multipage; page++) {
3246
 
      writepage = mpages[page];
3247
 
      findfonts(writepage, fontsused);
3248
 
   }
3249
 
 
3250
 
   for(i = 0; i <= fontcount; i++) {
 
3388
   for (curpage = 0; curpage < xobjs.pages; curpage++)
 
3389
      if (pagelist[curpage] > 0) {
 
3390
         writepage = xobjs.pagelist[curpage]->pageinst;
 
3391
         findfonts(writepage->thisobject, fontsused);
 
3392
      }
 
3393
      
 
3394
   for (i = 0; i <= fontcount; i++) {
3251
3395
      if (fontsused[i] & 0x8000)
3252
3396
         if ((fonts[i].flags & 0x8018) == 0x0) {
3253
3397
            stcount += strlen(fonts[i].psname) + 6;
3261
3405
 
3262
3406
   fprintf(ps, "\n%%%%EndComments\n");
3263
3407
 
3264
 
   sprintf(prologue, "%s/%s", PROLOGUE_DIR, PROLOGUE_FILE);
3265
 
   pro = fopen(prologue, "r");
 
3408
   tmp_s = getenv((const char *)"XCIRCUIT_LIB_DIR");
 
3409
   if (tmp_s != NULL) {
 
3410
      sprintf(prologue, "%s/%s", tmp_s, PROLOGUE_FILE);
 
3411
      pro = fopen(prologue, "r");
 
3412
   }
 
3413
   else
 
3414
      pro = NULL;
 
3415
 
3266
3416
   if (pro == NULL) {
3267
 
      sprintf(prologue, "%s", PROLOGUE_FILE);
 
3417
      sprintf(prologue, "%s/%s", PROLOGUE_DIR, PROLOGUE_FILE);
3268
3418
      pro = fopen(prologue, "r");
3269
3419
      if (pro == NULL) {
3270
 
         Wprintf("Can't open prolog.");
3271
 
         free(mpages);
3272
 
         free(mpageno);
3273
 
         fclose(ps);
3274
 
         return;
 
3420
         sprintf(prologue, "%s", PROLOGUE_FILE);
 
3421
         pro = fopen(prologue, "r");
 
3422
         if (pro == NULL) {
 
3423
            Wprintf("Can't open prolog.");
 
3424
            free(pagelist);
 
3425
            fclose(ps);
 
3426
            return;
 
3427
         }
3275
3428
      }
3276
3429
   }
3277
3430
 
3334
3487
 
3335
3488
   wroteobjs = (objectptr *) malloc (sizeof(objectptr));
3336
3489
 
3337
 
   for (page = 0; page < multipage; page++) {
3338
 
      writepage = mpages[page];
3339
 
      curpage = mpageno[page];
 
3490
   page = 0;
 
3491
   for (curpage = 0; curpage < xobjs.pages; curpage++) {
 
3492
      if (pagelist[curpage] == 0) continue;
 
3493
 
 
3494
      writepage = xobjs.pagelist[curpage]->pageinst;
 
3495
 
 
3496
#ifdef SCHEMA
 
3497
      width = toplevelwidth(writepage);
 
3498
      height = toplevelheight(writepage);
 
3499
#else
 
3500
      width = writepage->thisobject->bbox.width;
 
3501
      height = writepage->thisobject->bbox.height;
 
3502
#endif
3340
3503
 
3341
3504
      psnorm = xobjs.pagelist[curpage]->outscale;
3342
3505
      psscale = getpsscale(psnorm, curpage);
3343
3506
      if (xobjs.pagelist[curpage]->pmode & 1) {
3344
3507
         if (xobjs.pagelist[curpage]->orient == 90) {
3345
3508
            xmargin = (xobjs.pagelist[curpage]->pagesize.x -
3346
 
                ((float)writepage->height * psscale)) / 2;
 
3509
                ((float)height * psscale)) / 2;
3347
3510
            ymargin = (xobjs.pagelist[curpage]->pagesize.y -
3348
 
                ((float)writepage->width * psscale)) / 2;
 
3511
                ((float)width * psscale)) / 2;
3349
3512
         }
3350
3513
         else {
3351
3514
            xmargin = (xobjs.pagelist[curpage]->pagesize.x -
3352
 
                ((float)writepage->width * psscale)) / 2;
 
3515
                ((float)width * psscale)) / 2;
3353
3516
            ymargin = (xobjs.pagelist[curpage]->pagesize.y -
3354
 
                ((float)writepage->height * psscale)) / 2;
 
3517
                ((float)height * psscale)) / 2;
3355
3518
         }
3356
3519
      }
3357
3520
 
3358
3521
      /* Write all of the object definitions used, bottom up */
3359
3522
 
3360
 
      printobjects(ps, writepage, psnorm, xmargin, ymargin, page + 1,
3361
 
            mpageno[page], &wroteobjs, &written, DEFAULTCOLOR);
 
3523
      printobjects(ps, writepage->thisobject, psnorm, xmargin, ymargin, ++page,
 
3524
            curpage, &wroteobjs, &written, DEFAULTCOLOR);
3362
3525
      fprintf(ps, "pgsave restore showpage\n");
3363
3526
 
3364
3527
      /* For crash recovery, log the filename for each page */
3392
3555
   }
3393
3556
   else {       /* No unsaved changes in these objects */
3394
3557
      setassaved(wroteobjs, written);
3395
 
      setassaved(mpages, multipage);
 
3558
      for (i = 0; i < xobjs.pages; i++)
 
3559
         if (pagelist[i] > 0)
 
3560
            xobjs.pagelist[i]->pageinst->thisobject->changes = 0;
3396
3561
      xobjs.new_changes = countchanges(NULL);
3397
3562
   }
3398
3563
 
3399
 
   free (wroteobjs);
3400
 
   free (mpages);
 
3564
   /* Free allocated memory */
 
3565
   free((char *)pagelist);
 
3566
   free((char *)wroteobjs);
3401
3567
 
3402
3568
   /* Done! */
3403
3569
 
3410
3576
                (multipage > 1 ? "s" : ""));
3411
3577
   Wprintf(_STR);
3412
3578
 
3413
 
   /* remove the temporary redundant backup */
 
3579
   /* Remove the temporary redundant backup */
3414
3580
   if (mode == ALL_PAGES) {
3415
3581
      sprintf(outname, "%sB", xobjs.tempfile);
3416
3582
      unlink(outname);
3436
3602
   }
3437
3603
 
3438
3604
   /* The program can reach this point for any color which is   */
3439
 
   /* not listed in the table.  For instance, the "infolabel"   */
3440
 
   /* green color is not in the list.                           */
 
3605
   /* not listed in the table.  This should not happen.         */
3441
3606
 
3442
3607
   return -1;
3443
3608
}
3446
3611
/* Write string to PostScript string, ignoring NO_OPs */
3447
3612
/*----------------------------------------------------*/
3448
3613
 
3449
 
int nosprint(char *sptr)
 
3614
char *nosprint(char *sptr)
3450
3615
{
3451
 
   u_char *pptr, *qptr = _STR;
3452
 
   int retval = 0;
 
3616
   int qtmp, slen = 100;
 
3617
   u_char *pptr, *qptr, *bptr;
 
3618
 
 
3619
   bptr = (u_char *)malloc(slen);       /* initial length 100 */
 
3620
   qptr = bptr;
3453
3621
 
3454
3622
   *qptr++ = '(';
3455
3623
 
3456
3624
   /* Includes extended character set (non-ASCII) */
3457
3625
 
3458
3626
   for (pptr = sptr; pptr && *pptr != '\0'; pptr++) {
 
3627
      /* Ensure enough space for the string, including everything following the "for" loop */
 
3628
      qtmp = qptr - bptr;
 
3629
      if (qtmp + 7 >= slen) {
 
3630
         slen += 7;
 
3631
         bptr = (char *)realloc(bptr, slen);
 
3632
         qptr = bptr + qtmp;
 
3633
      }
 
3634
 
 
3635
      /* Deal with non-printable characters and parentheses */
3459
3636
      if (*pptr > (char)126) {
3460
3637
         sprintf(qptr, "\\%3o", (int)(*pptr));
3461
3638
         qptr += 4; 
3466
3643
         *qptr++ = *pptr;
3467
3644
      }
3468
3645
   }
3469
 
   if (qptr == (u_char *)_STR + 1) {
 
3646
   if (qptr == bptr + 1) {      /* Empty string gets a NULL result, not "()" */
3470
3647
      qptr--;
3471
 
      retval = -1;
3472
3648
   }
3473
3649
   else {
3474
3650
      *qptr++ = ')';
3476
3652
   }
3477
3653
   *qptr++ = '\0';
3478
3654
 
3479
 
   return retval;
 
3655
   return (char *)bptr;
3480
3656
}
3481
3657
 
3482
3658
/*--------------------------------------------------------------*/
3488
3664
   short i, segs = 0;
3489
3665
   stringpart *chrptr;
3490
3666
   char **ostr = (char **)malloc(sizeof(char *));
 
3667
   char *tmpstr;
3491
3668
   float lastscale = 1.0;
3492
3669
   int lastfont = -1;
3493
3670
 
3500
3677
         strcpy(ostr[segs], "()");
3501
3678
      }
3502
3679
      else {
3503
 
         writesegment(chrptr, &lastscale, &lastfont);
3504
 
         ostr[segs] = (char *)malloc(1 + strlen(_STR));
3505
 
         strcpy(ostr[segs], _STR);
 
3680
         tmpstr = writesegment(chrptr, &lastscale, &lastfont);
 
3681
         if (tmpstr[0] != '\0')
 
3682
            ostr[segs] = tmpstr;
 
3683
         else
 
3684
            segs--;
3506
3685
      }
3507
3686
      segs++;
3508
3687
   }
3523
3702
/* (Recursive, so we can write segments in the reverse order)   */
3524
3703
/*--------------------------------------------------------------*/
3525
3704
 
3526
 
void writesegment(stringpart *chrptr, float *lastscale, int *lastfont)
 
3705
char *writesegment(stringpart *chrptr, float *lastscale, int *lastfont)
3527
3706
{
3528
3707
   int type = chrptr->type;
 
3708
   char *retstr;
 
3709
 
3529
3710
   switch(type) {
3530
3711
      case PARAM_START:
3531
3712
         sprintf(_STR, "v%d ", chrptr->data.paramno + 1);
3582
3763
         break;
3583
3764
      case FONT_SCALE:
3584
3765
         if (*lastfont == -1) {
3585
 
            fprintf(stderr, "Warning:  Font may not be the one that was intended.\n");
 
3766
            Fprintf(stderr, "Warning:  Font may not be the one that was intended.\n");
3586
3767
            *lastfont = 0;
3587
3768
         }
3588
3769
         *lastscale = chrptr->data.scale;
3601
3782
         sprintf(_STR, "{%d %d Kn} ", chrptr->data.kern[0], chrptr->data.kern[1]);
3602
3783
         break;
3603
3784
      case TEXT_STRING:
3604
 
         nosprint(chrptr->data.string);
3605
 
         break;
 
3785
         /* Everything except TEXT_STRING will always fit in the _STR fixed-length character array. */
 
3786
         return nosprint(chrptr->data.string);
3606
3787
   }
 
3788
 
 
3789
   retstr = (char *)malloc(1 + strlen(_STR));
 
3790
   strcpy(retstr, _STR);
 
3791
   return retstr;
3607
3792
}
3608
3793
 
3609
3794
/*--------------------------------------------------------------*/
3715
3900
   int xaddin, yaddin;
3716
3901
   int curcolor = ccolor;
3717
3902
   float psscale = getpsscale(psnorm, mpage);
 
3903
   XPoint origin, corner;
3718
3904
 
3719
3905
   /* first, get a total count of all objects and give warning if large */
3720
3906
 
3724
3910
      Wprintf(_STR);
3725
3911
   }
3726
3912
           
3727
 
#ifdef SCHEMA
3728
 
#define height height2
3729
 
#define _width width2
3730
 
#else
3731
 
#define _width width
3732
 
#endif
3733
 
 
3734
3913
   /* search for all object definitions needed */
3735
3914
 
3736
3915
   for (gptr = localdata->plist; gptr < localdata->plist + localdata->parts; gptr++)
3760
3939
     
3761
3940
      fprintf (ps, "/pgsave save def bop\n");
3762
3941
 
 
3942
      origin = localdata->bbox.lowerleft;
 
3943
      corner.x = origin.x + localdata->bbox.width;
 
3944
      corner.y = origin.y + localdata->bbox.height;
 
3945
 
3763
3946
#ifdef SCHEMA
3764
3947
      if (localdata->symschem != NULL) {
3765
3948
         fprintf(ps, "%% %s is_symbol\n", localdata->symschem->name);
3766
3949
      }
 
3950
 
 
3951
      /* For a page, extend bounding box around schematic pins */
 
3952
      extendschembbox(xobjs.pagelist[mpage]->pageinst, &origin, &corner);
3767
3953
#endif
3768
3954
 
3769
 
      xaddin = (int)(xmargin / psscale) - localdata->lowerleft.x;
3770
 
      yaddin = (int)(ymargin / psscale) - localdata->lowerleft.y;
 
3955
      xaddin = (int)(xmargin / psscale) - origin.x;
 
3956
      yaddin = (int)(ymargin / psscale) - origin.y;
3771
3957
      fprintf(ps, "%% %hd %hd offsets\n", xaddin, yaddin);
3772
3958
 
3773
3959
      if (xobjs.pagelist[mpage]->drawingscale.x != 1
3782
3968
 
3783
3969
      if (xobjs.pagelist[mpage]->background.name != (char *)NULL) {
3784
3970
         float iscale = (xobjs.pagelist[mpage]->coordstyle == CM) ? CMSCALE : INCHSCALE;
3785
 
         fprintf(ps, "%d %d insertion\n",
3786
 
                (int)((float)xaddin * iscale), (int)((float)yaddin * iscale));
 
3971
         if (xobjs.pagelist[mpage]->orient == 90)
 
3972
            fprintf(ps, "%5.4f %d %d 90 psinsertion\n", psnorm,
 
3973
                  (int)((float)xaddin * iscale * psnorm) + (int)(ymargin - xmargin),
 
3974
                  (int)((float)yaddin * iscale * psnorm) -
 
3975
                  ((int)((float)(corner.y - origin.y) * psscale) +
 
3976
                  (int)(xmargin + ymargin)));
 
3977
         else
 
3978
            fprintf(ps, "%5.4f %d %d 0 psinsertion\n", psnorm,
 
3979
                  (int)((float)xaddin * iscale * psnorm),
 
3980
                  (int)((float)yaddin * iscale * psnorm));
3787
3981
         savebackground(ps, xobjs.pagelist[mpage]->background.name);
3788
 
         fprintf(ps, "end_insert\n");
 
3982
         fprintf(ps, "\nend_insert\n");
3789
3983
      }
3790
3984
 
3791
3985
      if (xobjs.pagelist[mpage]->orient == 90)
3792
3986
         fprintf(ps, "90 rotate %d %d translate\n", (int)(ymargin - xmargin),
3793
 
             -((int)((float)localdata->height * psscale) + 
 
3987
             -((int)((float)(corner.y - origin.y) * psscale) + 
3794
3988
             (int)(xmargin + ymargin)));
3795
3989
 
3796
3990
      fprintf(ps, "%5.4f ", psnorm);
3827
4021
 
3828
4022
      if (psscale == 0) {
3829
4023
         fprintf(ps, "/%s {\n", localdata->name);
3830
 
#ifdef SCHEMA
3831
 
         sprintf(_STR, "%% %hd %hd %hd %hd bbox\n", localdata->lleft2.x,
3832
 
              localdata->lleft2.y, localdata->_width, localdata->height);
3833
 
#else
3834
 
         sprintf(_STR, "%% %hd %hd %hd %hd bbox\n", localdata->lowerleft.x,
3835
 
              localdata->lowerleft.y, localdata->_width, localdata->height);
3836
 
#endif
3837
 
         fputs(_STR, ps);
 
4024
         /* No longer writes "bbox" record */
3838
4025
         if (localdata->hidden == True) fprintf(ps, "%% hidden\n");
3839
4026
 
3840
4027
#ifdef SCHEMA
3848
4035
#endif
3849
4036
 
3850
4037
         /* Check for parameters and default values */
3851
 
         if (localdata->params != NULL) {
 
4038
         if ((localdata->params != NULL) && (localdata->num_params > 0)) {
3852
4039
            short i;
3853
4040
            stcount = 0;
3854
4041
            for (i = 0; i < localdata->num_params; i++) {
3869
4056
                     break;
3870
4057
               }
3871
4058
            }
 
4059
 
3872
4060
            sprintf(_STR, "%d beginparm\n", localdata->num_params);
3873
4061
            dostcount (ps, &stcount, strlen(_STR));
3874
4062
            fputs(_STR, ps);
3881
4069
         xaddin = yaddin = 0;
3882
4070
      }
3883
4071
 
3884
 
 
3885
 
#ifdef SCHEMA
3886
 
#undef height
3887
 
#endif
3888
 
#undef _width
3889
 
 
3890
4072
      /* write all the elements in order */
3891
4073
 
3892
4074
      for (savegen = localdata->plist; savegen < localdata->plist +
4140
4322
      if (psscale == 0) fprintf(ps, "endgate\n} def\n\n");
4141
4323
 
4142
4324
   }
4143
 
 
4144
 
   /* If saving was successful, then set object "changed" flag to show  */
4145
 
   /* that there are no unsaved changes in the object.                  */
4146
4325
}
4147
4326
 
4148
4327
/*----------------------------------------------------------------------*/