grolbp output device
[s-roff.git] / src / devices / grolbp / lbp.h
blob332d0a436b187f1dfe8eaded5799c9d30cf3b560
2 // -*- C -*-
3 /* Copyright (C) 1994 Free Software Foundation, Inc.
4 Written by Francisco Andrés Verdú <pandres@dragonet.es>
6 groff is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
11 groff is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License along
17 with groff; see the file COPYING. If not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 /* This file contains a set of utility functions to use canon CAPSL printers
21 * (lbp-4 and lbp-8 series printers) */
23 #ifndef LBP_H
24 #define LBP_H
26 #include <stdio.h>
27 #include <stdarg.h>
29 static FILE *lbpoutput = NULL;
30 static FILE *vdmoutput = NULL;
32 static inline void
33 lbpinit(FILE *outfile)
35 lbpoutput = outfile;
39 static inline void
40 lbpprintf(char *format, ... )
41 { /* Taken from cjet */
42 va_list stuff;
44 va_start(stuff, format);
45 vfprintf(lbpoutput, format, stuff);
46 va_end(stuff);
49 static inline void
50 lbpputs(char *data)
52 fputs(data,lbpoutput);
55 static inline void
56 lbpputc(char c)
58 fputc(c,lbpoutput);
62 static inline void
63 lbpsavestatus(int index )
65 fprintf(lbpoutput,"\033[%d%%y",index);
68 static inline void
69 lbprestorestatus(int index )
71 fprintf(lbpoutput,"\033[%d%cz",index ,'%');
74 static inline void
75 lbpsavepos(int index)
77 fprintf(lbpoutput,"\033[1;%d;0x",index);
80 static inline void
81 lbprestorepos(int index)
83 fprintf(lbpoutput,"\033[0;%d;0x",index);
86 static inline void
87 lbprestoreposx(int index)
89 fprintf(lbpoutput,"\033[0;%d;1x",index);
92 static inline void
93 lbpmoverel(int despl, char direction)
95 fprintf(lbpoutput,"\033[%d%c",despl,direction);
98 static inline void
99 lbplinerel(int width,int despl,char direction )
101 fprintf(lbpoutput,"\033[%d;0;9{\033[%d%c\033[9}",width,despl,direction);
104 static inline void
105 lbpmoveabs(int x, int y)
107 fprintf(lbpoutput,"\033[%d;%df",y,x);
110 static inline void
111 lbplineto(int x,int y, int width )
113 fprintf(lbpoutput,"\033[%d;0;9{",width);
114 lbpmoveabs(x,y);
115 fprintf(lbpoutput,"\033[9}\n");
118 static inline void
119 lbpruleabs(int x, int y, int hsize, int vsize)
121 lbpmoveabs(x,y);
122 fprintf(lbpoutput,"\033[0;9;000s");
123 lbpmoveabs(x+hsize,y+vsize);
124 fprintf(lbpoutput,"\033[9r");
127 static inline void vdmprintf(char *format, ... );
129 static inline char *
130 vdmnum(int num,char *result)
132 char b1,b2,b3;
133 char *p = result;
134 int nm;
136 nm = abs(num);
137 /* First byte 1024 - 32768 */
138 b1 = ((nm >> 10) & 0x3F);
139 if (b1) *p++ = b1 | 0x40;
141 /* Second Byte 16 - 1024 */
142 b2 = ((nm >> 4) & 0x3F);
143 if ( b1 || b2) *p++= b2 | 0x40;
145 /* Third byte 0 - 15 */
146 b3 = ((nm & 0x0F) | 32);
147 if (num >= 0) b3 |= 16;
148 *p++ = b3;
149 *p = 0x00; /* End of the resulting string */
150 return result;
153 static inline void
154 vdmorigin(int newx, int newy)
156 char nx[4],ny[4];
158 vdmprintf("}\"%s%s\x1e",vdmnum(newx,nx),vdmnum(newy,ny));
159 }; /* vdmorigin */
162 static inline FILE *
163 vdminit(FILE *vdmfile)
165 char scale[4],size[4],lineend[4];
167 /* vdmoutput = tmpfile();*/
168 vdmoutput = vdmfile;
169 /* Initialize the VDM mode */
170 vdmprintf("\033[0&}#GROLBP\x1e!0%s%s\x1e$\x1e}F%s\x1e",\
171 vdmnum(-3,scale),vdmnum(1,size),vdmnum(1,lineend));
172 return vdmoutput;
176 static inline void
177 vdmend()
179 vdmprintf("}p\x1e");
182 static inline void
183 vdmprintf(char *format, ... )
184 { /* Taken from cjet */
185 va_list stuff;
187 if (vdmoutput == NULL) vdminit(tmpfile());
188 va_start(stuff, format);
189 vfprintf(vdmoutput, format, stuff);
190 va_end(stuff);
193 static inline void
194 vdmsetfillmode(int pattern,int perimeter, int inverted)
196 char patt[4],perim[4],
197 rot[4], /* rotation */
198 espejo[4], /* espejo */
199 inv[4]; /* Inverted */
201 vdmprintf("I%s%s%s%s%s\x1e",vdmnum(pattern,patt),\
202 vdmnum(perimeter,perim),vdmnum(0,rot),
203 vdmnum(0,espejo),vdmnum(inverted,inv));
206 static inline void
207 vdmcircle(int centerx, int centery, int radius)
209 char x[4],y[4],rad[4];
211 vdmprintf("5%s%s%s\x1e",vdmnum(centerx,x),vdmnum(centery,y),\
212 vdmnum(radius,rad));
215 static inline void
216 vdmaarc(int centerx, int centery, int radius,int startangle,int angle,int style,int arcopen)
218 char x[4],y[4],rad[4],stx[4],sty[4],styl[4],op[4];
220 vdmprintf("}6%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
221 vdmnum(centerx,x),vdmnum(centery,y),\
222 vdmnum(radius,rad),vdmnum(startangle,stx),vdmnum(angle,sty),\
223 vdmnum(style,styl));
226 static inline void
227 vdmvarc(int centerx, int centery,int radius, int startx, int starty, int endx, int endy,\
228 int style,int arcopen)
230 char x[4],y[4],rad[4],stx[4],sty[4],enx[4],eny[4],styl[4],op[4];
232 vdmprintf("}6%s%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
233 vdmnum(centerx,x),vdmnum(centery,y),\
234 vdmnum(radius,rad),vdmnum(startx,stx),vdmnum(starty,sty),\
235 vdmnum(endx,enx),vdmnum(endy,eny),vdmnum(style,styl));
238 static inline void
239 vdmellipse(int centerx, int centery, int radiusx, int radiusy,int rotation)
241 char x[4],y[4],radx[4],rady[4],rotat[4];
243 vdmprintf("}7%s%s%s%s%s\x1e\n",vdmnum(centerx,x),vdmnum(centery,y),\
244 vdmnum(radiusx,radx),vdmnum(radiusy,rady),\
245 vdmnum(rotation,rotat));
248 static inline void
249 vdmsetlinetype(int lintype)
251 char ltyp[4], expfact[4];
253 vdmprintf("E1%s%s\x1e",vdmnum(lintype,ltyp),vdmnum(1,expfact));
257 static inline void
258 vdmsetlinestyle(int lintype, int pattern,int unionstyle)
260 char patt[4],ltip[4],
261 rot[4], /* rotation */
262 espejo[4], /* espejo */
263 in[4]; /* Inverted */
265 vdmprintf("}G%s%s%s%s%s\x1e",vdmnum(lintype,ltip),\
266 vdmnum(pattern,patt),vdmnum(0,rot),
267 vdmnum(0,espejo),vdmnum(0,in));
268 vdmprintf("}F%s",vdmnum(unionstyle,rot));
271 static inline void
272 vdmlinewidth(int width)
274 char wh[4];
276 vdmprintf("F1%s\x1e",vdmnum(width,wh));
279 static inline void
280 vdmrectangle(int origx, int origy,int dstx, int dsty)
282 char xcoord[4],ycoord[4],sdstx[4],sdsty[4];
284 vdmprintf("}:%s%s%s%s\x1e\n",vdmnum(origx,xcoord),vdmnum(dstx,sdstx),\
285 vdmnum(origy,ycoord),vdmnum(dsty,sdsty));
286 }; /* polyline */
288 static inline void
289 vdmpolyline(int numpoints, int *points)
291 int i,*p = points;
292 char xcoord[4],ycoord[4];
294 if (numpoints < 2) return;
295 vdmprintf("1%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
296 p += 2;
297 for (i = 1; i < numpoints ; i++) {
298 vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
299 p += 2;
300 }; /* for */
301 vdmprintf("\x1e\n");
302 }; /* polyline */
304 static inline void
305 vdmpolygon(int numpoints, int *points)
307 int i,*p = points;
308 char xcoord[4],ycoord[4];
310 if (numpoints < 2) return;
311 vdmprintf("2%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
312 p += 2;
313 for (i = 1; i < numpoints ; i++) {
314 vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
315 p += 2;
316 }; /* for */
317 vdmprintf("\x1e\n");
319 }; /* vdmpolygon */
322 /************************************************************************
323 * Highter level auxiliary functions *
324 ************************************************************************/
325 static inline int
326 vdminited()
328 return (vdmoutput != NULL);
329 }; /* vdminited */
332 static inline void
333 vdmline(int startx, int starty, int sizex, int sizey)
335 int points[4];
337 points[0] = startx;
338 points[1] = starty;
339 points[2] = sizex;
340 points[3] = sizey;
342 vdmpolyline(2,points);
346 /*#define THRESHOLD .05 */ /* inch */
347 #define THRESHOLD 1 /* points (1/300 inch) */
348 static inline void
349 splinerel(double px,double py,int flush)
351 static int lx = 0 ,ly = 0;
352 static float pend = 0.0;
353 static int dx = 0,dy = 0, despx = 0, despy = 0, sigpend = 0;
354 int dxnew ,dynew, sg;
355 char xcoord[4],ycoord[4];
356 float npend ;
358 if (flush == -1) {lx = (int)px; ly = (int)py; return;};
360 if (flush == 0) {
361 dxnew = (int)px -lx;
362 dynew = (int)py -ly;
363 if ((dxnew == 0) && (dynew == 0)) return;
364 sg = (dxnew < 0)? -1 : 0;
365 /* fprintf(stderr,"s (%d,%d) (%d,%d)\n",dxnew,dynew,despx,despy);*/
366 if (dynew == 0) {
367 despx = dxnew;
368 if ((sg == sigpend) && (dy == 0)){
369 return;
371 dy = 0;
373 else {
374 dy = 1;
375 npend = (1.0*dxnew)/dynew;
376 if (( npend == pend) && (sigpend == sg))
377 { despy = dynew; despx = dxnew; return; }
378 else
379 { sigpend = sg;
380 pend = npend;
381 }; /* else (( npend == pend) && ... */
382 }; /* else (if (dynew == 0)) */
383 }; /* if (!flush ) */
385 /* if we've changed direction we must draw the line */
386 /* fprintf(stderr," (%d) %.2f,%.2f\n",flush,(float)px,(float)py);*/
387 if ((despx != 0) || (despy != 0)) vdmprintf("%s%s",vdmnum(despx,xcoord),\
388 vdmnum(despy,ycoord));
389 /*if ((despx != 0) || (despy != 0)) fprintf(stderr,"2
390 *%d,%d\n",despx,despy);*/
391 if (flush) {
392 dx = dxnew = dy = despx = despy = 0;
393 return;
394 }; /* if (flush) */
395 dxnew -= despx;
396 dynew -= despy;
397 if ((dxnew != 0) || (dynew != 0)) vdmprintf("%s%s",vdmnum(dxnew,xcoord),\
398 vdmnum(dynew,ycoord));
400 /* if ((dxnew != 0) || (dynew != 0)) fprintf(stderr,"3
401 * %d,%d\n",dxnew,dynew);*/
402 lx = (int)px; ly = (int)py;
403 dx = dxnew = dy = despx = despy = 0;
405 }; /* splinerel */
407 /**********************************************************************
408 * The following code to draw splines is adapted from the transfig package
410 static void
411 quadratic_spline(double a1,double b1, double a2, double b2, \
412 double a3, double b3, double a4, double b4)
414 double x1, y1, x4, y4;
415 double xmid, ymid;
417 x1 = a1; y1 = b1;
418 x4 = a4; y4 = b4;
419 xmid = (a2 + a3)/2.0;
420 ymid = (b2 + b3)/2.0;
421 if ((fabs(x1 - xmid) < THRESHOLD) && (fabs(y1 - ymid) < THRESHOLD)) {
422 splinerel(xmid,ymid,0);
423 /* fprintf(tfp, "PA%.4f,%.4f;\n", xmid, ymid);*/
425 else {
426 quadratic_spline(x1, y1, ((x1+a2)/2.0), ((y1+b2)/2.0),
427 ((3.0*a2+a3)/4.0), ((3.0*b2+b3)/4.0), xmid, ymid);
430 if ((fabs(xmid - x4) < THRESHOLD) && (fabs(ymid - y4) < THRESHOLD)) {
431 splinerel(x4,y4,0);
432 /* fprintf(tfp, "PA%.4f,%.4f;\n", x4, y4);*/
434 else {
435 quadratic_spline(xmid, ymid, ((a2+3.0*a3)/4.0), ((b2+3.0*b3)/4.0),
436 ((a3+x4)/2.0), ((b3+y4)/2.0), x4, y4);
438 }; /* quadratic_spline */
440 #define XCOORD(i) numbers[(2*i)]
441 #define YCOORD(i) numbers[(2*i)+1]
442 static void
443 vdmspline(int numpoints, int ox,int oy, int *numbers)
445 double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
446 double x1, y1, x2, y2;
447 char xcoord[4],ycoord[4];
448 int i;
450 /*p = s->points;
451 x1 = p->x/ppi;*/
452 x1 = ox;
453 y1 = oy;
454 /* p = p->next;
455 x2 = p->x/ppi;
456 y2 = p->y/ppi;*/
457 x2 = ox + XCOORD(0);
458 y2 = oy + YCOORD(0);
459 cx1 = (x1 + x2)/2.0;
460 cy1 = (y1 + y2)/2.0;
461 cx2 = (x1 + 3.0*x2)/4.0;
462 cy2 = (y1 + 3.0*y2)/4.0;
464 /* fprintf(stderr,"Spline %d (%d,%d)\n",numpoints,(int)x1,(int)y1);*/
465 vdmprintf("1%s%s",vdmnum((int)x1,xcoord),vdmnum((int)y1,ycoord));
466 splinerel(x1,y1,-1);
467 splinerel(cx1,cy1,0);
468 /* fprintf(tfp, "PA%.4f,%.4f;PD%.4f,%.4f;\n",
469 x1, y1, cx1, cy1);*/
471 /*for (p = p->next; p != NULL; p = p->next) {*/
472 for (i = 1; i < (numpoints); i++) {
473 x1 = x2;
474 y1 = y2;
475 /* x2 = p->x/ppi;
476 y2 = p->y/ppi;*/
477 x2 = x1 + XCOORD(i);
478 y2 = y1 + YCOORD(i);
479 cx3 = (3.0*x1 + x2)/4.0;
480 cy3 = (3.0*y1 + y2)/4.0;
481 cx4 = (x1 + x2)/2.0;
482 cy4 = (y1 + y2)/2.0;
483 /* fprintf(stderr,"Point (%d,%d) - (%d,%d)\n",(int)x1,(int)(y1),(int)x2,(int)y2);*/
484 quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
485 cx1 = cx4;
486 cy1 = cy4;
487 cx2 = (x1 + 3.0*x2)/4.0;
488 cy2 = (y1 + 3.0*y2)/4.0;
490 x1 = x2;
491 y1 = y2;
492 /* p = s->points->next;
493 x2 = p->x/ppi;
494 y2 = p->y/ppi;*/
495 x2 = ox + XCOORD(0);
496 y2 = oy + YCOORD(0);
497 cx3 = (3.0*x1 + x2)/4.0;
498 cy3 = (3.0*y1 + y2)/4.0;
499 cx4 = (x1 + x2)/2.0;
500 cy4 = (y1 + y2)/2.0;
501 splinerel(x1,y1,0);
502 splinerel(x1,y1,1);
503 /*vdmprintf("%s%s",vdmnum((int)(x1-lx),xcoord),\
504 vdmnum((int)(y1-ly),ycoord));*/
505 vdmprintf("\x1e\n");
506 /* fprintf(tfp, "PA%.4f,%.4f;PU;\n", x1, y1);*/
509 }; /* vdmspline */
512 #endif