2 /* Copyright (C) 1994, 2000, 2001, 2003, 2004 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 2, or (at your option) any later
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 along
16 with groff; see the file COPYING. If not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 /* This file contains a set of utility functions to use canon CAPSL printers
20 * (lbp-4 and lbp-8 series printers) */
28 static FILE *lbpoutput
= NULL
;
29 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
);
49 lbpputs(const char *data
)
51 fputs(data
,lbpoutput
);
55 lbpputc(unsigned char c
)
62 lbpsavestatus(int idx
)
64 fprintf(lbpoutput
,"\033[%d%%y",idx
);
68 lbprestorestatus(int idx
)
70 fprintf(lbpoutput
,"\033[%d%cz",idx
,'%');
76 fprintf(lbpoutput
,"\033[1;%d;0x",idx
);
80 lbprestorepos(int idx
)
82 fprintf(lbpoutput
,"\033[0;%d;0x",idx
);
86 lbprestoreposx(int idx
)
88 fprintf(lbpoutput
,"\033[0;%d;1x",idx
);
92 lbpmoverel(int despl
, char direction
)
94 fprintf(lbpoutput
,"\033[%d%c",despl
,direction
);
98 lbplinerel(int width
,int despl
,char direction
)
100 fprintf(lbpoutput
,"\033[%d;0;9{\033[%d%c\033[9}",width
,despl
,direction
);
104 lbpmoveabs(int x
, int y
)
106 fprintf(lbpoutput
,"\033[%d;%df",y
,x
);
110 lbplineto(int x
,int y
, int width
)
112 fprintf(lbpoutput
,"\033[%d;0;9{",width
);
114 fprintf(lbpoutput
,"\033[9}\n");
118 lbpruleabs(int x
, int y
, int hsize
, int vsize
)
121 fprintf(lbpoutput
,"\033[0;9;000s");
122 lbpmoveabs(x
+hsize
,y
+vsize
);
123 fprintf(lbpoutput
,"\033[9r");
126 static inline void vdmprintf(const char *format
, ... );
129 vdmnum(int num
,char *result
)
136 /* First byte 1024 - 32768 */
137 b1
= ((nm
>> 10) & 0x3F);
138 if (b1
) *p
++ = b1
| 0x40;
140 /* Second Byte 16 - 1024 */
141 b2
= ((nm
>> 4) & 0x3F);
142 if ( b1
|| b2
) *p
++= b2
| 0x40;
144 /* Third byte 0 - 15 */
145 b3
= ((nm
& 0x0F) | 32);
146 if (num
>= 0) b3
|= 16;
148 *p
= 0x00; /* End of the resulting string */
153 vdmorigin(int newx
, int newy
)
157 vdmprintf("}\"%s%s\x1e",vdmnum(newx
,nx
),vdmnum(newy
,ny
));
162 vdminit(FILE *vdmfile
)
164 char scale
[4],size
[4],lineend
[4];
166 /* vdmoutput = tmpfile();*/
168 /* Initialize the VDM mode */
169 vdmprintf("\033[0&}#GROLBP\x1e!0%s%s\x1e$\x1e}F%s\x1e",\
170 vdmnum(-3,scale
),vdmnum(1,size
),vdmnum(1,lineend
));
182 vdmprintf(const char *format
, ... )
183 { /* Taken from cjet */
186 if (vdmoutput
== NULL
) vdminit(tmpfile());
187 va_start(stuff
, format
);
188 vfprintf(vdmoutput
, format
, stuff
);
193 vdmsetfillmode(int pattern
,int perimeter
, int inverted
)
195 char patt
[4],perim
[4],
196 rot
[4], /* rotation */
197 espejo
[4], /* espejo */
198 inv
[4]; /* Inverted */
200 vdmprintf("I%s%s%s%s%s\x1e",vdmnum(pattern
,patt
),\
201 vdmnum(perimeter
,perim
),vdmnum(0,rot
),
202 vdmnum(0,espejo
),vdmnum(inverted
,inv
));
206 vdmcircle(int centerx
, int centery
, int radius
)
208 char x
[4],y
[4],rad
[4];
210 vdmprintf("5%s%s%s\x1e",vdmnum(centerx
,x
),vdmnum(centery
,y
),\
215 vdmaarc(int centerx
, int centery
, int radius
,int startangle
,int angle
,int style
,int arcopen
)
217 char x
[4],y
[4],rad
[4],stx
[4],sty
[4],styl
[4],op
[4];
219 vdmprintf("}6%s%s%s%s%s%s%s\x1e",vdmnum(arcopen
,op
),\
220 vdmnum(centerx
,x
),vdmnum(centery
,y
),\
221 vdmnum(radius
,rad
),vdmnum(startangle
,stx
),vdmnum(angle
,sty
),\
226 vdmvarc(int centerx
, int centery
,int radius
, int startx
, int starty
, int endx
, int endy
,\
227 int style
,int arcopen
)
229 char x
[4],y
[4],rad
[4],stx
[4],sty
[4],enx
[4],eny
[4],styl
[4],op
[4];
231 vdmprintf("}6%s%s%s%s%s%s%s%s%s\x1e",vdmnum(arcopen
,op
),\
232 vdmnum(centerx
,x
),vdmnum(centery
,y
),\
233 vdmnum(radius
,rad
),vdmnum(startx
,stx
),vdmnum(starty
,sty
),\
234 vdmnum(endx
,enx
),vdmnum(endy
,eny
),vdmnum(style
,styl
));
238 vdmellipse(int centerx
, int centery
, int radiusx
, int radiusy
,int rotation
)
240 char x
[4],y
[4],radx
[4],rady
[4],rotat
[4];
242 vdmprintf("}7%s%s%s%s%s\x1e\n",vdmnum(centerx
,x
),vdmnum(centery
,y
),\
243 vdmnum(radiusx
,radx
),vdmnum(radiusy
,rady
),\
244 vdmnum(rotation
,rotat
));
248 vdmsetlinetype(int lintype
)
250 char ltyp
[4], expfact
[4];
252 vdmprintf("E1%s%s\x1e",vdmnum(lintype
,ltyp
),vdmnum(1,expfact
));
257 vdmsetlinestyle(int lintype
, int pattern
,int unionstyle
)
259 char patt
[4],ltip
[4],
260 rot
[4], /* rotation */
261 espejo
[4], /* espejo */
262 in
[4]; /* Inverted */
264 vdmprintf("}G%s%s%s%s%s\x1e",vdmnum(lintype
,ltip
),\
265 vdmnum(pattern
,patt
),vdmnum(0,rot
),
266 vdmnum(0,espejo
),vdmnum(0,in
));
267 vdmprintf("}F%s",vdmnum(unionstyle
,rot
));
271 vdmlinewidth(int width
)
275 vdmprintf("F1%s\x1e",vdmnum(width
,wh
));
279 vdmrectangle(int origx
, int origy
,int dstx
, int dsty
)
281 char xcoord
[4],ycoord
[4],sdstx
[4],sdsty
[4];
283 vdmprintf("}:%s%s%s%s\x1e\n",vdmnum(origx
,xcoord
),vdmnum(dstx
,sdstx
),\
284 vdmnum(origy
,ycoord
),vdmnum(dsty
,sdsty
));
288 vdmpolyline(int numpoints
, int *points
)
291 char xcoord
[4],ycoord
[4];
293 if (numpoints
< 2) return;
294 vdmprintf("1%s%s",vdmnum(*p
,xcoord
),vdmnum(*(p
+1),ycoord
));
296 for (i
= 1; i
< numpoints
; i
++) {
297 vdmprintf("%s%s",vdmnum(*p
,xcoord
),vdmnum(*(p
+1),ycoord
));
304 vdmpolygon(int numpoints
, int *points
)
307 char xcoord
[4],ycoord
[4];
309 if (numpoints
< 2) return;
310 vdmprintf("2%s%s",vdmnum(*p
,xcoord
),vdmnum(*(p
+1),ycoord
));
312 for (i
= 1; i
< numpoints
; i
++) {
313 vdmprintf("%s%s",vdmnum(*p
,xcoord
),vdmnum(*(p
+1),ycoord
));
321 /************************************************************************
322 * Highter level auxiliary functions *
323 ************************************************************************/
327 return (vdmoutput
!= NULL
);
332 vdmline(int startx
, int starty
, int sizex
, int sizey
)
341 vdmpolyline(2,points
);
345 /*#define THRESHOLD .05 */ /* inch */
346 #define THRESHOLD 1 /* points (1/300 inch) */
348 splinerel(double px
,double py
,int flush
)
350 static int lx
= 0 ,ly
= 0;
351 static float pend
= 0.0;
352 static int dy
= 0, despx
= 0, despy
= 0, sigpend
= 0;
353 int dxnew
,dynew
, sg
;
354 char xcoord
[4],ycoord
[4];
357 if (flush
== -1) {lx
= (int)px
; ly
= (int)py
; return;};
362 if ((dxnew
== 0) && (dynew
== 0)) return;
363 sg
= (dxnew
< 0)? -1 : 0;
364 /* fprintf(stderr,"s (%d,%d) (%d,%d)\n",dxnew,dynew,despx,despy);*/
367 if ((sg
== sigpend
) && (dy
== 0)){
374 npend
= (1.0*dxnew
)/dynew
;
375 if (( npend
== pend
) && (sigpend
== sg
))
376 { despy
= dynew
; despx
= dxnew
; return; }
380 }; /* else (( npend == pend) && ... */
381 }; /* else (if (dynew == 0)) */
382 }; /* if (!flush ) */
384 /* if we've changed direction we must draw the line */
385 /* fprintf(stderr," (%d) %.2f,%.2f\n",flush,(float)px,(float)py);*/
386 if ((despx
!= 0) || (despy
!= 0)) vdmprintf("%s%s",vdmnum(despx
,xcoord
),\
387 vdmnum(despy
,ycoord
));
388 /*if ((despx != 0) || (despy != 0)) fprintf(stderr,"2
389 *%d,%d\n",despx,despy);*/
391 dxnew
= dy
= despx
= despy
= 0;
396 if ((dxnew
!= 0) || (dynew
!= 0)) vdmprintf("%s%s",vdmnum(dxnew
,xcoord
),\
397 vdmnum(dynew
,ycoord
));
399 /* if ((dxnew != 0) || (dynew != 0)) fprintf(stderr,"3
400 * %d,%d\n",dxnew,dynew);*/
401 lx
= (int)px
; ly
= (int)py
;
402 dxnew
= dy
= despx
= despy
= 0;
406 /**********************************************************************
407 * The following code to draw splines is adapted from the transfig package
410 quadratic_spline(double a_1
, double b_1
, double a_2
, double b_2
, \
411 double a_3
, double b_3
, double a_4
, double b_4
)
413 double x_1
, y_1
, x_4
, y_4
;
416 x_1
= a_1
; y_1
= b_1
;
417 x_4
= a_4
; y_4
= b_4
;
418 x_mid
= (a_2
+ a_3
)/2.0;
419 y_mid
= (b_2
+ b_3
)/2.0;
420 if ((fabs(x_1
- x_mid
) < THRESHOLD
)
421 && (fabs(y_1
- y_mid
) < THRESHOLD
)) {
422 splinerel(x_mid
, y_mid
, 0);
423 /* fprintf(tfp, "PA%.4f,%.4f;\n", x_mid, y_mid);*/
426 quadratic_spline(x_1
, y_1
, ((x_1
+a_2
)/2.0), ((y_1
+b_2
)/2.0),
427 ((3.0*a_2
+a_3
)/4.0), ((3.0*b_2
+b_3
)/4.0), x_mid
, y_mid
);
430 if ((fabs(x_mid
- x_4
) < THRESHOLD
)
431 && (fabs(y_mid
- y_4
) < THRESHOLD
)) {
432 splinerel(x_4
, y_4
, 0);
433 /* fprintf(tfp, "PA%.4f,%.4f;\n", x_4, y_4);*/
436 quadratic_spline(x_mid
, y_mid
,
437 ((a_2
+3.0*a_3
)/4.0), ((b_2
+3.0*b_3
)/4.0),
438 ((a_3
+x_4
)/2.0), ((b_3
+y_4
)/2.0), x_4
, y_4
);
440 }; /* quadratic_spline */
442 #define XCOORD(i) numbers[(2*i)]
443 #define YCOORD(i) numbers[(2*i)+1]
445 vdmspline(int numpoints
, int o_x
, int o_y
, int *numbers
)
447 double cx_1
, cy_1
, cx_2
, cy_2
, cx_3
, cy_3
, cx_4
, cy_4
;
448 double x_1
, y_1
, x_2
, y_2
;
449 char xcoord
[4],ycoord
[4];
459 x_2
= o_x
+ XCOORD(0);
460 y_2
= o_y
+ YCOORD(0);
461 cx_1
= (x_1
+ x_2
)/2.0;
462 cy_1
= (y_1
+ y_2
)/2.0;
463 cx_2
= (x_1
+ 3.0*x_2
)/4.0;
464 cy_2
= (y_1
+ 3.0*y_2
)/4.0;
466 /* fprintf(stderr,"Spline %d (%d,%d)\n",numpoints,(int)x_1,(int)y_1);*/
467 vdmprintf("1%s%s",vdmnum((int)x_1
,xcoord
),vdmnum((int)y_1
,ycoord
));
468 splinerel(x_1
,y_1
,-1);
469 splinerel(cx_1
,cy_1
,0);
470 /* fprintf(tfp, "PA%.4f,%.4f;PD%.4f,%.4f;\n",
471 x_1, y_1, cx_1, cy_1);*/
473 /*for (p = p->next; p != NULL; p = p->next) {*/
474 for (i
= 1; i
< (numpoints
); i
++) {
479 x_2
= x_1
+ XCOORD(i
);
480 y_2
= y_1
+ YCOORD(i
);
481 cx_3
= (3.0*x_1
+ x_2
)/4.0;
482 cy_3
= (3.0*y_1
+ y_2
)/4.0;
483 cx_4
= (x_1
+ x_2
)/2.0;
484 cy_4
= (y_1
+ y_2
)/2.0;
485 /* fprintf(stderr,"Point (%d,%d) - (%d,%d)\n",(int)x_1,(int)(y_1),(int)x_2,(int)y_2);*/
486 quadratic_spline(cx_1
, cy_1
, cx_2
, cy_2
, cx_3
, cy_3
, cx_4
, cy_4
);
489 cx_2
= (x_1
+ 3.0*x_2
)/4.0;
490 cy_2
= (y_1
+ 3.0*y_2
)/4.0;
494 /* p = s->points->next;
497 x_2
= o_x
+ XCOORD(0);
498 y_2
= o_y
+ YCOORD(0);
499 cx_3
= (3.0*x_1
+ x_2
)/4.0;
500 cy_3
= (3.0*y_1
+ y_2
)/4.0;
501 cx_4
= (x_1
+ x_2
)/2.0;
502 cy_4
= (y_1
+ y_2
)/2.0;
503 splinerel(x_1
, y_1
, 0);
504 splinerel(x_1
, y_1
, 1);
505 /*vdmprintf("%s%s",vdmnum((int)(x_1-lx),xcoord),\
506 vdmnum((int)(y_1-ly),ycoord));*/
508 /* fprintf(tfp, "PA%.4f,%.4f;PU;\n", x_1, y_1);*/