lbp.h revision 79543
175584Sru// -*- C -*-
275584Sru/* Copyright (C) 1994, 2000 Free Software Foundation, Inc.
375584Sru     Written by Francisco Andr�s Verd� <pandres@dragonet.es>
475584Sru
575584Srugroff is free software; you can redistribute it and/or modify it under
675584Sruthe terms of the GNU General Public License as published by the Free
775584SruSoftware Foundation; either version 2, or (at your option) any later
875584Sruversion.
975584Sru
1075584Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
1175584SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
1275584SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1375584Srufor more details.
1475584Sru
1575584SruYou should have received a copy of the GNU General Public License along
1675584Sruwith groff; see the file COPYING.  If not, write to the Free Software
1775584SruFoundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
1875584Sru
1975584Sru/*  This file contains a set of utility functions to use canon CAPSL printers
2075584Sru *  (lbp-4 and lbp-8 series printers) */
2175584Sru
2275584Sru#ifndef LBP_H
2375584Sru#define LBP_H
2475584Sru
2575584Sru#include <stdio.h>
2675584Sru#include <stdarg.h>
2775584Sru
2875584Srustatic FILE *lbpoutput = NULL;
2975584Srustatic FILE *vdmoutput = NULL;
3075584Sru
3175584Srustatic inline void
3275584Srulbpinit(FILE *outfile)
3375584Sru{
3475584Sru	lbpoutput = outfile;
3575584Sru};
3675584Sru
3775584Sru
3875584Srustatic inline void
3979543Srulbpprintf(const char *format, ... )
4075584Sru{ /* Taken from cjet */
4175584Sru  va_list stuff;
4275584Sru
4375584Sru  va_start(stuff, format);
4475584Sru  vfprintf(lbpoutput, format, stuff);
4575584Sru  va_end(stuff);
4675584Sru};
4775584Sru
4875584Srustatic inline void
4979543Srulbpputs(const char *data)
5075584Sru{
5175584Sru	fputs(data,lbpoutput);
5275584Sru};
5375584Sru
5475584Srustatic inline void
5575584Srulbpputc(char c)
5675584Sru{
5775584Sru	fputc(c,lbpoutput);
5875584Sru};
5975584Sru
6075584Sru
6175584Srustatic inline void
6275584Srulbpsavestatus(int index )
6375584Sru{
6475584Sru	fprintf(lbpoutput,"\033[%d%%y",index);
6575584Sru};
6675584Sru
6775584Srustatic inline void
6875584Srulbprestorestatus(int index )
6975584Sru{
7075584Sru	fprintf(lbpoutput,"\033[%d%cz",index ,'%');
7175584Sru};
7275584Sru
7375584Srustatic inline void
7475584Srulbpsavepos(int index)
7575584Sru{
7675584Sru	fprintf(lbpoutput,"\033[1;%d;0x",index);
7775584Sru};
7875584Sru
7975584Srustatic inline void
8075584Srulbprestorepos(int index)
8175584Sru{
8275584Sru	fprintf(lbpoutput,"\033[0;%d;0x",index);
8375584Sru};
8475584Sru
8575584Srustatic inline void
8675584Srulbprestoreposx(int index)
8775584Sru{
8875584Sru	fprintf(lbpoutput,"\033[0;%d;1x",index);
8975584Sru};
9075584Sru
9175584Srustatic inline void
9275584Srulbpmoverel(int despl, char direction)
9375584Sru{
9475584Sru	fprintf(lbpoutput,"\033[%d%c",despl,direction);
9575584Sru};
9675584Sru
9775584Srustatic inline void
9875584Srulbplinerel(int width,int despl,char direction )
9975584Sru{
10075584Sru	fprintf(lbpoutput,"\033[%d;0;9{\033[%d%c\033[9}",width,despl,direction);
10175584Sru};
10275584Sru
10375584Srustatic inline void
10475584Srulbpmoveabs(int x, int y)
10575584Sru{
10675584Sru	fprintf(lbpoutput,"\033[%d;%df",y,x);
10775584Sru};
10875584Sru
10975584Srustatic inline void
11075584Srulbplineto(int x,int y, int width )
11175584Sru{
11275584Sru	fprintf(lbpoutput,"\033[%d;0;9{",width);
11375584Sru	lbpmoveabs(x,y);
11475584Sru	fprintf(lbpoutput,"\033[9}\n");
11575584Sru};
11675584Sru
11775584Srustatic inline void
11875584Srulbpruleabs(int x, int y, int hsize, int vsize)
11975584Sru{
12075584Sru	lbpmoveabs(x,y);
12175584Sru	fprintf(lbpoutput,"\033[0;9;000s");
12275584Sru	lbpmoveabs(x+hsize,y+vsize);
12375584Sru	fprintf(lbpoutput,"\033[9r");
12475584Sru};
12575584Sru
12679543Srustatic inline void vdmprintf(const char *format, ... );
12775584Sru
12875584Srustatic inline char *
12975584Sruvdmnum(int num,char *result)
13075584Sru{
13175584Sru  char b1,b2,b3;
13275584Sru  char *p = result;
13375584Sru  int nm;
13475584Sru
13575584Sru  nm = abs(num);
13675584Sru  /* First byte 1024 - 32768 */
13775584Sru  b1 = ((nm >> 10) & 0x3F);
13875584Sru  if (b1) *p++ = b1 | 0x40;
13975584Sru
14075584Sru  /* Second Byte 16 - 1024 */
14175584Sru  b2 = ((nm >> 4) & 0x3F);
14275584Sru  if ( b1 || b2) *p++= b2 | 0x40;
14375584Sru
14475584Sru  /* Third byte 0 - 15 */
14575584Sru  b3 = ((nm & 0x0F) | 32);
14675584Sru  if (num >= 0) b3 |= 16;
14775584Sru  *p++ = b3;
14875584Sru  *p = 0x00; /* End of the resulting string */
14975584Sru  return result;
15075584Sru};
15175584Sru
15275584Srustatic inline void
15375584Sruvdmorigin(int newx, int newy)
15475584Sru{
15575584Sru   char nx[4],ny[4];
15675584Sru
15775584Sru	vdmprintf("}\"%s%s\x1e",vdmnum(newx,nx),vdmnum(newy,ny));
15875584Sru}; /* vdmorigin */
15975584Sru
16075584Sru
16175584Srustatic inline FILE *
16275584Sruvdminit(FILE *vdmfile)
16375584Sru{
16475584Sru  char scale[4],size[4],lineend[4];
16575584Sru
16675584Sru/*  vdmoutput = tmpfile();*/
16775584Sru  vdmoutput = vdmfile;
16875584Sru  /* Initialize the VDM mode */
16975584Sru  vdmprintf("\033[0&}#GROLBP\x1e!0%s%s\x1e$\x1e}F%s\x1e",\
17075584Sru		  vdmnum(-3,scale),vdmnum(1,size),vdmnum(1,lineend));
17175584Sru  return vdmoutput;
17275584Sru
17375584Sru};
17475584Sru
17575584Srustatic inline void
17675584Sruvdmend()
17775584Sru{
17875584Sru	vdmprintf("}p\x1e");
17975584Sru};
18075584Sru
18175584Srustatic inline void
18279543Sruvdmprintf(const char *format, ... )
18375584Sru{ /* Taken from cjet */
18475584Sru  va_list stuff;
18575584Sru
18675584Sru  if (vdmoutput == NULL)  vdminit(tmpfile());
18775584Sru  va_start(stuff, format);
18875584Sru  vfprintf(vdmoutput, format, stuff);
18975584Sru  va_end(stuff);
19075584Sru};
19175584Sru
19275584Srustatic inline void
19375584Sruvdmsetfillmode(int pattern,int perimeter, int inverted)
19475584Sru{
19575584Sru   char patt[4],perim[4],
19675584Sru   	rot[4], /* rotation */
19775584Sru	espejo[4], /* espejo */
19875584Sru	inv[4]; /* Inverted */
19975584Sru
20075584Sru   	vdmprintf("I%s%s%s%s%s\x1e",vdmnum(pattern,patt),\
20175584Sru		vdmnum(perimeter,perim),vdmnum(0,rot),
20275584Sru		vdmnum(0,espejo),vdmnum(inverted,inv));
20375584Sru};
20475584Sru
20575584Srustatic inline void
20675584Sruvdmcircle(int centerx, int centery, int radius)
20775584Sru{
20875584Sru  char x[4],y[4],rad[4];
20975584Sru
21075584Sru	vdmprintf("5%s%s%s\x1e",vdmnum(centerx,x),vdmnum(centery,y),\
21175584Sru			vdmnum(radius,rad));
21275584Sru};
21375584Sru
21475584Srustatic inline void
21575584Sruvdmaarc(int centerx, int centery, int radius,int startangle,int angle,int style,int arcopen)
21675584Sru{
21775584Sru  char x[4],y[4],rad[4],stx[4],sty[4],styl[4],op[4];
21875584Sru
21975584Sru	vdmprintf("}6%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
22075584Sru		vdmnum(centerx,x),vdmnum(centery,y),\
22175584Sru		vdmnum(radius,rad),vdmnum(startangle,stx),vdmnum(angle,sty),\
22275584Sru		vdmnum(style,styl));
22375584Sru};
22475584Sru
22575584Srustatic inline void
22675584Sruvdmvarc(int centerx, int centery,int radius, int startx, int starty, int endx, int endy,\
22775584Sru	int style,int arcopen)
22875584Sru{
22975584Sru  char x[4],y[4],rad[4],stx[4],sty[4],enx[4],eny[4],styl[4],op[4];
23075584Sru
23175584Sru	vdmprintf("}6%s%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
23275584Sru		vdmnum(centerx,x),vdmnum(centery,y),\
23375584Sru		vdmnum(radius,rad),vdmnum(startx,stx),vdmnum(starty,sty),\
23475584Sru		vdmnum(endx,enx),vdmnum(endy,eny),vdmnum(style,styl));
23575584Sru};
23675584Sru
23775584Srustatic inline void
23875584Sruvdmellipse(int centerx, int centery, int radiusx, int radiusy,int rotation)
23975584Sru{
24075584Sru  char x[4],y[4],radx[4],rady[4],rotat[4];
24175584Sru
24275584Sru	vdmprintf("}7%s%s%s%s%s\x1e\n",vdmnum(centerx,x),vdmnum(centery,y),\
24375584Sru			vdmnum(radiusx,radx),vdmnum(radiusy,rady),\
24475584Sru			vdmnum(rotation,rotat));
24575584Sru};
24675584Sru
24775584Srustatic inline void
24875584Sruvdmsetlinetype(int lintype)
24975584Sru{
25075584Sru  char ltyp[4], expfact[4];
25175584Sru
25275584Sru  vdmprintf("E1%s%s\x1e",vdmnum(lintype,ltyp),vdmnum(1,expfact));
25375584Sru
25475584Sru};
25575584Sru
25675584Srustatic inline void
25775584Sruvdmsetlinestyle(int lintype, int pattern,int unionstyle)
25875584Sru{
25975584Sru   char patt[4],ltip[4],
26075584Sru   	rot[4], /* rotation */
26175584Sru	espejo[4], /* espejo */
26275584Sru	in[4]; /* Inverted */
26375584Sru
26475584Sru   	vdmprintf("}G%s%s%s%s%s\x1e",vdmnum(lintype,ltip),\
26575584Sru		vdmnum(pattern,patt),vdmnum(0,rot),
26675584Sru		vdmnum(0,espejo),vdmnum(0,in));
26775584Sru	vdmprintf("}F%s",vdmnum(unionstyle,rot));
26875584Sru};
26975584Sru
27075584Srustatic inline void
27175584Sruvdmlinewidth(int width)
27275584Sru{
27375584Sru  char wh[4];
27475584Sru
27575584Sru  	vdmprintf("F1%s\x1e",vdmnum(width,wh));
27675584Sru};
27775584Sru
27875584Srustatic inline void
27975584Sruvdmrectangle(int origx, int origy,int dstx, int dsty)
28075584Sru{
28175584Sru  char xcoord[4],ycoord[4],sdstx[4],sdsty[4];
28275584Sru
28375584Sru  vdmprintf("}:%s%s%s%s\x1e\n",vdmnum(origx,xcoord),vdmnum(dstx,sdstx),\
28475584Sru		  vdmnum(origy,ycoord),vdmnum(dsty,sdsty));
28575584Sru}; /* polyline */
28675584Sru
28775584Srustatic inline void
28875584Sruvdmpolyline(int numpoints, int *points)
28975584Sru{
29075584Sru  int i,*p = points;
29175584Sru  char xcoord[4],ycoord[4];
29275584Sru
29375584Sru  if (numpoints < 2) return;
29475584Sru  vdmprintf("1%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
29575584Sru  p += 2;
29675584Sru  for (i = 1; i < numpoints ; i++) {
29775584Sru	  vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
29875584Sru	  p += 2;
29975584Sru  }; /* for */
30075584Sru  vdmprintf("\x1e\n");
30175584Sru}; /* polyline */
30275584Sru
30375584Srustatic inline void
30475584Sruvdmpolygon(int numpoints, int *points)
30575584Sru{
30675584Sru  int i,*p = points;
30775584Sru  char xcoord[4],ycoord[4];
30875584Sru
30975584Sru  if (numpoints < 2) return;
31075584Sru  vdmprintf("2%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
31175584Sru  p += 2;
31275584Sru  for (i = 1; i < numpoints ; i++) {
31375584Sru	  vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
31475584Sru	  p += 2;
31575584Sru  }; /* for */
31675584Sru  vdmprintf("\x1e\n");
31775584Sru
31875584Sru}; /* vdmpolygon */
31975584Sru
32075584Sru
32175584Sru/************************************************************************
32275584Sru *		Highter level auxiliary functions			*
32375584Sru ************************************************************************/
32475584Srustatic inline int
32575584Sruvdminited()
32675584Sru{
32775584Sru	return (vdmoutput != NULL);
32875584Sru}; /* vdminited */
32975584Sru
33075584Sru
33175584Srustatic inline void
33275584Sruvdmline(int startx, int starty, int sizex, int sizey)
33375584Sru{
33475584Sru  int points[4];
33575584Sru
33675584Sru  points[0] = startx;
33775584Sru  points[1] = starty;
33875584Sru  points[2] = sizex;
33975584Sru  points[3] = sizey;
34075584Sru
34175584Sru  vdmpolyline(2,points);
34275584Sru
34375584Sru};
34475584Sru
34575584Sru/*#define         THRESHOLD       .05    */ /* inch */
34675584Sru#define         THRESHOLD       1     /* points (1/300 inch) */
34775584Srustatic inline void
34875584Srusplinerel(double px,double py,int flush)
34975584Sru{
35075584Sru  static int lx = 0 ,ly = 0;
35175584Sru  static float pend = 0.0;
35275584Sru  static int dy = 0, despx = 0, despy = 0, sigpend = 0;
35375584Sru  int dxnew ,dynew, sg;
35475584Sru  char xcoord[4],ycoord[4];
35575584Sru  float npend ;
35675584Sru
35775584Sru  if (flush == -1) {lx = (int)px; ly = (int)py; return;};
35875584Sru
35975584Sru  if (flush == 0) {
36075584Sru  dxnew = (int)px -lx;
36175584Sru  dynew = (int)py -ly;
36275584Sru  if ((dxnew == 0) && (dynew == 0)) return;
36375584Sru  sg = (dxnew < 0)? -1 : 0;
36475584Sru/*  fprintf(stderr,"s (%d,%d) (%d,%d)\n",dxnew,dynew,despx,despy);*/
36575584Sru  if (dynew == 0) {
36675584Sru	  despx = dxnew;
36775584Sru	  if ((sg == sigpend) && (dy == 0)){
36875584Sru		  return;
36975584Sru	  };
37075584Sru	dy = 0;
37175584Sru  }
37275584Sru  else {
37375584Sru	  dy = 1;
37475584Sru	npend = (1.0*dxnew)/dynew;
37575584Sru  	if (( npend == pend) && (sigpend == sg))
37675584Sru  	{ despy = dynew; despx = dxnew; return; }
37775584Sru  	else
37875584Sru  	{ sigpend = sg;
37975584Sru    	pend = npend;
38075584Sru  	}; /* else (( npend == pend) && ... */
38175584Sru  }; /* else (if (dynew == 0)) */
38275584Sru  }; /* if (!flush ) */
38375584Sru
38475584Sru  /* if we've changed direction we must draw the line */
38575584Sru/*  fprintf(stderr," (%d) %.2f,%.2f\n",flush,(float)px,(float)py);*/
38675584Sru  if ((despx != 0) || (despy != 0)) vdmprintf("%s%s",vdmnum(despx,xcoord),\
38775584Sru		vdmnum(despy,ycoord));
38875584Sru  /*if ((despx != 0) || (despy != 0)) fprintf(stderr,"2
38975584Sru   *%d,%d\n",despx,despy);*/
39075584Sru  if (flush) {
39175584Sru  	dxnew = dy = despx = despy = 0;
39275584Sru	return;
39375584Sru  }; /* if (flush) */
39475584Sru  dxnew -= despx;
39575584Sru  dynew -= despy;
39675584Sru  if ((dxnew != 0) || (dynew != 0)) vdmprintf("%s%s",vdmnum(dxnew,xcoord),\
39775584Sru		vdmnum(dynew,ycoord));
39875584Sru
39975584Sru/*  if ((dxnew != 0) || (dynew != 0)) fprintf(stderr,"3
40075584Sru *  %d,%d\n",dxnew,dynew);*/
40175584Sru  lx = (int)px; ly = (int)py;
40275584Sru  dxnew = dy = despx = despy = 0;
40375584Sru
40475584Sru}; /* splinerel */
40575584Sru
40675584Sru/**********************************************************************
40775584Sru *  The following code to draw splines is adapted from the transfig package
40875584Sru */
40975584Srustatic void
41075584Sruquadratic_spline(double a1,double  b1, double a2, double b2, \
41175584Sru		double a3, double b3, double a4, double b4)
41275584Sru{
41375584Sru	double	x1, y1, x4, y4;
41475584Sru	double	xmid, ymid;
41575584Sru
41675584Sru	x1	 = a1; y1 = b1;
41775584Sru	x4	 = a4; y4 = b4;
41875584Sru	xmid	 = (a2 + a3)/2.0;
41975584Sru	ymid	 = (b2 + b3)/2.0;
42075584Sru	if ((fabs(x1 - xmid) < THRESHOLD) && (fabs(y1 - ymid) < THRESHOLD)) {
42175584Sru        	splinerel(xmid,ymid,0);
42275584Sru/*	    fprintf(tfp, "PA%.4f,%.4f;\n", xmid, ymid);*/
42375584Sru	}
42475584Sru	else {
42575584Sru	    quadratic_spline(x1, y1, ((x1+a2)/2.0), ((y1+b2)/2.0),
42675584Sru		((3.0*a2+a3)/4.0), ((3.0*b2+b3)/4.0), xmid, ymid);
42775584Sru	    }
42875584Sru
42975584Sru	if ((fabs(xmid - x4) < THRESHOLD) && (fabs(ymid - y4) < THRESHOLD)) {
43075584Sru		splinerel(x4,y4,0);
43175584Sru/*	    fprintf(tfp, "PA%.4f,%.4f;\n", x4, y4);*/
43275584Sru	}
43375584Sru	else {
43475584Sru	    quadratic_spline(xmid, ymid, ((a2+3.0*a3)/4.0), ((b2+3.0*b3)/4.0),
43575584Sru			((a3+x4)/2.0), ((b3+y4)/2.0), x4, y4);
43675584Sru	    };
43775584Sru}; /* quadratic_spline */
43875584Sru
43975584Sru#define XCOORD(i) numbers[(2*i)]
44075584Sru#define YCOORD(i) numbers[(2*i)+1]
44175584Srustatic void
44275584Sruvdmspline(int numpoints, int ox,int oy, int *numbers)
44375584Sru{
44475584Sru	double	cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
44575584Sru	double	x1, y1, x2, y2;
44675584Sru	char xcoord[4],ycoord[4];
44775584Sru	int i;
44875584Sru
44975584Sru	/*p	 = s->points;
45075584Sru	x1	 = p->x/ppi;*/
45175584Sru	x1	 = ox;
45275584Sru	y1	 = oy;
45375584Sru/*	p	 = p->next;
45475584Sru	x2	 = p->x/ppi;
45575584Sru	y2	 = p->y/ppi;*/
45675584Sru	x2	 = ox + XCOORD(0);
45775584Sru	y2	 = oy + YCOORD(0);
45875584Sru	cx1	 = (x1 + x2)/2.0;
45975584Sru	cy1	 = (y1 + y2)/2.0;
46075584Sru	cx2	 = (x1 + 3.0*x2)/4.0;
46175584Sru	cy2	 = (y1 + 3.0*y2)/4.0;
46275584Sru
46375584Sru/*	fprintf(stderr,"Spline %d (%d,%d)\n",numpoints,(int)x1,(int)y1);*/
46475584Sru    	vdmprintf("1%s%s",vdmnum((int)x1,xcoord),vdmnum((int)y1,ycoord));
46575584Sru	splinerel(x1,y1,-1);
46675584Sru	splinerel(cx1,cy1,0);
46775584Sru/*	    fprintf(tfp, "PA%.4f,%.4f;PD%.4f,%.4f;\n",
46875584Sru		    x1, y1, cx1, cy1);*/
46975584Sru
47075584Sru	/*for (p = p->next; p != NULL; p = p->next) {*/
47175584Sru	for (i = 1; i < (numpoints); i++) {
47275584Sru	    x1	 = x2;
47375584Sru	    y1	 = y2;
47475584Sru/*	    x2	 = p->x/ppi;
47575584Sru	    y2	 = p->y/ppi;*/
47675584Sru            x2   = x1 + XCOORD(i);
47775584Sru            y2   = y1 + YCOORD(i);
47875584Sru	    cx3	 = (3.0*x1 + x2)/4.0;
47975584Sru	    cy3	 = (3.0*y1 + y2)/4.0;
48075584Sru	    cx4	 = (x1 + x2)/2.0;
48175584Sru	    cy4	 = (y1 + y2)/2.0;
48275584Sru	    /* fprintf(stderr,"Point (%d,%d) - (%d,%d)\n",(int)x1,(int)(y1),(int)x2,(int)y2);*/
48375584Sru	    quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
48475584Sru	    cx1	 = cx4;
48575584Sru	    cy1	 = cy4;
48675584Sru	    cx2	 = (x1 + 3.0*x2)/4.0;
48775584Sru	    cy2	 = (y1 + 3.0*y2)/4.0;
48875584Sru	    }
48975584Sru	x1	 = x2;
49075584Sru	y1	 = y2;
49175584Sru/*	p	 = s->points->next;
49275584Sru	x2	 = p->x/ppi;
49375584Sru	y2	 = p->y/ppi;*/
49475584Sru        x2       = ox + XCOORD(0);
49575584Sru        y2       = oy + YCOORD(0);
49675584Sru	cx3	 = (3.0*x1 + x2)/4.0;
49775584Sru	cy3	 = (3.0*y1 + y2)/4.0;
49875584Sru	cx4	 = (x1 + x2)/2.0;
49975584Sru	cy4	 = (y1 + y2)/2.0;
50075584Sru	splinerel(x1,y1,0);
50175584Sru	splinerel(x1,y1,1);
50275584Sru       	/*vdmprintf("%s%s",vdmnum((int)(x1-lx),xcoord),\
50375584Sru			vdmnum((int)(y1-ly),ycoord));*/
50475584Sru        vdmprintf("\x1e\n");
50575584Sru/*	    fprintf(tfp, "PA%.4f,%.4f;PU;\n", x1, y1);*/
50675584Sru
50775584Sru
50875584Sru}; /* vdmspline */
50975584Sru
51075584Sru
51175584Sru#endif
512