Jspice3
postsc.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1988 Jeffrey M. Hsu
5  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * Postscript driver
10  */
11 
12 #include "spice.h"
13 #include "plotdev.h"
14 
15 static FILE *plotfile;
16 
17 #define SOLID 0
18 static char *linestyle[] = {
19  "[]", /* solid */
20  "[1 2]", /* dotted */
21  "[7 7]", /* longdashed */
22  "[3 3]", /* shortdashed */
23  "[3 5 1 5]" }; /* dotdashed */
24 
25 typedef struct {
26  int lastlinestyle; /* initial invalid value */
27  int strokecnt; /* count line elements, avoid overflow */
28 } PSdevdep;
29 
30 #define DEVDEP(g) (*((PSdevdep *) (g)->devdep))
31 
32 static int Xoff, Yoff;
33 
34 /* line memory */
35 static int lastx ,lasty;
36 
37 
38 int
40 {
42  dispdev->numcolors = 2;
43 
44  /* 8" X 10.5" drawable area */
45  dispdev->width = 576; /* 8 * 72 */
46  dispdev->height = 756; /* 10.5 * 72 */
47 
48  return (0);
49 }
50 
51 
52 int
54 
55 /* devdep initially contains name of output file */
56 GRAPH *graph;
57 {
58 
59  plotfile = fopen((char*)graph->devdep, "w");
60 
61  if (!plotfile) {
62  perror(graph->devdep);
63  graph->devdep = (char *) NULL;
64  return (1);
65  }
66 
67  switch (graph->graphtype) {
68  default:
69  case GR_PLOT:
70  case GR_GRAF:
71  case GR_MPLT:
72  /* square plotting area */
73  graph->absolute.width = dispdev->width;
74  graph->absolute.height = dispdev->width;
75  Xoff = 18;
76  Yoff = 108;
77  break;
78  case GR_SCED:
79  /* full page plot */
80  graph->absolute.width = dispdev->width;
81  graph->absolute.height = dispdev->height;
82  Xoff = 18;
83  Yoff = 18;
84  break;
85  }
86 
87  /* start file off with a % */
88  fprintf(plotfile, "%%! nutmeg plot\n");
89 
90  /* reasonable values, used in gr_ for placement */
91  graph->fontwidth = 5;
92  graph->fontheight = 10;
93 
94  /* set up a reasonable font */
95  fprintf(plotfile, "/Helvetica findfont 10 scalefont setfont\n");
96 
97  graph->devdep = tmalloc(sizeof(PSdevdep));
98  DEVDEP(graph).lastlinestyle = -1;
99  DEVDEP(graph).strokecnt = 0;
100  graph->linestyle = -1;
101  lastx = -1;
102  lasty = -1;
103 
104  return (0);
105 }
106 
107 
108 int
110 
111 {
112  return (0);
113 }
114 
115 
116 int
118 {
119 
120  if (plotfile) {
121  if (DEVDEP(currentgraph).lastlinestyle != -1) {
122  /* haven't stroked last path */
123  fprintf(plotfile, "stroke\n");
124  }
125  fprintf(plotfile, "showpage\n");
126  fclose(plotfile);
127  }
128  return (0);
129 }
130 
131 
132 /* ARGSUSED */
133 int
134 PS_Pixel(x, y)
135 
136 int x, y;
137 {
138  int savedlstyle;
139 
140  savedlstyle = currentgraph->linestyle;
142  if (DEVDEP(currentgraph).strokecnt > 499) {
143  if (DEVDEP(currentgraph).lastlinestyle == -1)
144  fprintf(plotfile, "newpath\n");
145  else
146  fprintf(plotfile, "stroke\n");
147  DEVDEP(currentgraph).strokecnt = 0;
148  }
149  fprintf(plotfile, "%d %d moveto\n", x+Xoff, y+Yoff);
150  fprintf(plotfile, "%d %d lineto\n", x+Xoff, y+Yoff+1);
151  (DEVDEP(currentgraph).strokecnt)++;
152  PS_SetLinestyle(savedlstyle);
153  return (0);
154 }
155 
156 
157 int
158 PS_Line(x1, y1, x2, y2)
159 
160 int x1, y1, x2, y2;
161 {
162  /* clip out unchanged points */
163  if (x1 == x2 && y1 == y2 && x1 == lastx && y1 == lasty)
164  return (0);
165 
166  if (currentgraph->linestyle == -1)
168  if (DEVDEP(currentgraph).lastlinestyle != currentgraph->linestyle ||
169  DEVDEP(currentgraph).strokecnt > 499) {
170  if (DEVDEP(currentgraph).lastlinestyle == -1)
171  fprintf(plotfile, "newpath\n");
172  else
173  fprintf(plotfile, "stroke\n");
174  DEVDEP(currentgraph).strokecnt = 0;
175  }
176  if ((x1 != lastx) || (y1 != lasty) || !DEVDEP(currentgraph).strokecnt)
177  fprintf(plotfile, "%d %d moveto\n", x1+Xoff, y1+Yoff);
178  if ((x2 != x1) || (y2 != y1))
179  fprintf(plotfile, "%d %d lineto\n", x2+Xoff, y2+Yoff);
180 
181  /* validate cache */
182  lastx = x2;
183  lasty = y2;
184  DEVDEP(currentgraph).lastlinestyle = currentgraph->linestyle;
185  (DEVDEP(currentgraph).strokecnt)++;
186  return (0);
187 }
188 
189 
190 int
191 PS_Box(x1, y1, x2, y2)
192 int x1, y1, x2, y2;
193 {
194  PS_Line(x1,y1,x1,y2);
195  PS_Line(x1,y2,x2,y2);
196  PS_Line(x2,y2,x2,y1);
197  PS_Line(x2,y1,x1,y1);
198  return (0);
199 }
200 
201 
202 /* ARGSUSED */
203 int
204 PS_Arc(x0, y0, radius, theta1, theta2)
205 
206 int x0, y0, radius;
207 double theta1, theta2;
208 {
209  int a1, a2;
210 
211  if (theta1 >= theta2)
212  theta2 = 2 * M_PI + theta2;
213 
214  a1 = (180.0 / M_PI) * theta1;
215  a2 = (180.0 / M_PI) * theta2;
216 
217  if (currentgraph->linestyle == -1)
219  if (DEVDEP(currentgraph).strokecnt) {
220  fprintf(plotfile, "stroke\n");
221  DEVDEP(currentgraph).strokecnt = 0;
222  }
223  else if (DEVDEP(currentgraph).lastlinestyle == -1) {
224  fprintf(plotfile, "newpath\n");
225  DEVDEP(currentgraph).lastlinestyle = currentgraph->linestyle;
226  }
227 
228  fprintf(plotfile, "%d %d %d %d %d arc\n",
229  x0+Xoff,y0+Yoff,radius,a1,a2);
230  fprintf(plotfile, "stroke\n");
231  lastx = -1;
232  lasty = -1;
233  return (0);
234 }
235 
236 
237 int
239 POLYGON *p;
240 {
241  /* This is currently used only to print dots for sced. The
242  * polygon code below looks bad and causes errors if the dots
243  * are too small, thus we use the specialized routine below.
244  */
245 
246  int *xy, x, y, savedlstyle;
247 
248  xy = (int*)p->xy;
249  if (xy[0] == xy[8]) {
250  x = xy[0];
251  y = xy[5];
252  }
253  else {
254  x = xy[4];
255  y = xy[1];
256  }
257  if (DEVDEP(currentgraph).strokecnt) {
258  fprintf(plotfile, "stroke\n");
259  DEVDEP(currentgraph).strokecnt = 0;
260  }
261  savedlstyle = currentgraph->linestyle;
263  fprintf(plotfile,"%d %d moveto\n",x+1+Xoff,y+Yoff);
264  fprintf(plotfile,"%d %d 3 0 359 arc closepath fill\n",x+Xoff,y+Yoff);
265  PS_SetLinestyle(savedlstyle);
266  lastx = -1;
267  lasty = -1;
268  return (0);
269 
270 
271 /*
272  int *xy, nvert, savedlstyle;
273 
274  xy = (int*)p->xy;
275  nvert = p->nvertices;
276  savedlstyle = currentgraph->linestyle;
277  PS_SetLinestyle(SOLID);
278 
279  fprintf(plotfile, "%d %d moveto ", *xy+Xoff, *(xy+1)+Yoff);
280  xy += 2;
281  nvert--;
282  while (nvert--) {
283  fprintf(plotfile, "%d %d lineto\n", *xy+Xoff, *(xy+1)+Yoff);
284  xy += 2;
285  }
286  fprintf(plotfile,"closepath\nfill\n");
287  PS_SetLinestyle(savedlstyle);
288  return (0);
289 */
290 }
291 
292 
293 int
294 PS_Text(text, x, y)
295 
296 char *text;
297 int x, y;
298 {
299 
300  int savedlstyle;
301  char tbuf[BSIZE_SP], *s;
302 
303  if (text == NULL)
304  return (0);
305 
306  s = tbuf;
307  while (*text) {
308  if (*text == '(' || *text == ')' || *text == '\\')
309  *s++ = '\\';
310  *s++ = *text++;
311  }
312  *s = '\0';
313 
314  if (DEVDEP(currentgraph).strokecnt) {
315  fprintf(plotfile, "stroke\n");
316  DEVDEP(currentgraph).strokecnt = 0;
317  }
318  /* set linestyle to solid
319  * or may get funny color text on some plotters
320  */
321  savedlstyle = currentgraph->linestyle;
323 
324  /* move to (x, y) */
325  fprintf(plotfile, "%d %d moveto\n", x+Xoff, y+Yoff);
326  fprintf(plotfile, "(%s) show\n", tbuf);
327 
328  /* restore old linestyle */
329  PS_SetLinestyle(savedlstyle);
330  lastx = -1;
331  lasty = -1;
332  return (0);
333 }
334 
335 
336 int
337 PS_SetLinestyle(linestyleid)
338 
339 int linestyleid;
340 {
341 
342  /* special case
343  get it when PS_Text restores a -1 linestyle */
344  if (linestyleid == -1) {
345  currentgraph->linestyle = -1;
346  return (0);
347  }
348 
349  if (linestyleid < 0) {
350  internalerror("bad linestyleid");
351  return (0);
352  }
353 
354  if (linestyleid > dispdev->numlinestyles)
355  linestyleid = (linestyleid % dispdev->numlinestyles) + 1;
356 
357  if (currentgraph->linestyle != linestyleid) {
358  if (DEVDEP(currentgraph).strokecnt) {
359  fprintf(plotfile, "stroke\n");
360  DEVDEP(currentgraph).strokecnt = 0;
361  lastx = -1;
362  lasty = -1;
363  }
364  fprintf(plotfile, "%s 0 setdash\n", linestyle[linestyleid]);
365  currentgraph->linestyle = linestyleid;
366  }
367  return (0);
368 }
369 
370 
371 /* ARGSUSED */
372 int
373 PS_SetColor(colorid)
374 {
375  /* do nothing */
376  return (0);
377 }
378 
379 
380 int
382 
383 {
384  fflush(plotfile);
385  return (0);
386 }
387 
388 
389 /* transformed text for sced hardcopy */
390 
391 int
392 PS_ScaledText(text,x,y,Xform)
393 
394 char *text;
395 int x, y, Xform;
396 {
397  /* Xform code:
398  * 0x8: mirror x
399  * 0x4: mirror y
400  * 0x3: 0-no rotation, 1-90, 2-180, 3-270
401  */
402  int savedlstyle, deg;
403  char tbuf[BSIZE_SP], *s;
404 
405  if (text == NULL)
406  return (0);
407 
408  if (Xform == (char)0) {
409  PS_Text(text,x,y);
410  return (0);
411  }
412 
413  s = tbuf;
414  while (*text) {
415  if (*text == '(' || *text == ')' || *text == '\\')
416  *s++ = '\\';
417  *s++ = *text++;
418  }
419  *s = '\0';
420 
421  if (DEVDEP(currentgraph).strokecnt) {
422  fprintf(plotfile, "stroke\n");
423  DEVDEP(currentgraph).strokecnt = 0;
424  }
425 
426  /* set linestyle to solid
427  * or may get funny color text on some plotters
428  */
429  savedlstyle = currentgraph->linestyle;
431 
432  fprintf(plotfile,"gsave\n");
433  fprintf(plotfile,"%d %d translate\n",x+Xoff,y+Yoff);
434  if (Xform & 12)
435  fprintf(plotfile,"%d %d scale\n",
436  (Xform & 8) ? -1 : 1, (Xform & 4) ? -1 : 1);
437  deg = (Xform & 3) * 90;
438  if (deg)
439  fprintf(plotfile,"%d rotate\n",deg);
440  fprintf(plotfile,"0 0 moveto\n");
441  fprintf(plotfile,"(%s) show\n",tbuf);
442  fprintf(plotfile,"grestore\n");
443 
444  /* restore old linestyle */
445  PS_SetLinestyle(savedlstyle);
446  lastx = -1;
447  lasty = -1;
448  return (0);
449 }
#define BSIZE_SP
Definition: misc.h:19
#define DEVDEP(g)
Definition: postsc.c:30
static int Xoff
Definition: postsc.c:32
Definition: cddefs.h:119
if(TDesc==NULL)
Definition: cd.c:1326
int numlinestyles
Definition: plotdev.h:67
int PS_Pixel(int x, int y)
Definition: postsc.c:134
internalerror(char *message)
Definition: error.c:91
DISPDEVICE * dispdev
Definition: display.c:112
#define M_PI
Definition: spice.h:132
static char * linestyle[]
Definition: postsc.c:18
int lastlinestyle
Definition: postsc.c:26
int PS_Polygon(POLYGON *p)
Definition: postsc.c:238
static int lastx
Definition: postsc.c:35
int PS_NewViewport(GRAPH *graph)
Definition: postsc.c:53
static int lasty
Definition: postsc.c:35
Definition: cddefs.h:215
Definition: plotdev.h:14
#define SOLID
Definition: postsc.c:17
#define GR_SCED
Definition: ftegraph.h:23
int PS_Box(int x1, int y1, int x2, int y2)
Definition: postsc.c:191
char * tmalloc()
int PS_SetLinestyle(int linestyleid)
Definition: postsc.c:337
#define NULL
Definition: spdefs.h:121
int PS_Line(int x1, int y1, int x2, int y2)
Definition: postsc.c:158
int PS_Halt()
Definition: postsc.c:117
Definition: ftegraph.h:29
void perror()
int PS_Close()
Definition: postsc.c:109
int PS_Init()
Definition: postsc.c:39
static int Yoff
Definition: postsc.c:32
int strokecnt
Definition: postsc.c:27
int height
Definition: plotdev.h:66
int numcolors
Definition: plotdev.h:67
int PS_Update()
Definition: postsc.c:381
int PS_ScaledText(char *text, int x, int y, int Xform)
Definition: postsc.c:392
#define GR_PLOT
Definition: ftegraph.h:20
int linestyle
Definition: ftegraph.h:42
#define GR_MPLT
Definition: ftegraph.h:22
int width
Definition: plotdev.h:66
GRAPH * currentgraph
Definition: graphdb.c:21
int PS_SetColor(colorid)
Definition: postsc.c:373
int PS_Text(char *text, int x, int y)
Definition: postsc.c:294
static FILE * plotfile
Definition: postsc.c:15
int PS_Arc(int x0, int y0, int radius, double theta1, double theta2)
Definition: postsc.c:204
#define GR_GRAF
Definition: ftegraph.h:21