File:  [CSRG BSD Unix] / 41BSD / cmd / cifplot / fill.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:12:53 2018 UTC (8 years, 1 month ago) by root
Branches: MAIN, BSD
CVS tags: HEAD, BSD41
BSD 4.1

/*******************************************************************
*                                                                  *
*    File: CIFPLOT/fill.c                                          *
*    Written by Dan Fitzpatrick & Dennis Wellborne                 *
*    copyright 1980 -- Regents of the University of California     *
*                                                                  *
********************************************************************/

#include "defs.h"
#include "globals.h"
#include "structs.h"
#include "out_structs.h"
#include "masks.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/vcmd.h>
#include <signal.h>
#include <errno.h>

extern int errno;

int plotmd [] = { VPLOT, 0, 0 };
int prtmd  [] = { VPRINT, 0, 0 };
struct stat stbuf;
int offline;
int Lock = 0;
char *tail = "a";	/* letter appended to temp file name for uniqueness */
int NormalSize;
double StartNextPlot;

IMPORT char *Concat();
IMPORT char *mktemp();
IMPORT char *getlogin();
IMPORT char *ctime();
IMPORT time();

#define VLIMIT  2112
#define VMAX	2000
#define VEXTRA	2100
#define VMIN	0
#define VRESOL	200.0
#define VSPLFL	"/usr/spool/vad/dfcXXXXXX"
#define VDAEMON "/vb/grad/fitz/graphics/vad"

#define WLIMIT	7040
#define	WMAX	7000
#define	WEXTRA	7030
#define WMIN	0
#define WRESOL	200.0
#define WSPLFL	"/usr/spool/vpd/dfcXXXXXX"
#define WDAEMON "/vb/grad/fitz/graphics/vpd"

#define HLIMIT  704
#define HMAX	700
#define HMIN	0
#define HRESOL  10.0

#define LOCK   "/usr/spool/vpd/lock"
#define DEVICE "/dev/vp0"
#define NAME   "Versatec"
#define DAEMON "/vb/grad/fitz/graphics/vpd"
#define VDUMP	"/usr/ucb/vdump"
#define VDMP	"/vb/grad/fitz/graphics/vdmp"

int xmax,xlimit,xlimitDiv32,xmin;
real resolution = 200;
char *heading,*name;

#ifdef  SHIFT
#define FROMMASK(from)	( 0xffffff00 | (0xff >> (from & 0x07))) << (from & 0x18)

#define TOMASK(to)		(~((0xffffff00 | (0xff >> (to & 0x07))) << (to & 0x18)))
#else
#define FROMMASK(from)  fromMask[from&0x1f]
#define TOMASK(to)      toMask[to&0x1f]
#endif
#define DOTMASK(x)	dotMask[x&0x1f]

char *outfile;
int filedesc;
int *OutBuf,*ScanLine;
int NoLine;


Fill(line,from,to,pattern)
int from,to;
register int pattern;
{
    int start,end;
    register int i;

    to++;
    if(to < from || xlimit < to || from < 0) { 
	/* fprintf(stderr,"Out of range in fill(%d,%d)\n",from,to); */
	return;
	}
    start = (from >> 5) + ((line - Bottom) % OUT_BUF_SIZE)*xlimitDiv32;
    end = (to >> 5) + ((line - Bottom) % OUT_BUF_SIZE)*xlimitDiv32;

    if (start == end)
		OutBuf[start] |= pattern & (FROMMASK(from)) & (TOMASK(to));
	else {
		OutBuf[start] |= pattern & (FROMMASK(from));

		for (i=start+1; i<end;)
			OutBuf[i++] |= pattern;
		
		OutBuf[end] |= pattern & TOMASK(to);
		}
}

#define ORDER(x,y)	if(x > y) { temp=x; x=y;y=temp;}

