Initial commit at Tue Apr 25 08:36:02 EDT 2017 by tim on stravinsky
[xcircuit.git] / asg / psfigs.c
blob3220a13acc2463b9b098d56f6f5ac219e10a3d95
1 /************************************************************
2 **
3 ** COPYRIGHT (C) 1993 UNIVERSITY OF PITTSBURGH
4 ** COPYRIGHT (C) 1996 GANNON UNIVERSITY
5 ** ALL RIGHTS RESERVED
6 **
7 ** This software is distributed on an as-is basis
8 ** with no warranty implied or intended. No author
9 ** or distributor takes responsibility to anyone
10 ** regarding its use of or suitability.
12 ** The software may be distributed and modified
13 ** freely for academic and other non-commercial
14 ** use but may NOT be utilized or included in whole
15 ** or part within any commercial product.
17 ** This copyright notice must remain on all copies
18 ** and modified versions of this software.
20 ************************************************************/
22 /*
23 *----------------------------------------------------------------------
24 * File psfigs.c
25 * Author s.t.frezza
27 * This file contains supporting post-script generation routines to produce
28 * figures for predefined schematic symbols
30 *----------------------------------------------------------------------
32 #include <stdio.h>
33 #include "network.h"
34 #include "route.h"
35 #include "psfigs.h"
36 #include "asg_module.h"
38 #define NAME_OFFSET -1.1
39 #define SIDE_CONVERT(n) ((n==0)?0:(n==1)?1:(n==2)?2:(n==3)?3:0)
40 #define PI 3.1415927
43 /* This definition is used to replace the old usage of "header.ps" file: */
44 #define HEADER "%! \n\
45 % head.ps \n\
46 % prologue file for ploting of schematics editor drawings \n\
47 % \n\
48 % routines: \n\
49 % init -- sets up the graphics state for the proper scaling \n\
50 % \n\
51 % some constants that can be changed: \n\
52 /swidth .1 def % width of lines \n\
53 /fwidth 1.6 def % scale factor for labels \n\
54 /hwidth 12 def % type size of header \n\
55 /hmargin 6 def % header margin \n\
56 /init { % (optional_header) xlo ylo xhi yhi -> - \n\
57 /yhi exch def /xhi exch def \n\
58 /ylo exch def /xlo exch def \n\
59 /lwunit 72 def % LaserWriter units per inch \n\
60 /marginx 0.27 lwunit mul def % x-margin \n\
61 /marginy 0.25 lwunit mul def % y-margin \n\
62 /pagex 8.5 lwunit mul % usable x-space on page \n\
63 2 marginx mul sub def \n\
64 /pagey 11.0 lwunit mul % usable y-space on page \n\
65 2 marginy mul sub def \n\
66 % \n\
67 count 1 ge { % header left on stack? \n\
68 /Helvetica-Bold findfont % set header font \n\
69 hwidth scalefont setfont \n\
70 marginx marginy pagey add hwidth sub \n\
71 moveto % position to place text \n\
72 show % print header string \n\
73 /pagey pagey hwidth hmargin add sub \n\
74 def % adjust page size for header \n\
75 } if \n\
76 % \n\
77 count 1 ge { % 2nd header left on stack? \n\
78 marginx marginy pagey add hwidth sub \n\
79 moveto % position to place text \n\
80 show % print header string \n\
81 /pagey pagey hwidth hmargin add sub \n\
82 def % adjust page size for header \n\
83 } if \n\
84 % \n\
85 % \n\
86 /Courier findfont % set the drawing font \n\
87 fwidth scalefont setfont \n\
88 % \n\
89 xhi xlo sub yhi ylo sub div % push delta x / delta y \n\
90 pagex pagey div % push pagex / pagey \n\
91 gt { \n\
92 90 rotate % rotate page and set origin \n\
93 marginy pagex marginx add neg translate \n\
94 pagey xhi xlo sub div % push x and y scales \n\
95 pagex yhi ylo sub div \n\
96 }{ \n\
97 marginx marginy translate % set origin \n\
98 pagex xhi xlo sub div % push x and y scales \n\
99 pagey yhi ylo sub div \n\
100 } ifelse \n\
101 % \n\
102 2 copy % dup the scales \n\
103 gt \n\
104 {dup scale pop} % xscale > yscale: use yscale \n\
105 {pop dup scale} % yscale > xscale: use xscale \n\
106 ifelse \n\
107 % \n\
108 xlo neg ylo neg translate % move origin to proper place \n\
109 swidth setlinewidth % set line width for strokes \n\
110 } def \n"
113 /*--------------------------------------------------------------------------------- */
115 int ps_print_seg(f,x1,y1,x2,y2)
116 FILE *f;
117 int x1,y1,x2,y2;
120 fprintf(f, "newpath %d %d moveto %d %d lineto \n", x1, y1, x2, y2);
121 fprintf(f, "closepath stroke [] 0 setdash\n");
123 /*--------------------------------------------------------------------------------- */
125 int ps_print_border(f,x1,y1,x2,y2)
126 FILE *f;
127 int x1,y1,x2,y2;
130 fprintf(f,"[4.0] 0 setdash\n");
131 fprintf(f, "newpath %d %d moveto %d %d lineto \n", x1, y1, x2, y1);
132 fprintf(f, "%d %d lineto %d %d lineto\n", x2, y2, x1, y2);
133 fprintf(f, "closepath stroke [] 0 setdash\n");
136 /*--------------------------------------------------------------------------------- */
137 int ps_print_mod(f,m)
138 FILE *f;
139 module *m;
141 int type, n, i;
142 float scale, arcLen, noOfExtensions, fractional, theta, mid_y, mid_x;
144 if (m != NULL)
146 type = validate(m->type);
147 scale = (float)m->x_size/(float)(ICON_SIZE * ICON_SIZE/2);
150 ps_print_sym(f, m->type, m->x_pos, m->y_pos, m->x_size, m->y_size,
151 m->rot, m->name,scale);
153 if ((type == BLOCK) || (type == DONT_KNOW)) ps_attach_outerms(f, m);
154 ps_attach_interms(f, m);
156 /* Special case stuff for mulit-terminal ANSI AND, NAND, OR, NOR, XOR, and
157 XNOR gates: */
158 if ((m->y_size > ICON_SIZE) && (type != BLOCK) && (type != DONT_KNOW))
160 scale = (float)m->x_size/(float)(ICON_SIZE * ICON_SIZE/2);
162 if ((type == AND) || (type == NAND))
163 { /* AND family - display a line to connect all inputs to the icon */
164 mid_x = (float)m->x_pos + (float)m->x_size/2.0;
165 fprintf(f, "newpath %f %d moveto ", mid_x - scale * 14.0, m->y_pos);
166 fprintf(f, "%d %d rlineto closepath stroke\n", 0, m->y_size);
169 else if ((type == OR) || (type == NOR))
170 { /* OR family -- Add line to the 1st Back Curve: */
171 mid_x = (float)m->x_pos + (float)m->x_size/2.0 - 0.4;
172 arcLen = (18.8232 * scale);
173 noOfExtensions = ((float)m->y_size - arcLen)/(2.0 * arcLen);
174 n = (int)noOfExtensions;
175 fractional = (noOfExtensions - (float)n) * arcLen;
176 for (i = n; i >= 0; i--)
177 { /* put down one arc, or fraction thereof */
178 theta = (i > 0) ? 28.072 :
179 (180.0/PI) * asin(fractional/(scale * 20)) - 28.072;
180 if (theta > (-28.072 * 1.10)) /* 10% margin */
182 mid_y = (float)m->y_pos + (float)m->y_size/2.0 +
183 (float)(n - i + 1) * arcLen;
184 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",
185 mid_x - scale * 28.5, mid_y, scale * 20.0,
186 -28.072, theta);
187 mid_y = (float)m->y_pos + (float)m->y_size/2.0 -
188 (float)(n - i + 1) * arcLen;
189 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",
190 mid_x - scale * 28.5, mid_y, scale * 20.0,
191 -(theta), 28.072);
195 else if ((type == XOR) || (type == XNOR))
196 { /* OR family -- Add line to the 2nd Back Curve: */
197 mid_x = (float)m->x_pos + (float)m->x_size/2.0;
198 arcLen = (18.8232 * scale);
199 noOfExtensions = ((float)m->y_size - arcLen)/(2.0 * arcLen);
200 n = (int)noOfExtensions;
201 fractional = (noOfExtensions - (float)n) * arcLen;
202 for (i = n; i >= 0; i--)
203 { /* put down one arc, or fraction thereof */
204 theta = (i > 0) ? 28.072 :
205 (180.0/PI) * asin(fractional/(scale * 20)) - 28.072;
206 if (theta > (-28.072 * 1.10)) /* 10% margin */
208 mid_y = (float)m->y_pos + (float)m->y_size/2.0 +
209 (float)(n - i + 1) * arcLen;
210 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",
211 mid_x - scale * 31.5, mid_y, scale * 20.0,
212 -28.072, theta);
213 mid_y = (float)m->y_pos + (float)m->y_size/2.0 -
214 (float)(n - i + 1) * arcLen;
215 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",
216 mid_x - scale * 31.5, mid_y, scale * 20.0,
217 -(theta), 28.072);
221 /* height of arc in Y is 2*rad*sin(28.072) = 40*scale*.47058 =
222 scale * 18.8232. */
226 /*--------------------------------------------------------------------------------- */
227 int ps_attach_interms(f, m)
228 FILE *f;
229 module *m;
231 /* attach all of the input terminals to the gate in question.
232 * NOTE: see "insert_all_modules" in route.c for the definition of the
233 * area in which the module must fit.
235 tlist *tl;
236 int mType = validate(m->type), x = m->x_pos, y = m->y_pos;
237 int term_x, term_y, icon_term_x;
238 char *temp = (char *)calloc(NET_NAME_SIZE + 1, sizeof(char));
239 float scale = (float)m->x_size/(float)(ICON_SIZE * ICON_SIZE/2);
240 float mid_x = (float)m->x_pos + (float)m->x_size/2.0;
241 float w;
243 for (tl = m->terms; tl != NULL; tl = tl->next)
245 term_x = tl->this->x_pos;
246 term_y = tl->this->y_pos;
247 if (tl->this->type == IN)
249 icon_term_x = m->x_size/2 - 3;
251 /* display a small line for each terminal */
252 fprintf(f, "newpath %d %d moveto ", term_x + x, term_y + y);
253 switch(mType)
255 case DONT_KNOW :
256 case BLOCK: fprintf(f, "%d %d lineto ", x, term_y + y);
257 break;
258 case AND :
259 case NAND : fprintf(f, "%f %d lineto ", mid_x - 14.0 * scale, term_y+y);
260 break;
261 default : fprintf(f, "%d 0 rlineto ", icon_term_x - term_x);
262 break;
264 fprintf(f, "closepath stroke\n ");
266 /* skip the dot: */
267 /* ps_print_contact(f,(float)term_x + x + 1, (float)term_y + y); */
269 if ((do_routing != TRUE) && (latex == FALSE))
271 /* At the net name */
272 str_end_copy(temp, tl->this->nt->name, NET_NAME_SIZE);
273 ps_put_label(f, temp,
274 (float)(term_x + x - strlen(tl->this->nt->name)),
275 (float)(term_y + y));
278 else if (tl->this->type == OUT)
280 /* skip the dot: */
281 /* ps_print_contact(f,(float)(term_x + x) - .5, (float)term_y + y); */
283 if (mType != INPUT_SYM)
284 { /* add the net name as a terminal name: */
285 str_end_copy(temp, tl->this->nt->name, NET_NAME_SIZE);
286 ps_put_label(f, temp,
287 (float)(term_x + x), (float)(term_y + y + 1));
290 else if (tl->this->type == INOUT)
292 if (m->x_size > ICON_SIZE)
294 /* display a line to connect all of the terminals to the icon */
296 /* Connect the line from the outside to the edge of the box... */
297 fprintf(f, "newpath %d %d moveto ", x + term_x, y + term_y + 1);
298 fprintf(f, "%d %d rlineto closepath stroke\n", 0, -(TERM_MARGIN));
300 else if (tl->this->type == OUTIN)
302 if (m->x_size > ICON_SIZE)
304 /* display a line to connect all of the terminals to the icon */
306 /* Connect the line from the outside to the edge of the box... */
307 fprintf(f, "newpath %d %d moveto ", x + term_x, y + term_y);
308 fprintf(f, "%d %d rlineto closepath stroke\n", 0, -(TERM_MARGIN));
310 else /* Special Terminals... */
312 icon_term_x = m->x_size/2 - 3;
313 fprintf(f, "newpath %6.4f %d moveto ",
314 (float)term_x/2.0 + (float)x, term_y + y);
315 switch(mType)
317 case DONT_KNOW :
318 case BLOCK: fprintf(f, "%d %d lineto ", x, term_y + y);
319 break;
320 case AND :
321 case NAND : fprintf(f, "%f %d lineto ", mid_x - 14.0 * scale, term_y+y);
322 break;
323 default : fprintf(f, "%d 0 rlineto ", icon_term_x - term_x);
324 break;
326 fprintf(f, "closepath stroke\n ");
328 w = 0.750;
329 if (tl->this->type == GND)
331 /* display a small GND Symbol for this terminal */
332 fprintf(f,"\n%s GND Symbol ->", "%%%");
333 fprintf(f, "\n newpath %6.4f %d moveto ",
334 (float)term_x/2.0 + (float)x, term_y + y);
335 fprintf(f,"0 -0.75 rlineto %6.5f 0 rmoveto %6.5f 0 rlineto ", w/4.0, w/-2.0);
336 fprintf(f,"%6.5f 0.25 rmoveto %6.5f 0 rlineto ", w/-16.0, 0.75*w);
337 fprintf(f,"%6.5f 0.25 rmoveto %6.5f 0 rlineto closepath stroke \n",
338 (-7.0/8.0)*w, w);
340 else if (tl->this->type == VDD)
342 /* display a small VDD symbol for this terminal */
343 fprintf(f,"\n%s Vdd Symbol on module \n", "%%%");
344 fprintf(f, "newpath %6.4f %d moveto ",
345 (float)term_x/2.0 + (float)x, term_y + y);
346 fprintf(f, "0 0.750 rlineto 0.1250 -0.250 rlineto ");
347 fprintf(f, "-0.25 0 rlineto 0.1250 0.250 rlineto closepath stroke \n");
349 else /* (tl->this->type == DUMMY) */
351 /* Simply put down a contact on the end of the stubbed terminal: */
352 ps_print_contact(f,(float)term_x/2.0 + x, (float)term_y + y);
357 /*--------------------------------------------------------------------------------- */
358 int xc_attach_interms(areastruct, m)
359 XCWindowData *areastruct;
360 module *m;
362 /* attach all of the input terminals to the gate in question.
363 * NOTE: see "insert_all_modules" in route.c for the definition of the
364 * area in which the module must fit.
366 tlist *tl;
367 int mType = validate(m->type), x = m->x_pos, y = m->y_pos;
368 int term_x, term_y, icon_term_x;
369 char *temp = (char *)calloc(NET_NAME_SIZE + 1, sizeof(char));
370 float scale = (float)m->x_size/(float)(ICON_SIZE * ICON_SIZE/2);
371 float mid_x = (float)m->x_pos + (float)m->x_size/2.0;
372 float w;
374 for (tl = m->terms; tl != NULL; tl = tl->next)
376 term_x = tl->this->x_pos;
377 term_y = tl->this->y_pos;
378 if (tl->this->type == IN)
380 icon_term_x = m->x_size/2 - 3;
382 /* display a small line for each terminal */
383 // fprintf(f, "newpath %d %d moveto ", term_x + x, term_y + y);
384 switch(mType)
386 case DONT_KNOW :
387 case BLOCK://code to be attached
388 break;
389 case AND :
390 case NAND ://code to be attached
391 break;
392 default : //code to be attached
393 break;
395 if ((do_routing != TRUE) && (latex == FALSE))
397 /* At the net name */
398 str_end_copy(temp, tl->this->nt->name, NET_NAME_SIZE);
399 /*ps_put_label(f, temp,
400 (float)(term_x + x - strlen(tl->this->nt->name)),
401 (float)(term_y + y));*/
404 else if (tl->this->type == OUT)
408 if (mType != INPUT_SYM)
409 { /* add the net name as a terminal name:
410 str_end_copy(temp, tl->this->nt->name, NET_NAME_SIZE);
411 ps_put_label(f, temp,
412 (float)(term_x + x), (float)(term_y + y + 1));*/
415 else if (tl->this->type == INOUT)
417 if (m->x_size > ICON_SIZE)
419 /* display a line to connect all of the terminals to the icon */
421 /* Connect the line from the outside to the edge of the box... */
422 // fprintf(f, "newpath %d %d moveto ", x + term_x, y + term_y + 1);
423 //fprintf(f, "%d %d rlineto closepath stroke\n", 0, -(TERM_MARGIN));
425 else if (tl->this->type == OUTIN)
427 if (m->x_size > ICON_SIZE)
429 /* display a line to connect all of the terminals to the icon */
431 /* Connect the line from the outside to the edge of the box...
432 fprintf(f, "newpath %d %d moveto ", x + term_x, y + term_y);
433 fprintf(f, "%d %d rlineto closepath stroke\n", 0, -(TERM_MARGIN));*/
435 else /* Special Terminals... */
437 icon_term_x = m->x_size/2 - 3;
438 // fprintf(f, "newpath %6.4f %d moveto ",
439 // (float)term_x/2.0 + (float)x, term_y + y);
440 switch(mType)
442 case DONT_KNOW :
443 case BLOCK: //fprintf(f, "%d %d lineto ", x, term_y + y);
444 break;
445 case AND :
446 case NAND : //fprintf(f, "%f %d lineto ", mid_x - 14.0 * scale, term_y+y);
447 break;
448 default : //fprintf(f, "%d 0 rlineto ", icon_term_x - term_x);
449 break;
451 // fprintf(f, "closepath stroke\n ");
453 w = 0.750;
454 if (tl->this->type == GND)
456 /* display a small GND Symbol for this terminal
457 fprintf(f,"\n%s GND Symbol ->", "%%%");
458 fprintf(f, "\n newpath %6.4f %d moveto ",
459 (float)term_x/2.0 + (float)x, term_y + y);
460 fprintf(f,"0 -0.75 rlineto %6.5f 0 rmoveto %6.5f 0 rlineto ", w/4.0, w/-2.0);
461 fprintf(f,"%6.5f 0.25 rmoveto %6.5f 0 rlineto ", w/-16.0, 0.75*w);
462 fprintf(f,"%6.5f 0.25 rmoveto %6.5f 0 rlineto closepath stroke \n",
463 (-7.0/8.0)*w, w);*/
465 else if (tl->this->type == VDD)
467 /* display a small VDD symbol for this terminal
468 fprintf(f,"\n%s Vdd Symbol on module \n", "%%%");
469 fprintf(f, "newpath %6.4f %d moveto ",
470 (float)term_x/2.0 + (float)x, term_y + y);
471 fprintf(f, "0 0.750 rlineto 0.1250 -0.250 rlineto ");
472 fprintf(f, "-0.25 0 rlineto 0.1250 0.250 rlineto closepath stroke \n");*/
474 else /* (tl->this->type == DUMMY) */
476 /* Simply put down a contact on the end of the stubbed terminal:
477 ps_print_contact(f,(float)term_x/2.0 + x, (float)term_y + y);*/
485 /*--------------------------------------------------------------------------------- */
486 int ps_attach_outerms(f, m)
487 FILE *f;
488 module *m;
490 /* attach all of the output terminals to the gate in question.
491 * NOTE: see "insert_all_modules" in route.c for the definition of the
492 * area in which the module must fit.
494 tlist *tl;
495 int x = m->x_pos;
496 int y = m->y_pos;
497 int term_x, term_y, icon_term_x;
499 for (tl = m->terms; tl != NULL; tl = tl->next)
501 term_x = tl->this->x_pos;
502 term_y = tl->this->y_pos;
503 if (tl->this->type == OUT)
505 /* display a small line for each terminal */
506 fprintf(f, "newpath ");
507 fprintf(f, "%d %d moveto ", term_x + x - 1, term_y + y);
508 fprintf(f, "%d %d rlineto ",TERM_MARGIN , 0);
509 fprintf(f, "closepath stroke\n ");
514 /*--------------------------------------------------------------------------------- */
515 int xc_attach_outerms(areastruct, m)
516 XCWindowData *areastruct;
517 module *m;
519 /* attach all of the output terminals to the gate in question.
520 * NOTE: see "insert_all_modules" in route.c for the definition of the
521 * area in which the module must fit.
523 tlist *tl;
524 int x = m->x_pos;
525 int y = m->y_pos;
526 int term_x, term_y, icon_term_x;
528 for (tl = m->terms; tl != NULL; tl = tl->next)
530 term_x = tl->this->x_pos;
531 term_y = tl->this->y_pos;
532 if (tl->this->type == OUT)
534 /* display a small line for each terminal
535 fprintf(f, "newpath ");
536 fprintf(f, "%d %d moveto ", term_x + x - 1, term_y + y);
537 fprintf(f, "%d %d rlineto ",TERM_MARGIN , 0);
538 fprintf(f, "closepath stroke\n ");*/
545 /*--------------------------------------------------------------------------------- */
546 int ps_print_contact(f, x, y)
547 FILE *f;
548 float x,y;
550 /* add the dot: */
552 fprintf(f, "newpath %f %f %f 0 360 arc closepath fill\n",
553 x, y, CONTACT_WIDTH);
555 /*--------------------------------------------------------------------------------- */
557 int ps_print_box(f, x, y, x_dis, y_dis, rot)
558 FILE *f;
559 int x, y, x_dis, y_dis, rot;
561 /* print a box of the given size at the given location : */
562 fprintf(f, "newpath\n");
563 fprintf(f, "%d %d %d moveto\n", rot, x, y);
564 fprintf(f, "%d %d rlineto\n", 0, y_dis);
565 fprintf(f, "%d %d rlineto\n", x_dis, 0);
566 fprintf(f, "%d %d neg rlineto\n", 0, y_dis);
567 fprintf(f, "closepath \nstroke\n ");
570 /*--------------------------------------------------------------------------------- */
572 int ps_print_sym(f, sym, x, y, x_dis, y_dis, rot, name,scale)
573 FILE *f;
574 char *sym, *name;
575 int x, y, x_dis, y_dis, rot;
576 float scale;
578 /* print the symbol that goes with this type: */
579 switch(validate(sym))
581 case BUFFER :
582 ps_put_label(f, name, (float)x + (float)x_dis/2. - (float)strlen(name)/2.0,
583 (float)y + 2.25);
584 break;
585 case INVNOT_ :
586 ps_print_inverted_not(f, x, y, x_dis, y_dis);
587 ps_put_label(f, name, (float)x + (float)x_dis/2. - (float)strlen(name)/2.0 +1.0,
588 (float)y + 2.25);
589 break;
590 case NOT_ :
592 ps_print_not(f, x, y, x_dis, y_dis);
593 ps_put_label(f, name, (float)x + (float)x_dis/2. - (float)strlen(name)/2.0,
594 (float)y + 2.25);
595 break;
596 case AND :
597 ps_print_and(f, x, y, x_dis, y_dis,scale);
598 ps_put_label(f, name,
599 (float)x + (float)x_dis/2. - (float)strlen(name)/2.0 - .2,
600 (float)y + (float)y_dis/2. - NAME_OFFSET);
601 break;
602 case NAND :
604 ps_print_nand(f, x, y, x_dis, y_dis,scale);
605 ps_put_label(f, name,
606 (float)x + (float)x_dis/2. - (float)strlen(name)/2.0 - .2,
607 (float)y + (float)y_dis/2. - NAME_OFFSET);
608 break;
609 case OR : ps_print_or(f, x, y, x_dis, y_dis);
610 ps_put_label(f, name,
611 (float)x + (float)x_dis/2. - (float)strlen(name)/2.0 - .2,
612 (float)y + (float)y_dis/2. - NAME_OFFSET);
613 break;
614 case NOR : ps_print_nor(f, x, y, x_dis, y_dis);
615 ps_put_label(f, name,
616 (float)x + (float)x_dis/2. - (float)strlen(name)/2.0 - .2,
617 (float)y + (float)y_dis/2. - NAME_OFFSET);
618 break;
619 case XOR : ps_print_xor(f, x, y, x_dis, y_dis);
620 ps_put_label(f, name,
621 (float)x + (float)x_dis/2. - (float)strlen(name)/2.0 - .2,
622 (float)y + (float)y_dis/2. - NAME_OFFSET);
623 break;
624 case XNOR :
625 ps_print_xnor(f, x, y, x_dis, y_dis);
626 ps_put_label(f, name,
627 (float)x + (float)x_dis/2. - (float)strlen(name)/2.0 - .2,
628 (float)y + (float)y_dis/2. - NAME_OFFSET);
629 break;
631 case INPUT_SYM :
632 ps_print_interm(f, x, y, x_dis, y_dis);
633 ps_put_label(f, name,
634 (float)x + (float)x_dis/2. - (float)strlen(name)/2.0 - 3.2,
635 (float)y + (float)y_dis/1.5 - NAME_OFFSET);
636 break;
637 case OUTPUT_SYM :
638 ps_print_outterm(f, x, y, x_dis, y_dis);
639 ps_put_label(f, name,
640 (float)x + (float)x_dis/2. - (float)strlen(name)/2.0 + .1,
641 (float)y + (float)y_dis/2. - NAME_OFFSET);
642 break;
644 case BLOCK :
645 ps_print_block(f, x, y, x_dis, y_dis, rot);
646 ps_put_label(f, name, (float)x + (float)x_dis/2. - 2.0,
647 (float)y + (float)y_dis/2. - NAME_OFFSET);
648 break;
650 default :ps_print_box(f, x, y, x_dis, y_dis, SIDE_CONVERT(rot));
651 ps_put_label(f, name, (float)x + (float)x_dis/2. - 2.0,
652 (float)y + (float)y_dis/2. - NAME_OFFSET);
654 return(0);
655 break;
657 return(1);
660 /*---------------------------------------------------------------------- */
662 int ps_put_label(f, str, x, y)
663 FILE *f;
664 char *str;
665 float x, y;
667 fprintf(f,"%f %f moveto (%s) show\n", x,y,str);
670 /*--------------------------------------------------------------------------------- */
672 int ps_put_int(f, i, x, y)
673 FILE *f;
674 int i;
675 float x, y;
677 fprintf(f,"%f %f moveto (%d) show\n", x,y,i);
681 /*----------------------------------------------------------------------- */
682 int ps_print_outterm(f, x, y, x_size, y_size)
683 FILE *f;
684 int x, y, x_size, y_size;
686 /* generate the ps code for an output terminal */
687 int mid_x = x + x_size/2;
688 int mid_y = y + y_size/2;
690 fprintf(f, "newpath %d %d moveto ", x - 1, mid_y);
691 fprintf(f, "%d %d rlineto ", x_size/2, 0);
692 fprintf(f, "%d %d rlineto ", -(x_size/2 - 1), y_size/2 - 2);
693 fprintf(f, " stroke\n");
694 fprintf(f, "%d %d moveto ", x - 1 + x_size/2, mid_y);
695 fprintf(f, "%d %d rlineto ", -(x_size/2 - 1), -(y_size/2 - 2));
696 fprintf(f, " stroke\n");
699 /*--------------------------------------------------------------------------------- */
700 int ps_print_interm(f, x, y, x_size, y_size)
701 FILE *f;
702 int x, y, x_size, y_size;
704 /* generate the ps code for an output terminal */
705 int mid_x = x + x_size/2;
706 int mid_y = y + y_size/2;
708 fprintf(f, "newpath %d %d moveto ", x + x_size + 1, mid_y);
709 fprintf(f, "%d %d rlineto ", -(x_size/2), 0);
710 fprintf(f, "%d %d rlineto ", -(x_size - 2), y_size/2 - 2);
711 fprintf(f, " stroke\n");
712 fprintf(f, "%d %d moveto ", x + 1 + x_size/2, mid_y);
713 fprintf(f, "%d %d rlineto ", -(x_size - 2), -(y_size/2 - 2));
714 fprintf(f, " stroke\n");
718 /*--------------------------------------------------------------------------------- */
719 int ps_print_block(f, x_pos, y_pos, x_size, y_size, rot)
720 FILE *f;
721 int x_pos, y_pos, x_size, y_size, rot;
723 ps_print_box(f, x_pos, y_pos, x_size, y_size, SIDE_CONVERT(rot));
726 /*--------------------------------------------------------------------------------- */
727 int ps_print_buffer(f, x, y, x_size, y_size)
728 FILE *f;
729 int x, y, x_size, y_size;
731 /* generate post-script code for a BUFFER_ gate to fit within the given box */
733 float mid_x = (float)x + (float)x_size/2.0;
734 float mid_y = (float)y + (float)(y_size/2);
735 float tip = mid_x - 2.25 + 4.330127; /* 2.55 * tan(60 deg) */
737 fprintf(f, "\n%%%% Buffer centered at %f %f w/ tip at %f... \n",
738 mid_x, mid_y, tip);
740 /* first put down the triangle: */
741 fprintf(f, "newpath %f %f moveto ", mid_x - 2.25, mid_y - BUFFER_SIZE/2.0);
742 fprintf(f, "%f %f lineto ", mid_x - 2.25, mid_y + BUFFER_SIZE/2.0);
743 fprintf(f, "%f %f lineto closepath stroke\n", tip, mid_y);
745 /* put down the terminal lines */
746 fprintf(f, "newpath %d %f moveto ", x + x_size + TERM_MARGIN, mid_y);
747 fprintf(f, "%f %f lineto closepath stroke\n", tip, mid_y);
748 fprintf(f, "newpath %f %f moveto ", mid_x - 2.25, mid_y);
749 fprintf(f, "%d %f lineto closepath stroke\n", x - TERM_MARGIN, mid_y);
751 return(1);
753 /*--------------------------------------------------------------------------------- */
754 int ps_print_inverted_not(f, x, y, x_size, y_size)
755 FILE *f;
756 int x, y, x_size, y_size;
758 /* generate post-script code for an inverted NOT gate to fit within the given box */
759 float mid_x = (float)x + (float)x_size/2.0;
760 float diam = 2 * CIRCLE_SIZE;
761 float base_x = mid_x - 2.25 + diam;
762 float mid_y = (float)y + (float)(y_size/2);
763 float tip = base_x + 4.330127; /* 4.330127 = 2.55 * tan(60 deg) */
765 fprintf(f, "\n%%%% Inverter centered at %f %f w/ tip at %f... \n",
766 mid_x, mid_y, tip);
768 /* first put down the triangle: */
769 fprintf(f, "newpath %f %f moveto ", base_x, mid_y - BUFFER_SIZE/2.0);
770 fprintf(f, "%f %f lineto ", base_x, mid_y + BUFFER_SIZE/2.0);
771 fprintf(f, "%f %f lineto closepath stroke\n", tip, mid_y);
773 /* now put down the little circle: */
774 fprintf(f, "newpath %f %f %f 0 360 arc closepath stroke\n",
775 base_x - CIRCLE_SIZE, mid_y, CIRCLE_SIZE);
777 /* put down the terminal line */
778 fprintf(f, "newpath %d %f moveto ", x + x_size + TERM_MARGIN, mid_y);
779 fprintf(f, "%f %f lineto closepath stroke\n", tip, mid_y);
780 fprintf(f, "newpath %f %f moveto ", base_x - diam, mid_y);
781 fprintf(f, "%d %f lineto closepath stroke\n", x - TERM_MARGIN, mid_y);
783 return(1);
785 /*--------------------------------------------------------------------------------- */
786 /*--------------------------------------------------------------------------------- */
787 int ps_print_not(f, x, y, x_size, y_size)
788 FILE *f;
789 int x, y, x_size, y_size;
791 /* generate post-script code for a NOT gate to fit within the given box */
792 float mid_x = (float)x + (float)x_size/2.0;
793 float mid_y = (float)y + (float)(y_size/2);
794 float tip = mid_x - 2.25 + 4.330127; /* 2.55 * tan(60 deg) */
796 fprintf(f, "\n%%%% Inverter centered at %f %f w/ tip at %f... \n",
797 mid_x, mid_y, tip);
799 /* first put down the triangle: */
800 fprintf(f, "newpath %f %f moveto ", mid_x - 2.25, mid_y - BUFFER_SIZE/2.0);
801 fprintf(f, "%f %f lineto ", mid_x - 2.25, mid_y + BUFFER_SIZE/2.0);
802 fprintf(f, "%f %f lineto closepath stroke\n", tip, mid_y);
804 /* now put down the little circle: */
805 fprintf(f, "newpath %f %f %f 0 360 arc closepath stroke\n",
806 tip + CIRCLE_SIZE, mid_y, CIRCLE_SIZE);
808 /* put down the terminal line */
809 fprintf(f, "newpath %d %f moveto ", x + x_size + TERM_MARGIN, mid_y);
810 fprintf(f, "%f %f lineto closepath stroke\n", tip + (2.0 * CIRCLE_SIZE), mid_y);
811 fprintf(f, "newpath %f %f moveto ", mid_x - 2.25, mid_y);
812 fprintf(f, "%d %f lineto closepath stroke\n", x - TERM_MARGIN, mid_y);
814 return(1);
816 /*--------------------------------------------------------------------------------- */
817 /*--------------------------------------------------------------------------------- */
818 int ps_print_and(f, x, y, x_size, y_size)
819 FILE *f;
820 int x, y, x_size, y_size;
822 /* generate postscript code for an AND gate within the given box: */
823 float mid_x = (float)x + (float)x_size/2.0;
824 float mid_y = (float)y + (float)y_size/2.0;
825 float scale = (float)x_size/(float)(ICON_SIZE * ICON_SIZE/2);
826 float rad = scale * 10.0;
828 /* first put down the figure: */
829 fprintf(f, "\n%%%% AND Gate centered at %f %f... \n", mid_x, mid_y);
831 /* Front Curve*/
832 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",
833 mid_x + (scale * 2.0), mid_y, rad, -90.081, 90.081);
835 /* Connecting Lines: */
836 fprintf(f, "newpath %f %f moveto %f %f lineto %f %f lineto %f %f lineto stroke\n ",
837 mid_x + scale * 2.0, mid_y + scale * 10,
838 mid_x - scale * 13.0, mid_y + scale * 10,
839 mid_x - scale * 13.0, mid_y - scale * 10,
840 mid_x + scale * 2.0, mid_y - scale * 10);
842 /* put down the terminal line */
843 fprintf(f, "newpath %f %f moveto ", mid_x + scale * 12.0, mid_y);
844 fprintf(f, "%d %f lineto stroke \n", x + x_size + TERM_MARGIN, mid_y);
846 return(1);
848 /*--------------------------------------------------------------------------------- */
849 int ps_print_nand(f, x, y, x_size, y_size)
850 FILE *f;
851 int x, y, x_size, y_size;
853 /* generate postscript code for a NAND gate within the given box: */
854 float mid_x = (float)x + (float)x_size/2.0;
855 float mid_y = (float)y + (float)y_size/2.0;
856 float scale = (float)x_size/(float)(ICON_SIZE * ICON_SIZE/2);
857 float rad = scale * 10.0;
859 /* first put down the figure: */
860 fprintf(f, "\n%%%% NAND Gate centered at %f %f... \n", mid_x, mid_y);
862 /* Front Curve */
863 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",
864 mid_x + (scale * 1.0), mid_y, rad, -90.081, 90.081);
866 /* Connecting Lines: */
867 fprintf(f, "newpath %f %f moveto %f %f lineto %f %f lineto %f %f lineto stroke\n ",
868 mid_x + scale * 1.0, mid_y + scale * 10,
869 mid_x - scale * 14.0, mid_y + scale * 10,
870 mid_x - scale * 14.0, mid_y - scale * 10,
871 mid_x + scale * 1.0, mid_y - scale * 10);
873 /* now put down the little circle: */
874 fprintf(f, "newpath ");
875 fprintf(f, "%f %f %f 0 360 arc closepath stroke\n",
876 mid_x + scale * 11.0 + CIRCLE_SIZE, mid_y, CIRCLE_SIZE);
878 /* put down the terminal line */
879 fprintf(f, "newpath %f %f moveto ",
880 mid_x + scale * 11.0 + (2.0 * CIRCLE_SIZE), mid_y);
881 fprintf(f, "%d %f lineto stroke \n", x + x_size + TERM_MARGIN, mid_y);
883 return(1);
885 /*--------------------------------------------------------------------------------- */
886 /*--------------------------------------------------------------------------------- */
887 int ps_print_nor(f, x, y, x_size, y_size)
888 FILE *f;
889 int x, y, x_size, y_size;
891 /* generate postscript code for a NOR gate within the given box: */
892 float mid_x = (float)x + (float)x_size/2.0 - 0.4;
893 float mid_y = (float)y + (float)y_size/2.0;
894 float scale = (float)x_size/(float)(ICON_SIZE * ICON_SIZE/2);
895 float rad = scale * 20.0;
897 /* first put down the figure: */
898 fprintf(f, "\n%%%% NOR Gate centered at %f %f... \n", mid_x, mid_y);
900 /* Top Curve ...newpath 383.167 283.167 195.877 91.219 29.291 arcn stroke */
901 fprintf(f, "newpath %f %f %f %f %f arcn stroke\n",mid_x - scale * 5.0,
902 mid_y - scale * 10.0, rad, 91.219, 29.219);
904 /* Bottom Curve: ...newpath 381.151 478.360 199.372 -90.618 -29.892 arc stroke */
905 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",mid_x - scale * 5.0,
906 mid_y + scale * 10.0, rad, -90.618, -29.892);
908 /* Back Curve: newpath 126.500 379.000 212.500 -31.072 31.072 arc stroke */
909 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",mid_x - scale * 29.0,
910 mid_y, rad, -28.072, 28.072);
912 /* Connecting Lines: */
913 fprintf(f, "newpath %f %f moveto %f %f lineto stroke\n ",
914 mid_x - scale * 12.3, mid_y + scale * 10,
915 mid_x - scale * 3.0, mid_y + scale * 10);
917 fprintf(f, "newpath %f %f moveto %f %f lineto stroke\n",
918 mid_x - scale * 12.3, mid_y - scale * 10,
919 mid_x - scale * 3.0, mid_y - scale * 10);
921 /* now put down the little circle: */
922 fprintf(f, "newpath ");
923 fprintf(f, "%f %f %f 0 360 arc closepath stroke\n",
924 mid_x + (scale * 13.50) + CIRCLE_SIZE, mid_y, CIRCLE_SIZE);
926 /* put down the terminal line */
927 fprintf(f, "newpath %f %f moveto ",
928 mid_x + (scale * 13.50) + (2 * CIRCLE_SIZE), mid_y);
929 fprintf(f, "%d %f lineto stroke \n", x + x_size + TERM_MARGIN, mid_y);
931 return(1);
933 /*--------------------------------------------------------------------------------- */
934 int ps_print_or(f, x, y, x_size, y_size)
935 FILE *f;
936 int x, y, x_size, y_size;
938 /* generate postscript code for an OR gate within the given box: */
939 float mid_x = (float)x + (float)x_size/2.0 - 0.4;
940 float mid_y = (float)y + (float)y_size/2.0;
941 float scale = (float)x_size/(float)(ICON_SIZE * ICON_SIZE/2);
942 float rad = scale * 20.0;
944 /* first put down the figure: */
945 fprintf(f, "\n%%%% OR Gate centered at %f %f... \n", mid_x, mid_y);
947 /* Top Curve ...newpath 383.167 283.167 195.877 91.219 29.291 arcn stroke */
948 fprintf(f, "newpath %f %f %f %f %f arcn stroke\n",mid_x - scale * 5.0,
949 mid_y - scale * 10.0, rad, 91.219, 29.219);
951 /* Bottom Curve: ...newpath 381.151 478.360 199.372 -90.618 -29.892 arc stroke */
952 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",
953 mid_x - scale * 5.0, mid_y + scale * 10.0, rad, -90.618, -29.892);
955 /* Back Curve: newpath 126.500 379.000 212.500 -31.072 31.072 arc stroke */
956 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",
957 mid_x - scale * 29.0, mid_y, rad, -28.072, 28.072);
959 /* Connecting Lines: */
960 fprintf(f, "newpath %f %f moveto %f %f lineto stroke\n ",
961 mid_x - scale * 12.3, mid_y + scale * 10,
962 mid_x - scale * 3.0, mid_y + scale * 10);
964 fprintf(f, "newpath %f %f moveto %f %f lineto stroke\n",
965 mid_x - scale * 12.3, mid_y - scale * 10,
966 mid_x - scale * 3.0, mid_y - scale * 10);
968 /* put down the terminal line */
969 fprintf(f, "newpath %f %f moveto %d %f lineto stroke\n",
970 mid_x + scale * 13.00, mid_y,
971 x + x_size + TERM_MARGIN, mid_y);
972 return(1);
974 /*--------------------------------------------------------------------------------- */
975 int ps_print_xnor(f, x, y, x_size, y_size)
976 FILE *f;
977 int x, y, x_size, y_size;
979 /* generate postscript code for a XNOR gate within the given box: */
980 float mid_x = (float)x + (float)x_size/2.0;
981 float mid_y = (float)y + (float)y_size/2.0;
982 float scale = (float)x_size/(float)(ICON_SIZE * ICON_SIZE/2);
983 float rad = scale * 20.0;
985 /* first put down the figure: */
986 fprintf(f, "\n%%%% XNOR Gate centered at %f %f... \n", mid_x, mid_y);
988 /* Top Curve */
989 fprintf(f, "newpath %f %f %f %f %f arcn stroke\n",mid_x - scale * 4.5,
990 mid_y - scale * 10.0, rad, 91.219, 29.219);
992 /* Bottom Curve */
993 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",mid_x - scale * 4.5,
994 mid_y + scale * 10.0, rad, -90.618, -29.892);
996 /* 1st Back Curve */
997 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",mid_x - scale * 28.5,
998 mid_y, rad, -28.072, 28.072);
1000 /* 2nd Back Curve */
1001 fprintf(f, "newpath %f %f %f %f %f arc stroke\n",mid_x - scale * 31.5,
1002 mid_y, rad, -28.072, 28.072);
1004 /* Connecting Lines: */
1005 fprintf(f, "newpath %f %f moveto %f %f lineto stroke\n ",
1006 mid_x - scale * 11.8, mid_y + scale * 10,
1007 mid_x - scale * 2.5, mid_y + scale * 10);
1009 fprintf(f, "newpath %f %f moveto %f %f lineto stroke\n",
1010 mid_x - scale * 11.8, mid_y - scale * 10,
1011 mid_x - scale * 2.5, mid_y - scale * 10);
1013 /* now put down the little circle: */
1014 fprintf(f, "newpath %f %f %f 0 360 arc closepath stroke\n",
1015 mid_x + (scale * 14.00) + CIRCLE_SIZE, mid_y, CIRCLE_SIZE);
1017 /* put down the terminal line */
1018 fprintf(f, "newpath %f %f moveto ",
1019 mid_x + (scale * 14.50) + (2.0 * CIRCLE_SIZE), mid_y);
1020 fprintf(f, "%d %f lineto stroke \n", x + x_size + TERM_MARGIN, mid_y);
1022 return(1);
1024 /*--------------------------------------------------------------------------------- */
1025 /*--------------------------------------------------------------------------------- */
1026 /*--------------------------------------------------------------------------------- */
1027 int ps_print_xor(f, x, y, x_size, y_size)
1028 FILE *f;
1029 int x, y, x_size, y_size;
1031 /* generate postscript code for a XOR gate within the given box: */
1032 float mid_x = (float)x + (float)x_size/2.0;
1033 float mid_y = (float)y + (float)y_size/2.0;
1034 float scale = (float)x_size/(float)(ICON_SIZE * ICON_SIZE/2);
1035 float rad = scale * 20.0;
1037 /* first put down the figure: */
1038 fprintf(f, "\n%%%% XOR Gate centered at %f %f... \n", mid_x, mid_y);
1040 /* Top Curve */
1041 fprintf(f, "newpath %f %f %f %f %f arcn stroke\n", mid_x - scale * 4.5,
1042 mid_y - scale * 10.0, rad, 91.219, 29.219);
1044 /* Bottom Curve: */
1045 fprintf(f, "newpath %f %f %f %f %f arc stroke\n", mid_x - scale * 4.5,
1046 mid_y + scale * 10.0, rad, -90.618, -29.892);
1048 /* 1st Back Curve: */
1049 fprintf(f, "newpath %f %f %f %f %f arc stroke\n", mid_x - scale * 28.5,
1050 mid_y, rad, -28.072, 28.072);
1052 /* 2nd Back Curve: */
1053 fprintf(f, "newpath %f %f %f %f %f arc stroke\n", mid_x - scale * 31.5,
1054 mid_y, rad, -28.072, 28.072);
1056 /* Connecting Lines: */
1057 fprintf(f, "newpath %f %f moveto %f %f lineto stroke\n ",
1058 mid_x - scale * 11.8, mid_y + scale * 10,
1059 mid_x - scale * 2.5, mid_y + scale * 10);
1061 fprintf(f, "newpath %f %f moveto %f %f lineto stroke\n",
1062 mid_x - scale * 11.8, mid_y - scale * 10,
1063 mid_x - scale * 2.5, mid_y - scale * 10);
1065 /* put down the terminal line */
1066 fprintf(f, "newpath %f %f moveto ", mid_x + scale * 14.0, mid_y);
1067 fprintf(f, "%d %f lineto stroke \n", x + x_size + TERM_MARGIN, mid_y);
1069 return(1);
1071 /*--------------------------------------------------------------------------------- */
1072 ps_print_standard_header(f)
1073 FILE *f;
1075 fprintf(f, "%s\n", HEADER);
1077 /*--------------------------------------------------------------------------------- */