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

📄 graf.c

📁 支持数字元件仿真的SPICE插件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  $Header: //pepper/atesse_spice/spice3/FTE/RCS/graf.c,v 1.1 91/04/02 12:11:41 bill Exp $ *  Copyright 1988 Jeffrey M. Hsu * *  Most of the gr_ module resides here, in particular, gr_init *      and gr_point, expect for the gr_ grid routines. * */#include "prefix.h"#include "CPdefs.h"     /* for VT_ */#ifndef CMS#include "FTEconstant.h"#else  /* CMS */#include "FTEconst.h"#endif /* CMS */#include "FTEdebug.h"       /* for iplot */#include "FTEdata.h"        /* for struct dvec */#include "FTEdefs.h"        /* for FTEextern.h and IPOINT{MIN,MAX} */#include "FTEgraph.h"#ifndef CMS#include "FTEdbgraph.h"#else  /* CMS */#include "FTEdbgra.h"#endif /* CMS */#ifndef CMS#include "FTEdevice.h"#else  /* CMS */#include "FTEdevic.h"#endif /* CMS */#include "suffix.h"extern struct dbcomm *dbs;  /* for iplot *//* note: let's try to get rid of these *//* global variables *//* Graphics mode in progress, so signal handlers know to call gr_clean *//* bool gr_gmode = false; *//* 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"#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 * *//* ARGSUSED */ /* since we don't really use many of them */gr_init(xlims, ylims, xname, plotname, hcopy, nplots, xdelta, ydelta, gridtype,                plottype, xlabel, ylabel, xtype, ytype, pname, commandline)        double *xlims, *ylims;          /* The size of the screen. */        char *xname, *plotname;         /* What to label things. */    char *hcopy;                    /* The raster file. */        int nplots;                     /* How many plots there will be. */        double xdelta, ydelta;          /* Line increments for the scale. */        GRIDTYPE gridtype;              /* The grid type ... */        PLOTTYPE plottype;              /*  and the plot type. */        char *xlabel, *ylabel;          /* Labels for axes. */        int xtype, ytype;               /* The types of the data graphed. */        char *pname;        char *commandline;              /* For xi_zoomdata()... */{    GRAPH *graph;    int b;    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;    }    /* set slow flag to stop between each plot and prompt the        user for a return       This is used mainly for graphics terminals w/o windows.    *//*    if (incremental)      slow = false;    else      (void) cp_getvar("slowplot", VT_BOOL, (char *) &slow);*/    if (!xlims || !ylims) {      internalerror("gr_init:  no range specified");      return(false);    }    /* indicate some graphics going on *//*  gr_gmode = true; */    /* set upper and lower limits */    graph->datawindow.xmin = xlims[0];    graph->datawindow.xmax = xlims[1];    graph->datawindow.ymin = ylims[0];    graph->datawindow.ymax = ylims[1];    /* note: have enum here or some better convention */    if (NewViewport(graph) == 1) {      /* note: where is the error message generated? */      /* note: undo mallocs */      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;    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.xlabel = "imag";        }    }    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;    if (dispdev->numcolors > 2)        curcolor = (graph->grid.gridtype == GRID_SMITH) ? 3 : 1;    else        curcolor = 1;    graph->commandline = copy(commandline);    graph->plotname = copy(pname);    /* note: what do we do with plotname?  use it as label XXX */    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(dv, newx, newy, oldx, oldy, np)struct dvec *dv;double newx, newy, oldx, oldy;int np;{    int oldtox, oldtoy;     /* value before clipping */    char pointc[2];    int fromx, fromy, tox, toy;    int ymin, dummy;    /* If it's a linear plot, ignore first point since we don't want        to connect with oldx and oldy. */    if (dv->v_plottype == PLOT_LIN && !np) return;    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) {      case PLOT_LIN:        DrawLine(fromx, fromy, tox, toy);        if ((currentgraph->ticmarks >0) && (np > -1)                && (np % currentgraph->ticmarks == 0)) {          /* Draw an 'x' */          Text("x", (int) (tox - currentgraph->fontwidth / 2),                (int) (toy - currentgraph->fontheight / 2));          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));        /* gr_redraw will redraw this w/o our having to save it */        /* SaveText(currentgraph, pointc,            (int) (tox - currentgraph->fontwidth / 2),            (int) (toy - currentgraph->fontheight / 2)); */      default:        break;    }}static voidgr_start_internal(dv, copyvec)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 &&                (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;/* note: XXX */#ifdef notdef    /* This is a minor hack -- reset the color... */    if (dv->v_defcolor)        ReSetColor(curcolor, dv->v_defcolor);#endif    /* save the data so we can refresh */    link = (struct dveclist *) calloc(1, 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(dv)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 */gr_relinestyle(graph)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;      }    }}staticdrawlegend(graph, plotno, dv)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(dv)struct dvec *dv;{    Update();#ifdef GI_MFB    /* hack! */    if (!strcmp(dispdev->name, "MFB") && dv->v_link2 == NULL) {      gr_pmsg("Hit return to continue");      MFBHalt();    }#endif}/* Print text in the bottom line. */voidgr_pmsg(text)    char *text;{#ifdef HPUX    char buf[128];#endif /* HPUX */    Update();    Text(text, currentgraph->absolute.width / 2,            currentgraph->fontheight);    Update();#ifdef HPUX /* This is crazy... Timeouts on read... Ack... */        while (read(0, buf, 1) < 1)            ;#else        (void) getchar();#endif    return;}

⌨️ 快捷键说明

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