draw.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:33k
- /* $Header: /usr/src/mash/repository/vint/xgraph/draw.c,v 1.1.1.1 1999/12/03 23:15:53 heideman Exp $ */
- /*
- * draw.c: xgraph drawing code
- *
- * Routines:
- * void DrawWindow();
- *
- * $Log: draw.c,v $
- * Revision 1.1.1.1 1999/12/03 23:15:53 heideman
- * xgraph-12.0
- *
- */
- #ifndef lint
- static char rcsid[] = "$Id: draw.c,v 1.1.1.1 1999/12/03 23:15:53 heideman Exp $";
- #endif
- #include "copyright.h"
- #include <stdio.h>
- #include <math.h>
- #include <pwd.h>
- #include <ctype.h>
- #include "xgraph.h"
- #include "xtb.h"
- #include "hard_devices.h"
- #include "params.h"
- static void DrawTitle();
- static void DrawGridAndAxis();
- static void WriteValue();
- static void DrawData();
- static void DrawLegend();
- static int TransformCompute();
- static double initGrid();
- static double stepGrid();
- static double RoundUp();
- static void set_mark_flags();
- void
- DrawWindow(win_info)
- LocalWin *win_info; /* Window information */
- /*
- * Draws the data in the window. Does not clear the window.
- * The data is scaled so that all of the data will fit.
- * Grid lines are drawn at the nearest power of 10 in engineering
- * notation. Draws axis numbers along bottom and left hand edges.
- * Centers title at top of window.
- */
- {
- /* Figure out the transformation constants */
- if (TransformCompute(win_info)) {
- /* Draw the title */
- DrawTitle(win_info);
- /* Draw the legend */
- if (!PM_BOOL("NoLegend"))
- DrawLegend(win_info);
- /* Draw the axis unit labels, grid lines, and grid labels */
- DrawGridAndAxis(win_info);
- /* Draw the data sets themselves */
- DrawData(win_info);
- }
- }
- static void
- DrawTitle(wi)
- LocalWin *wi; /* Window information */
- /*
- * This routine draws the title of the graph centered in
- * the window. It is spaced down from the top by an amount
- * specified by the constant PADDING. The font must be
- * fixed width. The routine returns the height of the
- * title in pixels.
- */
- {
- if (wi->DOrder == 0)
- wi->dev_info.xg_text(wi->dev_info.user_state,
- (int)(wi->dev_info.area_w*0.95) ,
- wi->dev_info.axis_pad,
- PM_STR("TitleText"), T_UPPERRIGHT, T_TITLE);
- else if (wi->DOrder == 1)
- wi->dev_info.xg_text(wi->dev_info.user_state,
- (int)(wi->dev_info.area_w*0.95) ,
- wi->dev_info.axis_pad,
- "First Derivative", T_UPPERRIGHT, T_TITLE);
- else if (wi->DOrder == 2)
- wi->dev_info.xg_text(wi->dev_info.user_state,
- (int)(wi->dev_info.area_w*0.95) ,
- wi->dev_info.axis_pad,
- "Second Derivative", T_UPPERRIGHT, T_TITLE);
- }
- static int
- TransformCompute(wi)
- LocalWin *wi; /* Window information */
- /*
- * This routine figures out how to draw the axis labels and grid lines.
- * Both linear and logarithmic axes are supported. Axis labels are
- * drawn in engineering notation. The power of the axes are labeled
- * in the normal axis labeling spots. The routine also figures
- * out the necessary transformation information for the display
- * of the points (it touches XOrgX, XOrgY, UsrOrgX, UsrOrgY, and
- * UnitsPerPixel).
- */
- {
- double bbCenX,
- bbCenY,
- bbHalfWidth,
- bbHalfHeight;
- int idx,
- maxName,
- leftWidth;
- char err[MAXBUFSIZE];
- char *XUnitText = PM_STR("XUnitText");
- /*
- * First, we figure out the origin in the X window. Above the space we
- * have the title and the Y axis unit label. To the left of the space we
- * have the Y axis grid labels.
- */
- wi->XOrgX = wi->dev_info.bdr_pad + (7 * wi->dev_info.axis_width)
- + wi->dev_info.bdr_pad;
- wi->XOrgY = wi->dev_info.bdr_pad + wi->dev_info.title_height
- + wi->dev_info.bdr_pad + wi->dev_info.axis_height
- + wi->dev_info.axis_height / 2 + wi->dev_info.bdr_pad;
- /*
- * Now we find the lower right corner. Below the space we have the X axis
- * grid labels. To the right of the space we have the X axis unit label
- * and the legend. We assume the worst case size for the unit label.
- */
- maxName = 0;
- for (idx = 0; idx < MAXSETS; idx++) {
- if (PlotData[idx].list) {
- int tempSize;
- tempSize = strlen(PlotData[idx].setName);
- if (tempSize > maxName)
- maxName = tempSize;
- }
- }
- if (PM_BOOL("NoLegend"))
- maxName = 0;
- /* Worst case size of the X axis label: */
- leftWidth = (strlen(XUnitText)) * wi->dev_info.axis_width;
- if ((maxName * wi->dev_info.axis_width) + wi->dev_info.bdr_pad > leftWidth)
- leftWidth = maxName * wi->dev_info.axis_width + wi->dev_info.bdr_pad;
- wi->XOppX = wi->dev_info.area_w - wi->dev_info.bdr_pad - leftWidth;
- wi->XOppY = wi->dev_info.area_h - wi->dev_info.bdr_pad
- - wi->dev_info.axis_height - wi->dev_info.bdr_pad;
- if ((wi->XOrgX >= wi->XOppX) || (wi->XOrgY >= wi->XOppY)) {
- do_error(strcpy(err, "Drawing area is too smalln"));
- return 0;
- }
- /*
- * We now have a bounding box for the drawing region. Figure out the units
- * per pixel using the data set bounding box.
- */
- wi->XUnitsPerPixel = (wi->hiX - wi->loX) /
- ((double) (wi->XOppX - wi->XOrgX));
- wi->YUnitsPerPixel = (wi->hiY - wi->loY) /
- ((double) (wi->XOppY - wi->XOrgY));
- /*
- * Find origin in user coordinate space. We keep the center of the
- * original bounding box in the same place.
- */
- bbCenX = (wi->loX + wi->hiX) / 2.0;
- bbCenY = (wi->loY + wi->hiY) / 2.0;
- bbHalfWidth = ((double) (wi->XOppX - wi->XOrgX)) / 2.0 * wi->XUnitsPerPixel;
- bbHalfHeight = ((double) (wi->XOppY - wi->XOrgY)) / 2.0 * wi->YUnitsPerPixel;
- wi->UsrOrgX = bbCenX - bbHalfWidth;
- wi->UsrOrgY = bbCenY - bbHalfHeight;
- wi->UsrOppX = bbCenX + bbHalfWidth;
- wi->UsrOppY = bbCenY + bbHalfHeight;
- /*
- * Everything is defined so we can now use the SCREENX and SCREENY
- * transformations.
- */
- return 1;
- }
- static void
- DrawGridAndAxis(wi)
- LocalWin *wi; /* Window information */
- /*
- * This routine draws grid line labels in engineering notation,
- * the grid lines themselves, and unit labels on the axes.
- */
- {
- int expX,
- expY; /* Engineering powers */
- int startX;
- int Yspot,
- Xspot;
- char power[10],
- value[10],
- final[MAXBUFSIZE + 10];
- double Xincr,
- Yincr,
- Xstart,
- Ystart,
- Yindex,
- Xindex,
- larger;
- XSegment segs[2];
- double initGrid(),
- stepGrid();
- int tickFlag = PM_BOOL("Ticks");
- int axisFlag = PM_BOOL("TickAxis");
- int logXFlag = PM_BOOL("LogX");
- int logYFlag = PM_BOOL("LogY");
- char *XUnitText = PM_STR("XUnitText");
- char *YUnitText = PM_STR("YUnitText");
- /*
- * Grid display powers are computed by taking the log of the largest
- * numbers and rounding down to the nearest multiple of 3.
- */
- if (logXFlag) {
- expX = 0;
- }
- else {
- if (fabs(wi->UsrOrgX) > fabs(wi->UsrOppX)) {
- larger = fabs(wi->UsrOrgX);
- }
- else {
- larger = fabs(wi->UsrOppX);
- }
- expX = ((int) floor(nlog10(larger) / 3.0)) * 3;
- }
- if (logYFlag) {
- expY = 0;
- }
- else {
- if (fabs(wi->UsrOrgY) > fabs(wi->UsrOppY)) {
- larger = fabs(wi->UsrOrgY);
- }
- else {
- larger = fabs(wi->UsrOppY);
- }
- expY = ((int) floor(nlog10(larger) / 3.0)) * 3;
- }
- /*
- * With the powers computed, we can draw the axis labels.
- */
- if (expY != 0) {
- (void) strcpy(final, YUnitText);
- (void) strcat(final, " x 10");
- Xspot = wi->dev_info.bdr_pad +
- ((strlen(YUnitText) + 5) * wi->dev_info.axis_width);
- Yspot = wi->dev_info.bdr_pad * 2 + wi->dev_info.title_height +
- wi->dev_info.axis_height / 2;
- wi->dev_info.xg_text(wi->dev_info.user_state,
- Xspot, Yspot, final, T_RIGHT, T_AXIS);
- (void) sprintf(power, "%d", expY);
- wi->dev_info.xg_text(wi->dev_info.user_state,
- Xspot, Yspot, power, T_LOWERLEFT, T_AXIS);
- }
- else {
- Yspot = wi->dev_info.bdr_pad * 2 + wi->dev_info.title_height;
- wi->dev_info.xg_text(wi->dev_info.user_state,
- wi->dev_info.bdr_pad, Yspot, YUnitText,
- T_UPPERLEFT, T_AXIS);
- }
- startX = wi->dev_info.area_w - wi->dev_info.bdr_pad;
- if (expX != 0) {
- (void) sprintf(power, "%d", expX);
- startX -= (strlen(power) * wi->dev_info.axis_width);
- wi->dev_info.xg_text(wi->dev_info.user_state,
- startX, wi->XOppY, power, T_LOWERLEFT, T_AXIS);
- (void) strcpy(final, XUnitText);
- (void) strcat(final, " x 10");
- wi->dev_info.xg_text(wi->dev_info.user_state,
- startX, wi->XOppY, final, T_RIGHT, T_AXIS);
- }
- else {
- wi->dev_info.xg_text(wi->dev_info.user_state,
- startX, wi->XOppY, XUnitText, T_RIGHT, T_AXIS);
- }
- /*
- * First, the grid line labels
- */
- Yincr = (wi->dev_info.axis_pad + wi->dev_info.axis_height) *
- wi->YUnitsPerPixel;
- Ystart = initGrid(wi->UsrOrgY, Yincr, logYFlag);
- for (Yindex = Ystart; Yindex < wi->UsrOppY; Yindex = stepGrid()) {
- Yspot = SCREENY(wi, Yindex);
- /* Write the axis label */
- WriteValue(value, PM_STR("Format X"), Yindex, expY, logYFlag);
- wi->dev_info.xg_text(wi->dev_info.user_state,
- wi->dev_info.bdr_pad +
- (7 * wi->dev_info.axis_width),
- Yspot, value, T_RIGHT, T_AXIS);
- }
- Xincr = (wi->dev_info.axis_pad + (wi->dev_info.axis_width * 7)) *
- wi->XUnitsPerPixel;
- Xstart = initGrid(wi->UsrOrgX, Xincr, logXFlag);
-
- for (Xindex = Xstart; Xindex < wi->UsrOppX; Xindex = stepGrid()) {
- Xspot = SCREENX(wi, Xindex);
- /* Write the axis label */
- WriteValue(value, PM_STR("Format Y"), Xindex, expX, logXFlag);
- wi->dev_info.xg_text(wi->dev_info.user_state,
- Xspot,
- wi->dev_info.area_h - wi->dev_info.bdr_pad,
- value, T_BOTTOM, T_AXIS);
- }
- /*
- * Now, the grid lines or tick marks
- */
- Yincr = (wi->dev_info.axis_pad + wi->dev_info.axis_height) *
- wi->YUnitsPerPixel;
- Ystart = initGrid(wi->UsrOrgY, Yincr, logYFlag);
- for (Yindex = Ystart; Yindex < wi->UsrOppY; Yindex = stepGrid()) {
- Yspot = SCREENY(wi, Yindex);
- /* Draw the grid line or tick mark */
- if (tickFlag && !(axisFlag && Yindex == Ystart)) {
- segs[0].x1 = wi->XOrgX;
- segs[0].x2 = wi->XOrgX + wi->dev_info.tick_len;
- segs[1].x1 = wi->XOppX - wi->dev_info.tick_len;
- segs[1].x2 = wi->XOppX;
- segs[0].y1 = segs[0].y2 = segs[1].y1 = segs[1].y2 = Yspot;
- }
- else {
- segs[0].x1 = wi->XOrgX;
- segs[0].x2 = wi->XOppX;
- segs[0].y1 = segs[0].y2 = Yspot;
- }
- if ((ABS(Yindex) < ZERO_THRES) && !logYFlag) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, segs, PM_INT("ZeroWidth"),
- L_ZERO, 0, 0);
- if (tickFlag) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &(segs[1]), PM_INT("ZeroWidth"),
- L_ZERO, 0, 0);
- }
- }
- else {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, segs, PM_INT("GridSize"),
- L_AXIS, 0, 0);
- if (tickFlag) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &(segs[1]), PM_INT("GridSize"),
- L_AXIS, 0, 0);
- }
- }
- }
- Xincr = (wi->dev_info.axis_pad + (wi->dev_info.axis_width * 7)) *
- wi->XUnitsPerPixel;
- Xstart = initGrid(wi->UsrOrgX, Xincr, logXFlag);
- for (Xindex = Xstart; Xindex < wi->UsrOppX; Xindex = stepGrid()) {
- Xspot = SCREENX(wi, Xindex);
- /* Draw the grid line or tick marks */
- if (tickFlag && !(axisFlag && Xindex == Xstart)) {
- segs[0].x1 = segs[0].x2 = segs[1].x1 = segs[1].x2 = Xspot;
- segs[0].y1 = wi->XOrgY;
- segs[0].y2 = wi->XOrgY + wi->dev_info.tick_len;
- segs[1].y1 = wi->XOppY - wi->dev_info.tick_len;
- segs[1].y2 = wi->XOppY;
- }
- else {
- segs[0].x1 = segs[0].x2 = Xspot;
- segs[0].y1 = wi->XOrgY;
- segs[0].y2 = wi->XOppY;
- }
- if ((ABS(Xindex) < ZERO_THRES) && !logXFlag) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, segs, PM_INT("ZeroWidth"), L_ZERO, 0, 0);
- if (tickFlag) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &(segs[1]), PM_INT("ZeroWidth"),
- L_ZERO, 0, 0);
- }
- }
- else {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, segs, PM_INT("GridSize"), L_AXIS, 0, 0);
- if (tickFlag) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &(segs[1]), PM_INT("GridSize"), L_AXIS, 0, 0);
- }
- }
- }
- /* Check to see if he wants a bounding box */
- if (PM_BOOL("BoundBox")) {
- XSegment bb[4];
- /* Draw bounding box */
- bb[0].x1 = bb[0].x2 = bb[1].x1 = bb[3].x2 = wi->XOrgX;
- bb[0].y1 = bb[2].y2 = bb[3].y1 = bb[3].y2 = wi->XOrgY;
- bb[1].x2 = bb[2].x1 = bb[2].x2 = bb[3].x1 = wi->XOppX;
- bb[0].y2 = bb[1].y1 = bb[1].y2 = bb[2].y1 = wi->XOppY;
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 4, bb, PM_INT("GridSize"), L_AXIS, 0, 0);
- }
- }
- static double gridBase,
- gridStep,
- gridJuke[101];
- static int gridNJuke,
- gridCurJuke;
- #define ADD_GRID(val) (gridJuke[gridNJuke++] = log10(val))
- static double
- initGrid(low, step, logFlag)
- double low; /* desired low value */
- double step; /* desired step (user coords) */
- int logFlag; /* is axis logarithmic? */
- {
- double ratio,
- x;
- double RoundUp(),
- stepGrid();
- gridNJuke = gridCurJuke = 0;
- gridJuke[gridNJuke++] = 0.0;
- if (logFlag) {
- ratio = pow(10.0, step);
- gridBase = floor(low);
- gridStep = ceil(step);
- if (ratio <= 3.0) {
- if (ratio > 2.0) {
- ADD_GRID(3.0);
- }
- else if (ratio > 1.333) {
- ADD_GRID(2.0);
- ADD_GRID(5.0);
- }
- else if (ratio > 1.25) {
- ADD_GRID(1.5);
- ADD_GRID(2.0);
- ADD_GRID(3.0);
- ADD_GRID(5.0);
- ADD_GRID(7.0);
- }
- else {
- for (x = 1.0; x < 10.0 && (x + .5) / (x + .4) >= ratio; x += .5) {
- ADD_GRID(x + .1);
- ADD_GRID(x + .2);
- ADD_GRID(x + .3);
- ADD_GRID(x + .4);
- ADD_GRID(x + .5);
- }
- if (floor(x) != x)
- ADD_GRID(x += .5);
- for (; x < 10.0 && (x + 1.0) / (x + .5) >= ratio; x += 1.0) {
- ADD_GRID(x + .5);
- ADD_GRID(x + 1.0);
- }
- for (; x < 10.0 && (x + 1.0) / x >= ratio; x += 1.0) {
- ADD_GRID(x + 1.0);
- }
- if (x == 7.0) {
- gridNJuke--;
- x = 6.0;
- }
- if (x < 7.0) {
- ADD_GRID(x + 2.0);
- }
- if (x == 10.0)
- gridNJuke--;
- }
- x = low - gridBase;
- for (gridCurJuke = -1; x >= gridJuke[gridCurJuke + 1]; gridCurJuke++) {
- }
- }
- }
- else {
- gridStep = RoundUp(step);
- gridBase = floor(low / gridStep) * gridStep;
- }
- return (stepGrid());
- }
- static double
- stepGrid()
- {
- if (++gridCurJuke >= gridNJuke) {
- gridCurJuke = 0;
- gridBase += gridStep;
- }
- return (gridBase + gridJuke[gridCurJuke]);
- }
- static double
- RoundUp(val)
- double val; /* Value */
- /*
- * This routine rounds up the given positive number such that
- * it is some power of ten times either 1, 2, or 5. It is
- * used to find increments for grid lines.
- */
- {
- int exponent,
- idx;
- exponent = (int) floor(nlog10(val));
- if (exponent < 0) {
- for (idx = exponent; idx < 0; idx++) {
- val *= 10.0;
- }
- }
- else {
- for (idx = 0; idx < exponent; idx++) {
- val /= 10.0;
- }
- }
- if (val > 5.0)
- val = 10.0;
- else if (val > 2.0)
- val = 5.0;
- else if (val > 1.0)
- val = 2.0;
- else
- val = 1.0;
- if (exponent < 0) {
- for (idx = exponent; idx < 0; idx++) {
- val /= 10.0;
- }
- }
- else {
- for (idx = 0; idx < exponent; idx++) {
- val *= 10.0;
- }
- }
- return val;
- }
- static void
- WriteValue(str, fmt, val, expv, logFlag)
- char *str; /* String to write into */
- char *fmt; /* Format to print str */
- double val; /* Value to print */
- int expv; /* Exponent */
- int logFlag; /* Is this a log axis? */
- /*
- * Writes the value provided into the string in a fixed format
- * consisting of seven characters. The format is:
- * -ddd.dd
- */
- {
- int idx;
- if (logFlag) {
- if (val == floor(val)) {
- if (strcmp(fmt, "%.2f") == 0)
- fmt = "%.0e";
- val = pow(10.0, val);
- }
- else {
- if (strcmp(fmt, "%.2f") == 0)
- fmt = "%.2g";
- val = pow(10.0, val - floor(val));
- }
- }
- else {
- if (expv < 0) {
- for (idx = expv; idx < 0; idx++) {
- val *= 10.0;
- }
- }
- else {
- for (idx = 0; idx < expv; idx++) {
- val /= 10.0;
- }
- }
- }
- if (strchr(fmt, 'd') || strchr(fmt, 'x'))
- (void) sprintf(str, fmt, (int) val);
- else
- (void) sprintf(str, fmt, val);
- }
- #define LEFT_CODE 0x01
- #define RIGHT_CODE 0x02
- #define BOTTOM_CODE 0x04
- #define TOP_CODE 0x08
- /* Clipping algorithm from Neumann and Sproull by Cohen and Sutherland */
- #define C_CODE(xval, yval, rtn)
- rtn = 0;
- if ((xval) < wi->UsrOrgX) rtn = LEFT_CODE;
- else if ((xval) > wi->UsrOppX) rtn = RIGHT_CODE;
- if ((yval) < wi->UsrOrgY) rtn |= BOTTOM_CODE;
- else if ((yval) > wi->UsrOppY) rtn |= TOP_CODE
- void
- EraseData(wi)
- LocalWin *wi;
- /*
- * This routine draws the data sets themselves using the macros
- * for translating coordinates.
- */
- {
- double sx1,
- sy1,
- sx2,
- sy2,
- tx = 0,
- ty = 0;
- int idx,
- subindex;
- int code1,
- code2,
- cd,
- mark_inside;
- int X_idx, StoreIDX; /* PW */
- XSegment *ptr;
- PointList *thisList,
- *lastList;
- int markFlag,
- pixelMarks,
- bigPixel,
- colorMark;
- int noLines = PM_BOOL("NoLines");
- int lineWidth = PM_INT("LineWidth");
- /* PW Suggests we Flush and set first */
- set_mark_flags(&markFlag, &pixelMarks, &bigPixel, &colorMark);
- for (idx = 0; idx < MAXSETS; idx++) {
- if (wi->DOrder == 0)
- thisList = PlotData[idx].list;
- else if (wi->DOrder == 1)
- thisList = DataD1[idx].list;
- else if (wi->DOrder == 2)
- thisList = DataD2[idx].list;
- else {
- printf ("Internal Error differentiating - order > 2!n");
- exit (1);
- }
- while (thisList) {
- X_idx = 0;
- for (subindex = 0; subindex < thisList->numPoints - 1; subindex++) {
- /* Put segment in (sx1,sy1) (sx2,sy2) */
- sx1 = thisList->xvec[subindex];
- sy1 = thisList->yvec[subindex];
- sx2 = thisList->xvec[subindex + 1];
- sy2 = thisList->yvec[subindex + 1];
- /* Now clip to current window boundary */
- C_CODE(sx1, sy1, code1);
- C_CODE(sx2, sy2, code2);
- mark_inside = (code1 == 0);
- while (code1 || code2) {
- if (code1 & code2)
- break;
- cd = (code1 ? code1 : code2);
- if (cd & LEFT_CODE) { /* Crosses left edge */
- ty = sy1 + (sy2 - sy1) * (wi->UsrOrgX - sx1) /
- (sx2 - sx1);
- tx = wi->UsrOrgX;
- }
- else if (cd & RIGHT_CODE) { /* Crosses right edge */
- ty = sy1 + (sy2 - sy1) * (wi->UsrOppX - sx1) /
- (sx2 - sx1);
- tx = wi->UsrOppX;
- }
- else if (cd & BOTTOM_CODE) {/* Crosses bottom edge */
- tx = sx1 + (sx2 - sx1) * (wi->UsrOrgY - sy1) /
- (sy2 - sy1);
- ty = wi->UsrOrgY;
- }
- else if (cd & TOP_CODE) { /* Crosses top edge */
- tx = sx1 + (sx2 - sx1) * (wi->UsrOppY - sy1) /
- (sy2 - sy1);
- ty = wi->UsrOppY;
- }
- if (cd == code1) {
- sx1 = tx;
- sy1 = ty;
- C_CODE(sx1, sy1, code1);
- }
- else {
- sx2 = tx;
- sy2 = ty;
- C_CODE(sx2, sy2, code2);
- }
- }
- if (!code1 && !code2) {
- /* Add segment to list */
- Xsegs[0][X_idx].x1 = Xsegs[1][X_idx].x1;
- Xsegs[0][X_idx].y1 = Xsegs[1][X_idx].y1;
- Xsegs[0][X_idx].x2 = Xsegs[1][X_idx].x2;
- Xsegs[0][X_idx].y2 = Xsegs[1][X_idx].y2;
- Xsegs[1][X_idx].x1 = SCREENX(wi, sx1);
- Xsegs[1][X_idx].y1 = SCREENY(wi, sy1);
- Xsegs[1][X_idx].x2 = SCREENX(wi, sx2);
- Xsegs[1][X_idx].y2 = SCREENY(wi, sy2);
- X_idx++;
- }
- /* Draw markers if requested and they are in drawing region */
- if (markFlag && mark_inside) {
- if (pixelMarks) {
- if (bigPixel) {
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x1,
- Xsegs[1][X_idx - 1].y1,
- P_DOT, 0, idx % MAXATTR);
- }
- else {
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x1,
- Xsegs[1][X_idx - 1].y1,
- P_PIXEL, 0, PIXVALUE(idx));
- }
- }
- else {
- /* Distinctive markers */
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x1,
- Xsegs[1][X_idx - 1].y1,
- P_MARK, MARKSTYLE(idx),
- PIXVALUE(idx));
- }
- }
- /* Draw bar elements if requested */
- if (PM_BOOL("BarGraph")) {
- int barPixels,
- baseSpot;
- XSegment line;
- barPixels = (int) ((PM_DBL("BarWidth") /
- wi->XUnitsPerPixel) + 0.5);
- if (barPixels <= 0)
- barPixels = 1;
- baseSpot = SCREENY(wi, PM_DBL("BarBase"));
- line.x1 = line.x2 = Xsegs[1][X_idx - 1].x1 +
- (int) ((PM_DBL("BarOffset") * idx /
- wi->XUnitsPerPixel) + 0.5);
- if (PM_BOOL("StackGraph") && idx != 0)
- line.y1 = Xsegs[0][X_idx - 1].y1;
- else
- line.y1 = baseSpot;
- line.y2 = Xsegs[1][X_idx - 1].y1;
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &line, barPixels, L_VAR,
- LINESTYLE(idx), PIXVALUE(idx));
- }
- }
- /* Handle last marker */
- if (markFlag && (thisList->numPoints > 0)) {
- C_CODE(thisList->xvec[thisList->numPoints - 1],
- thisList->yvec[thisList->numPoints - 1],
- mark_inside);
- if (mark_inside == 0) {
- if (pixelMarks) {
- if (bigPixel) {
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x2,
- Xsegs[1][X_idx - 1].y2,
- P_DOT, 0, idx % MAXATTR);
- }
- else {
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x2,
- Xsegs[1][X_idx - 1].y2,
- P_PIXEL, 0, PIXVALUE(idx));
- }
- }
- else {
- /* Distinctive markers */
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x2,
- Xsegs[1][X_idx - 1].y2,
- P_MARK, MARKSTYLE(idx),
- PIXVALUE(idx));
- }
- }
- }
- /* Handle last bar */
- if ((thisList->numPoints > 0) && PM_BOOL("BarGraph")) {
- int barPixels,
- baseSpot;
- XSegment line;
- barPixels = (int) ((PM_DBL("BarWidth") /
- wi->XUnitsPerPixel) + 0.5);
- if (barPixels <= 0)
- barPixels = 1;
- baseSpot = SCREENY(wi, PM_DBL("BarBase"));
- line.x1 = line.x2 = Xsegs[1][X_idx - 1].x2 +
- (int) ((PM_DBL("BarOffset") * idx /
- wi->XUnitsPerPixel) + 0.5);
- if (PM_BOOL("StackGraph") && idx != 0)
- line.y1 = Xsegs[0][X_idx - 1].y2;
- else
- line.y1 = baseSpot;
- line.y2 = Xsegs[1][X_idx - 1].y2;
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &line, barPixels, L_VAR,
- LINESTYLE(idx), PIXVALUE(idx));
- }
- /* Erase segments */
- if ((thisList->numPoints > 0) && (!noLines) && (X_idx > 0)) {
- ptr = Xsegs[1];
- while (X_idx > wi->dev_info.max_segs) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- wi->dev_info.max_segs, ptr,
- lineWidth, L_VAR,
- 16, (int)(1));
- /*LINESTYLE(8), (int)(1));*/
- ptr += wi->dev_info.max_segs;
- X_idx -= wi->dev_info.max_segs;
- }
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- X_idx, ptr,
- lineWidth, L_VAR,
- 16,(int)(1));
- }
- /* Next subset */
- thisList = thisList->next;
- }
- }
- XFlush (disp);
- }
- static void
- DrawData(wi)
- LocalWin *wi;
- /*
- * This routine draws the data sets themselves using the macros
- * for translating coordinates.
- */
- {
- double sx1,
- sy1,
- sx2,
- sy2,
- tx = 0,
- ty = 0;
- int idx,
- subindex;
- int code1,
- code2,
- cd,
- mark_inside;
- int X_idx, StoreIDX; /* PW */
- XSegment *ptr;
- PointList *thisList,
- *lastList;
- int markFlag,
- pixelMarks,
- bigPixel,
- colorMark;
- int noLines = PM_BOOL("NoLines");
- int lineWidth = PM_INT("LineWidth");
- /* PW */
- int theDelay;
- /* PW Suggests we Flush and set first */
- theDelay = PM_INT("DelayValue")*100000;
- XFlush(disp);
- if (PM_BOOL("Animate")) sleep(1);
- set_mark_flags(&markFlag, &pixelMarks, &bigPixel, &colorMark);
- for (idx = 0; idx < MAXSETS; idx++) {
- if (wi->DOrder == 0)
- thisList = PlotData[idx].list;
- else if (wi->DOrder == 1)
- thisList = DataD1[idx].list;
- else if (wi->DOrder == 2)
- thisList = DataD2[idx].list;
- else {
- printf ("Internal Error differentiating - order > 2!n");
- exit (1);
- }
- while (thisList) {
- X_idx = 0;
- for (subindex = 0; subindex < thisList->numPoints - 1; subindex++) {
- /* Put segment in (sx1,sy1) (sx2,sy2) */
- sx1 = thisList->xvec[subindex];
- sy1 = thisList->yvec[subindex];
- sx2 = thisList->xvec[subindex + 1];
- sy2 = thisList->yvec[subindex + 1];
- /* Now clip to current window boundary */
- C_CODE(sx1, sy1, code1);
- C_CODE(sx2, sy2, code2);
- mark_inside = (code1 == 0);
- while (code1 || code2) {
- if (code1 & code2)
- break;
- cd = (code1 ? code1 : code2);
- if (cd & LEFT_CODE) { /* Crosses left edge */
- ty = sy1 + (sy2 - sy1) * (wi->UsrOrgX - sx1) /
- (sx2 - sx1);
- tx = wi->UsrOrgX;
- }
- else if (cd & RIGHT_CODE) { /* Crosses right edge */
- ty = sy1 + (sy2 - sy1) * (wi->UsrOppX - sx1) /
- (sx2 - sx1);
- tx = wi->UsrOppX;
- }
- else if (cd & BOTTOM_CODE) {/* Crosses bottom edge */
- tx = sx1 + (sx2 - sx1) * (wi->UsrOrgY - sy1) /
- (sy2 - sy1);
- ty = wi->UsrOrgY;
- }
- else if (cd & TOP_CODE) { /* Crosses top edge */
- tx = sx1 + (sx2 - sx1) * (wi->UsrOppY - sy1) /
- (sy2 - sy1);
- ty = wi->UsrOppY;
- }
- if (cd == code1) {
- sx1 = tx;
- sy1 = ty;
- C_CODE(sx1, sy1, code1);
- }
- else {
- sx2 = tx;
- sy2 = ty;
- C_CODE(sx2, sy2, code2);
- }
- }
- if (!code1 && !code2) {
- /* Add segment to list */
- Xsegs[0][X_idx].x1 = Xsegs[1][X_idx].x1;
- Xsegs[0][X_idx].y1 = Xsegs[1][X_idx].y1;
- Xsegs[0][X_idx].x2 = Xsegs[1][X_idx].x2;
- Xsegs[0][X_idx].y2 = Xsegs[1][X_idx].y2;
- Xsegs[1][X_idx].x1 = SCREENX(wi, sx1);
- Xsegs[1][X_idx].y1 = SCREENY(wi, sy1);
- Xsegs[1][X_idx].x2 = SCREENX(wi, sx2);
- Xsegs[1][X_idx].y2 = SCREENY(wi, sy2);
- X_idx++;
- }
- /* Draw markers if requested and they are in drawing region */
- if (markFlag && mark_inside) {
- if (pixelMarks) {
- if (bigPixel) {
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x1,
- Xsegs[1][X_idx - 1].y1,
- P_DOT, 0, idx % MAXATTR);
- }
- else {
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x1,
- Xsegs[1][X_idx - 1].y1,
- P_PIXEL, 0, PIXVALUE(idx));
- }
- }
- else {
- /* Distinctive markers */
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x1,
- Xsegs[1][X_idx - 1].y1,
- P_MARK, MARKSTYLE(idx),
- PIXVALUE(idx));
- }
- }
- /* Draw bar elements if requested */
- if (PM_BOOL("BarGraph")) {
- int barPixels,
- baseSpot;
- XSegment line;
- barPixels = (int) ((PM_DBL("BarWidth") /
- wi->XUnitsPerPixel) + 0.5);
- if (barPixels <= 0)
- barPixels = 1;
- baseSpot = SCREENY(wi, PM_DBL("BarBase"));
- line.x1 = line.x2 = Xsegs[1][X_idx - 1].x1 +
- (int) ((PM_DBL("BarOffset") * idx /
- wi->XUnitsPerPixel) + 0.5);
- if (PM_BOOL("StackGraph") && idx != 0)
- line.y1 = Xsegs[0][X_idx - 1].y1;
- else
- line.y1 = baseSpot;
- line.y2 = Xsegs[1][X_idx - 1].y1;
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &line, barPixels, L_VAR,
- LINESTYLE(idx), PIXVALUE(idx));
- }
- }
- /* Handle last marker */
- if (markFlag && (thisList->numPoints > 0)) {
- C_CODE(thisList->xvec[thisList->numPoints - 1],
- thisList->yvec[thisList->numPoints - 1],
- mark_inside);
- if (mark_inside == 0) {
- if (pixelMarks) {
- if (bigPixel) {
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x2,
- Xsegs[1][X_idx - 1].y2,
- P_DOT, 0, idx % MAXATTR);
- }
- else {
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x2,
- Xsegs[1][X_idx - 1].y2,
- P_PIXEL, 0, PIXVALUE(idx));
- }
- }
- else {
- /* Distinctive markers */
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- Xsegs[1][X_idx - 1].x2,
- Xsegs[1][X_idx - 1].y2,
- P_MARK, MARKSTYLE(idx),
- PIXVALUE(idx));
- }
- }
- }
- /* Handle last bar */
- if ((thisList->numPoints > 0) && PM_BOOL("BarGraph")) {
- int barPixels,
- baseSpot;
- XSegment line;
- barPixels = (int) ((PM_DBL("BarWidth") /
- wi->XUnitsPerPixel) + 0.5);
- if (barPixels <= 0)
- barPixels = 1;
- baseSpot = SCREENY(wi, PM_DBL("BarBase"));
- line.x1 = line.x2 = Xsegs[1][X_idx - 1].x2 +
- (int) ((PM_DBL("BarOffset") * idx /
- wi->XUnitsPerPixel) + 0.5);
- if (PM_BOOL("StackGraph") && idx != 0)
- line.y1 = Xsegs[0][X_idx - 1].y2;
- else
- line.y1 = baseSpot;
- line.y2 = Xsegs[1][X_idx - 1].y2;
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &line, barPixels, L_VAR,
- LINESTYLE(idx), PIXVALUE(idx));
- }
- /* Draw segments */
- if (!PM_BOOL("Animate")) {
- if (thisList->numPoints > 0 && (!noLines) && (X_idx > 0)) {
- ptr = Xsegs[1];
- while (X_idx > wi->dev_info.max_segs) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- wi->dev_info.max_segs, ptr,
- lineWidth, L_VAR,
- LINESTYLE(idx), PIXVALUE(idx));
- ptr += wi->dev_info.max_segs;
- X_idx -= wi->dev_info.max_segs;
- }
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- X_idx, ptr,
- lineWidth, L_VAR,
- LINESTYLE(idx), PIXVALUE(idx));
- }
- } else {
- StoreIDX = X_idx;
- if (thisList->numPoints > 0 && (!noLines) && (X_idx > 0)) {
- ptr = Xsegs[1];
- while (X_idx > wi->dev_info.max_segs) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- wi->dev_info.max_segs, ptr,
- lineWidth, L_VAR,
- LINESTYLE(1), PIXVALUE(2));
- ptr += wi->dev_info.max_segs;
- X_idx -= wi->dev_info.max_segs;
- }
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- X_idx, ptr,
- lineWidth, L_VAR,
- LINESTYLE(1), PIXVALUE(2));
- }
- XFlush (disp);
- for (X_idx=1;X_idx<theDelay;X_idx++);
- X_idx = StoreIDX;
- if ((thisList->numPoints > 0) && (!noLines) && (X_idx > 0)) {
- ptr = Xsegs[1];
- while (X_idx > wi->dev_info.max_segs) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- wi->dev_info.max_segs, ptr,
- lineWidth, L_VAR,
- 16, (int)(1));
- /*LINESTYLE(8), (int)(1));*/
- ptr += wi->dev_info.max_segs;
- X_idx -= wi->dev_info.max_segs;
- }
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- X_idx, ptr,
- lineWidth, L_VAR,
- 16,(int)(1));
- }
- }
- /* Next subset */
- lastList = thisList;
- thisList = thisList->next;
- } /* End While */
- }
- if (PM_BOOL("Animate")) {
- X_idx = StoreIDX;
- thisList = lastList;
- if (thisList->numPoints > 0 && (!noLines) && (X_idx > 0)) {
- ptr = Xsegs[1];
- while (X_idx > wi->dev_info.max_segs) {
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- wi->dev_info.max_segs, ptr,
- lineWidth, L_VAR,
- LINESTYLE(1), PIXVALUE(2));
- ptr += wi->dev_info.max_segs;
- X_idx -= wi->dev_info.max_segs;
- }
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- X_idx, ptr,
- lineWidth, L_VAR,
- LINESTYLE(1), PIXVALUE(2));
- }
- }
- XFlush (disp);
- }
- static void
- DrawLegend(wi)
- LocalWin *wi;
- /*
- * This draws a legend of the data sets displayed. Only those that
- * will fit are drawn.
- */
- {
- int idx,
- spot,
- lineLen,
- oneLen,
- incr;
- XSegment leg_line;
- int markFlag,
- pixelMarks,
- bigPixel,
- colorMark;
- set_mark_flags(&markFlag, &pixelMarks, &bigPixel, &colorMark);
- spot = wi->XOrgY;
- lineLen = 0;
- incr = 2 + wi->dev_info.axis_height + wi->dev_info.bdr_pad;
- /* First pass draws the text */
- for (idx = 0; idx < MAXSETS; idx++) {
- if ((PlotData[idx].list) &&
- (spot + wi->dev_info.axis_height + 2 < wi->XOppY)) {
- /* Meets the criteria */
- oneLen = strlen(PlotData[idx].setName);
- if (oneLen > lineLen)
- lineLen = oneLen;
- wi->dev_info.xg_text(wi->dev_info.user_state,
- wi->XOppX + wi->dev_info.bdr_pad,
- spot + 2,
- PlotData[idx].setName,
- T_UPPERLEFT, T_AXIS);
- spot += incr;
- }
- }
- lineLen = lineLen * wi->dev_info.axis_width;
- leg_line.x1 = wi->XOppX + wi->dev_info.bdr_pad;
- leg_line.x2 = leg_line.x1 + lineLen;
- spot = wi->XOrgY;
- /* second pass draws the lines */
- for (idx = 0; idx < MAXSETS; idx++) {
- if ((PlotData[idx].list) &&
- (spot + wi->dev_info.axis_height + 2 < wi->XOppY)) {
- leg_line.y1 = leg_line.y2 = spot - wi->dev_info.legend_pad;
- if (PM_BOOL("BarGraph"))
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &leg_line,
- incr / 4,
- L_VAR, LINESTYLE(idx), PIXVALUE(idx));
- if (!PM_BOOL("NoLines"))
- wi->dev_info.xg_seg(wi->dev_info.user_state,
- 1, &leg_line, 1, L_VAR,
- LINESTYLE(idx), PIXVALUE(idx));
- if (markFlag && !pixelMarks) {
- wi->dev_info.xg_dot(wi->dev_info.user_state,
- leg_line.x1, leg_line.y1,
- P_MARK, MARKSTYLE(idx), PIXVALUE(idx));
- }
- spot += incr;
- }
- }
- }
- static void
- set_mark_flags(markFlag, pixelMarks, bigPixel, colorMark)
- int *markFlag;
- int *pixelMarks;
- int *bigPixel;
- int *colorMark;
- /*
- * Determines the values of the old boolean flags based on the
- * new values in the parameters database.
- */
- {
- *markFlag = 0;
- *pixelMarks = 0;
- *colorMark = 0;
- *bigPixel = 0;
- if (PM_BOOL("Markers")) {
- *markFlag = 1;
- *pixelMarks = 0;
- *colorMark = 0;
- }
- if (PM_BOOL("PixelMarkers")) {
- *markFlag = 1;
- *pixelMarks = 1;
- *bigPixel = 0;
- }
- if (PM_BOOL("LargePixels")) {
- *markFlag = 1;
- *pixelMarks = 1;
- *bigPixel = 1;
- }
- if (PM_BOOL("StyleMarkers")) {
- *markFlag = 1;
- *pixelMarks = 0;
- *colorMark = 1;
- }
- }
-
- #undef DELAY