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