lbp.h revision 75584
1// -*- C -*- 2/* Copyright (C) 1994, 2000 Free Software Foundation, Inc. 3 Written by Francisco Andr�s Verd� <pandres@dragonet.es> 4 5groff is free software; you can redistribute it and/or modify it under 6the terms of the GNU General Public License as published by the Free 7Software Foundation; either version 2, or (at your option) any later 8version. 9 10groff is distributed in the hope that it will be useful, but WITHOUT ANY 11WARRANTY; without even the implied warranty of MERCHANTABILITY or 12FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13for more details. 14 15You should have received a copy of the GNU General Public License along 16with groff; see the file COPYING. If not, write to the Free Software 17Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 18 19/* This file contains a set of utility functions to use canon CAPSL printers 20 * (lbp-4 and lbp-8 series printers) */ 21 22#ifndef LBP_H 23#define LBP_H 24 25#include <stdio.h> 26#include <stdarg.h> 27 28static FILE *lbpoutput = NULL; 29static FILE *vdmoutput = NULL; 30 31static inline void 32lbpinit(FILE *outfile) 33{ 34 lbpoutput = outfile; 35}; 36 37 38static inline void 39lbpprintf(char *format, ... ) 40{ /* Taken from cjet */ 41 va_list stuff; 42 43 va_start(stuff, format); 44 vfprintf(lbpoutput, format, stuff); 45 va_end(stuff); 46}; 47 48static inline void 49lbpputs(char *data) 50{ 51 fputs(data,lbpoutput); 52}; 53 54static inline void 55lbpputc(char c) 56{ 57 fputc(c,lbpoutput); 58}; 59 60 61static inline void 62lbpsavestatus(int index ) 63{ 64 fprintf(lbpoutput,"\033[%d%%y",index); 65}; 66 67static inline void 68lbprestorestatus(int index ) 69{ 70 fprintf(lbpoutput,"\033[%d%cz",index ,'%'); 71}; 72 73static inline void 74lbpsavepos(int index) 75{ 76 fprintf(lbpoutput,"\033[1;%d;0x",index); 77}; 78 79static inline void 80lbprestorepos(int index) 81{ 82 fprintf(lbpoutput,"\033[0;%d;0x",index); 83}; 84 85static inline void 86lbprestoreposx(int index) 87{ 88 fprintf(lbpoutput,"\033[0;%d;1x",index); 89}; 90 91static inline void 92lbpmoverel(int despl, char direction) 93{ 94 fprintf(lbpoutput,"\033[%d%c",despl,direction); 95}; 96 97static inline void 98lbplinerel(int width,int despl,char direction ) 99{ 100 fprintf(lbpoutput,"\033[%d;0;9{\033[%d%c\033[9}",width,despl,direction); 101}; 102 103static inline void 104lbpmoveabs(int x, int y) 105{ 106 fprintf(lbpoutput,"\033[%d;%df",y,x); 107}; 108 109static inline void 110lbplineto(int x,int y, int width ) 111{ 112 fprintf(lbpoutput,"\033[%d;0;9{",width); 113 lbpmoveabs(x,y); 114 fprintf(lbpoutput,"\033[9}\n"); 115}; 116 117static inline void 118lbpruleabs(int x, int y, int hsize, int vsize) 119{ 120 lbpmoveabs(x,y); 121 fprintf(lbpoutput,"\033[0;9;000s"); 122 lbpmoveabs(x+hsize,y+vsize); 123 fprintf(lbpoutput,"\033[9r"); 124}; 125 126static inline void vdmprintf(char *format, ... ); 127 128static inline char * 129vdmnum(int num,char *result) 130{ 131 char b1,b2,b3; 132 char *p = result; 133 int nm; 134 135 nm = abs(num); 136 /* First byte 1024 - 32768 */ 137 b1 = ((nm >> 10) & 0x3F); 138 if (b1) *p++ = b1 | 0x40; 139 140 /* Second Byte 16 - 1024 */ 141 b2 = ((nm >> 4) & 0x3F); 142 if ( b1 || b2) *p++= b2 | 0x40; 143 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; 150}; 151 152static inline void 153vdmorigin(int newx, int newy) 154{ 155 char nx[4],ny[4]; 156 157 vdmprintf("}\"%s%s\x1e",vdmnum(newx,nx),vdmnum(newy,ny)); 158}; /* vdmorigin */ 159 160 161static inline FILE * 162vdminit(FILE *vdmfile) 163{ 164 char scale[4],size[4],lineend[4]; 165 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; 172 173}; 174 175static inline void 176vdmend() 177{ 178 vdmprintf("}p\x1e"); 179}; 180 181static inline void 182vdmprintf(char *format, ... ) 183{ /* Taken from cjet */ 184 va_list stuff; 185 186 if (vdmoutput == NULL) vdminit(tmpfile()); 187 va_start(stuff, format); 188 vfprintf(vdmoutput, format, stuff); 189 va_end(stuff); 190}; 191 192static inline void 193vdmsetfillmode(int pattern,int perimeter, int inverted) 194{ 195 char patt[4],perim[4], 196 rot[4], /* rotation */ 197 espejo[4], /* espejo */ 198 inv[4]; /* Inverted */ 199 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)); 203}; 204 205static inline void 206vdmcircle(int centerx, int centery, int radius) 207{ 208 char x[4],y[4],rad[4]; 209 210 vdmprintf("5%s%s%s\x1e",vdmnum(centerx,x),vdmnum(centery,y),\ 211 vdmnum(radius,rad)); 212}; 213 214static inline void 215vdmaarc(int centerx, int centery, int radius,int startangle,int angle,int style,int arcopen) 216{ 217 char x[4],y[4],rad[4],stx[4],sty[4],styl[4],op[4]; 218 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)); 223}; 224 225static inline void 226vdmvarc(int centerx, int centery,int radius, int startx, int starty, int endx, int endy,\ 227 int style,int arcopen) 228{ 229 char x[4],y[4],rad[4],stx[4],sty[4],enx[4],eny[4],styl[4],op[4]; 230 231 vdmprintf("}6%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)); 235}; 236 237static inline void 238vdmellipse(int centerx, int centery, int radiusx, int radiusy,int rotation) 239{ 240 char x[4],y[4],radx[4],rady[4],rotat[4]; 241 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)); 245}; 246 247static inline void 248vdmsetlinetype(int lintype) 249{ 250 char ltyp[4], expfact[4]; 251 252 vdmprintf("E1%s%s\x1e",vdmnum(lintype,ltyp),vdmnum(1,expfact)); 253 254}; 255 256static inline void 257vdmsetlinestyle(int lintype, int pattern,int unionstyle) 258{ 259 char patt[4],ltip[4], 260 rot[4], /* rotation */ 261 espejo[4], /* espejo */ 262 in[4]; /* Inverted */ 263 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)); 268}; 269 270static inline void 271vdmlinewidth(int width) 272{ 273 char wh[4]; 274 275 vdmprintf("F1%s\x1e",vdmnum(width,wh)); 276}; 277 278static inline void 279vdmrectangle(int origx, int origy,int dstx, int dsty) 280{ 281 char xcoord[4],ycoord[4],sdstx[4],sdsty[4]; 282 283 vdmprintf("}:%s%s%s%s\x1e\n",vdmnum(origx,xcoord),vdmnum(dstx,sdstx),\ 284 vdmnum(origy,ycoord),vdmnum(dsty,sdsty)); 285}; /* polyline */ 286 287static inline void 288vdmpolyline(int numpoints, int *points) 289{ 290 int i,*p = points; 291 char xcoord[4],ycoord[4]; 292 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 */ 302 303static inline void 304vdmpolygon(int numpoints, int *points) 305{ 306 int i,*p = points; 307 char xcoord[4],ycoord[4]; 308 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"); 317 318}; /* vdmpolygon */ 319 320 321/************************************************************************ 322 * Highter level auxiliary functions * 323 ************************************************************************/ 324static inline int 325vdminited() 326{ 327 return (vdmoutput != NULL); 328}; /* vdminited */ 329 330 331static inline void 332vdmline(int startx, int starty, int sizex, int sizey) 333{ 334 int points[4]; 335 336 points[0] = startx; 337 points[1] = starty; 338 points[2] = sizex; 339 points[3] = sizey; 340 341 vdmpolyline(2,points); 342 343}; 344 345/*#define THRESHOLD .05 */ /* inch */ 346#define THRESHOLD 1 /* points (1/300 inch) */ 347static inline void 348splinerel(double px,double py,int flush) 349{ 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 ; 356 357 if (flush == -1) {lx = (int)px; ly = (int)py; return;}; 358 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; 369 }; 370 dy = 0; 371 } 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 ) */ 383 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)); 398 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; 403 404}; /* splinerel */ 405 406/********************************************************************** 407 * The following code to draw splines is adapted from the transfig package 408 */ 409static void 410quadratic_spline(double a1,double b1, double a2, double b2, \ 411 double a3, double b3, double a4, double b4) 412{ 413 double x1, y1, x4, y4; 414 double xmid, ymid; 415 416 x1 = a1; y1 = b1; 417 x4 = a4; y4 = b4; 418 xmid = (a2 + a3)/2.0; 419 ymid = (b2 + b3)/2.0; 420 if ((fabs(x1 - xmid) < THRESHOLD) && (fabs(y1 - ymid) < THRESHOLD)) { 421 splinerel(xmid,ymid,0); 422/* fprintf(tfp, "PA%.4f,%.4f;\n", xmid, ymid);*/ 423 } 424 else { 425 quadratic_spline(x1, y1, ((x1+a2)/2.0), ((y1+b2)/2.0), 426 ((3.0*a2+a3)/4.0), ((3.0*b2+b3)/4.0), xmid, ymid); 427 } 428 429 if ((fabs(xmid - x4) < THRESHOLD) && (fabs(ymid - y4) < THRESHOLD)) { 430 splinerel(x4,y4,0); 431/* fprintf(tfp, "PA%.4f,%.4f;\n", x4, y4);*/ 432 } 433 else { 434 quadratic_spline(xmid, ymid, ((a2+3.0*a3)/4.0), ((b2+3.0*b3)/4.0), 435 ((a3+x4)/2.0), ((b3+y4)/2.0), x4, y4); 436 }; 437}; /* quadratic_spline */ 438 439#define XCOORD(i) numbers[(2*i)] 440#define YCOORD(i) numbers[(2*i)+1] 441static void 442vdmspline(int numpoints, int ox,int oy, int *numbers) 443{ 444 double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4; 445 double x1, y1, x2, y2; 446 char xcoord[4],ycoord[4]; 447 int i; 448 449 /*p = s->points; 450 x1 = p->x/ppi;*/ 451 x1 = ox; 452 y1 = oy; 453/* p = p->next; 454 x2 = p->x/ppi; 455 y2 = p->y/ppi;*/ 456 x2 = ox + XCOORD(0); 457 y2 = oy + YCOORD(0); 458 cx1 = (x1 + x2)/2.0; 459 cy1 = (y1 + y2)/2.0; 460 cx2 = (x1 + 3.0*x2)/4.0; 461 cy2 = (y1 + 3.0*y2)/4.0; 462 463/* fprintf(stderr,"Spline %d (%d,%d)\n",numpoints,(int)x1,(int)y1);*/ 464 vdmprintf("1%s%s",vdmnum((int)x1,xcoord),vdmnum((int)y1,ycoord)); 465 splinerel(x1,y1,-1); 466 splinerel(cx1,cy1,0); 467/* fprintf(tfp, "PA%.4f,%.4f;PD%.4f,%.4f;\n", 468 x1, y1, cx1, cy1);*/ 469 470 /*for (p = p->next; p != NULL; p = p->next) {*/ 471 for (i = 1; i < (numpoints); i++) { 472 x1 = x2; 473 y1 = y2; 474/* x2 = p->x/ppi; 475 y2 = p->y/ppi;*/ 476 x2 = x1 + XCOORD(i); 477 y2 = y1 + YCOORD(i); 478 cx3 = (3.0*x1 + x2)/4.0; 479 cy3 = (3.0*y1 + y2)/4.0; 480 cx4 = (x1 + x2)/2.0; 481 cy4 = (y1 + y2)/2.0; 482 /* fprintf(stderr,"Point (%d,%d) - (%d,%d)\n",(int)x1,(int)(y1),(int)x2,(int)y2);*/ 483 quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4); 484 cx1 = cx4; 485 cy1 = cy4; 486 cx2 = (x1 + 3.0*x2)/4.0; 487 cy2 = (y1 + 3.0*y2)/4.0; 488 } 489 x1 = x2; 490 y1 = y2; 491/* p = s->points->next; 492 x2 = p->x/ppi; 493 y2 = p->y/ppi;*/ 494 x2 = ox + XCOORD(0); 495 y2 = oy + YCOORD(0); 496 cx3 = (3.0*x1 + x2)/4.0; 497 cy3 = (3.0*y1 + y2)/4.0; 498 cx4 = (x1 + x2)/2.0; 499 cy4 = (y1 + y2)/2.0; 500 splinerel(x1,y1,0); 501 splinerel(x1,y1,1); 502 /*vdmprintf("%s%s",vdmnum((int)(x1-lx),xcoord),\ 503 vdmnum((int)(y1-ly),ycoord));*/ 504 vdmprintf("\x1e\n"); 505/* fprintf(tfp, "PA%.4f,%.4f;PU;\n", x1, y1);*/ 506 507 508}; /* vdmspline */ 509 510 511#endif 512