File:  [CSRG BSD Unix] / 40BSD / cmd / cifplot / edges.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, BSD40
BSD 4.0

/*******************************************************************
*                                                                  *
*    File: CIFPLOT/edges.c                                         *
*    Written by Dan Fitzpatrick                                    *
*    copyright 1980 -- Regents of the University of California     *
*                                                                  *
********************************************************************/

#include <stdio.h>
#include "defs.h"
#include "globals.h"
#include "parser_defs.h"
#include "structs.h"
#include "out_structs.h"
#include <math.h>
#include "alloc.h"

IMPORT point *MakePoint();
IMPORT point *TransPt();
IMPORT Command *MakeFlash();
IMPORT Command *MakeBox();
IMPORT transform *MatrixMult();
IMPORT transform *Translate();
IMPORT real ICompare();
IMPORT real TCompare();
IMPORT StartEdgePath();
IMPORT iedge *NextEdgePath();
IMPORT iedge *EndEdgePath();

FORWARD iedge *MakeEdge();
FORWARD PolyDesc *MakeDesc();
FORWARD instance *MakeItem();

Instanciate(c,trans,n)
Command *c;
transform *trans;
int n;
{
    instance *i;
    Command *p;
    real x,y,xmin,ymin;

    if(c->type != SYMBOL)
	Error("Tried to Instanciate a Non-Symbol",INTERNAL);
    if(depth == 0 || n <= depth) {
    	for(p=c->Ctype.Symbl.CStart; p!=NIL; p=p->CLink) {
	    i = MakeItem(p,trans,n+1);
	    Selector(i);
	    }
        if(symbox) DrawBBox(&(c->CBBox),trans);
        if(*(c->Ctype.Symbl.SName) == '\0') return;
        xmin = c->CBBox.xmin;	ymin = c->CBBox.ymin;
        Trans(&xmin,&ymin,trans);
        
        x = c->CBBox.xmax;	y = c->CBBox.ymin;
        Trans(&x,&y,trans);
        if(x+y < xmin+ymin) { ymin = y; xmin = x; }

        x = c->CBBox.xmax;	y = c->CBBox.ymax;
        Trans(&x,&y,trans);
        if(x+y < xmin+ymin) { ymin = y; xmin = x; }

        x = c->CBBox.xmin;	y = c->CBBox.ymax;
        Trans(&x,&y,trans);
        if(x+y < xmin+ymin) { ymin = y; xmin = x; }

        ClipText(c->Ctype.Symbl.SName,xmin,ymin,'S');
	}
      else {	/* Don't instanciate this symbol; just draw box and name*/
	DrawBBox(&(c->CBBox),trans);
        if(*(c->Ctype.Symbl.SName) == '\0') return;
        xmin = c->CBBox.xmin;	ymin = c->CBBox.ymin;
        Trans(&xmin,&ymin,trans);
        x = c->CBBox.xmax;	y = c->CBBox.ymax;
        Trans(&x,&y,trans);
	x = (xmin+x)/2;		y = (ymin+y)/2;
        ClipText(c->Ctype.Symbl.SName,x,y,'C');
	}
    }

