⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graf.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1988 Jeffrey M. Hsu$Id: graf.c,v 1.9 2005/05/29 01:05:33 sjborley Exp $**********//* *  Most of the gr_ module resides here, in particular, gr_init *      and gr_point, expect for the gr_ grid routines. * */#include <ngspice.h>#include "cpdefs.h"		/* for VT_ */#include "cpextern.h"#include <plot.h>#include "ftedebug.h"		/* for iplot */#include <dvec.h>		/* for struct dvec */#include "ftedefs.h"		/* for FTEextern.h and IPOINT{MIN,MAX} */#include "fteinput.h"#include <graph.h>#include "ftedbgra.h"#include "ftedev.h"#include <terminal.h>#include <variable.h>#include "graf.h"#include "graphdb.h"#include "grid.h"#include "../terminal.h"#include "../breakp2.h"#include "../error.h"#include "../display.h"#include "../runcoms.h"/* static declarations */static void gr_start_internal(struct dvec *dv, bool copyvec);static int iplot(struct plot *pl, int id);static void set(struct plot *plot, struct dbcomm *db, bool unset, int mode);static char * getitright(char *buf, double num);/* for legends, set in gr_start, reset in gr_iplot and gr_init */static int plotno;static int curcolor = 1;        /* for assigning unique colors */static int curlst = 0;          /* for assigning line styles *//* invariant:  currentgraph contains the current graph *//* These are what gets plotted as points when you specify point plots */static char pointchars[128];#define DEFPOINTCHARS   "oxabcdefhgijklmnpqrstuvwyz"/* Buffer for ticmarks if given a list */static char ticbuf[1024];static char *ticlist = ticbuf;#define MAXTICS 100double *readtics(char *string);#define XFACTOR 2       /* How much to expand the X scale during iplot. */#define YFACTOR 1.5     /* How much to expand the Y scale during iplot. *//* *  Start of a new graph. *  Fill in the data that gets displayed. *  Difference from old gr_init *    we don't try to determine the look of the screen from here *    leave to lower level routines * */intgr_init(double *xlims, double *ylims, /* The size of the screen. */	char *xname, char *plotname, /* What to label things. */	char *hcopy,		/* The raster file. */	int nplots,		/* How many plots there will be. */	double xdelta, double ydelta, /* Line increments for the scale. */	GRIDTYPE gridtype,	/* The grid type */	PLOTTYPE plottype,	/*  and the plot type. */	char *xlabel, char *ylabel, /* Labels for axes. */	int xtype, int ytype,	/* The types of the data graphed. */	char *pname,	char *commandline)	/* For xi_zoomdata() */{    GRAPH *graph;    int b;    wordlist *wl;    char *comb_title;    if (!(graph = NewGraph())) {      return(FALSE);    }    /*        The global currentgraph will always be the current graph.    */    SetGraphContext(graph->graphid);    graph->onevalue = (xname ? FALSE : TRUE);    /* communicate filename to plot 5 driver */    if (hcopy) {      graph->devdep = hcopy;    }    plotno = 0;    /* note: should do only once, maybe in gr_init_once */    if (!cp_getvar("pointchars", VT_STRING, pointchars))          (void) strcpy(pointchars, DEFPOINTCHARS);    if (!cp_getvar("ticmarks", VT_NUM, (char *) &graph->ticmarks)) {      if (cp_getvar("ticmarks", VT_BOOL, (char *) &b))        graph->ticmarks = 10;      else        graph->ticmarks = 0;    }    if (cp_getvar("ticlist", VT_LIST, ticlist)) {	wl = (wordlist *)vareval("ticlist");	ticlist = (char *)wl_flatten(wl);	graph->ticdata = (double *) readtics(ticlist);    } else	graph->ticdata = NULL;    if (!xlims || !ylims) {      internalerror("gr_init:  no range specified");      return(FALSE);    }    /* save upper and lower limits */    graph->data.xmin = xlims[0];    graph->data.xmax = xlims[1];    graph->data.ymin = ylims[0];    graph->data.ymax = ylims[1];/* get title into plot window */#ifdef HAS_WINDOWS    if (!pname)	pname = "(unknown)";    if (!plotname)	plotname = "(unknown)";    comb_title = tmalloc(strlen(plotname) + strlen(pname) + 3);    sprintf(comb_title, "%s: %s", pname, plotname);    graph->plotname = comb_title;#endif    /* note: have enum here or some better convention */    if (NewViewport(graph) == 1) {      /* note: where is the error message generated? */      /* note: undo tmallocs */      fprintf(cp_err, "Can't open viewport for graphics.\n");      return(FALSE);    }    /* layout decisions */    /* note: have to do before gr_fixgrid and after NewViewport */    graph->viewportxoff = graph->fontwidth * 8; /* 8 lines on left */    graph->viewportyoff = graph->fontheight * 4;    /* 4 on bottom */    DevClear();    graph->grid.gridtype = gridtype;    graph->plottype = plottype;    graph->grid.xdatatype = xtype;    graph->grid.ydatatype = ytype;    graph->grid.xdelta = xdelta;    graph->grid.ydelta = ydelta;    graph->grid.ysized = 0;    graph->grid.xsized = 0;    if (!graph->onevalue) {        if (xlabel) {            graph->grid.xlabel = xlabel;        } else {            graph->grid.xlabel = xname;        }        if (ylabel) {            graph->grid.ylabel = ylabel;        }    } else {        if (xlabel) {            graph->grid.xlabel = xlabel;        } else {            graph->grid.xlabel = "real";        }        if (ylabel) {            graph->grid.ylabel = ylabel;        } else {            graph->grid.ylabel = "imag";        }    }#ifndef HAS_WINDOWS    if (!pname)	pname = "(unknown)";    if (!plotname)	plotname = "(unknown)";    comb_title = tmalloc(strlen(plotname) + strlen(pname) + 3);    sprintf(comb_title, "%s: %s", pname, plotname);    graph->plotname = comb_title;#endif    gr_resize_internal(graph);    gr_redrawgrid(graph);    /* Set up colors and line styles. */    if (dispdev->numlinestyles == 1)        curlst = 0; /* Use the same one all the time. */    else        curlst = 1;    /* XXX Special exception for SMITH */    if (dispdev->numcolors > 2 && (graph->grid.gridtype == GRID_SMITH	|| graph->grid.gridtype == GRID_SMITHGRID))    {        curcolor = 3;    } else        curcolor = 1;    graph->commandline = copy(commandline);    return(TRUE);}/* *  Add a point to the curve we're currently drawing. *  Should be in between a gr_init() and a gr_end() *    expect when iplotting, very bad hack *  Differences from old gr_point: *    We save points here, instead of in lower levels. *    Assume we are in right context *  Save points in data space (not screen space). *  We pass two points in so we can multiplex plots. * */voidgr_point(struct dvec *dv,	 double newx, double newy,	 double oldx, double oldy,	 int np){    int oldtox, oldtoy;     /* value before clipping */    char pointc[2];    int fromx, fromy, tox, toy;    int ymin, dummy;    DatatoScreen(currentgraph, oldx, oldy, &fromx, &fromy);    DatatoScreen(currentgraph, newx, newy, &tox, &toy);    /* note: we do not particularly want to clip here */    oldtox = tox; oldtoy = toy;    if (!currentgraph->grid.circular) {      if (clip_line(&fromx, &fromy, &tox, &toy,        currentgraph->viewportxoff, currentgraph->viewportyoff,        currentgraph->viewport.width + currentgraph->viewportxoff,        currentgraph->viewport.height + currentgraph->viewportyoff))        return;    } else {      if (clip_to_circle(&fromx, &fromy, &tox, &toy,            currentgraph->grid.xaxis.circular.center,            currentgraph->grid.yaxis.circular.center,            currentgraph->grid.xaxis.circular.radius))        return;    }    if (currentgraph->plottype != PLOT_POINT) {      SetLinestyle(dv->v_linestyle);    } else {      /* if PLOT_POINT,           don't want to plot an endpoint which have been clipped */      if (tox != oldtox || toy != oldtoy)    return;    }    SetColor(dv->v_color);    switch (currentgraph->plottype) {      double	*tics;      case PLOT_LIN:	/* If it's a linear plot, ignore first point since we don't	   want to connect with oldx and oldy. */	if (np)	    DrawLine(fromx, fromy, tox, toy);	if ((tics = (double *) currentgraph->ticdata)) {	    for (; *tics < HUGE; tics++) {		if (*tics == (double) np) {		    Text("x", (int) (tox - currentgraph->fontwidth / 2),			(int) (toy - currentgraph->fontheight / 2));		/* gr_redraw will redraw this w/o our having to save it                   Guenther Roehrich 22-Jan-99 */		/*    SaveText(currentgraph, "x",			(int) (tox - currentgraph->fontwidth / 2),			(int) (toy - currentgraph->fontheight / 2)); */		    break;		}	    }	} else if ((currentgraph->ticmarks >0) && (np > 0)	    && (np % currentgraph->ticmarks == 0))	{	    /* Draw an 'x' */	    Text("x", (int) (tox - currentgraph->fontwidth / 2),		(int) (toy - currentgraph->fontheight / 2));	 /* gr_redraw will redraw this w/o our having to save it                  Guenther Roehrich 22-Jan-99 */ 	  /*  SaveText(currentgraph, "x",		(int) (tox - currentgraph->fontwidth / 2),		(int) (toy - currentgraph->fontheight / 2)); */	}        break;      case PLOT_COMB:        DatatoScreen(currentgraph,                (double) 0, currentgraph->datawindow.ymin,                &dummy, &ymin);        DrawLine(tox, ymin, tox, toy);        break;      case PLOT_POINT:        /* Here, gi_linestyle is the character used for the point.  */        pointc[0] = dv->v_linestyle;        pointc[1] = '\0';        Text(pointc, (int) (tox - currentgraph->fontwidth / 2),            (int) (toy - currentgraph->fontheight / 2));      default:        break;    }}static voidgr_start_internal(struct dvec *dv, bool copyvec){    struct dveclist *link;    char *s;    /* Do something special with poles and zeros.  Poles are 'x's, and     * zeros are 'o's.  */    s = ft_typenames(dv->v_type);        if (eq(s, "pole")) {                dv->v_linestyle = 'x';                return;        } else if (eq(s, "zero")) {                dv->v_linestyle = 'o';                return;        }    /* Find a (hopefully) new line style and color. */    if (currentgraph->plottype == PLOT_POINT) {	if (pointchars[curlst - 1])	    curlst++;	else	    curlst = 2;    } else if ((curlst > 0) && (++curlst == dispdev->numlinestyles))	curlst = 2;    if ((curcolor > 0) && (++curcolor == dispdev->numcolors))	curcolor = (((currentgraph->grid.gridtype == GRID_SMITH	    || currentgraph->grid.gridtype == GRID_SMITHGRID) &&	    (dispdev->numcolors > 3)) ? 4 : 2);    if (currentgraph->plottype == PLOT_POINT)	dv->v_linestyle = pointchars[curlst - 2];    else	dv->v_linestyle = curlst;    dv->v_color = curcolor;    /* save the data so we can refresh */    link = (struct dveclist *) tmalloc(sizeof(struct dveclist));    link->next = currentgraph->plotdata;    if (copyvec) {      link->vector = vec_copy(dv);      /* vec_copy doesn't set v_color or v_linestyle */      link->vector->v_color = dv->v_color;      link->vector->v_linestyle = dv->v_linestyle;      link->vector->v_flags |= VF_PERMANENT;    } else {      link->vector = dv;    }    currentgraph->plotdata = link;    /* Put the legend entry on the screen. */    drawlegend(currentgraph, plotno, dv);    plotno++;}/* start one plot of a graph */voidgr_start(struct dvec *dv){    gr_start_internal(dv, TRUE);}/* make sure the linestyles in this graph don't exceed the number of   linestyles available in the current display device */voidgr_relinestyle(GRAPH *graph){    struct dveclist *link;    for (link = graph->plotdata; link; link = link->next) {      if (graph->plottype == PLOT_POINT) continue;      if (!(link->vector->v_linestyle < dispdev->numlinestyles)) {        link->vector->v_linestyle %= dispdev->numlinestyles;      }      if (!(link->vector->v_color < dispdev->numcolors)) {        link->vector->v_color %= dispdev->numcolors;      }    }} /* PN  static */voiddrawlegend(GRAPH *graph, int plotno, struct dvec *dv){    int x, y, i;    char buf[16];    x = ((plotno % 2) ? graph->viewportxoff :            ((graph->viewport.width) / 2));    y = graph->absolute.height - graph->fontheight            - ((plotno + 2) / 2) * (graph->fontheight);    i = y + graph->fontheight / 2 + 1;    SetColor(dv->v_color);    if (graph->plottype == PLOT_POINT) {        (void) sprintf(buf, "%c : ", dv->v_linestyle);        Text(buf, x + graph->viewport.width / 20                - 3 * graph->fontwidth, y);    } else {        SetLinestyle(dv->v_linestyle);        DrawLine(x, i, x + graph->viewport.width / 20, i);    }    SetColor(1);    Text(dv->v_name, x + graph->viewport.width / 20            + graph->fontwidth, y);}/* end one plot of a graph */voidgr_end(struct dvec *dv){    Update();}/* Print text in the bottom line. */voidgr_pmsg(char *text){    char buf[BSIZE_SP];    buf[0] = 0;    Update();    if (cp_getvar("device", VT_STRING, buf)	    && !(strcmp("/dev/tty", buf) == 0))	fprintf(cp_err, "%s", text);    else		/* MW. grid.xlabel may be NULL */	if (currentgraph->grid.xlabel)	    Text(text, currentgraph->viewport.width		 - (strlen(currentgraph->grid.xlabel) + 3)		 * currentgraph->fontwidth,		 currentgraph->absolute.height - currentgraph->fontheight);	else	    fprintf(cp_err, " %s \n", text);	    Update();    return;}voidgr_clean(void){    Update();    return;}/* call this routine after viewport size changes */voidgr_resize(GRAPH *graph){    double oldxratio, oldyratio;    double scalex, scaley;    struct _keyed *k;    oldxratio = graph->aspectratiox;    oldyratio = graph->aspectratioy;    graph->grid.xsized = 0;    graph->grid.ysized = 0;    gr_resize_internal(graph);    /* scale keyed text */    scalex = oldxratio / graph->aspectratiox;    scaley = oldyratio / graph->aspectratioy;    for (k = graph->keyed; k; k = k->next) {      k->x = (k->x - graph->viewportxoff) * scalex + graph->viewportxoff;      k->y = (k->y - graph->viewportyoff) * scaley + graph->viewportyoff;    }    /* X also generates an expose after a resize.       This is handled in X10 by not redrawing on resizes and waiting       for the expose event to redraw.  In X11, the expose routine       tries to be clever and only redraws the region specified in an       expose event, which does not cover the entire region of the       plot if the resize was from a small window to a larger window.       So in order to keep the clever X11 expose event handling, we       have the X11 resize routine pull out expose events for that       window, and we redraw on resize also.  */#ifdef X_DISPLAY_MISSING    gr_redraw(graph);#endif}/* PN static */ voidgr_resize_internal(GRAPH *graph)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -