home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / disks / disk373.lzh / Multiplot / source / mplot_src / src.zoo / plot.c < prev    next >
C/C++ Source or Header  |  1990-08-02  |  24KB  |  872 lines

  1. #include "struct.h"
  2. #include "plot.h"
  3. #include <graphics/gfxmacros.h>
  4.  
  5. extern struct Window *window;
  6. extern struct TextBox *ExtraText;
  7. extern int CHARWIDTH;
  8. extern int CHARHEIGHT;
  9. extern int LMARGIN;  /* CHARWIDTH x 7 */
  10. extern int RMARGIN;
  11. extern int TMARGIN;
  12. extern int BMARGIN;    /* CHARHEIGHT x 3 */
  13. extern int XMINP;      /* LMARGIN */
  14. extern int XMAXP;      /* MAXHORIZ - RMARGIN */
  15. extern int YMAXP;   /* MAXVERT - TMARGIN */
  16. extern int YMINP;    /* BMARGIN */
  17.  
  18. int OLD_XMINP;
  19. int CALC_XMIN;
  20. int CALC_YMIN;
  21. int OLD_YMIN;
  22.  
  23. /*** PLOT TYPES ***/
  24. #define LINEPLOT 0
  25. #define POINTPLOT 1
  26. #define BOTHPLOT 2
  27. #define STEP 3
  28.  
  29. extern int debug;
  30. extern int MAXVERT;
  31. extern int MAXHORIZ;
  32.  
  33. extern FFP fround();
  34. extern struct Pict *Pict;
  35. extern struct Menu Project;
  36.  
  37. #define ON 1
  38. #define OFF 0
  39.  
  40.  
  41. struct TextAttr xfont = { "Courier.font", 14, 0, 1 };
  42. struct TextAttr yfont = { "Courier.font", 14, 0, 1 };
  43. struct TextAttr tfont = { "Courier.font", 24, 0, 1 };
  44. struct TextAttr lfont = { "Courier.font", 14, 0, 1 };
  45.  
  46.  
  47. struct IntuiText XITLabel = {
  48.         1,0,JAM1, /* front and back text pens, drawmode and fill byte */
  49.         0,0,    /* XY origin relative to container TopLeft */
  50.         &xfont,   /* font pointer or NULL for default */
  51.         NULL,     /* pointer to text */
  52.         NULL    /* next IntuiText structure */
  53. };
  54.  
  55. struct IntuiText YITLabel = {
  56.         1,0,JAM1, /* front and back text pens, drawmode and fill byte */
  57.         0,0,    /* XY origin relative to container TopLeft */
  58.         &yfont,   /* font pointer or NULL for default */
  59.         NULL,     /* pointer to text */
  60.         NULL    /* next IntuiText structure */
  61. };
  62.  
  63. struct IntuiText TITLabel = {
  64.         1,0,JAM1, /* front and back text pens, drawmode and fill byte */
  65.         0,0,    /* XY origin relative to container TopLeft */
  66.         &tfont,   /* font pointer or NULL for default */
  67.         NULL,     /* pointer to text */
  68.         NULL    /* next IntuiText structure */
  69. };
  70.  
  71. struct IntuiText Legend = {
  72.         1,0,JAM1, /* front and back text pens, drawmode and fill byte */
  73.         0,0,    /* XY origin relative to container TopLeft */
  74.         &lfont,   /* font pointer or NULL for default */
  75.         NULL,     /* pointer to text */
  76.         NULL    /* next IntuiText structure */
  77. };
  78.  
  79. int OLD_XMINP;
  80. int CALC_XMIN;
  81. int CALC_YMIN;
  82. int OLD_YMINP;
  83.  
  84. struct TextFont *xf;
  85. struct TextFont *yf;
  86. struct TextFont *tf;
  87. struct TextFont *lf;
  88.  
  89. AllowForText(Pict)
  90. struct Pict *Pict;
  91. {
  92. int i,n=3;
  93. struct Tics *Tics;
  94. char tmpstr[20];
  95. struct Plot *Plot;
  96.  
  97.    OLD_YMINP=YMINP;
  98.    if (strlen(Pict->XLabel->String)) {
  99.       if (!xf) xf =(struct TextFont *) OpenDiskFont(&xfont);
  100.       if (xf)  {
  101.                  YMINP = BMARGIN=( xfont.ta_YSize +CHARHEIGHT *4);
  102.                }
  103.       else YMINP = BMARGIN= CHARHEIGHT *5;
  104.    }
  105.    else YMINP=BMARGIN= CHARHEIGHT*3;
  106.    if (OLD_YMINP!=YMINP) CALC_YMIN=TRUE;
  107.  
  108.    if (strlen(Pict->Title)) {
  109.       if (!tf) tf=(struct TextFont *) OpenDiskFont(&tfont);
  110.       if (tf) {
  111.                 YMAXP = MAXVERT - (TMARGIN=( tfont.ta_YSize +CHARHEIGHT *2));
  112.               }
  113.       else YMAXP = MAXVERT- (TMARGIN=CHARHEIGHT*4);
  114.    }
  115.    else YMAXP=MAXVERT-(TMARGIN=CHARHEIGHT*2);
  116.  
  117.    if (!lf) lf=(struct TextFont *) OpenDiskFont(&lfont);
  118.    RMARGIN=2;
  119.    if (Pict->RMargin) {
  120.      Plot=Pict->Plot;
  121.      while (Plot)
  122.        {
  123.           Legend.IText=Plot->Legend->String;
  124.           if (lf) { RMARGIN= max(RMARGIN,IntuiTextLength(&Legend)); }
  125.           else RMARGIN= max(RMARGIN,(strlen(Plot->Legend->String)*CHARWIDTH));
  126.           while (Plot->Continued) Plot=Plot->NextPlot;
  127.           Plot=Plot->NextPlot;
  128.        }
  129.      if (RMARGIN>2) {RMARGIN+=48;Pict->RMargin=TRUE;}
  130.      else Pict->RMargin=FALSE;
  131.    }
  132.    XMAXP=MAXHORIZ-RMARGIN;
  133.    OLD_XMINP=XMINP;
  134.  
  135.    Tics = Pict->Tics;
  136.    for (i=0; i < Tics->NY; i++) { n=max(n,GetString(&tmpstr,Tics->y[i]));}
  137.    XMINP=(n+2)*CHARWIDTH;
  138.    if (strlen(Pict->YLabel->String)) {
  139.       if (!yf) yf=(struct TextFont *) OpenDiskFont(&yfont);
  140.       YITLabel.IText=Pict->YLabel->String;
  141.       if (yf) { XMINP=LMARGIN=XMINP+CHARWIDTH+abs(IntuiTextLength(&YITLabel)/strlen(Pict->YLabel->String)); }
  142.       else XMINP=LMARGIN=XMINP+(2*CHARWIDTH);
  143.    }
  144.    if (OLD_XMINP!=XMINP) CALC_XMIN=TRUE;
  145.    return(0);
  146. }
  147.  
  148. void CloseFonts()
  149. {
  150.   if (xf) CloseFont(xf);
  151.   if (lf) CloseFont(lf);
  152.   if (yf) CloseFont(yf);
  153.   if (tf) CloseFont(tf);
  154. }
  155.  
  156.  
  157. /**********************/
  158. void GetDataLimits(Pict)
  159. struct Pict *Pict;
  160. {
  161.    short i;
  162.    FFP *x, *y, *e;
  163.    struct Plot *Plot;
  164.    FFP xmin, xmax, ymin, ymax;
  165.  
  166.    xmin = (ymin = FFPLARGE);
  167.    xmax = (ymax = -FFPLARGE);
  168.  
  169.    Plot = Pict->Plot;
  170.    while (Plot) {
  171.          if (Plot->Enabled) {
  172.             i = 0; x = Plot->x; y = Plot->y;
  173.             if (Pict->ShowErr) e = Plot->e;
  174.             while (i++ < Plot->NPts) {
  175.                xmax = max(*x,xmax);
  176.                xmin = min(*x,xmin);
  177.                x++;
  178.                if (Pict->ShowErr) {
  179.                   ymax = max((*y + *e), ymax);
  180.                   ymin = min((*y - *e), ymin);
  181.                   y++; e++;
  182.                }
  183.                else {
  184.                   ymax = max(*y,ymax);
  185.                   ymin = min(*y,ymin);
  186.                   y++;
  187.                }
  188.             }
  189.          }
  190.       Plot = Plot->NextPlot;
  191.    }
  192.  
  193.    if (!Pict->XRegionLock)
  194.       {Pict->CurrReg->XMax = xmax; Pict->CurrReg->XMin = xmin;}
  195.    if (!Pict->YRegionLock)
  196.       {Pict->CurrReg->YMax = ymax; Pict->CurrReg->YMin = ymin;}
  197. }
  198.  
  199.  
  200. void GetPlotLimits(Pict,Reg)
  201. struct PlotRegion *Reg;
  202. struct Pict *Pict;
  203. {
  204.    short i;
  205.    FFP *x, *y, *e;
  206.    struct Plot *Plot;
  207.    FFP xmin, xmax, ymin, ymax;
  208.  
  209.    xmin = (ymin = FFPLARGE);
  210.    xmax = (ymax = -FFPLARGE);
  211.  
  212.    Plot = Pict->Plot;
  213.    while (Plot) {
  214.      i = 0; x = Plot->x; y = Plot->y;
  215.      if (Pict->ShowErr) e = Plot->e;
  216.      while (i++ < Plot->NPts) {
  217.        xmax = max(*x,xmax);
  218.        xmin = min(*x,xmin);
  219.        x++;
  220.        if (Pict->ShowErr) {
  221.          ymax = max((*y + *e), ymax);
  222.          ymin = min((*y - *e), ymin);
  223.          y++; e++;
  224.        }
  225.        else {
  226.          ymax = max(*y,ymax);
  227.          ymin = min(*y,ymin);
  228.          y++;
  229.        }
  230.      }
  231.      Plot = Plot->NextPlot;
  232.   }
  233.   Reg->XMax=xmax; Reg->XMin=xmin;
  234.   Reg->YMax=ymax; Reg->YMin=ymin;
  235. }
  236.  
  237.  
  238. /*****************************************/
  239. void AdjustForTics(dmin, dmax, ntics, tics)
  240. FFP *dmin, *dmax, *tics;
  241. short ntics;
  242. {
  243.    FFP tmp, fract, f_ntics;
  244.    short i;
  245.  
  246.    f_ntics = (FFP)(ntics);
  247.    fract = (FFP)(ntics+1) / f_ntics;
  248.  
  249.    /*** adjust data limits to make "nice" numbers for tic marks ***/
  250.    tmp = *dmin - (*dmax - *dmin) / 5;
  251.    *dmin = fround( *dmin, DOWN, tmp);
  252.    tmp = (*dmax - *dmin) / f_ntics;
  253.    tmp = fround( tmp, UP, (tmp * fract) );
  254.    *dmax = *dmin + tmp * f_ntics;
  255.  
  256.    tics[0] = fround( *dmin, UP, *dmin+tmp/2);
  257.    for (i=1; i<ntics; i++) {
  258.       tics[i] = tics[i-1] + tmp;
  259.    }
  260. }
  261.  
  262.  
  263. /**************/
  264. void Scale(Pict)
  265. struct Pict *Pict;
  266. {
  267.    struct Plot *Plot;
  268.    struct PlotRegion *Reg;
  269.    struct Tics *Tics;
  270.    register short i, *xp, *yp;
  271.    register FFP *x, *y, xmin, ymin, xscale, yscale;
  272.    short *ep, err, err_sav = TRUE;
  273.    FFP *e, xmax, ymax;
  274.  
  275.    Reg = Pict->CurrReg;
  276.    xmin = Reg->XMin; xmax = Reg->XMax;
  277.    ymin = Reg->YMin; ymax = Reg->YMax;
  278.  
  279.    if (FFPSAME(xmax,xmin))
  280.       {Message("Scaling error: X to small"); xscale = FFPLARGE;}
  281.    else
  282.       Pict->XScale = xscale = (FFP)(XMAXP-XMINP) / (xmax - xmin);
  283.    if (FFPSAME(ymax,ymin))
  284.       {Message("Scaling error: Y to small"); yscale = FFPLARGE;}
  285.    else
  286.       Pict->YScale = yscale = (FFP)(YMAXP-YMINP) / (ymax - ymin);
  287.  
  288. #define NEW_X_REGION ( !FFPSAME(Reg->XMin,xmin) || !FFPSAME(Reg->XMax,xmax) )
  289. #define NEW_Y_REGION ( !FFPSAME(Reg->YMin,ymin) || !FFPSAME(Reg->YMax,ymax) )
  290.  
  291.    /* DATA */
  292.    Plot = Pict->Plot;
  293.    err = Pict->ShowErr;
  294.    while (Plot) {
  295.       if (Plot->Enabled) {
  296.          Reg = Plot->Reg;
  297.  
  298.          if ((NEW_X_REGION)||(CALC_XMIN)) {
  299.             x = Plot->x; xp = Plot->xp;
  300.             for (i = 0; i < Plot->NPts; i++) {
  301.                *xp++ = XMINP + (short)((*x++ - xmin) * xscale);
  302.             }
  303.             Reg->XMin = xmin; Reg->XMax = xmax;
  304.          }
  305.  
  306.          if ( (NEW_Y_REGION) || (err_sav!=err) || (CALC_YMIN)) {
  307.             y = Plot->y; yp = Plot->yp; e = Plot->e; ep = Plot->ep;
  308.             for (i = 0; i < Plot->NPts; i++) {
  309.                *yp++ = YMINP + (short)((*y++ - ymin) * yscale);
  310.                if (err) {
  311.                   *ep++ = (short)(*e++ * yscale);
  312.                }
  313.             }
  314.             Reg->YMin = ymin; Reg->YMax = ymax;
  315.          }
  316.  
  317.       }
  318.       Plot = Plot->NextPlot;
  319.    }
  320.    CALC_YMIN=CALC_XMIN=FALSE;
  321.    err_sav = err;
  322.  
  323.    /* TICS */
  324.    Tics = Pict->Tics;
  325.    for (i=0; i < Tics->NX; i++)
  326.       Tics->xp[i] = XMINP + (short)((Tics->x[i] - xmin) * xscale);
  327.  
  328.    for (i=0; i < Tics->NY; i++)
  329.       Tics->yp[i] = YMINP + (short)((Tics->y[i] - ymin) * yscale);
  330. }
  331.  
  332.  
  333. /**********************/
  334. void DrawAxes(Tics,Grid)
  335. struct Tics *Tics; short Grid;
  336. {
  337.    short *xp, *yp, n, tmpx, tmpy, i;
  338.    char tmpstr[20];
  339.    struct Plot *Plot;
  340.    struct TextBox *TempText;
  341.  
  342.    /*** DRAW BORDER ***/
  343.  
  344.    if ((Grid>1)&&(Grid<5)) {
  345.       SetDrMd(rp, JAM1);
  346.       SetAPen(rp,2);
  347.       SetOPen(rp,1);
  348.       if (Pict->RMargin) PRectFill(XMINP-1,YMINP-1,MAXHORIZ-1,YMAXP+1);
  349.       else PRectFill(XMINP-1,YMINP-1,XMAXP+1,YMAXP+1);
  350.       PRectFill(XMINP,YMINP,XMAXP,YMAXP);
  351.    }
  352.    else if (Grid<2) {
  353.       SetDrMd(rp, JAM1);
  354.       SetAPen(rp,2);
  355.       SetOPen(rp,2);
  356.       PRectFill(XMINP-1,YMINP-1,MAXHORIZ-1,YMAXP+1);
  357.       SetAPen(rp,1);
  358.       PMove(XMAXP+1,YMINP-1); PDraw(XMINP-1,YMINP-1); PDraw(XMINP-1,YMAXP+1);
  359.       PMove(XMAXP+1,YMINP); PDraw(XMINP,YMINP); PDraw(XMINP,YMAXP+1);
  360.    }
  361.  
  362.    /*** DRAW TICS/GRID ***/
  363.    xp=Tics->xp; yp=Tics->yp;
  364.    for (i=0; i < Tics->NX; i++) {
  365.       if (Grid==2) {
  366.          SetAPen(rp,3);
  367.          if (xp[i]>XMINP) {PMove(xp[i],YMINP+1); PDraw(xp[i],YMAXP-1);}
  368.       }
  369.       else {
  370.          SetAPen(rp,1);
  371.          if (xp[i]>XMINP)
  372.            {
  373.              if ((Grid==0)||(Grid==3)) {PMove(xp[i],YMINP+1); PDraw(xp[i],YMINP+X_TIC_SIZE);}
  374.              if (Grid==3) {PMove(xp[i],YMAXP-1); PDraw(xp[i],YMAXP-X_TIC_SIZE);}
  375.            }
  376.       }
  377.    }
  378.    for (i=0; i < Tics->NY; i++) {
  379.       if (Grid==2) {
  380.          SetAPen(rp,3);
  381.          if (yp[i]>YMINP) {PMove(XMINP+1,yp[i]); PDraw(XMAXP-1,yp[i]);}
  382.       }
  383.       else {
  384.          SetAPen(rp,1);
  385.          if (yp[i]>YMINP)
  386.            {
  387.               if ((Grid==0)||(Grid==3)) {PMove(XMINP+1,yp[i]); PDraw(XMINP+Y_TIC_SIZE,yp[i]);}
  388.               if (Grid==3) {PMove(XMAXP-1,yp[i]); PDraw(XMAXP-Y_TIC_SIZE,yp[i]);}
  389.            }
  390.       }
  391.    }
  392.  
  393.  
  394.    /*** PRINT TIC VALUES AND TEXT ***/
  395.    SetAPen(rp,1);
  396.    if ((Grid==0)||(Grid==2)||(Grid==3))
  397.      {
  398.         for (i=0; i < Tics->NX; i++) {
  399.           n=GetString(&tmpstr,Tics->x[i]);
  400.           tmpx = Tics->xp[i] - (n/2) * CHARWIDTH;
  401.           tmpy = max(0, YMINP-2*CHARHEIGHT);
  402.           PMove(tmpx, tmpy); Text(rp,tmpstr,n);
  403.           }
  404.      }
  405.  
  406.    XITLabel.IText=Pict->XLabel->String;
  407.    n=IntuiTextLength(&XITLabel);
  408.    tmpx=( (LMARGIN + (XMAXP-XMINP)/2) - (n/2) );
  409.    tmpy = (MAXVERT-xfont.ta_YSize-2);
  410.    PrintIText(rp,&XITLabel,tmpx,tmpy);
  411.  
  412.    TITLabel.IText=Pict->Title->String;
  413.    n=IntuiTextLength(&TITLabel);
  414.    tmpx=( (MAXHORIZ/2) - (n/2) );
  415.    tmpy = (CHARHEIGHT*2);
  416.    PrintIText(rp,&TITLabel,tmpx,tmpy);
  417.  
  418.    if (strlen(Pict->YLabel->String))
  419.      {
  420.         if (yf) { PrintVText(rp,&YITLabel,2,(MAXVERT/2)-strlen(Pict->YLabel->String)*(yfont.ta_YSize+1)/2); }
  421.         else PrintVText(rp,&YITLabel,2,(MAXVERT/2)-strlen(Pict->YLabel->String)*(CHARHEIGHT+1)/2);
  422.       }
  423.    if ((Grid==0)||(Grid==2)||(Grid==3))
  424.      {
  425.         for (i=0; i < Tics->NY; i++) {
  426.            n=GetString(&tmpstr,Tics->y[i]);
  427.            tmpx = max(0, XMINP-(n+1)*CHARWIDTH);
  428.            PMove(tmpx, Tics->yp[i]-CHARHEIGHT/2); Text(rp,tmpstr,n);
  429.            }
  430.      }
  431.    SetDrMd(rp, JAM1); SetAPen(rp,1);
  432.    Plot=Pict->Plot;
  433.    while (Plot)
  434.      {
  435.          if ((Plot->Enabled)&&(strlen(Plot->Legend->String)>0))
  436.            {
  437.               Legend.IText=Plot->Legend->String;
  438.               if (lf) PrintIText(rp,&Legend,Plot->Legend->x+34,MAXVERT-Plot->Legend->y-abs(lfont.ta_YSize/2));
  439.               else PrintIText(rp,&Legend,Plot->Legend->x+34,MAXVERT-Plot->Legend->y-abs(CHARHEIGHT/2));
  440.            }
  441.          while (Plot->Continued) Plot=Plot->NextPlot;
  442.          Plot=Plot->NextPlot;
  443.       }
  444.    TempText=ExtraText;
  445.    while (TempText)
  446.      {
  447.         Legend.IText=TempText->String;
  448.         if (lf) PrintIText(rp,&Legend,TempText->x,MAXVERT-TempText->y-abs(lfont.ta_YSize/2));
  449.         else PrintIText(rp,&Legend,TempText->x,MAXVERT-TempText->y-abs(CHARHEIGHT/2));
  450.         TempText=TempText->NextText;
  451.       }
  452. }
  453.  
  454. PlotPoint(Plot,x,y,m,n,Flag)
  455. struct Plot *Plot;
  456. short *x, *y, m, n, Flag;
  457. {
  458. void PDrawBox(), PDrawPlus(), PDrawEggs(), PDrawKite(), PDrawTri();
  459.  
  460.    switch (abs(n)) {
  461.      case 0: break;
  462.      case 1:
  463.             if (Flag || ClipPoint(*x,*y,XMINP,YMINP,XMAXP,YMAXP))
  464.                {
  465.                    PWritePixel(*x, *y);
  466.                    break;
  467.                 }
  468.      case 2:
  469.             if (Flag || ClipPoint(*x,*y,XMINP,YMINP,XMAXP,YMAXP))
  470.                 {
  471.                     PWritePixel(*x, *y);
  472.                     PWritePixel(*x, *y+1);
  473.                     break;
  474.                  }
  475.      case 3:
  476.             if (Flag || ClipPoint(*x,*y,XMINP,YMINP,XMAXP,YMAXP))
  477.                 {
  478.                     PRectFill(*x, *y, *x+1, *y+1);
  479.                     break;
  480.                  }
  481.      default:
  482.             if (Flag || ClipPoint(*x,*y,XMINP,YMINP,XMAXP,YMAXP))
  483.                 {
  484.                     switch (Plot->PointType) {
  485.                     case 1:  PDrawTri(m,*x,*y);  break;
  486.                     case 2:  PDrawKite(m,*x,*y); break;
  487.                     case 3:  PDrawEggs(m,*x,*y); break;
  488.                     case 4:  PDrawEggs(m,*x,*y); /* Fall through (fancy, huh?) */
  489.                     case 5:  PDrawPlus(m,*x,*y); break;
  490.                     case 6:
  491.                     default: PDrawBox(m,*x,*y); break;
  492.                     }
  493.                 }
  494.              break;
  495.     }
  496.     return(0);
  497. }
  498.  
  499.  
  500. CheckLegend(Pict)
  501. struct Pict *Pict;
  502. {
  503. int j=0;
  504. struct Plot *Plot;
  505. struct TextBox *TempText;
  506.  
  507.  
  508.    Plot=Pict->Plot;
  509.    while (Plot)
  510.      {
  511.          if ((Plot->Enabled)&&(strlen(Plot->Legend->String)>0)&&(Plot->Legend->x)&&(Plot->Legend->y))
  512.                 j=j+20;
  513.          while (Plot->Continued) Plot=Plot->NextPlot;
  514.          Plot=Plot->NextPlot;
  515.       }
  516.    Plot=Pict->Plot;
  517.    while (Plot)
  518.      {
  519.          if ((Plot->Enabled)&&(strlen(Plot->Legend->String)>0)&&(!Plot->Legend->x)&&(!Plot->Legend->y))
  520.            {
  521.                 if (!Plot->Legend->x) Plot->Legend->x=XMAXP+10;
  522.                 if (!Plot->Legend->y) Plot->Legend->y=abs(YMAXP/4*3)-j;
  523.                 j=j+20;
  524.            }
  525.          while (Plot->Continued) Plot=Plot->NextPlot;
  526.          Plot=Plot->NextPlot;
  527.       }
  528.     TempText=ExtraText;
  529.     while(TempText)
  530.       {
  531.          if (!TempText->x) TempText->x=XMAXP+10;
  532.          if (!TempText->y) TempText->y=abs(YMAXP/4*3)-j;
  533.          j=j+20;
  534.          TempText=TempText->NextText;
  535.       }
  536.     return(0);
  537. }
  538.  
  539.  
  540. /*****************/
  541. void DrawPlot(Pict)
  542. struct Pict *Pict;
  543. {
  544.    struct Plot *Plot, *TempPlot;
  545.    short *x, *y, *e, n, m, i;
  546.    short tempx1, tempx2, tempy1, tempy2, tempx3, tempy3;
  547.  
  548.    SetDrMd(rp, JAM1);
  549.    Plot = Pict->Plot;
  550.  
  551.    while (Plot) {
  552.       if (Plot->Enabled) {
  553.          SetAPen(rp, Plot->Color);
  554.          /* PLOT POINTS */
  555.          if (Plot->PointSize > 0) {
  556.             TempPlot=Plot;
  557.             n = TempPlot->PointSize;
  558.             if (abs(n) > 2) {m = (abs(n)/2)-1; SetOPen(rp, Plot->Color);}
  559.             if (strlen(Plot->Legend->String)>0)
  560.                {
  561.                   tempx1=Plot->Legend->x+24;
  562.                   PlotPoint(Plot,&Plot->Legend->x,&Plot->Legend->y,m,n,TRUE);
  563.                   PlotPoint(Plot,&tempx1,&Plot->Legend->y,m,n,TRUE);
  564.                }
  565.  
  566.             do {
  567.                   x = TempPlot->xp; y = TempPlot->yp;
  568.                   for (i=0; i<TempPlot->NPts; i++, x++, y++) PlotPoint(TempPlot,x,y,m,n,FALSE);
  569.                } while ((TempPlot->Continued)&&(TempPlot=TempPlot->NextPlot));
  570.          }
  571.  
  572.          /* PLOT LINES */
  573.          if (Plot->Lines != FALSE) {
  574.             switch (Plot->Lines) {
  575.             case 6: SetDrPt(rp,0xFCCC); break;
  576.             case 5: SetDrPt(rp,0xFF3C); break;
  577.             case 4: SetDrPt(rp,0xFFCC); break;
  578.             case 3: SetDrPt(rp,0xFFF0); break;
  579.             case 2: SetDrPt(rp,0xFF00); break;
  580.             case 1:
  581.             default: SetDrPt(rp,0xFFFF); break;
  582.             }
  583.             TempPlot=Plot;
  584.             tempx1=(TempPlot->xp[0]); tempy1=(TempPlot->yp[0]);
  585.             if (strlen(Plot->Legend->String)>0)
  586.               {
  587.                 PMove(Plot->Legend->x,Plot->Legend->y);
  588.                 PDraw(Plot->Legend->x+24,Plot->Legend->y);
  589.               }
  590.             /*** LINE OR LINE & POINT GRAPHS ***/
  591.             if (Plot->PlotType<STEP) {
  592.               do {
  593.                   for (i=0; i<TempPlot->NPts; i++) {
  594.                        tempx3=tempx2=TempPlot->xp[i];
  595.                        tempy3=tempy2=TempPlot->yp[i];
  596.                        if (Clip(&tempx1,&tempy1,&tempx2,&tempy2,XMINP,YMINP,XMAXP,YMAXP))
  597.                          {
  598.                             PMove(tempx1,tempy1);
  599.                             PDraw(tempx2,tempy2);
  600.                          }
  601.                        tempx1=tempx3;
  602.                        tempy1=tempy3;
  603.                   }
  604.               } while ((TempPlot->Continued)&&(TempPlot=TempPlot->NextPlot));
  605.             }
  606.             /*** STEP GRAPHS ***/
  607.             else do {
  608.                   for (i=0; i<TempPlot->NPts; i++) {
  609.                        tempx3=tempx2=TempPlot->xp[i];
  610.                        tempy3=tempy2=TempPlot->yp[i];
  611.                        if (Clip(&tempx1,&tempy1,&tempx2,&tempy1,XMINP,YMINP,XMAXP,YMAXP))
  612.                          {
  613.                             PMove(tempx1,tempy1);
  614.                             PDraw(tempx2,tempy1);
  615.                          }
  616.                        if (Clip(&tempx2,&tempy1,&tempx2,&tempy2,XMINP,YMINP,XMAXP,YMAXP))
  617.                          {
  618.                             PMove(tempx2,tempy1);
  619.                             PDraw(tempx2,tempy2);
  620.                          }
  621.                        tempx1=tempx3;
  622.                        tempy1=tempy3;
  623.                   }
  624.             } while ((TempPlot->Continued)&&(TempPlot=TempPlot->NextPlot));
  625.             SetDrPt(rp,0xFFFF);
  626.          }
  627.  
  628.          /* PLOT ERROR BARS */
  629.          if ((Pict->ShowErr)&&(Plot->PlotType!=STEP)) {
  630.             TempPlot=Plot;
  631.             do {
  632.                   x = TempPlot->xp; y = TempPlot->yp; e = TempPlot->ep;
  633.                   for (i=0; i < TempPlot->NPts; i++, x++, y++, e++) {
  634.                     if (abs(*e)>FFPSMALL)
  635.                       {
  636.                          tempy1=*y-*e; tempy2=*y+*e;
  637.                          if (QuickClip(*x,&tempy1,&tempy2,XMINP,YMINP,XMAXP,YMAXP))
  638.                            {
  639.                               PMove(*x, tempy1);
  640.                               PDraw(*x, tempy2);
  641.                            }
  642.                          if (ClipPoint(*x,*y-*e,XMINP,YMINP,XMAXP,YMAXP))
  643.                            {
  644.                               PMove(*x-ERR_DELIM,*y - *e);
  645.                               PDraw(*x+ERR_DELIM, *y - *e);
  646.                            }
  647.                          if (ClipPoint(*x,*y+*e,XMINP,YMINP,XMAXP,YMAXP))
  648.                            {
  649.                               PMove(*x-ERR_DELIM,*y + *e);
  650.                               PDraw(*x+ERR_DELIM, *y + *e);
  651.                            }
  652.                       }
  653.                    }
  654.                } while ((TempPlot->Continued)&&(TempPlot=TempPlot->NextPlot));
  655.          }
  656.  
  657.       }
  658.       while (Plot->Continued) Plot=Plot->NextPlot; Plot=Plot->NextPlot;
  659.    }
  660.    SetDrMd(rp, COMPLEMENT);
  661. }
  662.  
  663.  
  664. /*************************************************************/
  665. extern int CheckUser();
  666. extern int GetHowTo();
  667. extern void CleanUp();
  668. extern USHORT chip WaitSprite[];
  669. extern struct Window *window;
  670. extern short SCRIPT_ON;
  671.  
  672. void plot(Pict)
  673. struct Pict *Pict;
  674. {
  675. struct PlotRegion *Reg;
  676. struct Tics *Tics;
  677. int req;
  678. void CloseFonts();
  679.  
  680.    InitWind(Pict);
  681.    if (SCRIPT_ON)
  682.      {
  683.        AdjustTics(&(Pict->CurrReg->XMin),&(Pict->CurrReg->XMax),Pict->Tics->NX,Pict->Tics->x);
  684.        AdjustTics(&(Pict->CurrReg->YMin),&(Pict->CurrReg->YMax),Pict->Tics->NY,Pict->Tics->y);
  685.        req = REDRAW;
  686.      }
  687.    else  req = GETDATALIMITS;
  688.    GetHowTo(Pict);
  689.    Tics = Pict->Tics;
  690.  
  691.    do {
  692.       switch(req) {
  693.       case GETHOWTO:
  694.          GetHowTo(Pict); /* fall thru */
  695.       case GETDATALIMITS:
  696.          GetDataLimits(Pict);
  697.       case REPLOT:
  698.          SetPointer(window,WaitSprite,26,14,-4,-4);
  699.          Reg = Pict->CurrReg;
  700.          if (!Pict->XRegionLock)
  701.             AdjustForTics(&Reg->XMin, &Reg->XMax, Tics->NX, Tics->x);
  702.          if (!Pict->YRegionLock)
  703.             AdjustForTics(&Reg->YMin, &Reg->YMax, Tics->NY, Tics->y);
  704.       case REDRAW:
  705.          SetPointer(window,WaitSprite,26,14,-4,-4);
  706.          AllowForText(Pict);
  707.          CheckLegend(Pict);
  708.          Scale(Pict);
  709.       case REFRESH:
  710.       default: ;
  711.       }
  712.       SetPointer(window,WaitSprite,26,14,-4,-4);
  713.       SetRast(rp,0);
  714.       DrawAxes(Pict->Tics,Pict->Grid);
  715.       DrawPlot(Pict);
  716.       ClearPointer(window);
  717.       ClearMenuStrip(window); CheckMenu(Pict); SetMenuStrip(window, &Project);
  718.       req = CheckUser(Pict);
  719.    } while (req != QUIT);
  720.    CloseFonts();
  721.    CleanUp();
  722. }
  723.  
  724.  
  725. /***************************/
  726. void PToU(Pict, xp, yp, x, y)
  727. struct Pict *Pict;
  728. short xp, yp;
  729. FFP *x, *y;
  730. {
  731.    *x = Pict->CurrReg->XMin + (FFP)(xp-XMINP) / Pict->XScale;
  732.    *y = Pict->CurrReg->YMin + (FFP)(yp-YMINP) / Pict->YScale;
  733. }
  734.  
  735.  
  736.  
  737. PrintVText(rp,PText,X,Y)
  738. struct RastPort *rp;
  739. struct IntuiText *PText;
  740. int X;
  741. int Y;
  742. {
  743. struct TextFont *f;
  744. int height;
  745. int i,n,x,y;
  746. struct TextAttr *at;
  747. static struct TextAttr old_at;
  748. char c;
  749.  
  750.    AskFont(rp,&old_at);
  751.  
  752.    while (PText)
  753.      {
  754.         SetAPen(rp,PText->FrontPen);
  755.         SetBPen(rp,PText->BackPen);
  756.         SetDrMd(rp,PText->DrawMode);
  757.         at=PText->ITextFont;
  758.         f=NULL;
  759.         f=(struct TextFont *) OpenFont(at);
  760.         if (f) {
  761.            SetFont(rp,f);
  762.            height=at->ta_YSize+1;
  763.         }
  764.         else height=CHARHEIGHT+1;
  765.         x=X+PText->LeftEdge+TextLength(rp,"M",1);
  766.         y=Y+PText->TopEdge;
  767.  
  768.         n=strlen(PText->IText);
  769.         for (i=0;i<n;i++)
  770.           {
  771.              c=PText->IText[i];
  772.              Move(rp,abs(x-(TextLength(rp,&c,1)/2)),y+(i*height));
  773.              Text(rp,&c,1);
  774.           }
  775.         CloseFont(f);
  776.         PText=PText->NextText;
  777.      }
  778.    f=(struct TextFont *) OpenFont(&old_at);
  779.    SetFont(rp,f);
  780.    return(0);
  781. }
  782.  
  783.  
  784. void PDrawPlus(m,x,y)
  785. SHORT m,x,y;
  786. {
  787.    Move(rp,x-m,MAXVERT-y);
  788.    Draw(rp,x+m,MAXVERT-y);
  789.    Move(rp,x,MAXVERT-y-m);
  790.    Draw(rp,x,MAXVERT-y+m);
  791. }
  792.  
  793. void PDrawBox(m,x,y)
  794. SHORT m,x,y;
  795. {
  796.    SHORT points[10];
  797.  
  798.    points[0]=points[2]=points[8]= x-m;
  799.    points[1]=points[7]=points[9]=MAXVERT-y-m;
  800.    points[3]=points[5]=MAXVERT-y+m,
  801.    points[4]=points[6]=x+m;
  802.    Move(rp,x-m,MAXVERT-y-m);
  803.    PolyDraw(rp,5,points);
  804. }
  805.  
  806. void PDrawEggs(m,x,y)
  807. SHORT m,x,y;
  808. {
  809.    Move(rp,x-m,MAXVERT-y+m);
  810.    Draw(rp,x+m,MAXVERT-y-m);
  811.    Move(rp,x+m,MAXVERT-y+m);
  812.    Draw(rp,x-m,MAXVERT-y-m);
  813. }
  814.  
  815.  
  816. void PDrawKite(m,x,y)
  817. SHORT m,x,y;
  818. {
  819.    SHORT points[10];
  820.  
  821.    points[0]=points[4]=points[8]= x;
  822.    points[1]=points[9]=MAXVERT-y+m;
  823.    points[3]=points[7]=MAXVERT-y,
  824.    points[2]=x+m;
  825.    points[6]=x-m;
  826.    points[5]=MAXVERT-y-m;
  827.  
  828.    Move(rp,x,MAXVERT-y+m);
  829.    PolyDraw(rp,5,points);
  830. }
  831.  
  832.  
  833. void PDrawTri(m,x,y)
  834. SHORT m,x,y;
  835. {
  836.    SHORT points[8];
  837.  
  838.    points[0]=points[6]= x;
  839.    points[3]=points[5]=MAXVERT-y+m;
  840.    points[1]=points[7]=MAXVERT-y-m,
  841.    points[2]=x+m;
  842.    points[4]=x-m;
  843.  
  844.    Move(rp,x,MAXVERT-y-m);
  845.    PolyDraw(rp,4,points);
  846. }
  847.  
  848.  
  849. GetString(tmpstr,x)
  850. char *tmpstr;
  851. FFP x;
  852. {
  853. int n;
  854.  
  855.   if ((x==0.0)||((abs(x)>0.001)&&(abs(x)<99999)))
  856.      {
  857.         n=sprintf(tmpstr,"%-.3f",x);
  858.         while (tmpstr[n-1] == '0') n--;
  859.         if (tmpstr[n-1] == '.') n--;
  860.      }
  861.   else
  862.      {
  863.         n=sprintf(tmpstr,"%-.2g",x);
  864.         if (n>7) n=sprintf(tmpstr,"%-.1g",x);
  865.         if (n>7) n=sprintf(tmpstr,"%-.0g",x);
  866.      }
  867.   if (n<2) {strcat(tmpstr,".0"); n=n+2;}
  868.   tmpstr[n]='\0';
  869.   return(n);
  870. }
  871.  
  872.