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 Author: 1992 Stephen R. Whiteley
5 ****************************************************************************/
6
7 /*
8 * Hewlett-Packard Laserjet (and compatible) driver.
9 */
10
11 #include "spice.h"
12 #include "plotdev.h"
13
14 static FILE *plotfile;
15
16 struct hptext {
17 int x;
18 int y;
19 char *text;
20 struct hptext *next;
21 };
22
23 struct hplaser {
24 int bytpline;
25 int maxx;
26 int maxy;
27 char *base;
28 struct hptext *textlist;
29 unsigned char linestyle;
30 unsigned char linestyle_stored;
31 };
32
33 #define ror(x,n) ((x >> n) | (x << (8-n)))
34 #define swap(a,b) {int t=a; a=b; b=t;}
35
36 /* upper left of image in pcl coordinates */
37 #define OFFSETX 0
38 #define OFFSETY 90
39
40 /* dots per inch (75, 100, 150, 300) */
41 #define RESOL 150
42
43 int
HP_Init()44 HP_Init()
45
46 {
47 dispdev->numlinestyles = 1;
48 dispdev->numcolors = 2;
49
50 /* 8" X 10.5" drawable area */
51 dispdev->width = 8*RESOL;
52 dispdev->height = 10*RESOL + RESOL/2;
53 return (0);
54 }
55
56
57 int
HP_NewViewport(graph)58 HP_NewViewport(graph)
59
60 /* devdep initially contains name of output file */
61 GRAPH *graph;
62 {
63 struct hplaser *hp;
64 int bpline;
65
66 plotfile = fopen((char*)graph->devdep, "wb");
67 if (!plotfile) {
68 perror(graph->devdep);
69 graph->devdep = (char *) NULL;
70 return (1);
71 }
72 graph->devdep = tmalloc(sizeof(struct hplaser));
73 hp = (struct hplaser*)graph->devdep;
74
75 switch (graph->graphtype) {
76 default:
77 case GR_PLOT:
78 case GR_GRAF:
79 case GR_MPLT:
80 /* square plotting area */
81 graph->absolute.width = dispdev->width;
82 graph->absolute.height = dispdev->width;
83 break;
84 case GR_SCED:
85 /* full page plot */
86 graph->absolute.width = dispdev->width;
87 graph->absolute.height = dispdev->height;
88 break;
89 }
90 /* bytes per line */
91 bpline = (graph->absolute.width + 7)/8;
92
93 hp->base = malloc(graph->absolute.height*bpline);
94 if (hp->base == NULL) {
95 internalerror("Not enough memory for raster conversion");
96 return (1);
97 }
98 memset(hp->base,0,graph->absolute.height*bpline);
99
100 graph->fontwidth = 15;
101 graph->fontheight = 30;
102
103 hp->bytpline = bpline;
104 hp->maxx = graph->absolute.width - 1;
105 hp->maxy = graph->absolute.height - 1;
106 hp->linestyle = 0xff;
107 hp->linestyle_stored = 0xcc;
108 return (0);
109 }
110
111
112 int
HP_Close()113 HP_Close()
114
115 {
116 return (0);
117 }
118
119
120 int
HP_Halt()121 HP_Halt()
122
123 {
124 struct hplaser *hp = (struct hplaser *)currentgraph->devdep;
125 struct hptext *old;
126 char *buf, *rgen, *c;
127 int len, i;
128
129 /* dump the stuff */
130
131 /* reset printer
132 * top margin 10
133 * X cursor position OFFSETX
134 * Y cursor position OFFSETY
135 * resolution RESOL dpi
136 * start raster graphics at current position
137 */
138 fprintf(plotfile,
139 "\033E\033&l0E\033*p%dX\033*p%dY\033*t%dR\033*r1A",
140 OFFSETX,OFFSETY,RESOL);
141
142 buf = tmalloc(hp->bytpline+8);
143 sprintf(buf,"\033*b%dW",hp->bytpline);
144 len = strlen(buf);
145 c = buf + len;
146
147 rgen = hp->base;
148 for (i = 0; i <= hp->maxy; i++) {
149 memcpy(c,rgen,hp->bytpline);
150 rgen += hp->bytpline;
151
152 if (fwrite(buf,1,hp->bytpline+len,plotfile) != hp->bytpline+len) {
153 break;
154 }
155
156 }
157 /* end raster graphics */
158 fprintf(plotfile,"\033*rB");
159
160 /* now for the text */
161
162 while (hp->textlist) {
163 /* x position, y position, text */
164 fprintf(plotfile,"\033*p%dX\033*p%dY%s",
165 hp->textlist->x,hp->textlist->y,hp->textlist->text);
166 txfree(hp->textlist->text);
167 old = hp->textlist;
168 hp->textlist = hp->textlist->next;
169 txfree((char*)old);
170 }
171
172 /* form feed
173 * reset printer
174 */
175 fprintf(plotfile,"\033*rB\014\033E");
176
177 txfree(buf);
178 txfree(hp->base);
179 fclose(plotfile);
180 return (0);
181 }
182
183
184 int
HP_Pixel(x,y)185 HP_Pixel(x, y)
186
187 int x, y;
188 {
189 unsigned char c;
190 struct hplaser *hp = (struct hplaser *)currentgraph->devdep;
191
192 c = 0x80 >> (x & 7);
193 *(hp->base + ((x >> 3) + (hp->maxy-y)*hp->bytpline)) |= c;
194 return (0);
195 }
196
197
198 int
HP_Line(x1,y1,x2,y2)199 HP_Line(x1, y1, x2, y2)
200
201 int x1, y1, x2, y2;
202 {
203
204 struct hplaser *hp = (struct hplaser *)currentgraph->devdep;
205 int dx, dy, dy2, errterm = 0, next, lcnt;
206 char *rgen;
207 unsigned char cbuf, left, right;
208
209 if (x2 < x1) {
210 swap(x1,x2);
211 swap(y1,y2);
212 }
213 dx = x2 - x1;
214
215 next = hp->bytpline;
216 dy = y1 - y2;
217
218 lcnt = hp->maxy - y1;
219 rgen = hp->base + (x1 >> 3) + lcnt*next;
220 left = 0x80 >> ((lcnt+x1) & 7);
221 right = hp->linestyle;
222
223 if (y1 < y2) {
224 next = -next;
225 dy = -dy;
226 }
227 dy2 = dy;
228
229 cbuf = 0x80 >> (x1 & 7);
230
231 for (dy++; dy; dy--) {
232 errterm += dx;
233 if (errterm <= 0) {
234 if (left & right) *rgen |= cbuf;
235 rgen += next;
236 left = ror(left,1);
237 continue;
238 }
239 while (errterm > 0 && x1 != x2) {
240 if (left & right) *rgen |= cbuf;
241 left = ror(left,1);
242 cbuf = ror(cbuf,1);
243 if (cbuf & 0x80) rgen++;
244 x1++;
245 errterm -= dy2;
246 }
247 rgen += next;
248 left = ror(left,1);
249 }
250 return (0);
251 }
252
253
254 int
HP_Box(x1,y1,x2,y2)255 HP_Box(x1, y1, x2, y2)
256
257 int x1, y1, x2, y2;
258 {
259 HP_Line(x1,y1,x1,y2);
260 HP_Line(x1,y2,x2,y2);
261 HP_Line(x2,y2,x2,y1);
262 HP_Line(x2,y1,x1,y1);
263 return (0);
264 }
265
266
267 /* ARGSUSED */
268 int
HP_Arc(x0,y0,radius,theta1,theta2)269 HP_Arc(x0, y0, radius, theta1, theta2)
270
271 int x0, y0, radius;
272 double theta1, theta2;
273 {
274 return (0);
275 }
276
277
278 int
HP_Polygon(p)279 HP_Polygon(p)
280
281 POLYGON *p;
282 {
283 int i, n = 2*p->nvertices - 2;
284
285 for (i = 0; i < n; i += 2)
286 HP_Line(p->xy[i],p->xy[i+1],p->xy[i+2],p->xy[i+3]);
287
288 return (0);
289 }
290
291
292 int
HP_Text(text,x,y)293 HP_Text(text, x, y)
294
295 char *text;
296 int x, y;
297 {
298 struct hplaser *hp = (struct hplaser *)currentgraph->devdep;
299 struct hptext *hpt;
300
301 hpt = (struct hptext *)tmalloc(sizeof(struct hptext));
302 hpt->x = x*(300/RESOL) + OFFSETX;
303 hpt->y = (hp->maxy - y)*(300/RESOL) + OFFSETY;
304 hpt->text = copy(text);
305 hpt->next = hp->textlist;
306 hp->textlist = hpt;
307 return (0);
308 }
309
310
311 int
HP_DefineLinestyle(linestyleid,mask)312 HP_DefineLinestyle(linestyleid,mask)
313
314 int linestyleid, mask;
315 {
316 struct hplaser *hp = (struct hplaser *)currentgraph->devdep;
317
318 if (linestyleid) {
319 hp->linestyle_stored = mask;
320 hp->linestyle = mask;
321 }
322 }
323
324
325 int
HP_SetLinestyle(linestyleid)326 HP_SetLinestyle(linestyleid)
327
328 int linestyleid;
329 {
330 struct hplaser *hp = (struct hplaser *)currentgraph->devdep;
331
332 if (linestyleid)
333 hp->linestyle = hp->linestyle_stored;
334 else
335 hp->linestyle = 0xff;
336 return (0);
337 }
338