Update to groff 1.19.2.
[dragonfly.git] / contrib / groff-1.19 / src / devices / grolbp / lbp.h
1 // -*- C -*-
2 /* Copyright (C) 1994, 2000, 2001, 2003, 2004, 2005
3    Free Software Foundation, Inc.
4      Written by Francisco Andrés Verdú <pandres@dragonet.es>
5
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.
10
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.
15
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, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
19
20 /*  This file contains a set of utility functions to use canon CAPSL printers
21  *  (lbp-4 and lbp-8 series printers) */
22
23 #ifndef LBP_H
24 #define LBP_H
25
26 #include <stdio.h>
27 #include <stdarg.h>
28
29 static FILE *lbpoutput = NULL;
30 static FILE *vdmoutput = NULL;
31
32
33 static inline void 
34 lbpinit(FILE *outfile)
35 {
36         lbpoutput = outfile;
37 }
38
39
40 static void 
41 lbpprintf(const char *format, ... )
42 { /* Taken from cjet */
43   va_list stuff;
44
45   va_start(stuff, format);
46   vfprintf(lbpoutput, format, stuff);
47   va_end(stuff);
48 }
49
50
51 static inline void
52 lbpputs(const char *data)
53 {
54         fputs(data,lbpoutput);
55 }
56
57
58 static inline void
59 lbpputc(unsigned char c)
60 {
61         fputc(c,lbpoutput);
62 }
63
64
65 static inline void 
66 lbpsavestatus(int idx )
67 {
68         fprintf(lbpoutput,"\033[%d%%y",idx);
69 }
70
71
72 static inline void 
73 lbprestorestatus(int idx )
74 {
75         fprintf(lbpoutput,"\033[%d%cz",idx ,'%');
76 }
77
78
79 static inline void 
80 lbpsavepos(int idx)
81 {
82         fprintf(lbpoutput,"\033[1;%d;0x",idx);
83 }
84
85
86 static inline void 
87 lbprestorepos(int idx)
88 {
89         fprintf(lbpoutput,"\033[0;%d;0x",idx);
90 }
91
92
93 static inline void 
94 lbprestoreposx(int idx)
95 {
96         fprintf(lbpoutput,"\033[0;%d;1x",idx);
97 }
98
99
100 static inline void 
101 lbpmoverel(int despl, char direction)
102 {
103         fprintf(lbpoutput,"\033[%d%c",despl,direction);
104 }
105
106
107 static inline void 
108 lbplinerel(int width,int despl,char direction )
109 {
110         fprintf(lbpoutput,"\033[%d;0;9{\033[%d%c\033[9}",width,despl,direction);
111 }
112
113
114 static inline void 
115 lbpmoveabs(int x, int y)
116 {
117         fprintf(lbpoutput,"\033[%d;%df",y,x);
118 }
119
120
121 static inline void
122 lbplineto(int x,int y, int width )
123 {
124         fprintf(lbpoutput,"\033[%d;0;9{",width);
125         lbpmoveabs(x,y);
126         fprintf(lbpoutput,"\033[9}\n");
127 }
128
129
130 static inline void
131 lbpruleabs(int x, int y, int hsize, int vsize)
132 {
133         lbpmoveabs(x,y);
134         fprintf(lbpoutput,"\033[0;9;000s");
135         lbpmoveabs(x+hsize,y+vsize);
136         fprintf(lbpoutput,"\033[9r");
137 }
138
139
140 static void vdmprintf(const char *format, ... );
141
142
143 static inline char *
144 vdmnum(int num,char *result)
145 {
146   char b1,b2,b3;
147   char *p = result;
148   int nm;
149
150   nm = abs(num);
151   /* First byte 1024 - 32768 */
152   b1 = ((nm >> 10) & 0x3F);
153   if (b1) *p++ = b1 | 0x40;
154
155   /* Second Byte 16 - 1024 */
156   b2 = ((nm >> 4) & 0x3F);
157   if ( b1 || b2) *p++= b2 | 0x40;
158
159   /* Third byte 0 - 15 */
160   b3 = ((nm & 0x0F) | 32);
161   if (num >= 0) b3 |= 16;
162   *p++ = b3;
163   *p = 0x00; /* End of the resulting string */
164   return result;
165 }
166
167
168 static inline void
169 vdmorigin(int newx, int newy)
170 {
171    char nx[4],ny[4];
172
173         vdmprintf("}\"%s%s\x1e",vdmnum(newx,nx),vdmnum(newy,ny));
174 }
175
176
177 static inline FILE *
178 vdminit(FILE *vdmfile)
179 {
180   char scale[4],size[4],lineend[4];
181   
182 /*  vdmoutput = tmpfile();*/
183   vdmoutput = vdmfile;
184   /* Initialize the VDM mode */
185   vdmprintf("\033[0&}#GROLBP\x1e!0%s%s\x1e$\x1e}F%s\x1e",\
186                   vdmnum(-3,scale),vdmnum(1,size),vdmnum(1,lineend));
187   return vdmoutput;
188   
189 }
190
191
192 static inline void
193 vdmend()
194 {
195         vdmprintf("}p\x1e");
196 }
197
198
199 static void 
200 vdmprintf(const char *format, ... )
201 { /* Taken from cjet */
202   va_list stuff;
203   
204   if (vdmoutput == NULL)  vdminit(tmpfile());
205   va_start(stuff, format);
206   vfprintf(vdmoutput, format, stuff);
207   va_end(stuff);
208 }
209
210
211 static inline void
212 vdmsetfillmode(int pattern,int perimeter, int inverted)
213 {
214    char patt[4],perim[4],
215         rot[4], /* rotation */
216         espejo[4], /* espejo */
217         inv[4]; /* Inverted */
218
219         vdmprintf("I%s%s%s%s%s\x1e",vdmnum(pattern,patt),\
220                 vdmnum(perimeter,perim),vdmnum(0,rot),
221                 vdmnum(0,espejo),vdmnum(inverted,inv));
222 }
223
224
225 static inline void
226 vdmcircle(int centerx, int centery, int radius)
227 {
228   char x[4],y[4],rad[4];
229   
230         vdmprintf("5%s%s%s\x1e",vdmnum(centerx,x),vdmnum(centery,y),\
231                         vdmnum(radius,rad));
232 }
233
234
235 static inline void
236 vdmaarc(int centerx, int centery, int radius,int startangle,int angle,int style,int arcopen)
237 {
238   char x[4],y[4],rad[4],stx[4],sty[4],styl[4],op[4];
239   
240         vdmprintf("}6%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
241                 vdmnum(centerx,x),vdmnum(centery,y),\
242                 vdmnum(radius,rad),vdmnum(startangle,stx),vdmnum(angle,sty),\
243                 vdmnum(style,styl));
244 }
245
246
247 static inline void
248 vdmvarc(int centerx, int centery,int radius, int startx, int starty, int endx, int endy,\
249         int style,int arcopen)
250 {
251   char x[4],y[4],rad[4],stx[4],sty[4],enx[4],eny[4],styl[4],op[4];
252   
253         vdmprintf("}6%s%s%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
254                 vdmnum(centerx,x),vdmnum(centery,y),\
255                 vdmnum(radius,rad),vdmnum(startx,stx),vdmnum(starty,sty),\
256                 vdmnum(endx,enx),vdmnum(endy,eny),vdmnum(style,styl));
257 }
258
259
260 static inline void
261 vdmellipse(int centerx, int centery, int radiusx, int radiusy,int rotation)
262 {
263   char x[4],y[4],radx[4],rady[4],rotat[4];
264   
265         vdmprintf("}7%s%s%s%s%s\x1e\n",vdmnum(centerx,x),vdmnum(centery,y),\
266                         vdmnum(radiusx,radx),vdmnum(radiusy,rady),\
267                         vdmnum(rotation,rotat));
268 }
269
270
271 static inline void
272 vdmsetlinetype(int lintype)
273 {
274   char ltyp[4], expfact[4];
275
276   vdmprintf("E1%s%s\x1e",vdmnum(lintype,ltyp),vdmnum(1,expfact));
277   
278 }
279
280
281 static inline void
282 vdmsetlinestyle(int lintype, int pattern,int unionstyle)
283 {
284    char patt[4],ltip[4],
285         rot[4], /* rotation */
286         espejo[4], /* espejo */
287         in[4]; /* Inverted */
288
289         vdmprintf("}G%s%s%s%s%s\x1e",vdmnum(lintype,ltip),\
290                 vdmnum(pattern,patt),vdmnum(0,rot),
291                 vdmnum(0,espejo),vdmnum(0,in));
292         vdmprintf("}F%s",vdmnum(unionstyle,rot));
293 }
294
295
296 static inline void
297 vdmlinewidth(int width)
298 {
299   char wh[4];
300
301         vdmprintf("F1%s\x1e",vdmnum(width,wh));
302 }
303
304
305 static inline void
306 vdmrectangle(int origx, int origy,int dstx, int dsty)
307 {
308   char xcoord[4],ycoord[4],sdstx[4],sdsty[4];
309
310   vdmprintf("}:%s%s%s%s\x1e\n",vdmnum(origx,xcoord),vdmnum(dstx,sdstx),\
311                   vdmnum(origy,ycoord),vdmnum(dsty,sdsty));
312 }
313
314
315 static inline void
316 vdmpolyline(int numpoints, int *points)
317 {
318   int i,*p = points;
319   char xcoord[4],ycoord[4];
320
321   if (numpoints < 2) return;
322   vdmprintf("1%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
323   p += 2;
324   for (i = 1; i < numpoints ; i++) {
325           vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
326           p += 2;
327   } /* for */
328   vdmprintf("\x1e\n");
329 }
330          
331
332 static inline void
333 vdmpolygon(int numpoints, int *points)
334 {
335   int i,*p = points;
336   char xcoord[4],ycoord[4];
337
338   if (numpoints < 2) return;
339   vdmprintf("2%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
340   p += 2;
341   for (i = 1; i < numpoints ; i++) {
342           vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
343           p += 2;
344   } /* for */
345   vdmprintf("\x1e\n");
346
347 }
348
349
350 /************************************************************************
351  *              Highter level auxiliary functions                       *
352  ************************************************************************/              
353 static inline int
354 vdminited()
355 {
356         return (vdmoutput != NULL);
357 }
358
359
360 static inline void
361 vdmline(int startx, int starty, int sizex, int sizey)
362 {
363   int points[4];
364
365   points[0] = startx;
366   points[1] = starty;
367   points[2] = sizex;
368   points[3] = sizey;
369
370   vdmpolyline(2,points);
371
372 }
373
374
375 /*#define         THRESHOLD       .05    */ /* inch */
376 #define         THRESHOLD       1     /* points (1/300 inch) */
377 static inline void
378 splinerel(double px,double py,int flush)
379 {
380   static int lx = 0 ,ly = 0;
381   static double pend = 0.0;
382   static int dy = 0, despx = 0, despy = 0, sigpend = 0;
383   int dxnew = 0, dynew = 0, sg;
384   char xcoord[4],ycoord[4];
385   double npend ;
386
387   if (flush == -1) {lx = (int)px; ly = (int)py; return;}
388
389   if (flush == 0) {
390   dxnew = (int)px -lx;
391   dynew = (int)py -ly;
392   if ((dxnew == 0) && (dynew == 0)) return;
393   sg = (dxnew < 0)? -1 : 0;
394 /*  fprintf(stderr,"s (%d,%d) (%d,%d)\n",dxnew,dynew,despx,despy);*/
395   if (dynew == 0) { 
396           despx = dxnew; 
397           if ((sg == sigpend) && (dy == 0)){
398                   return;
399           }
400         dy = 0;
401   }
402   else {
403           dy = 1;
404         npend = (1.0*dxnew)/dynew;
405         if (( npend == pend) && (sigpend == sg))
406         { despy = dynew; despx = dxnew; return; }
407         else
408         { sigpend = sg;
409         pend = npend;
410         } /* else (( npend == pend) && ... */
411   } /* else (if (dynew == 0)) */
412   } /* if (!flush ) */
413
414   /* if we've changed direction we must draw the line */
415 /*  fprintf(stderr," (%d) %.2f,%.2f\n",flush,(float)px,(float)py);*/
416   if ((despx != 0) || (despy != 0)) vdmprintf("%s%s",vdmnum(despx,xcoord),\
417                 vdmnum(despy,ycoord));
418   /*if ((despx != 0) || (despy != 0)) fprintf(stderr,"2
419    *%d,%d\n",despx,despy);*/
420   if (flush) {
421         dxnew = dy = despx = despy = 0;
422         return;
423   } /* if (flush) */
424   dxnew -= despx;
425   dynew -= despy;
426   if ((dxnew != 0) || (dynew != 0)) vdmprintf("%s%s",vdmnum(dxnew,xcoord),\
427                 vdmnum(dynew,ycoord));
428   
429 /*  if ((dxnew != 0) || (dynew != 0)) fprintf(stderr,"3
430  *  %d,%d\n",dxnew,dynew);*/
431   lx = (int)px; ly = (int)py; 
432   dxnew = dy = despx = despy = 0;
433   
434 }
435
436
437 /**********************************************************************
438  *  The following code to draw splines is adapted from the transfig package
439  */
440 static void
441 quadratic_spline(double a_1, double b_1, double a_2, double b_2, \
442                  double a_3, double b_3, double a_4, double b_4)
443 {
444         double  x_1, y_1, x_4, y_4;
445         double  x_mid, y_mid;
446
447         x_1      = a_1; y_1 = b_1;
448         x_4      = a_4; y_4 = b_4;
449         x_mid    = (a_2 + a_3)/2.0;
450         y_mid    = (b_2 + b_3)/2.0;
451         if ((fabs(x_1 - x_mid) < THRESHOLD)
452             && (fabs(y_1 - y_mid) < THRESHOLD)) {
453                 splinerel(x_mid, y_mid, 0);
454 /*          fprintf(tfp, "PA%.4f,%.4f;\n", x_mid, y_mid);*/
455         }
456         else {
457             quadratic_spline(x_1, y_1, ((x_1+a_2)/2.0), ((y_1+b_2)/2.0),
458                 ((3.0*a_2+a_3)/4.0), ((3.0*b_2+b_3)/4.0), x_mid, y_mid);
459         }
460
461         if ((fabs(x_mid - x_4) < THRESHOLD)
462             && (fabs(y_mid - y_4) < THRESHOLD)) {
463                 splinerel(x_4, y_4, 0);
464 /*          fprintf(tfp, "PA%.4f,%.4f;\n", x_4, y_4);*/
465         }
466         else {
467             quadratic_spline(x_mid, y_mid,
468                              ((a_2+3.0*a_3)/4.0), ((b_2+3.0*b_3)/4.0),
469                              ((a_3+x_4)/2.0), ((b_3+y_4)/2.0), x_4, y_4);
470         }
471 }
472
473
474 #define XCOORD(i) numbers[(2*i)]
475 #define YCOORD(i) numbers[(2*i)+1]
476 static void
477 vdmspline(int numpoints, int o_x, int o_y, int *numbers)
478 {
479         double  cx_1, cy_1, cx_2, cy_2, cx_3, cy_3, cx_4, cy_4;
480         double  x_1, y_1, x_2, y_2;
481         char xcoord[4],ycoord[4];
482         int i;
483
484         /*p      = s->points;
485         x_1      = p->x/ppi;*/
486         x_1      = o_x;
487         y_1      = o_y;
488 /*      p        = p->next;
489         x_2      = p->x/ppi;
490         y_2      = p->y/ppi;*/
491         x_2      = o_x + XCOORD(0);
492         y_2      = o_y + YCOORD(0);
493         cx_1     = (x_1 + x_2)/2.0;
494         cy_1     = (y_1 + y_2)/2.0;
495         cx_2     = (x_1 + 3.0*x_2)/4.0;
496         cy_2     = (y_1 + 3.0*y_2)/4.0;
497
498 /*      fprintf(stderr,"Spline %d (%d,%d)\n",numpoints,(int)x_1,(int)y_1);*/
499         vdmprintf("1%s%s",vdmnum((int)x_1,xcoord),vdmnum((int)y_1,ycoord));
500         splinerel(x_1,y_1,-1);
501         splinerel(cx_1,cy_1,0);
502 /*          fprintf(tfp, "PA%.4f,%.4f;PD%.4f,%.4f;\n",
503                     x_1, y_1, cx_1, cy_1);*/
504
505         /*for (p = p->next; p != NULL; p = p->next) {*/
506         for (i = 1; i < (numpoints); i++) {
507             x_1  = x_2;
508             y_1  = y_2;
509 /*          x_2  = p->x/ppi;
510             y_2  = p->y/ppi;*/
511             x_2  = x_1 + XCOORD(i);
512             y_2  = y_1 + YCOORD(i);
513             cx_3 = (3.0*x_1 + x_2)/4.0;
514             cy_3 = (3.0*y_1 + y_2)/4.0;
515             cx_4 = (x_1 + x_2)/2.0;
516             cy_4 = (y_1 + y_2)/2.0;
517             /* fprintf(stderr,"Point (%d,%d) - (%d,%d)\n",(int)x_1,(int)(y_1),(int)x_2,(int)y_2);*/
518             quadratic_spline(cx_1, cy_1, cx_2, cy_2, cx_3, cy_3, cx_4, cy_4);
519             cx_1 = cx_4;
520             cy_1 = cy_4;
521             cx_2 = (x_1 + 3.0*x_2)/4.0;
522             cy_2 = (y_1 + 3.0*y_2)/4.0;
523         }
524         x_1     = x_2; 
525         y_1     = y_2;
526 /*      p       = s->points->next;
527         x_2     = p->x/ppi;
528         y_2     = p->y/ppi;*/
529         x_2     = o_x + XCOORD(0);
530         y_2     = o_y + YCOORD(0);
531         cx_3    = (3.0*x_1 + x_2)/4.0;
532         cy_3    = (3.0*y_1 + y_2)/4.0;
533         cx_4    = (x_1 + x_2)/2.0;
534         cy_4    = (y_1 + y_2)/2.0;
535         splinerel(x_1, y_1, 0);
536         splinerel(x_1, y_1, 1);
537         /*vdmprintf("%s%s",vdmnum((int)(x_1-lx),xcoord),\
538                         vdmnum((int)(y_1-ly),ycoord));*/
539         vdmprintf("\x1e\n");
540 /*          fprintf(tfp, "PA%.4f,%.4f;PU;\n", x_1, y_1);*/
541
542
543 }
544         
545
546 #endif