Activate(i)
instance *i;
{
    switch(i->type) {
	case CALL:
	    {	transform *t;
		t = MatrixMult(i->item->Ctype.Call.trans,i->trans);
		Instanciate(i->item->Ctype.Call.CSymb,t,i->depth);
		}
		FreeItem(i);
		break;
	case ARRAY:
	    {   int j,k;
		point pt;
		transform *trans,*t;
		instance *inst;

		pt.x = 0.0;
		for(j=0; j<i->item->Ctype.Array.Am; j++) {
		    pt.y = 0.0;
		    for(k=0; k<i->item->Ctype.Array.An; k++) {
			trans = Translate(&pt,ident);
			t = MatrixMult(trans,i->trans);
			FreeTransform(trans);
			inst = MakeItem(i->item->Ctype.Array.ACom,t,i->depth);
			Selector(inst);
			pt.y += i->item->Ctype.Array.Ady;
			}
		    pt.x += i->item->Ctype.Array.Adx;
		    }
		}
		break;
	case POLYGON:
	    {	PolyDesc *poly;
		PointList *path;
		iedge *e;
		point *pt;

		poly = MakeDesc(i->item);
		path = i->item->Ctype.Path;
		pt = &(path->pt);
		StartEdgePath(pt->x,pt->y,i->trans,poly);
		/* Assertion: there are at least two points
		 * in every polygon	*/
		for(path = path->PLink; path != NIL; path = path->PLink){
			pt = &(path->pt);
			e = NextEdgePath(pt->x,pt->y);
			Selector(e);
			}
		e = EndEdgePath();
		Selector(e);
		}
		FreeItem(i);
		break;
	case BOX:
	    {	PolyDesc *poly;
		point *d;
		real ly,lx,wx,wy,cx,cy,c;
		iedge *e;
		
		poly = MakeDesc(i->item);
		d = &(i->item->Ctype.Box.bdirect);
		c = sqrt(d->x*d->x + d->y*d->y);
		cx = i->item->Ctype.Box.bcenter.x;
		cy = i->item->Ctype.Box.bcenter.y;
		lx = (d->x*i->item->Ctype.Box.blength)/(c*2.0);
		ly = (d->y*i->item->Ctype.Box.blength)/(c*2.0);
		wx = -(d->y*i->item->Ctype.Box.bwidth)/(c*2.0);
		wy = (d->x*i->item->Ctype.Box.bwidth)/(c*2.0);
		StartEdgePath(cx-lx-wx,cy-ly-wy,i->trans,poly);
		e = NextEdgePath(cx-lx+wx,cy-ly+wy);
		Selector(e);
		e = NextEdgePath(cx+lx+wx,cy+ly+wy);
		Selector(e);
		e = NextEdgePath(cx+lx-wx,cy+ly-wy);
		Selector(e);
		e = EndEdgePath();
		Selector(e);
		/*
		e = MakeEdge(cx-lx-wx,cy-ly-wy,cx-lx+wx,cy-ly+wy,i->trans,poly);
		Selector(e);
		e = MakeEdge(cx-lx+wx,cy-ly+wy,cx+lx+wx,cy+ly+wy,i->trans,poly);
		Selector(e);
		e = MakeEdge(cx+lx+wx,cy+ly+wy,cx+lx-wx,cy+ly-wy,i->trans,poly);
		Selector(e);
		e = MakeEdge(cx+lx-wx,cy+ly-wy,cx-lx-wx,cy-ly-wy,i->trans,poly);
		Selector(e);
		*/
		FreeItem(i);
		}
		break;
	case FLASH:
	    {	PolyDesc *poly;

		poly = MakeDesc(i->item);
		MakeNgon(circle,&(i->item->Ctype.Flash.fcenter),i->item->Ctype.Flash.fdia/2.0,i->trans,poly);
		}
		FreeItem(i);
		break;
	case WIRE:
	    {	real width;
		PointList *p1,*p2;
		Command *com;
		instance *inst;
		point *dir,*cen;
		real x,y;
		int level;

		if(i->item->Ctype.Wire.WIns == NIL) {
		    width = i->item->Ctype.Wire.WWidth;
		    level = i->item->level;
		    p1 = i->item->Ctype.Wire.WPath;
		    com = MakeFlash(width,&(p1->pt));
		    com->level = level;
		    com->CLink = NIL;
		    i->item->Ctype.Wire.WIns = com;
		    inst = MakeItem(com,i->trans,i->depth);
		    Selector(inst);
		    for((p2=p1,p1=p1->PLink);p1 != NIL;(p2=p1,p1=p1->PLink)) {
			x = p1->pt.x - p2->pt.x; y = p1->pt.y - p2->pt.y;
			com = MakeFlash(width,&(p1->pt));
			com->level = level;
			com->CLink = i->item->Ctype.Wire.WIns;
			i->item->Ctype.Wire.WIns = com;
			inst = MakeItem(com,i->trans,i->depth);
			Selector(inst);

			dir = MakePoint(x,y);
			cen = MakePoint((p1->pt.x + p2->pt.x)/2.0,(p1->pt.y + p2->pt.y)/2.0);
			com = MakeBox(sqrt(x*x+y*y),width,cen,dir);
			com->level = level;
			com->CLink = i->item->Ctype.Wire.WIns;
			i->item->Ctype.Wire.WIns = com;
			inst = MakeItem(com,i->trans,i->depth);
			Selector(inst);
			Free(cen); Free(dir);
			}
		    }
		  else {
		    for(com=i->item->Ctype.Wire.WIns;com!=NIL;com=com->CLink) {
			inst = MakeItem(com,i->trans,i->depth);
			Selector(inst);
			}
		    }
		}
		FreeItem(i);
		break;
	case EDGE:
		Clip(i);
		if(--(((iedge *) i)->poly->refs) == 0)
			FreeDesc(((iedge *) i)->poly);
		FreeIEdge(i);
		break;
	case POINTNAME:
	    {   real x,y;
		x = i->item->Ctype.PointName.loc.x;
		y = i->item->Ctype.PointName.loc.y;
		Trans(&x,&y,i->trans);
		if(!extractor)
		    ClipText(i->item->Ctype.PointName.Name,x,y,'T');
		  else
		    OutputExtPoint(x,y,i->item->Ctype.PointName.Name,
				    i->item->level);
		}
		break;
	case STEXT:
	    {   real x,y;
		Command *icom;
		icom = (Command *) i;

		x = icom->Ctype.PointName.loc.x;
		y = icom->Ctype.PointName.loc.y;
		ClipText(icom->Ctype.PointName.Name,x,y,'T');
		FreeStif(icom);
		}
		break;
	case VECTOR:
	    {   Command *icom;
		PointList *p1,*p2;
		icom = (Command *) i;

		p1 = icom->Ctype.Path;
		if(p1 == NIL) Error("Vector has null path in edge",INTERNAL);
		for((p2=p1,p1=p1->PLink); p1 != NIL;(p2=p1,p1=p1->PLink)) {
		    MakeLine(p1->pt.x,p1->pt.y,p2->pt.x,p2->pt.y,ident);
		    }
		FreeStif(icom);
		}
		break;
	case SPOLYGON:
	    {	PolyDesc *poly;
		PointList *path;
		iedge *e;
		point *pt;
		Command *icom;
		icom = (Command *) i;
		i = (instance *) 0xffffffff; /* debugging */

		poly = MakeDesc(icom);
		path = icom->Ctype.Path;
		pt = &(path->pt);
		StartEdgePath(pt->x,pt->y,ident,poly);
		/* Assertion: there are at least two points
		 * in every polygon	*/
		for(path = path->PLink; path != NIL; path = path->PLink){
			pt = &(path->pt);
			e = NextEdgePath(pt->x,pt->y);
			Selector(e);
			}
		e = EndEdgePath();
		Selector(e);
		FreeStif(icom);
		}
		break;
	case SFLASH:
	    {	PolyDesc *poly;
		Command *icom;
		icom = (Command *) i;
		i = (instance *) 0xffffffff; /* debugging */

		poly = MakeDesc(icom);
		MakeNgon(circle,&(icom->Ctype.Flash.fcenter),icom->Ctype.Flash.fdia/2.0,ident,poly);
		FreeStif(icom);
		}
		break;
	case SWIRE:
	    {	real width;
		PointList *p1,*p2;
		Command *ncom;
		instance *inst;
		point *dir,*cen;
		real x,y;
		int level;
		Command *icom;
		icom = (Command *) i;
		i = (instance *) 0xffffffff; /* debugging */

		width = icom->Ctype.Wire.WWidth;
		level = icom->level;
		p1 = icom->Ctype.Wire.WPath;
		ncom = MakeFlash(width,&(p1->pt));
		ncom->level = level;
		ncom->CLink = NIL;
		inst = MakeItem(ncom,ident,0);
		Selector(inst);
		for((p2=p1,p1=p1->PLink);p1 != NIL;(p2=p1,p1=p1->PLink)) {
		    x = p1->pt.x - p2->pt.x; y = p1->pt.y - p2->pt.y;
		    ncom = MakeFlash(width,&(p1->pt));
		    ncom->level = level;
		    inst = MakeItem(ncom,ident,0);
		    Selector(inst);

		    dir = MakePoint(x,y);
		    cen = MakePoint((p1->pt.x + p2->pt.x)/2.0,(p1->pt.y + p2->pt.y)/2.0);
		    ncom = MakeBox(sqrt(x*x+y*y),width,cen,dir);
		    ncom->level = level;
		    inst = MakeItem(ncom,ident,0);
		    Selector(inst);
		    Free(cen); Free(dir);
		    }
		FreeStif(icom);
		}
		break;
	case SCALL:
		StifCall(i);
		FreeStif(i);
		break;
	default:
		Error("Tried to Activate Unknown type",INTERNAL);
	}
    }

