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