FillTrap(xLeft,xRight,deltaxLeft,deltaxRight,yBottom,yTop,patNo)
real xLeft,xRight,deltaxLeft,deltaxRight;
int yTop,yBottom;
int patNo;
{
    register int xStart,xEnd,from,to;
    register int i,pattern;
    int y,yStart,yEnd;
    int n,temp;

    if(yBottom > yTop) Error("yBottom > yTop in FillTrap",INTERNAL);
    yStart = (yBottom - Bottom) % OUT_BUF_SIZE;
    yEnd = (yTop - yBottom) + yStart;
    if(yEnd > OUT_BUF_SIZE || yStart < 0) Error("Trap bigger than buf size",INTERNAL);

    if(!(deltaxLeft == 0.0 && deltaxRight ==  0.0)) {
	for(y=yStart; y<yEnd; y++) {
	    from = xLeft;
	    to = xRight+1;
	    if(to < from || xlimit < to || from < 0) { 
		/* fprintf(stderr,"Out of range in fill(%d,%d)\n",from,to); */
		return;
		}
	    xStart = (from >> 5) + (y*xlimitDiv32);
	    xEnd = (to >> 5) + (y*xlimitDiv32);
	    pattern = Pats[patNo][y%NO_PAT_LINE];
	    if(pattern != 0) {
		if(xStart == xEnd)
		    OutBuf[xStart] |= pattern & (FROMMASK(from)) & (TOMASK(to));
		  else {
		    OutBuf[xStart] |= pattern & (FROMMASK(from));
		    for(i=xStart+1; i<xEnd;)
			OutBuf[i++] |= pattern;
		    OutBuf[xEnd] |= pattern & (TOMASK(to));
		    }
		}
	    if(outline || pattern == 0xffffffff) {
		to = xLeft + deltaxLeft;
		ORDER(from,to); to++;
		xStart = (from >> 5) + (y*xlimitDiv32);
		n = (to >> 5) + (y*xlimitDiv32);
		if(xStart == n)
		    OutBuf[xStart] |= 0xffffffff & (FROMMASK(from)) & (TOMASK(to));
		  else {
		    OutBuf[xStart] |= 0xffffffff & (FROMMASK(from));
		    for(i=xStart+1; i<n;)
			OutBuf[i++] |= 0xffffffff;
		    OutBuf[n] |= 0xffffffff & (TOMASK(to));
		    }
		to = xRight;
		from = xRight + deltaxRight;
		ORDER(from,to); to++;
		n = (from >> 5) + (y*xlimitDiv32);
		xEnd = (to >> 5) + (y*xlimitDiv32);
		if(n == xEnd)
		    OutBuf[n] |= 0xffffffff & (FROMMASK(from)) & (TOMASK(to));
		  else {
		    OutBuf[n] |= 0xffffffff & (FROMMASK(from));
		    for(i=n+1; i<xEnd;)
			OutBuf[i++] |= 0xffffffff;
		    OutBuf[xEnd] |= 0xffffffff & (TOMASK(to));
		    }
		}
	    xLeft += deltaxLeft;
	    xRight += deltaxRight;
	    }
	}
      else {
	from = xLeft;
	to = xRight+1;
	if(to < from || xlimit < to || from < 0) { 
	    /* fprintf(stderr,"Out of range in fill(%d,%d)\n",from,to); */
	    return;
	    }
	xStart = (from >> 5) + (yStart*xlimitDiv32);
	xEnd = (to >> 5) + (yStart*xlimitDiv32);
	for(y=yStart; y<yEnd; y++) {
	    pattern = Pats[patNo][y%NO_PAT_LINE];
	    if(pattern != 0) {
		if(xStart == xEnd)
		    OutBuf[xStart] |= pattern & (FROMMASK(from)) & (TOMASK(to));
		  else {
		    OutBuf[xStart] |= pattern & (FROMMASK(from));
		    for(i=xStart+1; i<xEnd;)
			OutBuf[i++] |= pattern;
			OutBuf[xEnd] |= pattern & (TOMASK(to));
		    }
		}
	    if(outline || pattern == 0xffffffff) {
		OutBuf[xStart] |= DOTMASK(from);
		OutBuf[xEnd] |= DOTMASK(to);
		}
	    xEnd += xlimitDiv32;
	    xStart += xlimitDiv32;
	    }
	}
    }