instance *
MakeItem(c,trans,n)
Command *c;
transform *trans;
int n;
{
    instance *i;

    i = GetItem();
    i->type = c->type;
    i->Link = NIL;
    i->trans = trans;
    trans->refs++;
    i->item = c;
    i->depth = n;
    return(i);
    }
		
iedge *
MakeEdge(rx1,ry1,rx2,ry2,trans,poly)
real rx1,rx2,ry1,ry2;
transform *trans;
PolyDesc *poly;
{
    iedge *e;
    real t;
    
    e = GetIEdge();
    e->type = EDGE;
    e->poly = poly;
    (poly->refs)++;
    Trans(&rx1,&ry1,trans);
    Trans(&rx2,&ry2,trans);
    if(rx1 <= rx2)  e->dir = 1;
	else {	e->dir = -1;
		SWAP(rx1,rx2,t);
		SWAP(ry1,ry2,t);
		}
    /* Now rx1 <= rx2 and the direction is set */
    /* Now convert from CIF units to plotter units */
    e->x1 = CONVERT(rx1); e->y1 = CONVERT(ry1);
    e->x2 = CONVERT(rx2); e->y2 = CONVERT(ry2);
    e->min = CONVERT(rx1);
    return(e);
    }

PolyDesc *
MakeDesc(c)
Command *c;
{
    PolyDesc *p;

    p = GetDesc();
    if(c != NIL)
    	p->level = c->level;
     else
	p->level = 0;
    p->count = 0;
    p->refs = 0;
    return(p);
    }

/*
FreeInstance(i)
instance *i;
{
    if(--(i->trans->refs) == 0) FreeTransform(i->trans);
    FreeItem(i);
    }
    */


unix.superglobalmegacorp.com

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