home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
199.lha
/
GimmeLib
/
graph.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-27
|
21KB
|
800 lines
/*
* FILE: graph.c
* Support routines for creating and manipulating graphs.
*
* Public Domain, but keep my name in it as the original author.
* 31-Oct-88 Jan Sven Trabandt added to gimme.lib
*/
#define I_AM_GRAPH
#include "gimmelib/gimmefuncs.h"
#include "gimmelib/graph.h"
#include "gimmelib/postext.h"
#include <clib/macros.h>
/* macros for internal scaling */
#define SCALEUP(x) ((long)(x) << SCALE) /* x * 2^SCALE */
#define SCALEDN(x) ((long)(x) >> SCALE) /* x / 2^SCALE */
/* macros to translate pixel offset from origin to pixel offset in rastport */
#define TRANSX(gr,off) ((short)((gr)->X.origin + (off)))
#define TRANSY(gr,off) ((short)((gr)->Y.origin - (off)))
/* leeways for titles */
#define XLEEWAY 4
#define YLEEWAY 3
#define TOLERANCE 2 /* pixel tolerance for fancy auto label */
/* internal flags for graphWriteLabel */
#define GWL_RESERVED_VAL (0x0000ffffL) /* lower short reserved for value */
#define GWL_NO_HIGH (1L << 16) /* for internal use only!! */
/* forward declarations */
static SHORT coordToOffset();
static SHORT offsetToCoord();
static VOID initAxis();
static SHORT updateCoord();
static VOID doBlock();
GRAPH *gimmeGraph( newgr, bm, areainfo, tmpras )
register NEWGRAPH *newgr;
struct BitMap *bm;
struct AreaInfo *areainfo;
struct TmpRas *tmpras;
{
register GRAPH *gr;
void *mymh = NULL;
UBYTE *raster;
SHORT width, height;
#ifdef GIMME_WIMPY
if( !newgr ) {
return( NULL );
}
#endif
if( !bm && (!newgr->rp || !newgr->rp->BitMap) ) {
return( NULL );
}
gr = (GRAPH *) chainAllocMem( &mymh, (ULONG)sizeof(GRAPH),
MEMF_PUBLIC | MEMF_CLEAR );
if( !gr ) {
return( NULL );
}
if( !newgr->rp ) {
InitRastPort( &gr->rp );
} else {
gr->rp = *newgr->rp; /* copy struct */
if( newgr->rp->Layer ) {
gr->rp.Layer = chainAllocMem( &mymh, (ULONG)sizeof(struct Layer),
MEMF_PUBLIC | MEMF_CLEAR );
if( !gr->rp.Layer ) {
chainFreeMem( mymh );
return( NULL );
}
*gr->rp.Layer = *newgr->rp->Layer; /* copy struct */
gr->rp.Layer->rp = &gr->rp; /* make this layer come back */
}
}
if( bm ) {
gr->rp.BitMap = bm;
}
gr->title = newgr->title;
gr->xtitle = newgr->xtitle;
gr->ytitle = newgr->ytitle;
gr->FPen = newgr->FPen;
gr->BPen = newgr->BPen;
gr->AxesPen = newgr->AxesPen;
gr->XlabPen = gr->YlabPen = gr->AxesPen;
gr->TitlePen = newgr->TitlePen;
gr->XtitlePen = gr->YtitlePen = gr->TitlePen;
gr->flags = newgr->flags;
gr->ctlflags = newgr->ctlflags;
if( newgr->titleta ) {
gr->titletf = gimmeFont( newgr->titleta );
}
if( newgr->xta ) {
gr->xlabtf = gr->xtf = gimmeFont( newgr->xta );
}
if( newgr->yta ) {
gr->ylabtf = gr->ytf = gimmeFont( newgr->yta );
}
if( !(gr->ctlflags & GGR_NOCLEARSTART) ) {
SetRast( &gr->rp, (long) gr->BPen );
}
initAxis( gr, &gr->X, &newgr->X );
initAxis( gr, &gr->Y, &newgr->Y );
SetAPen( &gr->rp, (long) gr->FPen );
SetBPen( &gr->rp, (long) gr->BPen );
SetDrMd( &gr->rp, (ULONG) JAM1 );
if( newgr->flags & (GGR_FILLTOX | GGR_FILLTOY) ) {
if( areainfo ) {
gr->rp.AreaInfo = areainfo;
} else if( !gr->rp.AreaInfo ) {
gr->rp.AreaInfo = chainAllocMem( &mymh,
(ULONG)sizeof(struct AreaInfo) + 5 * 2 * sizeof(LONG),
MEMF_PUBLIC | MEMF_CLEAR );
if( !gr->rp.AreaInfo ) {
chainFreeMem( mymh );
return( NULL );
}
InitArea( gr->rp.AreaInfo, (SHORT *)(gr->rp.AreaInfo + 1), 5L );
}
if( tmpras ) {
gr->rp.TmpRas = tmpras;
} else if( !gr->rp.TmpRas ) {
gr->rp.TmpRas = chainAllocMem( &mymh, (ULONG)sizeof(struct TmpRas),
MEMF_PUBLIC | MEMF_CLEAR );
if( !gr->rp.TmpRas ) {
chainFreeMem( mymh );
return( NULL );
}
width = gr->rp.BitMap->BytesPerRow << 3;
height = gr->rp.BitMap->Rows;
raster = chainAllocMem( &mymh,
(long)RASSIZE((long)width, (long)height),
MEMF_CHIP | MEMF_CLEAR );
if( !raster ) {
chainFreeMem( mymh );
return( NULL );
}
InitTmpRas( gr->rp.TmpRas, raster,
(long)RASSIZE((long)width, (long)height) );
}
}
if( !(gr->ctlflags & GGR_NOLABELS) ) {
drawGraphAxes( gr );
}
if( gr->ctlflags & (GGR_INITPOINT | GGR_INITORIGIN) ) {
gr->points = 1;
} else {
gr->points = 0;
}
gr->memhead = mymh;
return( gr );
} /* gimmeGraph */
short getRidOfGraph( gr )
GRAPH *gr;
{
#ifdef GIMME_WIMPY
if( !gr ) {
return( -1 );
}
#endif
if( gr->ctlflags & GGR_CLEARONEND ) {
clearGraph( gr );
}
if( gr->ytf ) {
getRidOfFont( gr->ytf );
}
if( gr->xtf ) {
getRidOfFont( gr->xtf );
}
if( gr->titletf ) {
getRidOfFont( gr->titletf );
}
chainFreeMem( gr->memhead );
return( 0 );
} /* getRidOfGraph */
VOID clearGraph( gr )
register GRAPH *gr;
{
BYTE fpen, bpen, axespen, titlepen;
BYTE xlabpen, ylabpen, xtitlepen, ytitlepen;
if( !(gr->ctlflags & GGR_NOCLEARSTART) ) {
SetRast( &gr->rp, (long) gr->BPen );
} else {
fpen = gr->FPen;
bpen = gr->BPen;
axespen = gr->AxesPen;
titlepen = gr->TitlePen;
xlabpen = gr->XlabPen;
ylabpen = gr->YlabPen;
xtitlepen = gr->XtitlePen;
ytitlepen = gr->YtitlePen;
gr->FPen = bpen;
gr->AxesPen = bpen;
gr->TitlePen = bpen;
gr->XlabPen = bpen;
gr->YlabPen = bpen;
gr->XtitlePen = bpen;
gr->YtitlePen = bpen;
SetAPen( &gr->rp, (long) bpen );
RectFill( &gr->rp, (long) TRANSX(gr,1), (long) TRANSY(gr,gr->Y.size),
(long) TRANSX(gr,gr->X.size), (long) TRANSY(gr,1) );
if( !(gr->ctlflags & GGR_NOLABELS) ) {
drawGraphAxes( gr );
}
gr->FPen = fpen;
gr->AxesPen = axespen;
gr->TitlePen = titlepen;
gr->XlabPen = xlabpen;
gr->YlabPen = ylabpen;
gr->XtitlePen = xtitlepen;
gr->YtitlePen = ytitlepen;
}
} /* clearGraph */
VOID resetGraph( gr )
register GRAPH *gr;
{
clearGraph( gr );
gr->X.low = gr->X.flow;
gr->X.high = gr->X.fhigh;
gr->X.lastdata = gr->X.fdata;
gr->X.lastoff = gr->X.foff;
gr->Y.low = gr->Y.flow;
gr->Y.high = gr->Y.fhigh;
gr->Y.lastdata = gr->Y.fdata;
gr->Y.lastoff = gr->Y.foff;
if( gr->ctlflags & (GGR_INITPOINT | GGR_INITORIGIN) ) {
gr->points = 1;
} else {
gr->points = 0;
}
if( !(gr->ctlflags & GGR_NOLABELS) ) {
drawGraphAxes( gr );
}
} /* resetGraph */
VOID drawGraphAxesOnly( gr )
register GRAPH *gr;
{
SHORT maxrastlen, maxlen;
SetAPen( &gr->rp, (long) gr->AxesPen );
Move( &gr->rp, (long) TRANSX(gr,0), (long) TRANSY(gr,gr->Y.size) );
Draw( &gr->rp, (long) TRANSX(gr,0), (long) TRANSY(gr,0) );
Draw( &gr->rp, (long) TRANSX(gr,gr->X.size), (long) TRANSY(gr,0) );
SetAPen( &gr->rp, (long) gr->FPen );
} /* drawGraphAxesOnly */
SHORT drawGraphAxes( gr )
register GRAPH *gr;
{
SHORT maxrastlen, maxlen;
SHORT yoff;
ULONG flags;
drawGraphAxesOnly( gr );
maxrastlen = graphWriteLabel( gr, GWL_XAXIS, gr->X.low, gr->X.high,
gr->X.step );
maxlen = graphWriteLabel( gr, GWL_YAXIS, gr->Y.low, gr->Y.high,
gr->Y.step );
drawGraphTitle( gr, gr->X.size >> 1, gr->Y.size + YLEEWAY,
GPT_XCENTRE | GPT_YBOTTOM );
yoff = - (YLEEWAY << 1);
if( !(gr->ctlflags & GGR_NOLABELS) ) {
yoff -= (gr->xlabtf ? gr->xlabtf->tf_YSize : gr->rp.TxHeight);
}
drawGraphXtitle( gr, gr->X.size >> 1, yoff, GPT_XCENTRE | GPT_YTOP );
flags = GPT_XCENTRE | GPT_YBOTTOM | GPT_YUPWARDS;
if( (gr->ctlflags & GGR_HIRES) && !(gr->ctlflags & GGR_INTERLACE) ) {
flags |= GPT_XTHICKEN;
}
drawGraphYtitle( gr, -maxlen - XLEEWAY*2, gr->Y.size >> 1, flags );
if( maxlen > maxrastlen ) {
maxrastlen = maxlen;
}
return( maxrastlen );
} /* drawGraphAxes */
VOID drawGraphTitle( gr, xoff, yoff, myflags )
register GRAPH *gr;
SHORT xoff, yoff;
ULONG myflags;
{
struct TextFont *tf;
if( gr->title ) {
tf = gr->rp.Font;
if( gr->titletf ) {
SetFont( &gr->rp, gr->titletf );
}
SetAPen( &gr->rp, (long) gr->TitlePen );
positionText( &gr->rp, myflags, gr->title, 0L,
TRANSX(gr,xoff), TRANSY(gr,yoff) );
SetAPen( &gr->rp, (long) gr->FPen );
if( gr->titletf && tf ) {
SetFont( &gr->rp, tf );
}
}
} /* drawGraphTitle */
VOID drawGraphXtitle( gr, xoff, yoff, myflags )
register GRAPH *gr;
SHORT xoff, yoff;
ULONG myflags;
{
struct TextFont *tf;
if( gr->xtitle ) {
tf = gr->rp.Font;
if( gr->xtf ) {
SetFont( &gr->rp, gr->xtf );
}
SetAPen( &gr->rp, (long) gr->XtitlePen );
positionText( &gr->rp, myflags, gr->xtitle, 0L,
TRANSX(gr,xoff), TRANSY(gr,yoff) );
SetAPen( &gr->rp, (long) gr->FPen );
if( gr->xtf && tf ) {
SetFont( &gr->rp, tf );
}
}
} /* drawGraphXtitle */
VOID drawGraphYtitle( gr, xoff, yoff, myflags )
register GRAPH *gr;
SHORT xoff, yoff;
ULONG myflags;
{
SHORT destx, desty;
struct TextFont *tf;
if( gr->ytitle ) {
tf = gr->rp.Font;
if( gr->ytf ) {
SetFont( &gr->rp, gr->ytf );
}
SetAPen( &gr->rp, (long) gr->YtitlePen );
positionText( &gr->rp, myflags, gr->ytitle, 0L,
TRANSX(gr,xoff), TRANSY(gr,yoff) );
SetAPen( &gr->rp, (long) gr->FPen );
if( gr->ytf && tf ) {
SetFont( &gr->rp, tf );
}
}
} /* drawGraphYtitle */
static SHORT coordToOffset( axis, coord )
register AXIS *axis;
SHORT coord;
{
if( axis->scale <= 0 ) {
return( SCALEUP(coord - axis->low) / -axis->scale );
} else {
return( SCALEDN((coord - axis->low) * axis->scale) );
}
} /* coordToOffset */
static SHORT offsetToCoord( axis, offset )
register AXIS *axis;
SHORT offset;
{
SHORT coord;
if( axis->scale <= 0 ) {
coord = SCALEDN(offset * -axis->scale);
} else {
/* offset in "window" belongs to next higher coordinate */
coord = (SCALEUP(offset) + axis->scale - 1) / axis->scale;
}
return( axis->low + coord );
} /* offsetToCoord */
/* internal use only!!
* initialize a graph's axis given a new axis structure
static VOID initAxis( gr, axis, nax )
GRAPH *gr;
register AXIS *axis;
register NEWAXIS *nax;
{
SHORT temp;
SHORT amt;
ULONG flags;
if( axis == &gr->X ) {
flags = gr->flags & GGR_X_FLAGS;
} else {
flags = gr->flags & GGR_Y_FLAGS;
}
axis->origin = nax->origin;
axis->size = nax->size;
axis->flow = axis->low = nax->low;
axis->step = nax->step;
axis->labnum = nax->labnum;
if( !nax->labdenom ) { /* to avoid divide by zero!! */
axis->labnum = 1;
axis->labdenom = 1;
} else {
axis->labdenom = nax->labdenom;
}
amt = nax->amt;
if( flags & (GGR_X_SPACING | GGR_Y_SPACING) ) {
if( !amt ) {
++amt;
}
axis->scale = SCALEUP(amt);
temp = axis->size;
do {
axis->high = offsetToCoord( axis, temp );
axis->usesize = coordToOffset( axis, axis->high );
} while( axis->usesize > temp-- );
} else {
if( flags & (GGR_X_INTERVALS | GGR_Y_INTERVALS) ) {
if( amt <= 0 ) {
amt = 5;
}
axis->high = axis->low + amt;
} else { /* if( flags & (GGR_X_MAX | GGR_Y_MAX) ) */
if( amt < axis->low ) {
amt = axis->low + 5;
}
axis->high = amt;
}
temp = axis->high - axis->low;
if( temp >= nax->size ) {
axis->scale = - ( SCALEUP(temp) / axis->size );
temp = SCALE - 1;
while( (axis->usesize = coordToOffset(axis, axis->high))
> axis->size ) {
if( temp < 0 ) break;
axis->scale -= SCALEUP(5) >> temp;
--temp;
} /* while */
if( flags & (GGR_X_INTEGRAL | GGR_DELTAX |
GGR_Y_INTEGRAL | GGR_DELTAY) ) {
if( (temp = SCALEUP(SCALEDN(-axis->scale))) < -axis->scale ) {
axis->scale = -SCALEUP( SCALEDN(-axis->scale) + 1 );
} else {
axis->scale = -temp;
}
}
} else {
axis->scale = SCALEUP(axis->size) / temp;
if( flags & (GGR_X_INTEGRAL | GGR_DELTAX |
GGR_Y_INTEGRAL | GGR_DELTAY) ) {
axis->scale = SCALEUP( SCALEDN(axis->scale) );
}
axis->usesize = coordToOffset( axis, axis->high );
}
}
axis->fhigh = axis->high;
if( gr->ctlflags & GGR_INITPOINT ) {
axis->lastdata = nax->initpt;
axis->lastoff = coordToOffset( axis, axis->lastdata );
} else { /* if( gr->ctlflags & GGR_INITORIGIN ) */
axis->lastdata = axis->low;
axis->lastoff = 1;
}
axis->fdata = axis->lastdata;
axis->foff = axis->lastoff;
if( !axis->scale ) {
axis->scale = 1; /* to avoid divide by zero!! */
}
} /* initAxis */
SHORT graphWriteLabel( gr, myflags, first, last, step )
register GRAPH *gr;
ULONG myflags;
SHORT first, last;
SHORT step;
{
AXIS *axis;
SHORT full, spacing;
SHORT low, high;
SHORT maxrlen = 0, len;
SHORT coord, loop;
SHORT x, y;
struct TextFont *tf;
BYTE xpen, ypen;
BYTE bpen, dmode;
if( !(myflags & GWL_NO_HIGH) ) {
if( myflags & (GWL_CLEAR_OLD | GWL_CLEAR_ONLY) ) {
if( myflags & GWL_XAXIS ) {
xpen = gr->XlabPen;
gr->XlabPen = gr->BPen;
} else {
ypen = gr->YlabPen;
gr->YlabPen = gr->BPen;
}
maxrlen = graphWriteLabel( gr,
myflags & ~(GWL_CLEAR_OLD | GWL_CLEAR_ONLY),
first, last, step );
if( myflags & GWL_XAXIS ) {
gr->XlabPen = xpen;
} else {
gr->YlabPen = ypen;
}
if( myflags & GWL_CLEAR_ONLY ) {
return( maxrlen );
}
}
tf = gr->rp.Font;
bpen = gr->rp.BgPen;
dmode = gr->rp.DrawMode;
if( myflags & GWL_XAXIS ) {
SetAPen( &gr->rp, (long) gr->XlabPen );
if( gr->xlabtf ) {
SetFont( &gr->rp, gr->xlabtf );
}
} else { /* else YAXIS */
SetAPen( &gr->rp, (long) gr->YlabPen );
if( gr->ylabtf ) {
SetFont( &gr->rp, gr->ylabtf );
}
}
}
if( step > 0 ) { /* if we want even-spaced labels */
for( loop = first; loop <= last; loop += step ) {
if( myflags & GWL_YAXIS) {
y = coordToOffset(&gr->Y, loop);
WritePixel( &gr->rp, (long)TRANSX(gr,-1), (long)TRANSY(gr,y) );
len = positionText( &gr->rp, GPT_XRIGHT | GPT_YCENTREBASE, NULL,
(long) (loop) * gr->Y.labnum / gr->Y.labdenom,
TRANSX(gr,-XLEEWAY), TRANSY(gr,y) );
} else { /* x-axis */
x = coordToOffset(&gr->X, loop);
WritePixel( &gr->rp, (long)TRANSX(gr,x), (long)TRANSY(gr,-1) );
len = positionText( &gr->rp, GPT_XCENTRE | GPT_YTOP, NULL,
(long) (loop) * gr->X.labnum / gr->X.labdenom,
TRANSX(gr,x), TRANSY(gr,-YLEEWAY) );
}
maxrlen = MAX(maxrlen, len);
} /* for */
} else {
if( myflags & GWL_YAXIS) {
high = coordToOffset(&gr->Y, last);
if( !(myflags & GWL_NO_HIGH) ) {
WritePixel( &gr->rp, (long)TRANSX(gr,-1),
(long)TRANSY(gr,high) );
maxrlen = positionText(&gr->rp, GPT_XRIGHT | GPT_YCENTREBASE,
NULL, (long) (last) * gr->Y.labnum / gr->Y.labdenom,
TRANSX(gr,-XLEEWAY), TRANSY(gr,high) );
}
low = coordToOffset(&gr->Y, first);
WritePixel( &gr->rp, (long)TRANSX(gr,-1), (long)TRANSY(gr,low) );
positionText( &gr->rp, GPT_XRIGHT | GPT_YCENTREBASE, NULL,
(long) (first) * gr->Y.labnum / gr->Y.labdenom,
TRANSX(gr,-XLEEWAY), TRANSY(gr,low) );
full = gr->rp.TxHeight;
axis = &gr->Y;
} else { /* x-axis */
high = coordToOffset(&gr->X, last);
if( !(myflags & GWL_NO_HIGH) ) {
WritePixel( &gr->rp, (long)TRANSX(gr,high),
(long)TRANSY(gr,-1) );
maxrlen = positionText( &gr->rp, GPT_XCENTRE| GPT_YTOP, NULL,
(long) (last) * gr->X.labnum / gr->X.labdenom,
TRANSX(gr,high), TRANSY(gr,-YLEEWAY) );
full = maxrlen;
myflags = (myflags & ~0xFFFFL) | full;
} else {
full = myflags & 0xFFFFL;
}
low = coordToOffset(&gr->X, first);
WritePixel( &gr->rp, (long)TRANSX(gr,low), (long)TRANSY(gr,-1) );
positionText( &gr->rp, GPT_XCENTRE | GPT_YTOP, NULL,
(long) (first) * gr->X.labnum / gr->X.labdenom,
TRANSX(gr,low), TRANSY(gr,-YLEEWAY) );
axis = &gr->X;
}
spacing = full << 1;
low += spacing;
coord = offsetToCoord( axis, low );
low = coordToOffset( axis, coord );
if( high - low >= spacing - TOLERANCE ) {
graphWriteLabel( gr, myflags | GWL_NO_HIGH, coord, last, step );
}
}
if( !(myflags & GWL_NO_HIGH) ) {
SetAPen( &gr->rp, (long) gr->FPen );
if( tf ) {
SetFont( &gr->rp, tf );
}
}
return( maxrlen );
} /* graphWriteLabel */
VOID addToGraph( gr, x, y )
register GRAPH *gr;
SHORT x, y;
{
SHORT amt;
SHORT newX, newY;
newX = updateCoord( gr, &gr->X, x );
newY = updateCoord( gr, &gr->Y, y );
SetAPen( &gr->rp, (long) gr->FPen );
if( !(gr->ctlflags & GGR_NOCONNECTLINE) ) {
Move( &gr->rp, (long) TRANSX(gr,gr->X.lastoff),
(long) TRANSY(gr,gr->Y.lastoff) );
Draw( &gr->rp, (long)TRANSX(gr,newX), (long)TRANSY(gr,newY) );
} else {
Move( &gr->rp, (long)TRANSX(gr,newX), (long)TRANSY(gr,newY) );
}
if( gr->flags & GGR_LINETOX ) {
Move( &gr->rp, (long)TRANSX(gr,newX), (long)TRANSY(gr,newY) );
Draw( &gr->rp, (long)TRANSX(gr,newX), (long)TRANSY(gr,1) );
}
if( gr->flags & GGR_LINETOY ) {
Move( &gr->rp, (long)TRANSX(gr,newX), (long)TRANSY(gr,newY) );
Draw( &gr->rp, (long)TRANSX(gr,1), (long)TRANSY(gr,newY) );
}
if( gr->flags & GGR_FILLTOX ) {
doBlock( &gr->rp, TRANSX(gr, gr->X.lastoff), TRANSY(gr, 1),
TRANSX(gr, gr->X.lastoff), TRANSY(gr, gr->Y.lastoff),
TRANSX(gr, newX), TRANSY(gr, newY),
TRANSX(gr, newX), TRANSY(gr, 1) );
}
if( gr->flags & GGR_FILLTOY ) {
doBlock( &gr->rp, TRANSX(gr, 1), TRANSY(gr, gr->Y.lastoff),
TRANSX(gr,gr->X.lastoff), TRANSY(gr, gr->Y.lastoff),
TRANSX(gr, newX), TRANSY(gr, newY),
TRANSX(gr, 1), TRANSY(gr, newY) );
}
if( gr->flags & GGR_BLACKTOX ) {
SetAPen( &gr->rp, (long) gr->BPen );
Move( &gr->rp, (long) TRANSX(gr, gr->X.lastoff),(long)TRANSY(gr, 1) );
Draw( &gr->rp, (long) TRANSX(gr, gr->X.lastoff),
(long) TRANSY(gr, gr->Y.lastoff) );
SetAPen( &gr->rp, (long) gr->FPen );
}
if( gr->flags & GGR_BLACKTOY ) {
SetAPen( &gr->rp, (long) gr->BPen );
Move(&gr->rp, (long) TRANSX(gr, 1),(long)TRANSY(gr, gr->Y.lastoff) );
Draw(&gr->rp, (long) TRANSX(gr, gr->X.lastoff),
(long) TRANSY(gr, gr->Y.lastoff) );
SetAPen( &gr->rp, (long) gr->FPen );
}
gr->X.lastoff = newX;
gr->Y.lastoff = newY;
++gr->points;
} /* addToGraph */
/* internal use only!!
* add a coordinate to an axis, doing the actual scrolling if necessary
* and updating some AXIS fields
*
* note: truncates to the rectangle defined by the origin and the axis' size.
*
* returns the standard pixel offset for the coordinate
static SHORT updateCoord( gr, axis, coord )
GRAPH *gr;
register AXIS *axis;
SHORT coord;
{
SHORT offset;
SHORT amt;
LONG Xamt, Yamt;
ULONG flags, awlflags;
if( axis == &gr->X ) {
flags = gr->flags & GGR_X_FLAGS;
} else {
flags = gr->flags & GGR_Y_FLAGS;
}
if( flags & (GGR_DELTAX | GGR_DELTAY) ) {
axis->lastdata += coord;
offset = coordToOffset( axis, axis->lastdata );
if( offset > axis->usesize ) {
if( axis == &gr->X ) {
Xamt = amt = offset - axis->lastoff;
Yamt = 0L;
} else {
Xamt = 0L;
Yamt = amt = offset - axis->lastoff;
}
ScrollRaster( &gr->rp, (long) Xamt, (long) Yamt,
(long) TRANSX(gr,1), (long) TRANSY(gr,gr->Y.size),
(long) TRANSX(gr,axis->size), (long) TRANSY(gr,1) );
awlflags = (axis == &gr->X) ? GWL_XAXIS : GWL_YAXIS;
if( !(gr->ctlflags & GGR_NOLABELS) ) {
graphWriteLabel( gr, awlflags | GWL_CLEAR_ONLY, axis->low,
axis->high, axis->step );
}
axis->low += coord;
axis->high += coord;
/* drawGraphAxesOnly( gr ); */
if( !(gr->ctlflags & GGR_NOLABELS) ) {
graphWriteLabel( gr, awlflags, axis->low, axis->high,
axis->step );
}
offset = axis->lastoff;
axis->lastoff -= amt;
}
} else {
offset = coordToOffset( axis, coord );
if( offset < 0 ) {
offset = 0;
} else if( offset > axis->size ) {
offset = axis->size;
}
axis->lastdata = coord;
}
return( offset );
} /* updateCoord */
/* internal use only!!
* do an area fill on the 4 pairs of coordinates,
* clipped to the rastport's bitmap size
* NOTE: the TmpRas should be (at least) the same size as this bitmap
static VOID doBlock( rp, x1, y1, x2, y2, x3, y3, x4, y4 )
register struct RastPort *rp;
SHORT x1, y1, x2, y2, x3, y3, x4, y4;
{
SHORT width, height;
width = rp->BitMap->BytesPerRow << 3;
height = rp->BitMap->Rows;
if( x1 < 0 ) x1 = 0;
else if( x1 > width ) x1 = width;
if( x2 < 0 ) x2 = 0;
else if( x2 > width ) x2 = width;
if( x3 < 0 ) x3 = 0;
else if( x3 > width ) x3 = width;
if( x4 < 0 ) x4 = 0;
else if( x4 > width ) x4 = width;
if( x1 == x3 ) return;
if( y1 < 0 ) y1 = 0;
else if( y1 > height ) y1 = height;
if( y2 < 0 ) y2 = 0;
else if( y2 > height ) y2 = height;
if( y3 < 0 ) y3 = 0;
else if( y3 > height ) y3 = height;
if( y4 < 0 ) y4 = 0;
else if( y4 > height ) y4 = height;
if( y1 == y3 ) return;
AreaMove( rp, (long) x1, (long) y1 );
AreaDraw( rp, (long) x2, (long) y2 );
AreaDraw( rp, (long) x3, (long) y3 );
AreaDraw( rp, (long) x4, (long) y4 );
AreaEnd( rp );
} /* doBlock */