blank(from,to,line)
int from,to;
{
    int start,end;
    register int i;

    to++;
    if(to < from || xlimit < to || from < 0) { 
	/* fprintf(stderr,"Out of range in blank(%d,%d)\n",from,to); */
	return;
	}
    start = (from >> 5) + ((line - Bottom) % OUT_BUF_SIZE)*xlimitDiv32;
    end = (to >> 5) + ((line - Bottom) % OUT_BUF_SIZE)*xlimitDiv32;

    if (start == end)
		OutBuf[start] &= ~((FROMMASK(from)) & (TOMASK(to)));
	else {
		OutBuf[start] &= ~(FROMMASK(from));

		for (i=start+1; i<end;)
			OutBuf[i++] = 0;
		
		OutBuf[end] &=  ~(TOMASK(to));
		}
}

match(pat,pos,line)
int pat,pos,line;
{
    int pat1,pat2,offset;

    line = (line-Bottom) % OUT_BUF_SIZE;
    offset = (line*xlimitDiv32);
    pat &= 0xff;
    /*
    pat1 = ((0xff >> (pos & 07)) & 0xff) << (pos & 0x18);
    OutBuf[(pos>>5)+offset] &= ~pat1;
    */
    pat1 = ((pat >> (pos & 07)) & 0xff) << (pos & 0x18);
    OutBuf[(pos>>5)+offset] |= pat1;
    pos += 8;
    /*
    pat2 = ((0xff00 >> (pos & 07)) & 0xff) << (pos & 0x18);
    OutBuf[(pos>>5)+offset] &= ~pat2;
    */
    pat = pat << 8;
    pat2 = ((pat >> (pos & 07)) & 0xff) << (pos & 0x18);
    OutBuf[(pos>>5)+offset] |= pat2;
    }

/*
ClearLine(){
    register int i,limit;
    limit = (OUT_BUF_SIZE*xlimit)/32;
    for(i=0; i<limit ; OutBuf[i++] = 0);
    }
    */

Clear(lp, nbytes)
	int *lp;
	int nbytes;
{

	asm("movc5 $0,(sp),$0,8(ap),*4(ap)");

}

DumpBuf(x)
int x;
{
    int i;
    for(i=xLast; i < x; i++) Text(i);
    if(plot) {
	if(write(filedesc, OutBuf, (OUT_BUF_SIZE*xlimit)/8) != (OUT_BUF_SIZE*xlimit/8)) {
	    perror(outfile);
	    if(output != VERSATEC)
	    	Error("Bad Write on temp file",RUNTIME);
	      else
		Error("Looks like someone turned off the Versatec",RUNTIME);
	    }
	Clear(OutBuf,(OUT_BUF_SIZE*xlimit)/8);
	xLast = x;
	}
    }

/*
DumpLine()
{
    NoLine++;
    if(NoLine == OUT_BUF_SIZE) {
       if(plot)
    	if(write( filedesc, OutBuf, (OUT_BUF_SIZE*xlimit)/8) != (OUT_BUF_SIZE*xlimit/8)) {
	    perror(outfile);
	    if(output != VERSATEC)
	    	Error("Bad Write on temp file",RUNTIME);
	      else
		Error("Looks like someone turned off the Versatec",RUNTIME);
	    }
    	Clear(OutBuf,(OUT_BUF_SIZE*xlimit)/8);
	NoLine = 0;
	}
    ScanLine = &(OutBuf[(NoLine*xlimit)/32]);
    }
    */

FlushLine()
{
    NoLine++;
    if(plot)
      if(write( filedesc, &(OutBuf[0]), (NoLine*xlimit)/8) != (NoLine*xlimit)/8) {
        perror(outfile);
        Error("Bad Write on temp file",RUNTIME);
        }
    Clear(OutBuf,(OUT_BUF_SIZE*xlimit)/8);
    NoLine = 0;
    ScanLine = OutBuf;
    }

