#include "struct.h" #include "plot.h" #include extern struct Window *window; extern int CHARWIDTH; extern int CHARHEIGHT; extern int LMARGIN; /* CHARWIDTH x 7 */ extern int TMARGIN; extern int BMARGIN; /* CHARHEIGHT x 3 */ extern int XMINP; /* LMARGIN */ extern int YMAXP; /* MAXVERT - TMARGIN */ extern int YMINP; /* BMARGIN */ extern int debug; extern int MAXVERT; extern FFP fround(); extern struct Pict *Pict; struct TextAttr xfont = { "Times.font", 14, 0, 1 }; struct TextAttr yfont = { "Times.font", 14, 0, 1 }; struct TextAttr tfont = { "Times.font", 24, 0, 1 }; struct IntuiText XITLabel = { 1,0,JAM1, /* front and back text pens, drawmode and fill byte */ 0,0, /* XY origin relative to container TopLeft */ &xfont, /* font pointer or NULL for default */ NULL, /* pointer to text */ NULL /* next IntuiText structure */ }; struct IntuiText YITLabel = { 1,0,JAM1, /* front and back text pens, drawmode and fill byte */ 0,0, /* XY origin relative to container TopLeft */ &yfont, /* font pointer or NULL for default */ NULL, /* pointer to text */ NULL /* next IntuiText structure */ }; struct IntuiText TITLabel = { 1,0,JAM1, /* front and back text pens, drawmode and fill byte */ 0,0, /* XY origin relative to container TopLeft */ &tfont, /* font pointer or NULL for default */ NULL, /* pointer to text */ NULL /* next IntuiText structure */ }; struct TextFont *xf; struct TextFont *yf; struct TextFont *tf; AllowForText() { if (Pict->XLabel!=NULL) { xf=(struct TextFont *) OpenDiskFont(&xfont); if (xf) { YMINP = BMARGIN=( xfont.ta_YSize +CHARHEIGHT *4); CloseFont(xf); } else YMINP = BMARGIN= CHARHEIGHT *5; } if (Pict->Title!=NULL) { tf=(struct TextFont *) OpenDiskFont(&tfont); if (tf) { YMAXP = MAXVERT - (TMARGIN=( tfont.ta_YSize +CHARHEIGHT *2)); CloseFont(tf); } else YMAXP = MAXVERT- (TMARGIN=CHARHEIGHT*3); } if (Pict->YLabel!=NULL) { yf=(struct TextFont *) OpenDiskFont(&yfont); YITLabel.IText=Pict->YLabel; if (yf) { XMINP=LMARGIN=abs(IntuiTextLength(&YITLabel)/strlen(Pict->YLabel))+(9*CHARWIDTH); CloseFont(yf); } else XMINP=LMARGIN=9*CHARWIDTH; } return(0); } /**********************/ void GetDataLimits(Pict) struct Pict *Pict; { short i; FFP *x, *y, *e; struct Plot *Plot; FFP xmin, xmax, ymin, ymax; xmin = (ymin = FFPLARGE); xmax = (ymax = -FFPLARGE); Plot = Pict->Plot; while (Plot) { if (Plot->Enabled) { i = 0; x = Plot->x; y = Plot->y; if (Pict->ShowErr) e = Plot->e; while (i++ < Plot->NPts) { xmax = max(*x,xmax); xmin = min(*x,xmin); x++; if (Pict->ShowErr) { ymax = max((*y + *e), ymax); ymin = min((*y - *e), ymin); y++; e++; } else { ymax = max(*y,ymax); ymin = min(*y,ymin); y++; } } } Plot = Plot->NextPlot; } if (!Pict->XRegionLock) {Pict->CurrReg->XMax = xmax; Pict->CurrReg->XMin = xmin;} if (!Pict->YRegionLock) {Pict->CurrReg->YMax = ymax; Pict->CurrReg->YMin = ymin;} } /*****************************************/ void AdjustForTics(dmin, dmax, ntics, tics) FFP *dmin, *dmax, *tics; short ntics; { FFP tmp, fract, f_ntics; short i; f_ntics = (FFP)(ntics); fract = (FFP)(ntics+1) / f_ntics; /*** adjust data limits to make "nice" numbers for tic marks ***/ tmp = *dmin - (*dmax - *dmin) / 5; *dmin = fround( *dmin, DOWN, tmp); tmp = (*dmax - *dmin) / f_ntics; tmp = fround( tmp, UP, (tmp * fract) ); *dmax = *dmin + tmp * f_ntics; tics[0] = fround( *dmin, UP, *dmin+tmp/2); if (debug) printf("... tic[0]=%f\n", tics[0]); for (i=1; iCurrReg; xmin = Reg->XMin; xmax = Reg->XMax; ymin = Reg->YMin; ymax = Reg->YMax; if (FFPSAME(xmax,xmin)) {printf("Scale: xmax = xmin, xscale := 0.\n"); xscale = (FFP)0;} else Pict->XScale = xscale = (FFP)(XMAXP-XMINP) / (xmax - xmin); if (FFPSAME(ymax,ymin)) {printf("Scale: ymax = ymin, yscale := 0.\n"); yscale = (FFP)0;} else Pict->YScale = yscale = (FFP)(YMAXP-YMINP) / (ymax - ymin); #define NEW_X_REGION ( !FFPSAME(Reg->XMin,xmin) || !FFPSAME(Reg->XMax,xmax) ) #define NEW_Y_REGION ( !FFPSAME(Reg->YMin,ymin) || !FFPSAME(Reg->YMax,ymax) ) /* DATA */ Plot = Pict->Plot; err = Pict->ShowErr; while (Plot) { if (Plot->Enabled) { Reg = Plot->Reg; if (NEW_X_REGION) { x = Plot->x; xp = Plot->xp; for (i = 0; i < Plot->NPts; i++) { *xp++ = XMINP + (short)((*x++ - xmin) * xscale); if (debug) printf("*xp=%d\n", *(xp-1)); } Reg->XMin = xmin; Reg->XMax = xmax; } if ( (NEW_Y_REGION) || (err_sav!=err) ) { y = Plot->y; yp = Plot->yp; e = Plot->e; ep = Plot->ep; for (i = 0; i < Plot->NPts; i++) { *yp++ = YMINP + (short)((*y++ - ymin) * yscale); if (debug) printf("*yp=%d", *(yp-1)); if (err) { *ep++ = (short)(*e++ * yscale); if (debug) printf(", *ep=%d", *(ep-1)); } if (debug) printf("\n"); } Reg->YMin = ymin; Reg->YMax = ymax; } } Plot = Plot->NextPlot; } err_sav = err; /* TICS */ Tics = Pict->Tics; for (i=0; i < Tics->NX; i++) Tics->xp[i] = XMINP + (short)((Tics->x[i] - xmin) * xscale); for (i=0; i < Tics->NY; i++) Tics->yp[i] = YMINP + (short)((Tics->y[i] - ymin) * yscale); if (debug) printf("Scale: entry\n"); } /**********************/ void DrawAxes(Tics,Grid) struct Tics *Tics; short Grid; { short *xp, *yp, n, tmpx, tmpy, i; char tmpstr[20]; /*** DRAW BORDER ***/ SetDrMd(rp, JAM1); SetAPen(rp,2); SetOPen(rp,1); PRectFill(XMINP-1,YMINP-1,XMAXP+1,YMAXP+1); PRectFill(XMINP,YMINP,XMAXP,YMAXP); /*** DRAW TICS/GRID ***/ SetAPen(rp,3); xp=Tics->xp; yp=Tics->yp; if (Grid) SetRGB4(vp,3,0,15,15); for (i=1; i < Tics->NX; i++) { if (Grid) { PMove(xp[i],YMINP+1); PDraw(xp[i],YMAXP-1); } else { PMove(xp[i],YMINP+1); PDraw(xp[i],YMINP+X_TIC_SIZE); PMove(xp[i],YMAXP-1); PDraw(xp[i],YMAXP-X_TIC_SIZE); } } for (i=1; i < Tics->NY; i++) { if (Grid) { PMove(XMINP+1,yp[i]); PDraw(XMAXP-1,yp[i]); } else { PMove(XMINP+1,yp[i]); PDraw(XMINP+Y_TIC_SIZE,yp[i]); PMove(XMAXP-1,yp[i]); PDraw(XMAXP-Y_TIC_SIZE,yp[i]); } } /*** PRINT TIC VALUES AND TEXT ***/ SetAPen(rp,1); for (i=0; i < Tics->NX; i++) { n = sprintf(&tmpstr, "%-.4f", Tics->x[i]); n = min(n, 7); while (tmpstr[n-1] == '0') n--; tmpx = Tics->xp[i] - ((n/2) - (FFP)1/2) * CHARWIDTH; tmpy = max(0, YMINP-2*CHARHEIGHT); PMove(tmpx, tmpy); Text(rp,tmpstr,n); } XITLabel.IText=Pict->XLabel; n=IntuiTextLength(&XITLabel); tmpx=( (LMARGIN + (XMAXP-XMINP)/2) - (n/2) ); tmpy = (MAXVERT-xfont.ta_YSize-CHARHEIGHT); PrintIText(rp,&XITLabel,tmpx,tmpy); TITLabel.IText=Pict->Title; n=IntuiTextLength(&TITLabel); tmpx=( (MAXHORIZ/2) - (n/2) ); tmpy = (CHARHEIGHT); PrintIText(rp,&TITLabel,tmpx,tmpy); PrintVText(rp,&YITLabel,2,(MAXVERT/2)-( (strlen(Pict->YLabel)/2)*(yfont.ta_YSize+1))); for (i=0; i < Tics->NY; i++) { n = sprintf(&tmpstr, "%-.4f", Tics->y[i]); n = min( n, (LMARGIN/CHARWIDTH)-1 ); while (tmpstr[n-1] == '0') n--; tmpx = max(0, XMINP-(n+1)*CHARWIDTH); PMove(tmpx, Tics->yp[i]-CHARHEIGHT/2); Text(rp,tmpstr,n); } } /*****************/ void DrawPlot(Pict) struct Pict *Pict; { struct Plot *Plot; short *x, *y, *e, n, m, i; SetDrMd(rp, JAM1); Plot = Pict->Plot; while (Plot) { if (Plot->Enabled) { SetAPen(rp, Plot->Color); /* PLOT POINTS */ if (Plot->PointSize != 0) { n = Plot->PointSize; if (abs(n) > 2) {m = (abs(n)/2)-1; SetOPen(rp, Plot->Color);} x = Plot->xp; y = Plot->yp; for (i=0; iNPts; i++, x++, y++) { switch (abs(n)) { case 0: break; case 1: PWritePixel(*x, *y); break; case 2: PWritePixel(*x, *y); PWritePixel(*x, *y+1); break; case 3: PRectFill(*x, *y, *x+1, *y+1); break; default: PRectFill(*x-m, *y-m, *x+m, *y+m); break; } } } /* PLOT LINES */ if (Plot->PointSize <= 0) { PMove(*Plot->xp, *Plot->yp); x = &(Plot->xp[1]); y = &(Plot->yp[1]); for (i=1; iNPts; i++, x++, y++) PDraw(*x, *y); } /* PLOT ERROR BARS */ if (Pict->ShowErr) { x = Plot->xp; y = Plot->yp; e = Plot->ep; for (i=0; i < Plot->NPts; i++, x++, y++, e++) { PMove(*x, *y - *e); PDraw(*x, *y + *e); } } } Plot = Plot->NextPlot; } SetDrMd(rp, COMPLEMENT); } /*************************************************************/ extern int CheckUser(); extern int GetHowTo(); extern void CleanUp(); extern USHORT chip WaitSprite[]; extern struct Window *window; void plot(Pict) struct Pict *Pict; { struct PlotRegion *Reg; struct Tics *Tics; int req = GETDATALIMITS; GetHowTo(Pict); Tics = Pict->Tics; InitWind(); do { switch(req) { case GETHOWTO: GetHowTo(Pict); /* fall thru */ case GETDATALIMITS: AllowForText(); GetDataLimits(Pict); case REPLOT: default: ; } SetPointer(window,WaitSprite,26,14,-4,-4); Reg = Pict->CurrReg; if (!Pict->XRegionLock) AdjustForTics(&Reg->XMin, &Reg->XMax, Tics->NX, Tics->x); if (!Pict->YRegionLock) AdjustForTics(&Reg->YMin, &Reg->YMax, Tics->NY, Tics->y); Scale(Pict); SetRast(rp,0); if (Pict->Axes) DrawAxes(Pict->Tics,Pict->Grid); DrawPlot(Pict); ClearPointer(window); req = CheckUser(Pict); } while (req != QUIT); CleanUp(); } /***************************/ void PToU(Pict, xp, yp, x, y) struct Pict *Pict; short xp, yp; FFP *x, *y; { if (debug) printf("PToU: entry, xp=%d, yp=%d\n", xp, yp); *x = Pict->CurrReg->XMin + (FFP)(xp-XMINP) / Pict->XScale; *y = Pict->CurrReg->YMin + (FFP)(yp-YMINP) / Pict->YScale; if (debug) printf("PToU: exit, *x=%f, *y=%f\n", *x, *y); } PrintVText(rp,PText,X,Y) struct RastPort *rp; struct IntuiText *PText; int X; int Y; { struct TextFont *f; int height; int i,n,x,y; struct TextAttr *at; static struct TextAttr old_at; char c; AskFont(rp,&old_at); while (PText) { SetAPen(rp,PText->FrontPen); SetBPen(rp,PText->BackPen); SetDrMd(rp,PText->DrawMode); at=PText->ITextFont; f=NULL; f=(struct TextFont *) OpenFont(at); if (f) { SetFont(rp,f); height=at->ta_YSize+1; } else height=9; x=X+PText->LeftEdge+TextLength(rp,"M",1); y=Y+PText->TopEdge; n=strlen(PText->IText); for (i=0;iIText[i]; Move(rp,abs(x-(TextLength(rp,&c,1)/2)),y+(i*height)); Text(rp,&c,1); } CloseFont(f); PText=PText->NextText; } f=(struct TextFont *) OpenFont(&old_at); SetFont(rp,f); return(0); }