2 /* Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 Written by Francisco Andrés Verdú <pandres@dragonet.es>
5 groff is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 groff is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* This file contains a set of utility functions to use canon CAPSL printers
19 * (lbp-4 and lbp-8 series printers) */
27 static FILE *lbpoutput = NULL;
28 static FILE *vdmoutput = NULL;
32 lbpinit(FILE *outfile)
39 lbpprintf(const char *format, ... )
40 { /* Taken from cjet */
43 va_start(stuff, format);
44 vfprintf(lbpoutput, format, stuff);
50 lbpputs(const char *data)
52 fputs(data,lbpoutput);
57 lbpputc(unsigned char c)
64 lbpsavestatus(int idx )
66 fprintf(lbpoutput,"\033[%d%%y",idx);
71 lbprestorestatus(int idx )
73 fprintf(lbpoutput,"\033[%d%cz",idx ,'%');
80 fprintf(lbpoutput,"\033[1;%d;0x",idx);
85 lbprestorepos(int idx)
87 fprintf(lbpoutput,"\033[0;%d;0x",idx);
92 lbprestoreposx(int idx)
94 fprintf(lbpoutput,"\033[0;%d;1x",idx);
99 lbpmoverel(int despl, char direction)
101 fprintf(lbpoutput,"\033[%d%c",despl,direction);
106 lbplinerel(int width,int despl,char direction )
108 fprintf(lbpoutput,"\033[%d;0;9{\033[%d%c\033[9}",width,despl,direction);
113 lbpmoveabs(int x, int y)
115 fprintf(lbpoutput,"\033[%d;%df",y,x);
120 lbplineto(int x,int y, int width )
122 fprintf(lbpoutput,"\033[%d;0;9{",width);
124 fprintf(lbpoutput,"\033[9}\n");
129 lbpruleabs(int x, int y, int hsize, int vsize)
132 fprintf(lbpoutput,"\033[0;9;000s");
133 lbpmoveabs(x+hsize,y+vsize);
134 fprintf(lbpoutput,"\033[9r");
138 static void vdmprintf(const char *format, ... );
142 vdmnum(int num,char *result)
149 /* First byte 1024 - 32768 */
150 b1 = ((nm >> 10) & 0x3F);
151 if (b1) *p++ = b1 | 0x40;
153 /* Second Byte 16 - 1024 */
154 b2 = ((nm >> 4) & 0x3F);
155 if ( b1 || b2) *p++= b2 | 0x40;
157 /* Third byte 0 - 15 */
158 b3 = ((nm & 0x0F) | 32);
159 if (num >= 0) b3 |= 16;
161 *p = 0x00; /* End of the resulting string */
167 vdmorigin(int newx, int newy)
171 vdmprintf("}\"%s%s\x1e",vdmnum(newx,nx),vdmnum(newy,ny));
176 vdminit(FILE *vdmfile)
178 char scale[4],size[4],lineend[4];
180 /* vdmoutput = tmpfile();*/
182 /* Initialize the VDM mode */
183 vdmprintf("\033[0&}#GROLBP\x1e!0%s%s\x1e$\x1e}F%s\x1e",\
184 vdmnum(-3,scale),vdmnum(1,size),vdmnum(1,lineend));
198 vdmprintf(const char *format, ... )
199 { /* Taken from cjet */
202 if (vdmoutput == NULL) vdminit(tmpfile());
203 va_start(stuff, format);
204 vfprintf(vdmoutput, format, stuff);
210 vdmsetfillmode(int pattern,int perimeter, int inverted)
212 char patt[4],perim[4],
213 rot[4], /* rotation */
214 espejo[4], /* espejo */
215 inv[4]; /* Inverted */
217 vdmprintf("I%s%s%s%s%s\x1e",vdmnum(pattern,patt),\
218 vdmnum(perimeter,perim),vdmnum(0,rot),
219 vdmnum(0,espejo),vdmnum(inverted,inv));
224 vdmcircle(int centerx, int centery, int radius)
226 char x[4],y[4],rad[4];
228 vdmprintf("5%s%s%s\x1e",vdmnum(centerx,x),vdmnum(centery,y),\
234 vdmaarc(int centerx, int centery, int radius,int startangle,int angle,int style,int arcopen)
236 char x[4],y[4],rad[4],stx[4],sty[4],styl[4],op[4];
238 vdmprintf("}6%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
239 vdmnum(centerx,x),vdmnum(centery,y),\
240 vdmnum(radius,rad),vdmnum(startangle,stx),vdmnum(angle,sty),\
246 vdmvarc(int centerx, int centery,int radius, int startx, int starty, int endx, int endy,\
247 int style,int arcopen)
249 char x[4],y[4],rad[4],stx[4],sty[4],enx[4],eny[4],styl[4],op[4];
251 vdmprintf("}6%s%s%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
252 vdmnum(centerx,x),vdmnum(centery,y),\
253 vdmnum(radius,rad),vdmnum(startx,stx),vdmnum(starty,sty),\
254 vdmnum(endx,enx),vdmnum(endy,eny),vdmnum(style,styl));
259 vdmellipse(int centerx, int centery, int radiusx, int radiusy,int rotation)
261 char x[4],y[4],radx[4],rady[4],rotat[4];
263 vdmprintf("}7%s%s%s%s%s\x1e\n",vdmnum(centerx,x),vdmnum(centery,y),\
264 vdmnum(radiusx,radx),vdmnum(radiusy,rady),\
265 vdmnum(rotation,rotat));
270 vdmsetlinetype(int lintype)
272 char ltyp[4], expfact[4];
274 vdmprintf("E1%s%s\x1e",vdmnum(lintype,ltyp),vdmnum(1,expfact));
280 vdmsetlinestyle(int lintype, int pattern,int unionstyle)
282 char patt[4],ltip[4],
283 rot[4], /* rotation */
284 espejo[4], /* espejo */
285 in[4]; /* Inverted */
287 vdmprintf("}G%s%s%s%s%s\x1e",vdmnum(lintype,ltip),\
288 vdmnum(pattern,patt),vdmnum(0,rot),
289 vdmnum(0,espejo),vdmnum(0,in));
290 vdmprintf("}F%s",vdmnum(unionstyle,rot));
295 vdmlinewidth(int width)
299 vdmprintf("F1%s\x1e",vdmnum(width,wh));
304 vdmrectangle(int origx, int origy,int dstx, int dsty)
306 char xcoord[4],ycoord[4],sdstx[4],sdsty[4];
308 vdmprintf("}:%s%s%s%s\x1e\n",vdmnum(origx,xcoord),vdmnum(dstx,sdstx),\
309 vdmnum(origy,ycoord),vdmnum(dsty,sdsty));
314 vdmpolyline(int numpoints, int *points)
317 char xcoord[4],ycoord[4];
319 if (numpoints < 2) return;
320 vdmprintf("1%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
322 for (i = 1; i < numpoints ; i++) {
323 vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
331 vdmpolygon(int numpoints, int *points)
334 char xcoord[4],ycoord[4];
336 if (numpoints < 2) return;
337 vdmprintf("2%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
339 for (i = 1; i < numpoints ; i++) {
340 vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
348 /************************************************************************
349 * Highter level auxiliary functions *
350 ************************************************************************/
354 return (vdmoutput != NULL);
359 vdmline(int startx, int starty, int sizex, int sizey)
368 vdmpolyline(2,points);
373 /*#define THRESHOLD .05 */ /* inch */
374 #define THRESHOLD 1 /* points (1/300 inch) */
376 splinerel(double px,double py,int flush)
378 static int lx = 0 ,ly = 0;
379 static double pend = 0.0;
380 static int dy = 0, despx = 0, despy = 0, sigpend = 0;
381 int dxnew = 0, dynew = 0, sg;
382 char xcoord[4],ycoord[4];
385 if (flush == -1) {lx = (int)px; ly = (int)py; return;}
390 if ((dxnew == 0) && (dynew == 0)) return;
391 sg = (dxnew < 0)? -1 : 0;
392 /* fprintf(stderr,"s (%d,%d) (%d,%d)\n",dxnew,dynew,despx,despy);*/
395 if ((sg == sigpend) && (dy == 0)){
402 npend = (1.0*dxnew)/dynew;
403 if (( npend == pend) && (sigpend == sg))
404 { despy = dynew; despx = dxnew; return; }
408 } /* else (( npend == pend) && ... */
409 } /* else (if (dynew == 0)) */
412 /* if we've changed direction we must draw the line */
413 /* fprintf(stderr," (%d) %.2f,%.2f\n",flush,(float)px,(float)py);*/
414 if ((despx != 0) || (despy != 0)) vdmprintf("%s%s",vdmnum(despx,xcoord),\
415 vdmnum(despy,ycoord));
416 /*if ((despx != 0) || (despy != 0)) fprintf(stderr,"2
417 *%d,%d\n",despx,despy);*/
419 dxnew = dy = despx = despy = 0;
424 if ((dxnew != 0) || (dynew != 0)) vdmprintf("%s%s",vdmnum(dxnew,xcoord),\
425 vdmnum(dynew,ycoord));
427 /* if ((dxnew != 0) || (dynew != 0)) fprintf(stderr,"3
428 * %d,%d\n",dxnew,dynew);*/
429 lx = (int)px; ly = (int)py;
430 dxnew = dy = despx = despy = 0;
435 /**********************************************************************
436 * The following code to draw splines is adapted from the transfig package
439 quadratic_spline(double a_1, double b_1, double a_2, double b_2, \
440 double a_3, double b_3, double a_4, double b_4)
442 double x_1, y_1, x_4, y_4;
445 x_1 = a_1; y_1 = b_1;
446 x_4 = a_4; y_4 = b_4;
447 x_mid = (a_2 + a_3)/2.0;
448 y_mid = (b_2 + b_3)/2.0;
449 if ((fabs(x_1 - x_mid) < THRESHOLD)
450 && (fabs(y_1 - y_mid) < THRESHOLD)) {
451 splinerel(x_mid, y_mid, 0);
452 /* fprintf(tfp, "PA%.4f,%.4f;\n", x_mid, y_mid);*/
455 quadratic_spline(x_1, y_1, ((x_1+a_2)/2.0), ((y_1+b_2)/2.0),
456 ((3.0*a_2+a_3)/4.0), ((3.0*b_2+b_3)/4.0), x_mid, y_mid);
459 if ((fabs(x_mid - x_4) < THRESHOLD)
460 && (fabs(y_mid - y_4) < THRESHOLD)) {
461 splinerel(x_4, y_4, 0);
462 /* fprintf(tfp, "PA%.4f,%.4f;\n", x_4, y_4);*/
465 quadratic_spline(x_mid, y_mid,
466 ((a_2+3.0*a_3)/4.0), ((b_2+3.0*b_3)/4.0),
467 ((a_3+x_4)/2.0), ((b_3+y_4)/2.0), x_4, y_4);
472 #define XCOORD(i) numbers[(2*i)]
473 #define YCOORD(i) numbers[(2*i)+1]
475 vdmspline(int numpoints, int o_x, int o_y, int *numbers)
477 double cx_1, cy_1, cx_2, cy_2, cx_3, cy_3, cx_4, cy_4;
478 double x_1, y_1, x_2, y_2;
479 char xcoord[4],ycoord[4];
489 x_2 = o_x + XCOORD(0);
490 y_2 = o_y + YCOORD(0);
491 cx_1 = (x_1 + x_2)/2.0;
492 cy_1 = (y_1 + y_2)/2.0;
493 cx_2 = (x_1 + 3.0*x_2)/4.0;
494 cy_2 = (y_1 + 3.0*y_2)/4.0;
496 /* fprintf(stderr,"Spline %d (%d,%d)\n",numpoints,(int)x_1,(int)y_1);*/
497 vdmprintf("1%s%s",vdmnum((int)x_1,xcoord),vdmnum((int)y_1,ycoord));
498 splinerel(x_1,y_1,-1);
499 splinerel(cx_1,cy_1,0);
500 /* fprintf(tfp, "PA%.4f,%.4f;PD%.4f,%.4f;\n",
501 x_1, y_1, cx_1, cy_1);*/
503 /*for (p = p->next; p != NULL; p = p->next) {*/
504 for (i = 1; i < (numpoints); i++) {
509 x_2 = x_1 + XCOORD(i);
510 y_2 = y_1 + YCOORD(i);
511 cx_3 = (3.0*x_1 + x_2)/4.0;
512 cy_3 = (3.0*y_1 + y_2)/4.0;
513 cx_4 = (x_1 + x_2)/2.0;
514 cy_4 = (y_1 + y_2)/2.0;
515 /* fprintf(stderr,"Point (%d,%d) - (%d,%d)\n",(int)x_1,(int)(y_1),(int)x_2,(int)y_2);*/
516 quadratic_spline(cx_1, cy_1, cx_2, cy_2, cx_3, cy_3, cx_4, cy_4);
519 cx_2 = (x_1 + 3.0*x_2)/4.0;
520 cy_2 = (y_1 + 3.0*y_2)/4.0;
524 /* p = s->points->next;
527 x_2 = o_x + XCOORD(0);
528 y_2 = o_y + YCOORD(0);
529 cx_3 = (3.0*x_1 + x_2)/4.0;
530 cy_3 = (3.0*y_1 + y_2)/4.0;
531 cx_4 = (x_1 + x_2)/2.0;
532 cy_4 = (y_1 + y_2)/2.0;
533 splinerel(x_1, y_1, 0);
534 splinerel(x_1, y_1, 1);
535 /*vdmprintf("%s%s",vdmnum((int)(x_1-lx),xcoord),\
536 vdmnum((int)(y_1-ly),ycoord));*/
538 /* fprintf(tfp, "PA%.4f,%.4f;PU;\n", x_1, y_1);*/