InitFill(){
    switch(output) {
	case VARIAN:
		xlimit = VLIMIT;
		NoPixcels = NormalSize = VMAX;
		xmax = VEXTRA;
		xmin = VMIN;
		resolution = VRESOL;
		break;
	case VSPOOL:
	case VERSATEC:
		xlimit = WLIMIT;
		NoPixcels = NormalSize = WMAX;
		xmax = WEXTRA;
		xmin = WMIN;
		resolution = WRESOL;
		break;;
	case HP2648A:
		xlimit = HLIMIT;
		NoPixcels = NormalSize = xmax = HMAX;
		xmin = HMIN;
		resolution = HRESOL;
		break;;
	default:
		Error("Unknown output device in InitFill",INTERNAL);
	}
    OutBuf = (int *) alloc((int) ((OUT_BUF_SIZE * xlimit)/8));
    ScanLine = OutBuf;
    NoLine = 0;
    xlimitDiv32 = xlimit/32;
    }


vopen()
{
    char s[256];
    int i;
    long clock;
  
    name = getlogin();
    if(Window.ymax != Window.ymin)	/* Check for divide by zero */
    sprintf(s,"%s Window: %d %d %d %d --- Scale: 1 micron is %f inches",
	programName,(int)Window.xmin,(int)Window.xmax,
	(int)Window.ymin,(int)Window.ymax,scale);
    heading = Concat(s,"\n",banner,0);


    if((output==VARIAN || output==HP2648A) && plot) {
   	outfile = (char *) mktemp("/usr/tmp/cifXXXXXX");
	outfile = Concat(outfile,tail,0);
	*tail += 1;	/* insures uniqueness */
   	if((filedesc = creat(outfile,0666)) < 0) {
		perror(outfile);
		Error("Can't create temp file",RUNTIME);
		}
    	fileopen = 1;
	}

    if(output==VSPOOL && plot) {
   	outfile = (char *) mktemp("/usr/tmp/cifXXXXXX");
	outfile = Concat(outfile,tail,0);
	*tail += 1;	/* insures uniqueness */
   	if((filedesc = creat(outfile,0666)) < 0) {
		perror(outfile);
		Error("Can't create temp file",RUNTIME);
		}
    	fileopen = 1;
	}

     if(output==VERSATEC && plot) {
	/* Drive the Versatec directly */
     	while( stat(LOCK, &stbuf) >= 0) {
		sleep(30);
		}

     	if( (i = creat(LOCK, 0666)) < 0) {
		perror(LOCK);
		Error("Can't create lock file",RUNTIME);
		}
	 if( close(i) < 0) {
		perror(LOCK);
		Error("Can't close lock file",RUNTIME);
		}
    	 
	Lock = 1;
     	while(1) {
		if( (filedesc = open(DEVICE, 1)) >= 0) break;
		if( errno != EIO ) {
	    		perror(DEVICE);
			Error("I/O Error",RUNTIME);
	    		}
		if(offline == 0) {
	    		fprintf(stderr,"%s is offline\n",NAME);
	    		offline = 1;
	    		}
		sleep(30);
		}
    	fileopen = 1;
	fprintf(stderr,"Plotting\n");
	ioctl(filedesc,VSETSTATE,prtmd);
	clock = time(0);
	sprintf(s,"%s: %s",getlogin(),ctime(&clock));
	if(write(filedesc,s,LengthString(s)) != LengthString(s) ||
	   write(filedesc,heading,LengthString(heading)) != LengthString(heading)) {
		perror("");
		Error("Can't write on Versatec",RUNTIME);
		}
	write(filedesc,"\n\n",2);
	ioctl(filedesc,VSETSTATE,plotmd);
        }
    }

