xref: /netbsd-src/external/gpl2/groff/dist/src/devices/grolbp/lbp.h (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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
36 lbpinit(FILE *outfile)
37 {
38 	lbpoutput = outfile;
39 }
40 
41 
42 static void
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
54 lbpputs(const char *data)
55 {
56 	fputs(data,lbpoutput);
57 }
58 
59 
60 static inline void
61 lbpputc(unsigned char c)
62 {
63 	fputc(c,lbpoutput);
64 }
65 
66 
67 static inline void
68 lbpsavestatus(int idx )
69 {
70 	fprintf(lbpoutput,"\033[%d%%y",idx);
71 }
72 
73 
74 static inline void
75 lbprestorestatus(int idx )
76 {
77 	fprintf(lbpoutput,"\033[%d%cz",idx ,'%');
78 }
79 
80 
81 static inline void
82 lbpsavepos(int idx)
83 {
84 	fprintf(lbpoutput,"\033[1;%d;0x",idx);
85 }
86 
87 
88 static inline void
89 lbprestorepos(int idx)
90 {
91 	fprintf(lbpoutput,"\033[0;%d;0x",idx);
92 }
93 
94 
95 static inline void
96 lbprestoreposx(int idx)
97 {
98 	fprintf(lbpoutput,"\033[0;%d;1x",idx);
99 }
100 
101 
102 static inline void
103 lbpmoverel(int despl, char direction)
104 {
105 	fprintf(lbpoutput,"\033[%d%c",despl,direction);
106 }
107 
108 
109 static inline void
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
117 lbpmoveabs(int x, int y)
118 {
119 	fprintf(lbpoutput,"\033[%d;%df",y,x);
120 }
121 
122 
123 static inline void
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
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 *
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
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 *
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
195 vdmend()
196 {
197 	vdmprintf("}p\x1e");
198 }
199 
200 
201 static void
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
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
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
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
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
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
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
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
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
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
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
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
356 vdminited()
357 {
358 	return (vdmoutput != NULL);
359 }
360 
361 
362 static inline void
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
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
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
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