#ifndef LBP_H
#define LBP_H
#include <stdio.h>
#include <stdarg.h>
static FILE *lbpoutput = NULL;
static FILE *vdmoutput = NULL;
static inline void
lbpinit(FILE *outfile)
{
lbpoutput = outfile;
};
static inline void
lbpprintf(const char *format, ... )
{
va_list stuff;
va_start(stuff, format);
vfprintf(lbpoutput, format, stuff);
va_end(stuff);
};
static inline void
lbpputs(const char *data)
{
fputs(data,lbpoutput);
};
static inline void
lbpputc(char c)
{
fputc(c,lbpoutput);
};
static inline void
lbpsavestatus(int index )
{
fprintf(lbpoutput,"\033[%d%%y",index);
};
static inline void
lbprestorestatus(int index )
{
fprintf(lbpoutput,"\033[%d%cz",index ,'%');
};
static inline void
lbpsavepos(int index)
{
fprintf(lbpoutput,"\033[1;%d;0x",index);
};
static inline void
lbprestorepos(int index)
{
fprintf(lbpoutput,"\033[0;%d;0x",index);
};
static inline void
lbprestoreposx(int index)
{
fprintf(lbpoutput,"\033[0;%d;1x",index);
};
static inline void
lbpmoverel(int despl, char direction)
{
fprintf(lbpoutput,"\033[%d%c",despl,direction);
};
static inline void
lbplinerel(int width,int despl,char direction )
{
fprintf(lbpoutput,"\033[%d;0;9{\033[%d%c\033[9}",width,despl,direction);
};
static inline void
lbpmoveabs(int x, int y)
{
fprintf(lbpoutput,"\033[%d;%df",y,x);
};
static inline void
lbplineto(int x,int y, int width )
{
fprintf(lbpoutput,"\033[%d;0;9{",width);
lbpmoveabs(x,y);
fprintf(lbpoutput,"\033[9}\n");
};
static inline void
lbpruleabs(int x, int y, int hsize, int vsize)
{
lbpmoveabs(x,y);
fprintf(lbpoutput,"\033[0;9;000s");
lbpmoveabs(x+hsize,y+vsize);
fprintf(lbpoutput,"\033[9r");
};
static inline void vdmprintf(const char *format, ... );
static inline char *
vdmnum(int num,char *result)
{
char b1,b2,b3;
char *p = result;
int nm;
nm = abs(num);
b1 = ((nm >> 10) & 0x3F);
if (b1) *p++ = b1 | 0x40;
b2 = ((nm >> 4) & 0x3F);
if ( b1 || b2) *p++= b2 | 0x40;
b3 = ((nm & 0x0F) | 32);
if (num >= 0) b3 |= 16;
*p++ = b3;
*p = 0x00;
return result;
};
static inline void
vdmorigin(int newx, int newy)
{
char nx[4],ny[4];
vdmprintf("}\"%s%s\x1e",vdmnum(newx,nx),vdmnum(newy,ny));
};
static inline FILE *
vdminit(FILE *vdmfile)
{
char scale[4],size[4],lineend[4];
vdmoutput = vdmfile;
vdmprintf("\033[0&}#GROLBP\x1e!0%s%s\x1e$\x1e}F%s\x1e",\
vdmnum(-3,scale),vdmnum(1,size),vdmnum(1,lineend));
return vdmoutput;
};
static inline void
vdmend()
{
vdmprintf("}p\x1e");
};
static inline void
vdmprintf(const char *format, ... )
{
va_list stuff;
if (vdmoutput == NULL) vdminit(tmpfile());
va_start(stuff, format);
vfprintf(vdmoutput, format, stuff);
va_end(stuff);
};
static inline void
vdmsetfillmode(int pattern,int perimeter, int inverted)
{
char patt[4],perim[4],
rot[4],
espejo[4],
inv[4];
vdmprintf("I%s%s%s%s%s\x1e",vdmnum(pattern,patt),\
vdmnum(perimeter,perim),vdmnum(0,rot),
vdmnum(0,espejo),vdmnum(inverted,inv));
};
static inline void
vdmcircle(int centerx, int centery, int radius)
{
char x[4],y[4],rad[4];
vdmprintf("5%s%s%s\x1e",vdmnum(centerx,x),vdmnum(centery,y),\
vdmnum(radius,rad));
};
static inline void
vdmaarc(int centerx, int centery, int radius,int startangle,int angle,int style,int arcopen)
{
char x[4],y[4],rad[4],stx[4],sty[4],styl[4],op[4];
vdmprintf("}6%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
vdmnum(centerx,x),vdmnum(centery,y),\
vdmnum(radius,rad),vdmnum(startangle,stx),vdmnum(angle,sty),\
vdmnum(style,styl));
};
static inline void
vdmvarc(int centerx, int centery,int radius, int startx, int starty, int endx, int endy,\
int style,int arcopen)
{
char x[4],y[4],rad[4],stx[4],sty[4],enx[4],eny[4],styl[4],op[4];
vdmprintf("}6%s%s%s%s%s%s%s%s\x1e",vdmnum(arcopen,op),\
vdmnum(centerx,x),vdmnum(centery,y),\
vdmnum(radius,rad),vdmnum(startx,stx),vdmnum(starty,sty),\
vdmnum(endx,enx),vdmnum(endy,eny),vdmnum(style,styl));
};
static inline void
vdmellipse(int centerx, int centery, int radiusx, int radiusy,int rotation)
{
char x[4],y[4],radx[4],rady[4],rotat[4];
vdmprintf("}7%s%s%s%s%s\x1e\n",vdmnum(centerx,x),vdmnum(centery,y),\
vdmnum(radiusx,radx),vdmnum(radiusy,rady),\
vdmnum(rotation,rotat));
};
static inline void
vdmsetlinetype(int lintype)
{
char ltyp[4], expfact[4];
vdmprintf("E1%s%s\x1e",vdmnum(lintype,ltyp),vdmnum(1,expfact));
};
static inline void
vdmsetlinestyle(int lintype, int pattern,int unionstyle)
{
char patt[4],ltip[4],
rot[4],
espejo[4],
in[4];
vdmprintf("}G%s%s%s%s%s\x1e",vdmnum(lintype,ltip),\
vdmnum(pattern,patt),vdmnum(0,rot),
vdmnum(0,espejo),vdmnum(0,in));
vdmprintf("}F%s",vdmnum(unionstyle,rot));
};
static inline void
vdmlinewidth(int width)
{
char wh[4];
vdmprintf("F1%s\x1e",vdmnum(width,wh));
};
static inline void
vdmrectangle(int origx, int origy,int dstx, int dsty)
{
char xcoord[4],ycoord[4],sdstx[4],sdsty[4];
vdmprintf("}:%s%s%s%s\x1e\n",vdmnum(origx,xcoord),vdmnum(dstx,sdstx),\
vdmnum(origy,ycoord),vdmnum(dsty,sdsty));
};
static inline void
vdmpolyline(int numpoints, int *points)
{
int i,*p = points;
char xcoord[4],ycoord[4];
if (numpoints < 2) return;
vdmprintf("1%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
p += 2;
for (i = 1; i < numpoints ; i++) {
vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
p += 2;
};
vdmprintf("\x1e\n");
};
static inline void
vdmpolygon(int numpoints, int *points)
{
int i,*p = points;
char xcoord[4],ycoord[4];
if (numpoints < 2) return;
vdmprintf("2%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
p += 2;
for (i = 1; i < numpoints ; i++) {
vdmprintf("%s%s",vdmnum(*p,xcoord),vdmnum(*(p+1),ycoord));
p += 2;
};
vdmprintf("\x1e\n");
};
static inline int
vdminited()
{
return (vdmoutput != NULL);
};
static inline void
vdmline(int startx, int starty, int sizex, int sizey)
{
int points[4];
points[0] = startx;
points[1] = starty;
points[2] = sizex;
points[3] = sizey;
vdmpolyline(2,points);
};
#define THRESHOLD 1
static inline void
splinerel(double px,double py,int flush)
{
static int lx = 0 ,ly = 0;
static float pend = 0.0;
static int dy = 0, despx = 0, despy = 0, sigpend = 0;
int dxnew ,dynew, sg;
char xcoord[4],ycoord[4];
float npend ;
if (flush == -1) {lx = (int)px; ly = (int)py; return;};
if (flush == 0) {
dxnew = (int)px -lx;
dynew = (int)py -ly;
if ((dxnew == 0) && (dynew == 0)) return;
sg = (dxnew < 0)? -1 : 0;
if (dynew == 0) {
despx = dxnew;
if ((sg == sigpend) && (dy == 0)){
return;
};
dy = 0;
}
else {
dy = 1;
npend = (1.0*dxnew)/dynew;
if (( npend == pend) && (sigpend == sg))
{ despy = dynew; despx = dxnew; return; }
else
{ sigpend = sg;
pend = npend;
};
};
};
if ((despx != 0) || (despy != 0)) vdmprintf("%s%s",vdmnum(despx,xcoord),\
vdmnum(despy,ycoord));
if (flush) {
dxnew = dy = despx = despy = 0;
return;
};
dxnew -= despx;
dynew -= despy;
if ((dxnew != 0) || (dynew != 0)) vdmprintf("%s%s",vdmnum(dxnew,xcoord),\
vdmnum(dynew,ycoord));
lx = (int)px; ly = (int)py;
dxnew = dy = despx = despy = 0;
};
static void
quadratic_spline(double a1,double b1, double a2, double b2, \
double a3, double b3, double a4, double b4)
{
double x1, y1, x4, y4;
double xmid, ymid;
x1 = a1; y1 = b1;
x4 = a4; y4 = b4;
xmid = (a2 + a3)/2.0;
ymid = (b2 + b3)/2.0;
if ((fabs(x1 - xmid) < THRESHOLD) && (fabs(y1 - ymid) < THRESHOLD)) {
splinerel(xmid,ymid,0);
}
else {
quadratic_spline(x1, y1, ((x1+a2)/2.0), ((y1+b2)/2.0),
((3.0*a2+a3)/4.0), ((3.0*b2+b3)/4.0), xmid, ymid);
}
if ((fabs(xmid - x4) < THRESHOLD) && (fabs(ymid - y4) < THRESHOLD)) {
splinerel(x4,y4,0);
}
else {
quadratic_spline(xmid, ymid, ((a2+3.0*a3)/4.0), ((b2+3.0*b3)/4.0),
((a3+x4)/2.0), ((b3+y4)/2.0), x4, y4);
};
};
#define XCOORD(i) numbers[(2*i)]
#define YCOORD(i) numbers[(2*i)+1]
static void
vdmspline(int numpoints, int ox,int oy, int *numbers)
{
double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
double x1, y1, x2, y2;
char xcoord[4],ycoord[4];
int i;
x1 = ox;
y1 = oy;
x2 = ox + XCOORD(0);
y2 = oy + YCOORD(0);
cx1 = (x1 + x2)/2.0;
cy1 = (y1 + y2)/2.0;
cx2 = (x1 + 3.0*x2)/4.0;
cy2 = (y1 + 3.0*y2)/4.0;
vdmprintf("1%s%s",vdmnum((int)x1,xcoord),vdmnum((int)y1,ycoord));
splinerel(x1,y1,-1);
splinerel(cx1,cy1,0);
for (i = 1; i < (numpoints); i++) {
x1 = x2;
y1 = y2;
x2 = x1 + XCOORD(i);
y2 = y1 + YCOORD(i);
cx3 = (3.0*x1 + x2)/4.0;
cy3 = (3.0*y1 + y2)/4.0;
cx4 = (x1 + x2)/2.0;
cy4 = (y1 + y2)/2.0;
quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
cx1 = cx4;
cy1 = cy4;
cx2 = (x1 + 3.0*x2)/4.0;
cy2 = (y1 + 3.0*y2)/4.0;
}
x1 = x2;
y1 = y2;
x2 = ox + XCOORD(0);
y2 = oy + YCOORD(0);
cx3 = (3.0*x1 + x2)/4.0;
cy3 = (3.0*y1 + y2)/4.0;
cx4 = (x1 + x2)/2.0;
cy4 = (y1 + y2)/2.0;
splinerel(x1,y1,0);
splinerel(x1,y1,1);
vdmprintf("\x1e\n");
};
#endif