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