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 36 lbpinit(FILE *outfile) 37 { 38 lbpoutput = outfile; 39 } 40 41 42 static void 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 54 lbpputs(const char *data) 55 { 56 fputs(data,lbpoutput); 57 } 58 59 60 static inline void 61 lbpputc(unsigned char c) 62 { 63 fputc(c,lbpoutput); 64 } 65 66 67 static inline void 68 lbpsavestatus(int idx ) 69 { 70 fprintf(lbpoutput,"\033[%d%%y",idx); 71 } 72 73 74 static inline void 75 lbprestorestatus(int idx ) 76 { 77 fprintf(lbpoutput,"\033[%d%cz",idx ,'%'); 78 } 79 80 81 static inline void 82 lbpsavepos(int idx) 83 { 84 fprintf(lbpoutput,"\033[1;%d;0x",idx); 85 } 86 87 88 static inline void 89 lbprestorepos(int idx) 90 { 91 fprintf(lbpoutput,"\033[0;%d;0x",idx); 92 } 93 94 95 static inline void 96 lbprestoreposx(int idx) 97 { 98 fprintf(lbpoutput,"\033[0;%d;1x",idx); 99 } 100 101 102 static inline void 103 lbpmoverel(int despl, char direction) 104 { 105 fprintf(lbpoutput,"\033[%d%c",despl,direction); 106 } 107 108 109 static inline void 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 117 lbpmoveabs(int x, int y) 118 { 119 fprintf(lbpoutput,"\033[%d;%df",y,x); 120 } 121 122 123 static inline void 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 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 * 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 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 * 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 195 vdmend() 196 { 197 vdmprintf("}p\x1e"); 198 } 199 200 201 static void 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 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 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 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 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 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 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 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 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 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 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 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 356 vdminited() 357 { 358 return (vdmoutput != NULL); 359 } 360 361 362 static inline void 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 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 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 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