1 /*
2  * gdsreader - simple Calma parser/printer tool
3  * Copyright (C) 1999 Serban-Mihai Popescu, serbanp@ix.netcom.com
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <math.h>
23 
24 #include <GDSstructs.h>
25 #include <GDSconsts.h>
26 #include <GDSglobals.h>
27 #include <GDSaux.h>
28 #include <GDSreader.h>
29 #include <GDSboundary.h>
30 #include <GDSpath.h>
31 #include <GDSsref.h>
32 #include <GDSaref.h>
33 #include <GDStext.h>
34 #include <GDStext.h>
35 #include <GDSnode.h>
36 #include <GDSbox.h>
37 #include <GDSstruct.h>
38 #include <GDStransf.h>
39 
40 static void
writeHPGLHeader(FILE * hpglfile)41 writeHPGLHeader(FILE *hpglfile)
42 {
43   fprintf(hpglfile, "%%-1BBPINNP64MC1QL100WU0PW0.13\n");
44 }
45 
46 static void
writeHPGLTail(FILE * hpglfile)47 writeHPGLTail(FILE *hpglfile)
48 {
49   fprintf(hpglfile, "PUSP0PG;\n");
50 }
51 
52 static void
writeHPGLHatch(FILE * hpglfile,PSStyle psStyle,double scale)53 writeHPGLHatch(FILE *hpglfile, PSStyle psStyle, double scale)
54 {
55   if(psStyle.fill)
56   {
57     fprintf(hpglfile, "FT1\n");
58     return;
59   }
60   switch(psStyle.hatch)
61   {
62     case 1:
63       fprintf(hpglfile, "FT3,%d,%.2f\n",
64               (int)(psStyle.step * 40.0 / scale), psStyle.angle);
65       return;
66     case 2:
67       fprintf(hpglfile, "FT4,%d,%.2f\n",
68               (int)(psStyle.step * 40.0 / scale), psStyle.angle);
69       return;
70     case 0:
71     default:
72       return;
73   }
74 }
75 
76 static void
writeHPGLPen(FILE * hpglfile,PSStyle psStyle)77 writeHPGLPen(FILE *hpglfile, PSStyle psStyle)
78 {
79   if(psStyle.hidden)
80     return;
81   fprintf(hpglfile, "PC%d,%d,%d,%d", psStyle.gdsno,
82           (int)(255.0 * psStyle.edgecolor.r + 0.5),
83           (int)(255.0 * psStyle.edgecolor.g + 0.5),
84           (int)(255.0 * psStyle.edgecolor.b + 0.5));
85 }
86 
87 void
GDStoHPGL(GDSlibrary * libptr,char * hpglfile,char * topcellname)88 GDStoHPGL(GDSlibrary *libptr, char *hpglfile, char *topcellname)
89 {
90   GDSstruct *structptr;
91   GDScell *cellptr;
92   FILE *hpglfileptr;
93   bbox bbx;
94   double scale, scalex, scaley;
95   int i;
96 
97   if(topcellname == NULL)
98     return;
99 
100   hpglfileptr = fopen(hpglfile, "w");
101   if(hpglfileptr == NULL)
102   {
103     fprintf(stderr, "Couldn't open %s for writing. Aborting...\n", hpglfile);
104     exit(1);
105   }
106   writeHPGLHeader(hpglfileptr);
107   for(i = 0; i < howmanylayers; i++)
108     writeHPGLPen(hpglfileptr, psStyles[i]);
109 
110   structptr = GDSgetStructByName(libptr, topcellname);
111   if(structptr == NULL)
112   {
113     fprintf(stderr, "Couldn't find the structure named \"%s\"\n",
114             topcellname);
115     return;
116   }
117   bbx = GDSgetStructBBox(structptr);
118   scalex = 33.6 * InternalScaleFactor * 1016.0 * 1.0 / (bbx.ur.x - bbx.ll.x);
119   scaley = 42.6 * InternalScaleFactor * 1016.0 * 1.0 / (bbx.ur.y - bbx.ll.y);
120   scale = scalex;
121   fprintf(stderr, "scalex = %f, scaley = %f\n", scalex, scaley);
122   fprintf(hpglfileptr, "\nPS%d,%d;\n", (int)(33.6 * 1016),
123           (int)(33.6 * 1016 * (bbx.ur.y - bbx.ll.y) / (bbx.ur.x - bbx.ll.x)));
124 
125   fprintf(stderr, "scale = %f\n", scale);
126   fprintf(hpglfileptr, "IP%d,%d,%d,%dSC%d,%d,%d,%d\n",
127           0, 0, (int)(33.6 * 1016),
128           (int)(33.6 * 1016 * (bbx.ur.y - bbx.ll.y) / (bbx.ur.x - bbx.ll.x)),
129           (int)(bbx.ll.x / InternalScaleFactor - 33.6 * 1016.0 * 0.05 / scale),
130           (int)(bbx.ur.x / InternalScaleFactor + 33.6 * 1016.0 * 0.05 / scale),
131           (int)(bbx.ll.y / InternalScaleFactor - 33.6 * 1016.0 * 0.05 / scale),
132           (int)(bbx.ur.y / InternalScaleFactor + 33.6 * 1016.0 * 0.05 / scale));
133   for(i = 0; i < howmanylayers; i++)
134   {
135     if(psStyles[i].hidden)
136       continue;
137 
138     fprintf(hpglfileptr, "SP%d\n", psStyles[i].gdsno);
139     writeHPGLHatch(hpglfileptr, psStyles[i], scale);
140 
141     for(cellptr = structptr->cells; cellptr != NULL;
142         cellptr = cellptr->next)
143     {
144       switch(cellptr->type)
145       {
146         case BOUNDARY:
147           BoundaryToHPGL(hpglfileptr, cellptr->detail.boundary, psStyles[i]);
148           break;
149         case PATH:
150           PathToHPGL(hpglfileptr, cellptr->detail.path, psStyles[i]);
151           break;
152         case SREF:
153           SrefToHPGL(hpglfileptr, cellptr->detail.sref,
154                        cellptr->detail.sref->transfptr, psStyles[i]);
155           break;
156         case AREF:
157           ArefToHPGL(hpglfileptr, cellptr->detail.aref, &Ident, psStyles[i]);
158           break;
159         case TEXT:
160           TextToHPGL(hpglfileptr, cellptr->detail.text, &Ident, psStyles[i]);
161           break;
162         case NODE:
163           NodeToHPGL(hpglfileptr, cellptr->detail.node, psStyles[i]);
164           break;
165         case BOX:
166           BoxToHPGL(hpglfileptr, cellptr->detail.box, psStyles[i]);
167           break;
168         default:
169           break;
170       } /* switch */
171     } /* cell loop */
172   }
173   writeHPGLTail(hpglfileptr);
174   fclose(hpglfileptr);
175 }
176