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 <strings.h>
22
23 #include <GDSstructs.h>
24 #include <GDSconsts.h>
25 #include <GDStransf.h>
26 #include <GDSsref.h>
27 #include <GDSaux.h>
28
29 bbox
GDSgetArefBBox(arefEl * aref,transform * transf)30 GDSgetArefBBox(arefEl *aref, transform *transf)
31 {
32 bbox bbx, bbx1;
33 srefEl sref;
34 transform *newtransf;
35 point refpoint;
36 int i, j;
37
38 bbx.ll.x = BIGVAL;
39 bbx.ll.y = BIGVAL;
40 bbx.ur.x = -BIGVAL;
41 bbx.ur.y = -BIGVAL;
42
43 for(i = 0; i < aref->cols; i++)
44 for(j = 0; j < aref->rows; j++)
45 {
46 sref.strptr = aref->strptr;
47 sref.refname = aref->refname;
48
49 refpoint.x = i * aref->colspacing;
50 refpoint.y = j * aref->rowspacing;
51 sref.transfptr = GDStranslateTransf(&Ident, refpoint);
52 newtransf = GDStransfTransf(aref->transfptr, transf);
53 bbx1 = GDSgetSrefBBox(&sref, newtransf);
54
55 GDSfreeTransf(sref.transfptr);
56 GDSfreeTransf(newtransf);
57
58 if(bbx.ll.x > bbx1.ll.x)
59 bbx.ll.x = bbx1.ll.x;
60 if(bbx.ll.y > bbx1.ll.y)
61 bbx.ll.y = bbx1.ll.y;
62 if(bbx.ur.x < bbx1.ur.x)
63 bbx.ur.x = bbx1.ur.x;
64 if(bbx.ur.y < bbx1.ur.y)
65 bbx.ur.y = bbx1.ur.y;
66 }
67 return bbx;
68 }
69
70 void
ArefToPS(FILE * psfile,arefEl * aref,transform * transf,PSStyle psStyle)71 ArefToPS(FILE *psfile, arefEl *aref, transform *transf, PSStyle psStyle)
72 {
73 srefEl sref;
74 transform *newtransf;
75 point refpoint;
76 int i, j;
77
78 for(i = 0; i < aref->cols; i++)
79 for(j = 0; j < aref->rows; j++)
80 {
81 sref.strptr = aref->strptr;
82 sref.refname = aref->refname;
83
84 refpoint.x = i * aref->colspacing;
85 refpoint.y = j * aref->rowspacing;
86 sref.transfptr = GDStranslateTransf(&Ident, refpoint);
87 newtransf = GDStransfTransf(aref->transfptr, transf);
88 SrefToPS(psfile, &sref, newtransf, psStyle);
89 GDSfreeTransf(sref.transfptr);
90 GDSfreeTransf(newtransf);
91 }
92 }
93
94 void
ArefToPOV(FILE * povfile,arefEl * aref,transform * transf,PSStyle psStyle)95 ArefToPOV(FILE *povfile, arefEl *aref, transform *transf, PSStyle psStyle)
96 {
97 srefEl sref;
98 transform *newtransf;
99 point refpoint;
100 int i, j;
101 fprintf(stderr,"Rendering Aref->POV\n"
102 " Rows: %d\n Cols: %d\n RowSpace: %d\n ColSpace: %d\n",
103 aref->rows,aref->cols,aref->rowspacing,aref->colspacing
104 );
105 for(i = 0; i < aref->cols; i++)
106 for(j = 0; j < aref->rows; j++)
107 {
108 sref.strptr = aref->strptr;
109 sref.refname = aref->refname;
110
111 refpoint.x = i * aref->colspacing;
112 refpoint.y = j * aref->rowspacing;
113 sref.transfptr = GDStranslateTransf(&Ident, refpoint);
114 newtransf = GDStransfTransf(aref->transfptr, transf);
115 /* Here we have a sref being instanced with additional
116 translations. */
117 SrefToPOV(povfile, &sref, newtransf, psStyle);
118 GDSfreeTransf(sref.transfptr);
119 GDSfreeTransf(newtransf);
120 }
121 }
122
123 void
ArefToHPGL(FILE * hpglfile,arefEl * aref,transform * transf,PSStyle psStyle)124 ArefToHPGL(FILE *hpglfile, arefEl *aref, transform *transf, PSStyle psStyle)
125 {
126 srefEl sref;
127 transform *transfptr, *tp1;
128 point refpoint;
129 int i, j;
130
131 for(i = 0; i < aref->cols; i++)
132 for(j = 0; j < aref->rows; j++)
133 {
134 sref.strptr = aref->strptr;
135 sref.refname = aref->refname;
136
137 refpoint.x = i * aref->colspacing;
138 refpoint.y = j * aref->rowspacing;
139 tp1 = GDStranslateTransf(&Ident, refpoint);
140 transfptr = GDStransfTransf(tp1, aref->transfptr);
141 sref.transfptr = GDStransfTransf(transfptr, transf);
142 SrefToHPGL(hpglfile, &sref, sref.transfptr, psStyle);
143 GDSfreeTransf(sref.transfptr);
144 GDSfreeTransf(transfptr);
145 GDSfreeTransf(tp1);
146 }
147 }
148
149 GDScell *
GDSreadAref(int gdsfildes,GDSstruct * structptr)150 GDSreadAref(int gdsfildes, GDSstruct *structptr)
151 {
152 unsigned char *record, chunk;
153 int rectype, nbytes;
154 point ref, col, row;
155 double angle, mag;
156 int mirror = 0;
157 GDScell *newcell;
158 arefEl *arefptr;
159
160 arefptr = (arefEl *)MALLOC(sizeof(arefEl));
161 arefptr->strptr = NULL; /* to be inserted after all structs have been read */
162 newcell = (GDScell *)MALLOC(sizeof(GDScell));
163 newcell->type = AREF;
164 newcell->detail.aref = arefptr;
165 if(GDSreadRecord(gdsfildes, &record, &nbytes) != SNAME)
166 {
167 fprintf(stderr, "Missing SNAME field in AREF element. Abort!\n");
168 /* exit(1); */
169 }
170 if((arefptr->refname = GDSreadString(record + 2, nbytes - 4)) == NULL)
171 {
172 fprintf(stderr, "Bad STRING field in AREF element. Abort!\n");
173 exit(1);
174 }
175 FREE(record);
176
177 rectype = GDSreadRecord(gdsfildes, &record, &nbytes);
178 if(rectype == STRANS)
179 {
180 chunk = record[2];
181 if(chunk & 0x80)
182 mirror = 1;
183
184 FREE(record);
185 switch(GDSreadRecord(gdsfildes, &record, &nbytes))
186 {
187 case MAG:
188 mag = GDSreadReal8(record + 2);
189 if(!(chunk & 0x02))
190 mag *= CURRENTMAG;
191 FREE(record);
192 switch(GDSreadRecord(gdsfildes, &record, &nbytes))
193 {
194 case ANGLE:
195 angle = GDSreadReal8(record + 2);
196 if(!(chunk & 0x01))
197 angle += CURRENTANGLE;
198 FREE(record);
199 if(GDSreadRecord(gdsfildes, &record, &nbytes) != COLROW)
200 {
201 fprintf(stderr, "Missing COLROW field in AREF element. Abort!\n");
202 exit(1);
203 }
204 arefptr->cols = GDSreadInt2(record + 2);
205 arefptr->rows = GDSreadInt2(record + 4);
206 FREE(record);
207 break;
208 case COLROW:
209 angle = CURRENTANGLE;
210 arefptr->cols = GDSreadInt2(record + 2);
211 arefptr->rows = GDSreadInt2(record + 4);
212 FREE(record);
213 break;
214 default:
215 fprintf(stderr, "Missing COLROW field in AREF element. Abort!\n");
216 exit(1);
217 }
218 break;
219 case ANGLE:
220 mag = CURRENTMAG;
221 angle = GDSreadReal8(record + 2);
222 if(!(chunk & 0x01))
223 angle += CURRENTANGLE;
224 FREE(record);
225 if(GDSreadRecord(gdsfildes, &record, &nbytes) != COLROW)
226 {
227 fprintf(stderr, "Missing COLROW field in AREF element. Abort!\n");
228 exit(1);
229 }
230 arefptr->cols = GDSreadInt2(record + 2);
231 arefptr->rows = GDSreadInt2(record + 4);
232 FREE(record);
233 break;
234 case COLROW:
235 mag = CURRENTMAG;
236 angle = CURRENTANGLE;
237 arefptr->cols = GDSreadInt2(record + 2);
238 arefptr->rows = GDSreadInt2(record + 4);
239 FREE(record);
240 break;
241 default:
242 fprintf(stderr,
243 "Missing MAG, ANGLE or COLROW field in AREF element. Abort!\n");
244 exit(1);
245 }
246 }
247 else if(rectype == COLROW)
248 {
249 mag = CURRENTMAG;
250 angle = CURRENTANGLE;
251 arefptr->cols = GDSreadInt2(record + 2);
252 arefptr->rows = GDSreadInt2(record + 4);
253 FREE(record);
254 }
255 else
256 {
257 fprintf(stderr, "Missing STRANS or COLROW field in AREF element. Abort!\n");
258 exit(1);
259 }
260
261 if(GDSreadRecord(gdsfildes, &record, &nbytes) != XY)
262 {
263 fprintf(stderr, "Missing XY field in AREF element. Abort!\n");
264 exit(1);
265 }
266 if(arefptr->rows == 0 || arefptr->cols == 0)
267 {
268 fprintf(stderr, "AREF element with 0 rows/cols. Abort!\n");
269 exit(1);
270 }
271
272 ref.x = GDSreadInt4(record + 2);
273 ref.y = GDSreadInt4(record + 6);
274 col.x = GDSreadInt4(record + 10);
275 col.y = GDSreadInt4(record + 14);
276 row.x = GDSreadInt4(record + 18);
277 row.y = GDSreadInt4(record + 22);
278 FREE(record);
279
280 arefptr->transfptr = GDSgetTransf(ref, angle, mag, mirror);
281
282 /* Since GDSinvtransfPoint performs also the translation, the unused dimension
283 must be equal to 0 (i.e. the original one was identical to the reference
284 point one) and the useful one is exactly the spacing multiplied by the number
285 of cells in that direction */
286
287 col = GDSinvtransfPoint(&col, arefptr->transfptr);
288
289 if(col.x < 0)
290 {
291 fprintf(stdout, "Error in AREF! Found a y-axis mirrored array. This is impossible so I'm exiting.\n");
292 exit(1);
293 }
294 if(col.y != 0)
295 {
296 fprintf(stdout, "Error in AREF! The second point in XY is broken.\n");
297 exit(1);
298 }
299
300 row = GDSinvtransfPoint(&row, arefptr->transfptr);
301
302 if(row.x != 0)
303 {
304 fprintf(stdout, "Error in AREF! The third point in XY is broken.\n");
305 exit(1);
306 }
307
308 arefptr->colspacing =
309 col.x / arefptr->cols;
310 arefptr->rowspacing =
311 row.y / arefptr->rows;
312
313 if(row.y < 0)
314 arefptr->rowspacing *=-1.0;
315 /* arefptr->transfptr->c -= arefptr->rowspacing; */
316 if(GDSreadRecord(gdsfildes, &record, &nbytes) != ENDEL)
317 {
318 fprintf(stderr, "Missing ENDEL field in AREF element. Abort!\n");
319 exit(1);
320 }
321 FREE(record);
322
323 fprintf(stdout, "Aref at %d,%d/ of cell named \"%s\", c/r = %d/%d, spacing = %d/%d, mirror = %d\n",
324 ref.x, ref.y, arefptr->refname, arefptr->cols, arefptr->rows,
325 arefptr->colspacing, arefptr->rowspacing, mirror);
326 return newcell;
327 }
328