vclose()
{
    int i;
    fileopen = 0;
    FlushLine();
    if(plot && close(filedesc) < 0) {
	perror("outfile");
	Error("Can't close temp file",RUNTIME);
	}

    if(output==VERSATEC) {
	ioctl(filedesc,VSETSTATE,prtmd);
	for(i=0; i < 10; i++)
	    write(filedesc,"\n\n\n\n\n\n\n\n\n\n",10);
	unlock();
	Lock = 0;
	fprintf(stderr,"Plotting Done\n");
	}

    if(plot && (output==VARIAN)) /* || output==VSPOOL)) */
  	if(vfork() == 0)
	    if(! 1) {
		char *tmpFile;
		char *spoolFile;
		FILE *tmp;
		tmpFile = mktemp("/usr/tmp/cpltXXXXXX");
		if(output==VARIAN)
		    spoolFile = mktemp(VSPLFL);
		  else
		    spoolFile = mktemp(WSPLFL);
		spoolFile = Concat(spoolFile,tail,0);
		if((tmp = fopen(tmpFile,"w")) == NULL) {
		    perror(tmpFile);
		    Error("Can't open temp spool file",RUNTIME);
		    }
		fprintf(tmp,"L%s\n",name);
		fprintf(tmp,"B%s\n",heading);
		fprintf(tmp,"B%s\n",banner);
		fprintf(tmp,"C%s\n",outfile);
		fprintf(tmp,"U%s\n",outfile);
		fclose(tmp);
		link(tmpFile,spoolFile);
		unlink(tmpFile);
		if(output==VARIAN)
			execl(VDAEMON,"vad",0);
		    else
			execl(WDAEMON,"vpd",0);
		Error("Can't start up daemon",RUNTIME);
		}
	      else {
		if(execl(VDUMP,"vdump",outfile,heading,"Plotting Done",0) < 0) {
		    perror(VDUMP);
		    Error("Can't start up plotting routine",RUNTIME);
		    }
		}

    if(plot && output==VSPOOL)
  	if(vfork() == 0)
	    if(!debug) {
		if(execl(VDUMP,"vdump",outfile,heading,"","-W",0) < 0) {
		    perror(VDUMP);
		    Error("Can't start up plotting routine",RUNTIME);
		    }
		}
	      else {
		if(execl(VDUMP,"vdump",outfile,heading,"Plotting Done","-W",0) < 0) {
		    perror(VDUMP);
		    Error("Can't start up plotting routine",RUNTIME);
		    }
		}
  }

unlock()
{
    if(output==VERSATEC && Lock) {
    	if(unlink(LOCK) < 0) {
		perror(LOCK);
		Error("Can't remove lock",RUNTIME);
		}
	if(vfork()==0) {
	    if(execl(DAEMON,DAEMON) < 0) {
  	    	perror(DAEMON);
  	    	Error("Can't start up daemon",RUNTIME);
	    	}
	    }
	}
    }

float
PlotSize()
{
    return(((float) (Top-Bottom))/(resolution * 12.0));
    }

float
PlotScale()
{
   if(Window.ymax == Window.ymin) return(0.0);
   return((100.0 * ((real) xmax))/(resolution * (Window.ymax-Window.ymin)));
   }

FixScale()
/* Set up the correct conversion factor for chip to plotter conversion*/
{
    if(SetScale && scale != 0.0) {
	ConvertFactor = (scale * resolution)/100.0;
	StartNextPlot = GWindow.ymin;
	NoPixcels = xmax;
	}
      else {
   	if(GWindow.ymax == GWindow.ymin) {
	    ConvertFactor = 0.0;
	    scale = 0.0;
	    }
	  else {
	    ConvertFactor = NormalSize/(GWindow.ymax - GWindow.ymin);
	    scale = 100.0 * ((real) NoPixcels)/(resolution * (GWindow.ymax-GWindow.ymin));
	    }
	StartNextPlot = GWindow.ymin;
	}
    }

AdjustWindow()
{
	Window.xmin = GWindow.xmin;
	Window.xmax = GWindow.xmax;
	Window.ymin = StartNextPlot;
	Window.ymax = NoPixcels/ConvertFactor + Window.ymin;
	StartNextPlot = NormalSize/ConvertFactor + Window.ymin;
	if(Window.ymax < GWindow.ymax-1) {
	    MoreToPlot = ((GWindow.ymax - Window.ymax)*ConvertFactor)/NormalSize + 0.9999;
	    }
	  else {
	    MoreToPlot = 0;
	    Window.ymax = GWindow.ymax;
	    NoPixcels = CONVERT(Window.ymax) + 1;
	    }
    }


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.