1 /**********
2 Author: Jim Groves
3 **********/
4
5 /*
6 HPGL driver
7 */
8
9 /*
10 1000 plotter units / inch - 1pu = 0.025mm 1pu = 1mil
11
12 SP - select pen
13 PU - pen up (PU x,y)
14 PD - pen down (PD x,y)
15 LT - line type
16 0 dots only at plotted points
17 1 . . . . .
18 2 ___ ___ ___ ___
19 3 ---- ---- ---- ----
20 4 ----- . ----- . ----- . -----.
21 5 ---- - ---- - ---- -
22 6 --- - - --- - - --- - - --- - -
23 null - solid line
24 IN - initialize
25 DF - default values (PA, solid line, set 0)
26 PA - plot absolute
27 SI - absolute character size (SI width, height) in cm
28
29 */
30
31 #include "ngspice/ngspice.h"
32 #include "ngspice/cpdefs.h"
33 #include "ngspice/graph.h"
34 #include "ngspice/ftedbgra.h"
35 #include "ngspice/ftedev.h"
36 #include "ngspice/fteinput.h"
37 #include "ngspice/fteext.h"
38 #include "variable.h"
39 #include "plotting/graphdb.h"
40 #include "hpgl.h"
41
42 #define RAD_TO_DEG (180.0 / M_PI)
43 #define DEVDEP(g) (*((GLdevdep *) (g)->devdep))
44 #define MAX_GL_LINES 9999
45 #define SOLID 0
46 #define DOTTED 1
47
48 #define gtype graph->grid.gridtype
49 #define xoff dispdev->minx
50 #define yoff dispdev->miny
51 #define XOFF 25 /* printer left margin */
52 #define YOFF 28 /* printer bottom margin */
53 #define XTADJ 0 /* printer text adjustment x */
54 #define YTADJ 0 /* printer text adjustment y */
55
56 #define DELXMAX 360 /* printer gridsize divisible by 10, [7-2] */
57 #define DELYMAX 360 /* printer gridsize divisible by [10-8], [6-2] */
58
59 #define FONTWIDTH 6 /* printer default fontwidth */
60 #define FONTHEIGHT 8 /* printer default fontheight */
61
62 typedef struct {
63 int lastlinestyle; /* initial invalid value */
64 int lastx, lasty, linecount;
65 } GLdevdep;
66
67 static char *linestyle[] = {
68 "", /* solid */
69 "1", /* was 1 - dotted */
70 "", /* longdashed */
71 "3", /* shortdashed */
72 "4", /* longdotdashed */
73 "5", /* shortdotdashed */
74 "1"
75 };
76
77 static FILE *plotfile;
78 extern char psscale[32];
79 static int fontwidth = FONTWIDTH;
80 static int fontheight = FONTHEIGHT;
81 static int jgmult = 10;
82 static int screenflag = 0;
83 static double tocm = 0.0025;
84 static double scale; /* Used for fine tuning */
85 static int hcopygraphid;
86
87
GL_Init(void)88 int GL_Init(void)
89 {
90 if (!cp_getvar("hcopyscale", CP_STRING, psscale, sizeof(psscale))) {
91 scale = 1.0;
92 }
93 else {
94 sscanf(psscale, "%lf", &scale);
95 if ((scale <= 0) || (scale > 10))
96 scale = 1.0;
97 }
98
99 dispdev->numlinestyles = NUMELEMS(linestyle);
100 dispdev->numcolors = 6;
101
102 dispdev->width = (int)(DELXMAX * scale);
103 dispdev->height = (int)(DELYMAX * scale);
104
105
106 screenflag = 0;
107 dispdev->minx = (int)(XOFF * 1.0);
108 dispdev->miny = (int)(YOFF * 1.0);
109
110 return 0;
111 }
112
113
114 /* devdep initially contains name of output file */
GL_NewViewport(GRAPH * graph)115 int GL_NewViewport(GRAPH *graph)
116 {
117 hcopygraphid = graph->graphid;
118
119 if ((plotfile = fopen((char*) graph->devdep, "w")) == NULL) {
120 perror((char *) graph->devdep);
121 free(graph->devdep);
122 graph->devdep = NULL;
123 graph->n_byte_devdep = 0;
124 return 1;
125 }
126
127 if (graph->absolute.width) {
128 /* hardcopying from the screen */
129
130 screenflag = 1;
131
132 /* scale to fit on 8 1/2 square */
133
134 }
135
136 /* reasonable values, used in gr_ for placement */
137 graph->fontwidth = (int)(fontwidth * scale); /* was 12, p.w.h. */
138 graph->fontheight = (int)(fontheight * scale); /* was 24, p.w.h. */
139
140 graph->absolute.width = dispdev->width;
141 graph->absolute.height = dispdev->height;
142 /* Also done in gr_init, if called . . . */
143 graph->viewportxoff = 16 * fontwidth;
144 graph->viewportyoff = 8 * fontheight;
145
146 xoff = XOFF;
147 yoff = YOFF;
148
149 /* start file off with a % */
150 fprintf(plotfile, "IN;DF;PA;");
151 fprintf(plotfile, "SI %f,%f;",
152 tocm * jgmult * fontwidth * scale,
153 tocm * jgmult * fontheight * scale);
154
155 #ifdef notdef
156 if (!screenflag)
157 #endif
158 {
159 graph->devdep = TMALLOC(GLdevdep, 1);
160 graph->n_byte_devdep = sizeof(GLdevdep);
161 }
162
163 DEVDEP(graph).lastlinestyle = -1;
164 DEVDEP(graph).lastx = -1;
165 DEVDEP(graph).lasty = -1;
166 DEVDEP(graph).linecount = 0;
167 graph->linestyle = -1;
168
169 return 0;
170 }
171
172
GL_Close(void)173 int GL_Close(void)
174 {
175 /* in case GL_Close is called as part of an abort,
176 w/o having reached GL_NewViewport */
177 if (plotfile) {
178 if (DEVDEP(currentgraph).lastlinestyle != -1) {
179 DEVDEP(currentgraph).linecount = 0;
180 }
181 fclose(plotfile);
182 plotfile = NULL;
183 }
184 /* In case of hardcopy command destroy the hardcopy graph
185 * and reset currentgraph to graphid 1, if possible
186 */
187 if (!screenflag) {
188 DestroyGraph(hcopygraphid);
189 currentgraph = FindGraph(1);
190 }
191
192 return 0;
193 }
194
195
GL_Clear(void)196 int GL_Clear(void)
197 {
198 /* do nothing */
199
200 return 0;
201 }
202
203
204 int
GL_DrawLine(int x1,int y1,int x2,int y2,bool isgrid)205 GL_DrawLine(int x1, int y1, int x2, int y2, bool isgrid)
206 {
207 NG_IGNORE(isgrid);
208 /* note: this is not extendible to more than one graph
209 => will have to give NewViewport a writeable graph XXX */
210
211
212 if (DEVDEP(currentgraph).linecount == 0
213 || x1 != DEVDEP(currentgraph).lastx
214 || y1 != DEVDEP(currentgraph).lasty) {
215 fprintf(plotfile, "PU;PA %d , %d ;",
216 jgmult * (x1 + xoff), jgmult * (y1 + yoff));
217 }
218 if (x1 != x2 || y1 != y2) {
219 fprintf(plotfile, "PD;PA %d , %d ;",
220 jgmult * (x2 + xoff), jgmult * (y2 + yoff));
221 DEVDEP(currentgraph).linecount += 1;
222 }
223
224 DEVDEP(currentgraph).lastx = x2;
225 DEVDEP(currentgraph).lasty = y2;
226 DEVDEP(currentgraph).lastlinestyle = currentgraph->linestyle;
227
228 return 0;
229 }
230
231
232 /* ARGSUSED */
GL_Arc(int x0,int y0,int r,double theta,double delta_theta)233 int GL_Arc(int x0, int y0, int r, double theta, double delta_theta)
234 {
235 int x1, y1, angle;
236
237 x1 = x0 + (int)(r * cos(theta));
238 y1 = y0 + (int)(r * sin(theta));
239
240 angle = (int)(RAD_TO_DEG * delta_theta);
241
242 fprintf(plotfile, "PU;PA %d , %d;",
243 jgmult * (x1 + xoff + XTADJ), jgmult * (y1 + yoff + YTADJ));
244 fprintf(plotfile, "PD;AA %d , %d, %d;",
245 jgmult * (x0 + xoff + XTADJ), jgmult*(y0 + yoff + YTADJ), angle);
246
247 DEVDEP(currentgraph).linecount = 0;
248
249 return 0;
250 }
251
252
GL_Text(const char * text,int x,int y,int angle)253 int GL_Text(const char *text, int x, int y, int angle)
254 {
255 NG_IGNORE(angle);
256
257 /* move to (x, y) */
258 NG_IGNORE(angle);
259
260 fprintf(plotfile, "PU;PA %d , %d;",
261 jgmult * (x + xoff + XTADJ), jgmult * (y + yoff + YTADJ));
262 fprintf(plotfile, "LB %s \x03", text);
263
264 DEVDEP(currentgraph).lastx = -1;
265 DEVDEP(currentgraph).lasty = -1;
266
267 return 0;
268 }
269
270
GL_SetLinestyle(int linestyleid)271 int GL_SetLinestyle(int linestyleid)
272 {
273 /* special case
274 get it when GL_Text restores a -1 linestyle */
275 if (linestyleid == -1) {
276 currentgraph->linestyle = -1;
277 return 0;
278 }
279
280 if (linestyleid < 0 || linestyleid > dispdev->numlinestyles) {
281 internalerror("bad linestyleid");
282 return 0;
283 }
284
285 if (currentgraph->linestyle != linestyleid) {
286 fprintf(plotfile, "LT %s ;", linestyle[linestyleid]);
287 currentgraph->linestyle = linestyleid;
288 }
289
290 return 0;
291 }
292
293
GL_SetColor(int colorid)294 int GL_SetColor(int colorid)
295 {
296 fprintf(plotfile, "SP %d;", colorid);
297
298 return 0;
299 }
300
301
GL_Update(void)302 int GL_Update(void)
303 {
304 fflush(plotfile);
305
306 return 0;
307 }
308