* src/libs/libgroff/glyphuni.cpp (glyph_to_unicode_list),
[s-roff.git] / src / devices / grolbp / lbp.h
blob0604af27e3ffb665eaa6a68540ff8485f0f34d46
1 // -*- C -*-
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
8 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
13 for more details.
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) */
22 #ifndef LBP_H
23 #define LBP_H
25 #include <stdio.h>
26 #include <stdarg.h>
28 static FILE *lbpoutput = NULL;
29 static FILE *vdmoutput = NULL;
31 static inline void
32 lbpinit(FILE *outfile)
34 lbpoutput = outfile;
38 static inline void
39 lbpprintf(const char *format, ... )
40 { /* Taken from cjet */
41 va_list stuff;
43 va_start(stuff, format);
44 vfprintf(lbpoutput, format, stuff);
45 va_end(stuff);
48 static inline void
49 lbpputs(const char *data)
51 fputs(data,lbpoutput);
54 static inline void
55 lbpputc(unsigned char c)
57 fputc(c,lbpoutput);
61 static inline void
62 lbpsavestatus(int idx )
64 fprintf(lbpoutput,"\033[%d%%y",idx);
67 static inline void
68 lbprestorestatus(int idx )
70 fprintf(lbpoutput,"\033[%d%cz",idx ,'%');
73 static inline void
74 lbpsavepos(int idx)
76 fprintf(lbpoutput,"\033[1;%d;0x",idx);
79 static inline void
80 lbprestorepos(int idx)
82 fprintf(lbpoutput,"\033[0;%d;0x",idx);
85 static inline void
86 lbprestoreposx(int idx)
88 fprintf(lbpoutput,"\033[0;%d;1x",idx);
91 static inline void
92 lbpmoverel(int despl, char direction)
94 fprintf(lbpoutput,"\033[%d%c",despl,direction);
97 static inline void
98 lbplinerel(int width,int despl,char direction )
100 fprintf(lbpoutput,"\033[%d;0;9{\033[%d%c\033[9}",width,despl,direction);
103 static inline void
104 lbpmoveabs(int x, int y)
106 fprintf(lbpoutput,"\033[%d;%df",y,x);
109 static inline void
110 lbplineto(int x,int y, int width )
112 fprintf(lbpoutput,"\033[%d;0;9{",width);
113 lbpmoveabs(x,y);
114 fprintf(lbpoutput,"\033[9}\n");
117 static inline void
118 lbpruleabs(int x, int y, int hsize, int vsize)
120 lbpmoveabs(x,y);
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, ... );
128 static inline char *
129 vdmnum(int num,char *result)
131 char b1,b2,b3;
132 char *p = result;
133 int nm;
135 nm = abs(num);
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;
147 *p++ = b3;
148 *p = 0x00; /* End of the resulting string */
149 return result;
152 static inline void
153 vdmorigin(int newx, int newy)
155 char nx[4],ny[4];
157 vdmprintf("}\"%s%s\x1e",vdmnum(newx,nx),vdmnum(newy,ny));
158 }; /* vdmorigin */
161 static inline FILE *
162 vdminit(FILE *vdmfile)
164 char scale[4],size[4],lineend[4];
166 /* vdmoutput = tmpfile();*/
167 vdmoutput = vdmfile;
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));
171 return vdmoutput;
175 static inline void
176 vdmend()
178 vdmprintf("}p\x1e");
181 static inline void
182 vdmprintf(const char *format, ... )
183 { /* Taken from cjet */
184 va_list stuff;
186 if (vdmoutput == NULL) vdminit(tmpfile());
187 va_start(stuff, format);
188 vfprintf(vdmoutput, format, stuff);
189 va_end(stuff);
192 static inline void
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));
205 static inline void
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),\
211 vdmnum(radius,rad));
214 static inline void
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),\
222 vdmnum(style,styl));
225 static inline void
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));
237 static inline void
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));
247 static inline void
248 vdmsetlinetype(int lintype)
250 char ltyp[4], expfact[4];
252 vdmprintf("E1%s%s\x1e",vdmnum(lintype,ltyp),vdmnum(1,expfact));
256 static inline void
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));
270 static inline void
271 vdmlinewidth(int width)
273 char wh[4];
275 vdmprintf("F1%s\x1e",vdmnum(width,wh));
278 static inline void
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));
285 }; /* polyline */
287 static inline void
288 vdmpolyline(int numpoints, int *points)
290 int i,*p = points;
291 char xcoord[4],ycoord[4];
293 if (numpoints < 2) return;
294 vdmprintf("1%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
295 p += 2;
296 for (i = 1; i < numpoints ; i++) {
297 vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
298 p += 2;
299 }; /* for */
300 vdmprintf("\x1e\n");
301 }; /* polyline */
303 static inline void
304 vdmpolygon(int numpoints, int *points)
306 int i,*p = points;
307 char xcoord[4],ycoord[4];
309 if (numpoints < 2) return;
310 vdmprintf("2%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
311 p += 2;
312 for (i = 1; i < numpoints ; i++) {
313 vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
314 p += 2;
315 }; /* for */
316 vdmprintf("\x1e\n");
318 }; /* vdmpolygon */
321 /************************************************************************
322 * Highter level auxiliary functions *
323 ************************************************************************/
324 static inline int
325 vdminited()
327 return (vdmoutput != NULL);
328 }; /* vdminited */
331 static inline void
332 vdmline(int startx, int starty, int sizex, int sizey)
334 int points[4];
336 points[0] = startx;
337 points[1] = starty;
338 points[2] = sizex;
339 points[3] = sizey;
341 vdmpolyline(2,points);
345 /*#define THRESHOLD .05 */ /* inch */
346 #define THRESHOLD 1 /* points (1/300 inch) */
347 static inline void
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];
355 float npend ;
357 if (flush == -1) {lx = (int)px; ly = (int)py; return;};
359 if (flush == 0) {
360 dxnew = (int)px -lx;
361 dynew = (int)py -ly;
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);*/
365 if (dynew == 0) {
366 despx = dxnew;
367 if ((sg == sigpend) && (dy == 0)){
368 return;
370 dy = 0;
372 else {
373 dy = 1;
374 npend = (1.0*dxnew)/dynew;
375 if (( npend == pend) && (sigpend == sg))
376 { despy = dynew; despx = dxnew; return; }
377 else
378 { sigpend = sg;
379 pend = npend;
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);*/
390 if (flush) {
391 dxnew = dy = despx = despy = 0;
392 return;
393 }; /* if (flush) */
394 dxnew -= despx;
395 dynew -= despy;
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;
404 }; /* splinerel */
406 /**********************************************************************
407 * The following code to draw splines is adapted from the transfig package
409 static void
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;
414 double x_mid, y_mid;
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);*/
425 else {
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);*/
435 else {
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]
444 static void
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];
450 int i;
452 /*p = s->points;
453 x_1 = p->x/ppi;*/
454 x_1 = o_x;
455 y_1 = o_y;
456 /* p = p->next;
457 x_2 = p->x/ppi;
458 y_2 = p->y/ppi;*/
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++) {
475 x_1 = x_2;
476 y_1 = y_2;
477 /* x_2 = p->x/ppi;
478 y_2 = p->y/ppi;*/
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);
487 cx_1 = cx_4;
488 cy_1 = cy_4;
489 cx_2 = (x_1 + 3.0*x_2)/4.0;
490 cy_2 = (y_1 + 3.0*y_2)/4.0;
492 x_1 = x_2;
493 y_1 = y_2;
494 /* p = s->points->next;
495 x_2 = p->x/ppi;
496 y_2 = p->y/ppi;*/
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));*/
507 vdmprintf("\x1e\n");
508 /* fprintf(tfp, "PA%.4f,%.4f;PU;\n", x_1, y_1);*/
511 }; /* vdmspline */
514 #endif