/* ___________________________ A graphics header file of simple graphics functions. Author: John E. Howland, Ph.D. Department of Computer Science Trinity University 715 Stadium Drive San Antonio, Texas 78212 Voice: (512) 736-7480 Fax: (512) 694-0125 Bitnet: jhowland@trinity.edu Last Change: 900903 (Added some functionality for SGRP) */ #include #include /* ______________________________________________________________ constants */ #define PLAIN_WINDOW 0 /* plain WindowFrame style */ #define DROP_SHADOW_WINDOW 1 /* drop shadow WindowFrame style */ #define TICKLENGTH 6 /* size, in pixels of a tick mark */ #define MARKER_SIZE 2 /* default MarkerSize */ #define MARKER_CIRCLE 0 /* circle MarkerStyle */ #define MARKER_SQUARE 1 /* square MarkerStyle */ #define LINE_WIDTH 1 /* default LineWidth */ #define CONTINUOUS 0 /* default LineStyle (continuous) */ #define DASHED 1 /* dashed LineStyle */ #define DOTTED 2 /* dotted LineStyle */ /* ______________________________________________________________ types and globals */ typedef double Xform[3][3]; /* the transform type */ typedef struct /* a rectangle in world coordinates */ { double top, left, bottom, right; } windRect ; extern Rect _viewport; /* the viewport */ extern windRect _window; /* the window */ extern double _windowCenterx, _windowCentery; extern short _viewportCenterx, _viewportCentery; extern double _scalex, _scaley;/* the x and y scale factors */ extern double _cx, _cy; /* the graphics cursor location(world) */ extern GrafPtr gOldPort; /* the previous (console) GrafPtr */ extern Boolean gPreserveAspectRatio; /* Preserve aspect ration in viewing xform */ extern short gWindowFrame; /* window or viewport frame */ extern short gMarkerSize; /* Marker Size in pixels */ extern short gMarkerStyle; /* Marker Style */ extern short gLineWidth; /* Line Width in pixels */ extern short gLineStyle; /* Line Style */ /* ______________________________________________________________ function prototypes */ void initToolboxManagers(void); WindowPtr makeDrawingWindow(char *name, int left, int top, int right, int bottom); void disposeDrawingWindow(WindowPtr wPtr, int sec); void setScale(void); void setWindow(double top, double left, double bottom, double right); void setViewport(short top, short left, short bottom, short right); void view(double x, double y, short *viewx, short *viewy); void FrameViewport(void); void FrameWindow(void); void waitForKey(void); void waitForMouse(void); void eraseConsole(void); void circle(double x, double y, double r); void label(char *s); void point(double x, double y); void verticalTickMark(double x, double y, char *str); void horizontalTickMark(double x, double y, char *str); void scale(double sx, double sy, Xform transMatrix); void translate(double tx, double ty, Xform transMatrix); void rotate(double theta, Xform transMatrix); void multXform(Xform x, Xform y, Xform z); void printXform(Xform xform); void transformObject(int n, double object[][3], Xform xform, double result[][3]); void printObject(int n, double object[][3]); Boolean readObject(int *n, double object[][3]); void centerObject(int n, double object[][3], double *xcenter, double *ycenter); void drawObject(int n, double object[][3]); Boolean getInteger(int *x); Boolean getDoubleFloat(double *x); void plotBar(double x, double y); void plotPoint(double x, double y); void eraseViewport(void); void eraseWindow(void); /* These are the normal QuickDraw functions void LineTo(int x, int y); void Line(int dx, int dy); void MoveTo(int x, int y); void Move(int dx, int dy); */ void lineto(double x, double y); void line(double dx, double dy); void moveto(double x, double y); void move(double dx, double dy); void drawline(double x, double y, double x1, double y1); void SRGP_lineCoord(short x1, short y1, short x2, short y2); void SRGP_line(Point pt1, Point pt2); void SRGP_polyLineCoord(short vertexCount, short xArray[], short yArray[]); void SRGP_polyLine(short vertexCount, Point vertexList[]); void SRGP_setMarkerSize(short value); void SRGP_setMarkerStyle(short value); void SRGP_markerCoord(short x, short y); void SRGP_marker(Point pt); void SRGP_polyMarkerCoord(short vertexCount, short xArray[], short yArray[]); void SRGP_polyMarker(short vertexCount, Point vertexList[]); void SRGP_rectangleCoord(short leftX, short leftY, short rightX, short rightY); void SRGP_rectanglePt(Point bottomLeft, Point topRight); void SRGP_rectangle(Rect *rectangle); void SRGP_defPoint(short x, short y, Point *pt); void SRGP_defRectangle(short leftX, short leftY, short rightX, short rightY, Rect *rectangle); void SRGP_ellipseArc(Rect *extentRect, double startAngle, double endAngle); void SRGP_setLineStyle(short value); void SRGP_setLineWidth(short value); /* ______________________________________________________________ initToolboxManagers This function initializes the Macintosh toolbox managers. */ void initToolboxManagers(void) { InitGraf(&thePort); /* Init quickdraw, */ InitFonts(); /* font manager, */ InitWindows(); /* window manager, */ InitMenus(); /* menu manager, */ TEInit(); /* textedit (used by dialog manager), */ InitDialogs(0L); /* and dialog manager. */ InitCursor(); /* Show the cursor and set it to the standard arrow. */ } /* End of initToolboxManagers */ /* ______________________________________________________________ makeDrawingWindow This function makes a plain (named) drawing window and returns a WindowPtr to that window. left, top, right, bottom are the coordinates (in device units) of the upper left and lower right corners of the window on the main gDevice (Mac II's support multiple gDevices). You must pass a pointer to a Pascal string for name. */ WindowPtr makeDrawingWindow(char *name, int left, int top, int right, int bottom) { Rect windowRect; WindowPtr wPtr; /* set the window rect from thePort(a toolbox global) */ SetRect(&windowRect, left , top , right, bottom); wPtr = NewWindow((Ptr)0L, &windowRect, name, (Boolean)TRUE, (short)noGrowDocProc, (WindowPtr)(-1L), (Boolean)FALSE, 0L); GetPort(&gOldPort); /* Get old grafport */ SetPort((GrafPtr)wPtr); /* Set the current grafport to be the window */ return wPtr; } /* End of makeDrawingWindow */ /* ______________________________________________________________ disposeDrawingWindow This function disposes the drawing window pointed to by wPtr after sec seconds or a keypress or mouse click, which ever comes first. */ void disposeDrawingWindow(WindowPtr wPtr, int sec) { long i; EventRecord theEvent; /* Clear the event queue of all events. */ FlushEvents(everyEvent, 0); for(i = TickCount(); ((TickCount() - i) < (60 * sec)) && (!GetNextEvent((short)(mDownMask + keyDownMask), &theEvent));); SetPort(gOldPort); /* Restore previous grafport */ DisposeWindow(wPtr); /* Get rid of the window */ } /* End of disposeDrawingWindow */ /* ______________________________________________________________ setScale This function sets the x and y scale factors given the current window and viewports. This function is called from setWindow and setViewport. */ void setScale(void) { _scalex = (double)(_viewport.right - _viewport.left)/ (double)(_window.right - _window.left); _scaley = (double)(_viewport.bottom - _viewport.top)/ (double)(_window.bottom - _window.top); if(gPreserveAspectRatio) if(_scalex < _scaley) _scaley = _scalex; else _scalex = _scaley; } /* End of setScale */ /* ______________________________________________________________ setWindow This function sets a global variable, named _window. _window is a rectangle of type windRect. */ void setWindow(double top, double left, double bottom, double right) { _window.top = top; _window.left = left; _window.bottom = bottom; _window.right = right; _windowCenterx = (_window.left + _window.right) / 2.0; _windowCentery = (_window.top + _window.bottom) / 2.0; setScale(); } /* End of setWindow */ /* ______________________________________________________________ setViewport This function sets a global variable, named _viewport. _viewport is a rectangle of type Rect. */ void setViewport(short top, short left, short bottom, short right) { SetRect(&_viewport, left, top, right, bottom); _viewportCenterx = (_viewport.left + _viewport.right) / 2; _viewportCentery = (_viewport.top + _viewport.bottom) / 2; setScale(); } /* End of setViewport */ /* ______________________________________________________________ view This function performs the viewing transformation which maps the contents of a window into a viewport. */ void view(double x, double y, short *viewx, short *viewy) { (*viewx) = 0.5 + _viewportCenterx + _scalex * (x - _windowCenterx); (*viewy) = 0.5 + _viewportCentery - _scaley * (y - _windowCentery); } /* End of view */ /* ______________________________________________________________ FrameViewport This function draws a frame around the current viewport. FrameViewport produces the same result as FrameWindow when PreserveAspectRation == FALSE (the default setting). WindowFrame == 0 <--> plain dialog window WindowFrame == 1 <--> plain drop shadow window */ void FrameViewport(void) { Rect rect = _viewport; /* a temporary rectangle */ switch(gWindowFrame) { default: case PLAIN_WINDOW: InsetRect(&rect, -5, -5); /* offset to get outside viewport */ EraseRect(&rect); /* erase the rect */ FrameRect(&rect); /* draw the viewport frame */ InsetRect(&rect, 3, 3); /* offset to get outside viewport */ FrameRect(&rect); /* draw the viewport frame */ InsetRect(&rect, 1, 1); /* offset to get outside viewport */ FrameRect(&rect); /* draw the viewport frame */ break; case DROP_SHADOW_WINDOW: InsetRect(&rect, -1, -1); /* offset to get outside viewport */ FrameRect(&rect); /* draw the viewport frame */ MoveTo(1 + rect.left, rect.bottom); /* drop shadow */ LineTo(rect.right, rect.bottom); LineTo(rect.right, 1 + rect.top); break; } } /* End of FrameViewport */ /* ______________________________________________________________ FrameWindow This function draws a frame around the current window. FrameWindow produces the same result as FrameViewport when PreserveAspectRation == FALSE (the default setting). WindowFrame == 0 <--> plain dialog window WindowFrame == 1 <--> plain drop shadow window */ void FrameWindow(void) { Rect rect; /* a temporary rectangle */ view(_window.left, _window.bottom, &rect.left, &rect.top); view(_window.right, _window.top, &rect.right, &rect.bottom); switch(gWindowFrame) { default: case PLAIN_WINDOW: InsetRect(&rect, -5, -5); /* offset to get outside viewport */ EraseRect(&rect); /* erase the window */ FrameRect(&rect); /* draw the window frame */ InsetRect(&rect, 3, 3); /* offset to get outside viewport */ FrameRect(&rect); /* draw the window frame */ InsetRect(&rect, 1, 1); /* offset to get outside viewport */ FrameRect(&rect); /* draw the window frame */ break; case DROP_SHADOW_WINDOW: InsetRect(&rect, -1, -1); /* offset to get outside viewport */ FrameRect(&rect); /* draw the viewport frame */ MoveTo(1 + rect.left, rect.bottom); /* drop shadow */ LineTo(rect.right, rect.bottom); LineTo(rect.right, 1 + rect.top); break; } } /* End of FrameWindow */ /* ______________________________________________________________ waitForKey This function waits for a key to be pressed. The character is read and discarded. */ void waitForKey(void) { getchar(); /* throw away the character */ } /* End of waitForKey */ /* ______________________________________________________________ waitForMouse This function waits until the mouse button is pressed. */ void waitForMouse(void) { while(!Button()); } /* End of waitForMouse */ /* ______________________________________________________________ eraseConsole This function clears the current stdio console. */ void eraseConsole(void) { putchar('\f'); } /* End of eraseConsole */ /* ______________________________________________________________ circle This function draws a circle having center at (x,y) and radius r. */ void circle(double x, double y, double r) { Rect theRect; /* a rect for circle drawing */ short ix, iy, ir; RgnHandle clip; /* the current clipping region */ Rect rect; /* a temp rect */ view(_window.left, _window.bottom, &rect.left, &rect.top); view(_window.right, _window.top, &rect.right, &rect.bottom); clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ ClipRect(&rect); /* set clip rect to viewport */ /* this is correct only if PreserveAspectRatio is TRUE */ ir = (r * _scalex) + 0.5; view(x, y, &ix, &iy); SetRect(&theRect, ix - ir, iy - ir, ix + ir, iy + ir); FrameArc(&theRect, 0, 360); SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of circle */ /* ______________________________________________________________ label This function draws the character string s at the current graphics cursor location. */ void label(char *s) { RgnHandle clip; /* the current clipping region */ Rect rect; /* a temp rect */ view(_window.left, _window.bottom, &rect.left, &rect.top); view(_window.right, _window.top, &rect.right, &rect.bottom); clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ ClipRect(&rect); /* set clip rect to viewport */ CtoPstr(s); DrawString(s); PtoCstr(s); SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of label */ /* ______________________________________________________________ point This function draws a point at the current graphics cursor location. The coordinates (x,y) are given in world coordinates. */ void point(double x, double y) { Rect theRect; /* make a point by painting a rect */ short ix, iy; RgnHandle clip; /* the current clipping region */ Rect rect; /* a temp rect */ view(_window.left, _window.bottom, &rect.left, &rect.top); view(_window.right, _window.top, &rect.right, &rect.bottom); clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ ClipRect(&rect); /* set clip rect to viewport */ view(x, y, &ix, &iy); SetRect(&theRect, ix, iy, ix+1, iy+1); PaintRect(&theRect); SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of point */ /* ______________________________________________________________ verticalTickMark This function puts a vertical tick mark at the specified location in world coordinate space. */ void verticalTickMark(double x, double y, char *str) { short ix, iy; /* the transformed point */ view(x, y, &ix, &iy); /* transform the point */ iy++; MoveTo(ix, iy); LineTo(ix, iy + TICKLENGTH); MoveTo(ix - 3, iy + TICKLENGTH + 11); CtoPstr(str); DrawString(str); PtoCstr(str); } /* End of verticalTickMark */ /* ______________________________________________________________ horizontalTickMark This function puts a horizontal tick mark at the specified location in world coordinate space. */ void horizontalTickMark(double x, double y, char *str) { short ix, iy; /* the transformed point */ view(x, y, &ix, &iy); /* transform the point */ ix++; MoveTo(ix, iy); LineTo(ix + TICKLENGTH, iy); MoveTo(ix + TICKLENGTH + 1, iy + 5); CtoPstr(str); DrawString(str); PtoCstr(str); } /* End of horizontalTickMark */ /* ______________________________________________________________ scale This function returns the scaling matrix given x and y scaling factors. */ void scale(double sx, double sy, Xform scaleMatrix) { scaleMatrix[0][0] = sx; scaleMatrix[0][1] = 0.0; scaleMatrix[0][2] = 0.0; scaleMatrix[1][0] = 0.0; scaleMatrix[1][1] = sy; scaleMatrix[1][2] = 0.0; scaleMatrix[2][0] = 0.0; scaleMatrix[2][1] = 0.0; scaleMatrix[2][2] = 1.0; } /* End of scale */ /* ______________________________________________________________ translate This function returns the translation matrix given x and y translation factors. */ void translate(double tx, double ty, Xform transMatrix) { transMatrix[0][0] = 1.0; transMatrix[0][1] = 0.0; transMatrix[0][2] = 0.0; transMatrix[1][0] = 0.0; transMatrix[1][1] = 1.0; transMatrix[1][2] = 0.0; transMatrix[2][0] = tx; transMatrix[2][1] = ty; transMatrix[2][2] = 1.0; } /* End of translate */ /* ______________________________________________________________ rotate This function returns the rotation matrix given an angle in radians. */ void rotate(double theta, Xform rotateMatrix) { double sine=sin(theta), cosine=cos(theta); rotateMatrix[0][0] = cosine; rotateMatrix[0][1] = sine; rotateMatrix[0][2] = 0.0; rotateMatrix[1][0] = -sine; rotateMatrix[1][1] = cosine; rotateMatrix[1][2] = 0.0; rotateMatrix[2][0] = 0.0; rotateMatrix[2][1] = 0.0; rotateMatrix[2][2] = 1.0; } /* End of rotate */ /* ______________________________________________________________ multXform This function multiplies two 3 by 3 transformation matricies producing a resulting 3 by 3 transformation. For efficiency, we assume the last column of the transform on the right is 0 0 1. */ void multXform(Xform xform1, Xform xform2, Xform resultxform) { resultxform[0][0] = xform1[0][0] * xform2[0][0] + xform1[0][1] * xform2[1][0]; resultxform[0][1] = xform1[0][0] * xform2[0][1]+ xform1[0][1] * xform2[1][1]; resultxform[0][2] = 0.0; resultxform[1][0] = xform1[1][0] * xform2[0][0] + xform1[1][1] * xform2[1][0]; resultxform[1][1] = xform1[1][0] * xform2[0][1] + xform1[1][1] * xform2[1][1]; resultxform[1][2] = 0.0; resultxform[2][0] = xform1[2][0] * xform2[0][0] + xform1[2][1] * xform2[1][0] + xform2[2][0]; resultxform[2][1] = xform1[2][0] * xform2[0][1] + xform1[2][1] * xform2[1][1] + xform2[2][1]; resultxform[2][2] = 1.0; } /* End of multXform */ /* ______________________________________________________________ printXform This function prints a transformation matrix. It is used primarily for debugging purposes. */ void printXform(Xform xform) { int i,j; /* two counters */ for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { printf("%lf ",xform[i][j]); } printf("\n"); } printf("\n"); } /* End of printXform */ /* ______________________________________________________________ transformObject This function multiplies an n by 3 graphics object by a 3 by 3 transformation matrix producing a resulting n by 3 object. */ void transformObject(int n, double object[][3], Xform xform, double result[][3]) { int i; /* a counter */ for(i = 0; i < n; i++) { result[i][0] = object[i][0] * xform[0][0] + object[i][1] * xform[1][0] + xform[2][0]; result[i][1] = object[i][0] * xform[0][1] + object[i][1] * xform[1][1] + xform[2][1]; result[i][2] = object[i][2]; } } /* End of transformObject */ /* ______________________________________________________________ printObject This function prints an n by 3 graphics object. */ void printObject(int n, double object[][3]) { int i; /* a counter */ for(i = 0; i < n; i++) printf("%lf %lf %lf \n",object[i][0], object[i][1], object[i][2]); printf("\n"); } /* End of printObject */ /* ______________________________________________________________ readObject This function reads an n by 3 graphics object. It is assumed that the object consists of the value for n followed by the n rows of data describing the object ( x coord., y coord., and drawing code ). */ Boolean readObject(int *nptr, double object[][3]) { int i; /* a counter */ if(getInteger(nptr)) /* read n */ { for(i = 0; i < *nptr; i++) if(!(getDoubleFloat(&object[i][0]) && getDoubleFloat(&object[i][1]) && getDoubleFloat(&object[i][2]))) return FALSE; return TRUE; } else return FALSE; } /* End of readObject */ /* ______________________________________________________________ centerObject This function computes the center of an n by 3 graphics object. The center is defined as the center of the smallest rectangle which contains the object. */ void centerObject(int n, double object[][3], double *xcenter, double *ycenter) { int i; /* a counter */ double xmax = object[0][0], xmin = object[0][0], ymax = object[0][1], ymin = object[0][1]; /* max and min values */ for(i = 1; i < n; i++) { if(object[i][0] > xmax) xmax = object[i][0]; if(object[i][0] < xmin) xmin = object[i][0]; if(object[i][1] > ymax) ymax = object[i][1]; if(object[i][1] < ymin) ymin = object[i][1]; } (*xcenter) = (xmax + xmin) / 2.0; (*ycenter) = (ymax + ymin) / 2.0; } /* End of centerObject */ /* ______________________________________________________________ drawObject This function draws an n by 3 graphics object. This function assumes that the first graphics command is a move. */ void drawObject(int n, double object[][3]) { int i; /* a counter */ for(i = 0; i < n; i++) { if(object[i][2]) lineto(object[i][0], object[i][1]); else moveto(object[i][0],object[i][1]); } } /* End of drawObject */ /* ______________________________________________________________ getInteger This function reads a single integer from standard input. That integer is is then stored in the location in the calling program pointed to by the argument x. If a value is not read for some reason, the function returns FALSE, otherwise it returns TRUE. Arguments: x a pointer to an integer Returns: TRUE if an integer is read FALSE otherwise Side Effects: reads from standard input Problems: none */ Boolean getInteger(int *x) { if(1 == scanf("%d", x)) return TRUE; else return FALSE; } /* End of getInteger */ /* ______________________________________________________________ getDoubleFloat This function reads a single double value from standard input. That double is is then stored in the location in the calling program pointed to by the argument x. If a value is not read for some reason, the function returns FALSE, otherwise it returns TRUE. Arguments: x a pointer to a double Returns: TRUE if a double is read FALSE otherwise Side Effects: reads from standard input Problems: none */ Boolean getDoubleFloat(double *x) { if(1 == scanf("%lf", x)) return TRUE; else return FALSE; } /* End of getDoubleFloat */ /* ______________________________________________________________ plotBar This function plots a filled rectangle of height value (in world coordinates) at the x location given by at (again, in world coordinates). A pen mode of Xor is used. This means that a bar may be plotted on top of a picture an still be visible (in inverted form). Also, the bar may be removed simply by drawing the bar a second time. Arguments: x a double, the x location of value y a double, the value to plot Returns: nothing Side Effects: draws on the console output window Problems: none */ void plotBar(double x, double y) { Rect theRect; /* the rect we will fill */ short iy, ix; /* locations for the viewing xform */ PenState pen; /* the penstate */ RgnHandle clip; /* the current clipping region */ Pattern ourGray = {170, 85, 170, 85, 170, 85, 170, 85}; Rect rect; /* a temp rect */ view(_window.left, _window.bottom, &rect.left, &rect.top); view(_window.right, _window.top, &rect.right, &rect.bottom); GetPenState(&pen); /* get the current penstate */ PenMode(patXor); /* pen to Xor mode */ view(x, y, &ix, &iy); /* convert to QuickDraw coordinates */ theRect.top = iy; theRect.left = ix; view(x + 1.0, 0.0, &ix, &iy);/* convert to QuickDraw coordinates */ theRect.bottom = iy; if(ix == theRect.left) theRect.right = ix + 1; else theRect.right = ix; clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ ClipRect(&rect); /* set clip rect to viewport */ FrameRect(&theRect); /* draw the rect */ InsetRect(&theRect, 1, 1); /* inset the rect 1 pixel */ PenPat(&ourGray); /* set pen pattern to 50% gray */ PaintRect(&theRect); /* paint it gray */ SetPenState(&pen); /* restore the original pen state */ SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of plotBar */ /* ______________________________________________________________ plotPoint This function plots a filled rectangle centered at the point (value,at). A pen mode of Xor is used. This means that a point may be plotted on top of a picture an still be visible (in inverted form). Also, the point may be removed simply by drawing the point a second time. Arguments: x a double, the x location of value y a double, the value to plot Returns: nothing Side Effects: draws on the console output window Problems: none */ void plotPoint(double x, double y) { Rect theRect; /* the rect we will fill */ short iy, ix; /* locations for the viewing xform */ PenState pen; /* the penstate */ RgnHandle clip; /* the current clipping region */ Pattern ourGray = {170, 85, 170, 85, 170, 85, 170, 85}; Rect rect; /* a temp rect */ view(_window.left, _window.bottom, &rect.left, &rect.top); view(_window.right, _window.top, &rect.right, &rect.bottom); GetPenState(&pen); /* get the current penstate */ PenMode(patXor); /* pen to Xor mode */ view(x - .5, y + .5, &ix, &iy); /* convert to QuickDraw coordinates */ theRect.top = iy; theRect.left = ix; view(x+.5, y - .5, &ix, &iy); /* convert to QuickDraw coordinates */ if(theRect.top == iy) theRect.bottom = iy + 1; else theRect.bottom = iy; if(theRect.left == ix) theRect.right = ix + 1; else theRect.right = ix; clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ ClipRect(&rect); /* set clip rect to viewport */ FrameRect(&theRect); /* draw the rect */ InsetRect(&theRect, 1, 1); /* inset the rect 1 pixel */ PenPat(&ourGray); /* set pen pattern to 50% gray */ PaintRect(&theRect); /* paint it gray */ SetPenState(&pen); /* restore the original pen state */ SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of plotPoint */ /* ______________________________________________________________ eraseViewport This function erases the currently defined viewport. This function erases the same screen region as eraseWindow when PreserveAspectRatio == FALSE, otherwise it may erase a larger area than eraseWindow. Arguments: none Returns: nothing Side Effects: erases the _viewport region of device space Problems: none */ void eraseViewport(void) { EraseRect(&_viewport); } /* End of eraseViewport */ /* ______________________________________________________________ eraseWindow This function erases the currently defined World coordinate window. This function erases the same screen region as eraseViewport when PreserveAspectRatio == FALSE, otherwise it may erase a smaller area than eraseViewport. Arguments: none Returns: nothing Side Effects: erases the _viewport region of device space Problems: none */ void eraseWindow(void) { Rect rect; /* a temp rect */ view(_window.left, _window.bottom, &rect.left, &rect.top); view(_window.right, _window.top, &rect.right, &rect.bottom); EraseRect(&rect); } /* End of eraseWindow */ /* ______________________________________________________________ lineto This function draws a line to (x,y) from the current point. (x,y) is given in world coordinates. The drawing is clipped to the window. Arguments: x a double, the x coordinate y a double, the y coordinate Returns: nothing Side Effects: draws a line in the window and updates the graphics cursor location Problems: none */ void lineto(double x, double y) { short ix, iy; /* device coordinates for (x,y) */ RgnHandle clip; /* the current clipping region */ Rect rect; /* a temp rect */ view(_window.left, _window.bottom, &rect.left, &rect.top); view(_window.right, _window.top, &rect.right, &rect.bottom); clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ ClipRect(&rect); /* set clip rect to window */ _cx=x; /* update global cursor location */ _cy=y; view(x, y, &ix, &iy); /* viewing transform */ LineTo(ix, iy); /* draw the line */ SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of lineto */ /* ______________________________________________________________ line This function draws a line (dx,dy) from the current point. (dx,dy) is given in world coordinates. The drawing is clipped to the window. Arguments: dx a double, the x coordinate increment dy a double, the y coordinate increment Returns: nothing Side Effects: draws a line in the window and updates the graphics cursor location Problems: none */ void line(double dx, double dy) { short ix, iy; /* device coordinates for (x,y) */ RgnHandle clip; /* the current clipping region */ Rect rect; /* a temp rect */ view(_window.left, _window.bottom, &rect.left, &rect.top); view(_window.right, _window.top, &rect.right, &rect.bottom); clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ ClipRect(&rect); /* set clip rect to viewport */ _cx += dx; /* update global cursor location */ _cy += dy; view(_cx, _cy, &ix, &iy);/* viewing transform */ LineTo(ix, iy); /* draw the line */ SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of line */ /* ______________________________________________________________ moveto This function moves the graphics cursor to (x,y). (x,y) is given in world coordinates. Arguments: x a double, the x coordinate y a double, the y coordinate Returns: nothing Side Effects: changes the graphics cursor location Problems: none */ void moveto(double x, double y) { short ix, iy; /* device coordinates for (x,y) */ _cx = x; /* set world cursor location */ _cy = y; view(x, y, &ix, &iy); /* viewing transform */ MoveTo(ix, iy); /* move the graphics cursor */ } /* End of moveto */ /* ______________________________________________________________ move This function moves the graphics cursor to (dx,dy) from the current cursor location. Arguments: dx a double, the x coordinate increment dy a double, the y coordinate increment Returns: nothing Side Effects: changes the graphics cursor location Problems: none */ void move(double dx, double dy) { short ix, iy; /* device coordinates for (x,y) */ _cx += dx; /* update global cursor location */ _cy += dy; view(_cx, _cy, &ix, &iy); /* viewing transform */ MoveTo(ix, iy); /* move the graphics cursor */ } /* End of move */ /* ______________________________________________________________ drawline This function draws a line from (x,y) to (x1,y1) using world coordinates. Arguments: x a double, the x coordinate of point 1 y a double, the y coordinate of point 1 x1 a double, the x coordinate of point 2 y1 a double, the y coordinate of point 2 Returns: nothing Side Effects: changes the graphics cursor location Problems: none */ void drawline(double x, double y, double x1, double y1) { short ix, iy, ix1, iy1; RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ view(_window.left, _window.bottom, &tempRect.left, &tempRect.top); view(_window.right, _window.top, &tempRect.right, &tempRect.bottom); clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ ClipRect(&tempRect); /* set clip rect to viewport */ view(x, y, &ix, &iy); view(x1, y1, &ix1, &iy1); MoveTo(ix, iy); /* move the graphics cursor */ LineTo(ix1, iy1); /* draw the line */ SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of drawline */ /* ______________________________________________________________ SRGP_lineCoord This function draws a line from (x1,y1) to (x2,y2) using device coordinates. Arguments: x1 a short, the x coordinate of point 1 y1 a short, the y coordinate of point 1 x2 a short, the x coordinate of point 2 y2 a short, the y coordinate of point 2 Returns: nothing Side Effects: changes the graphics cursor location Problems: none */ void SRGP_lineCoord(short x1, short y1, short x2, short y2) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ MoveTo(x1 + _viewport.left, _viewport.bottom - y1); /* move the graphics cursor */ LineTo(x2 + _viewport.left, _viewport.bottom - y2); /* draw the line */ SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_lineCoord */ /* ______________________________________________________________ SRGP_line This function draws a line from pt1 = (x1,y1) to pt2 = (x2,y2) using device coordinates. Arguments: pt1 a Point, the coordinates of point 1 pt2 a Point, the coordinates of point 2 Returns: nothing Side Effects: changes the graphics cursor location Problems: none */ void SRGP_line(Point pt1, Point pt2) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ MoveTo(pt1.h + _viewport.left, _viewport.bottom - pt1.v); /* move the graphics cursor */ LineTo(pt2.h + _viewport.left, _viewport.bottom - pt2.v); /* draw the line */ SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_line */ /* ______________________________________________________________ SRGP_polyLineCoord This function draws a polygonal line connecting the successive points whose x and y coordinates are given by two equal sized arrays. Arguments: vertexCount a short, the number of points xArray an array of shorts, the x coordinates of points yArray an array of shorts, the y coordinates of points Returns: nothing Side Effects: changes the graphics cursor location Problems: none */ void SRGP_polyLineCoord(short vertexCount, short xArray[], short yArray[]) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ short i; /* a counter */ clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ if(vertexCount > 0) MoveTo(xArray[0] + _viewport.left, _viewport.bottom - yArray[0]); /* move the graphics cursor */ for (i = 1; i < vertexCount; i++) LineTo(xArray[i] + _viewport.left, _viewport.bottom - yArray[i]); /* draw the lines */ SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_polyLineCoord */ /* ______________________________________________________________ SRGP_polyLine This function draws a polygonal line connecting the successive points whose x and y coordinates are given by an array of points. Arguments: vertexCount a short, the number of points vertexList an array of Point, the coordinates of points Returns: nothing Side Effects: changes the graphics cursor location Problems: none */ void SRGP_polyLine(short vertexCount, Point vertexList[]) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ short i; /* a counter */ clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ if(vertexCount > 0) MoveTo(vertexList[0].h + _viewport.left, _viewport.bottom - vertexList[0].v); /* move the graphics cursor */ for (i = 1; i < vertexCount; i++) LineTo(vertexList[i].h + _viewport.left, _viewport.bottom - vertexList[i].v); /* draw the lines */ SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_polyLine */ /* ______________________________________________________________ SRGP_setMarkerSize This function sets the MarkerSize global variable. Arguments: value a short, the marker size Returns: nothing Side Effects: changes the MarkerSize global Problems: none (no checking for invalid marker sizes is done by this function. */ void SRGP_setMarkerSize(short value) { gMarkerSize = value; } /* End of SRGP_setMarkerSize */ /* ______________________________________________________________ SRGP_setMarkerStyle This function sets the MarkerStyle global variable. Arguments: value a short, the marker style Returns: nothing Side Effects: changes the MarkerStyle global Problems: none (no checking for invalid marker styles is done by this function. */ void SRGP_setMarkerStyle(short value) { gMarkerStyle = value; } /* End of SRGP_setMarkerStyle */ /* ______________________________________________________________ SRGP_markerCoord This function draws a marker at (x,y) Arguments: x a short, the x coordinate of the marker point. y a short, the y coordinate of the marker point. Returns: nothing Side Effects: changes the graphics screen Problems: none */ void SRGP_markerCoord(short x, short y) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ Rect markerRect; /* the marker rectangle */ short halfMarkerSize = gMarkerSize / 2; clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ x = x - halfMarkerSize; y = y + halfMarkerSize; SetRect(&markerRect, _viewport.left + x, _viewport.bottom - y, _viewport.left + x + gMarkerSize, _viewport.bottom - (y - gMarkerSize)); switch(gMarkerStyle) { case MARKER_CIRCLE: PaintArc(&markerRect, 0, 360); break; case MARKER_SQUARE: PaintRect(&markerRect); break; default: break; } SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_markerCoord */ /* ______________________________________________________________ SRGP_marker This function draws a marker at pt = (x,y) Arguments: pt a Point, the marker point. Returns: nothing Side Effects: changes the graphics screen Problems: none */ void SRGP_marker(Point pt) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ Rect markerRect; /* the marker rectangle */ short halfMarkerSize = gMarkerSize / 2; clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ pt.h = pt.h - halfMarkerSize; pt.v = pt.v + halfMarkerSize; SetRect(&markerRect, _viewport.left + pt.h, _viewport.bottom - pt.v, _viewport.left + pt.h + gMarkerSize, _viewport.bottom - (pt.v - gMarkerSize)); switch(gMarkerStyle) { case MARKER_CIRCLE: PaintArc(&markerRect, 0, 360); break; case MARKER_SQUARE: PaintRect(&markerRect); break; default: break; } SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_marker */ /* ______________________________________________________________ SRGP_polyMarkerCoord This function draws a markers at an array of points. Arguments: vertexCount a short, the number of marker points. xArray an array of shorts, the x coordinate of the marker points. yArray an array of shorts, the x coordinate of the marker points. Returns: nothing Side Effects: changes the graphics screen Problems: none */ void SRGP_polyMarkerCoord(short vertexCount, short xArray[], short yArray[]) { short i; /* a counter */ for(i = 0; i < vertexCount; i++) SRGP_markerCoord(xArray[i], yArray[i]); } /* End of SRGP_polyMarkerCoord */ /* ______________________________________________________________ SRGP_polyMarker This function draws a markers at an array of Points. Arguments: vertexCount a short, the number of marker points. vertextList an array of Point, the coordinates of the marker points. Returns: nothing Side Effects: changes the graphics screen Problems: none */ void SRGP_polyMarker(short vertexCount, Point vertexList[]) { short i; /* a counter */ for(i = 0; i < vertexCount; i++) SRGP_marker(vertexList[i]); } /* End of SRGP_polyMarker */ /* ______________________________________________________________ SRGP_rectangleCoord This function draws a rectangle given two points. Arguments: leftX a short, the x coordinate of the lower left leftY a short, the y coordinate of the lower left rightX a short, the x coordinate of the upper right rightY a short, the y coordinate of the upper right Returns: nothing Side Effects: changes the graphics screen Problems: none */ void SRGP_rectangleCoord(short leftX, short leftY, short rightX, short rightY) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ Rect theRect; /* the Rect to draw */ clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ SetRect(&theRect, _viewport.left + leftX, _viewport.bottom - rightY, _viewport.left + rightX, _viewport.bottom - leftY); FrameRect(&theRect); SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_rectangleCoord */ /* ______________________________________________________________ SRGP_rectanglePt This function draws a rectangle given two Points. Arguments: bottomLeft a Point, the lower left point of the rectangle topRight a Point, the upper right point of the rectangle Returns: nothing Side Effects: changes the graphics screen Problems: none */ void SRGP_rectanglePt(Point bottomLeft, Point topRight) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ Rect theRect; /* the Rect to draw */ clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ SetRect(&theRect, _viewport.left + bottomLeft.h, _viewport.bottom - topRight.v, _viewport.left + topRight.h, _viewport.bottom - bottomLeft.v); FrameRect(&theRect); SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_rectanglePt */ /* ______________________________________________________________ SRGP_rectangle This function draws a rectangle given a Rect. Arguments: rectangle a pointer to a Rect, the rectangle Returns: nothing Side Effects: changes the graphics screen Problems: none */ void SRGP_rectangle(Rect *rectangle) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ Rect theRect; /* the Rect to draw */ clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ SetRect(&theRect, _viewport.left + (*rectangle).left, _viewport.bottom - (*rectangle).bottom, _viewport.left + (*rectangle).right, _viewport.bottom - (*rectangle).top); FrameRect(&theRect); SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_rectangle */ /* ______________________________________________________________ SRGP_defPoint This function sets a Point given x and y. Arguments: x a short, the x coordinate of the Point y a short, the y coordinate of the Point pt a pointer to a Point, the Point to be defined Returns: nothing Side Effects: changes pt Problems: none */ void SRGP_defPoint(short x, short y, Point *pt) { (*pt).h = x; (*pt).v = y; } /* End of SRGP_defPoint */ /* ______________________________________________________________ SRGP_defRectangle This function sets a Rect given left x, left y, right x and right y. Arguments: leftX a short, the x coordinate of lower left leftY a short, the y coordinate of lower left rightX a short, the x coordinate of upper right rightY a short, the y coordinate of upper right rectangle a pointer to a Rect, the Rect to be defined Returns: nothing Side Effects: changes rectangle Problems: none */ void SRGP_defRectangle(short leftX, short leftY, short rightX, short rightY, Rect *rectangle) { (*rectangle).left = leftX; (*rectangle).bottom = rightY; (*rectangle).right = rightX; (*rectangle).top = leftY; } /* End of SRGP_defRectangle */ /* ______________________________________________________________ SRGP_ellipseArc This function draws an arc of an ellipse which is bounded by a Rect. Arguments: extentRect a pointer to a Rect, the extent of the ellipse arc. startAngle a double, the starting angle of the arc endAngle a double, the ending angle of the arc Returns: nothing Side Effects: changes graphics screen Problems: none */ void SRGP_ellipseArc(Rect *extentRect, double startAngle, double endAngle) { RgnHandle clip; /* the current clipping region */ Rect tempRect; /* a temp rect */ Rect extent; /* the extent of the ellipse */ short start = startAngle, end = endAngle; clip = NewRgn(); /* create a new region */ GetClip(clip); /* get the current clip region */ tempRect = _viewport; ClipRect(&tempRect); /* set clip rect to viewport */ SetRect(&extent, _viewport.left + (*extentRect).left, _viewport.bottom - (*extentRect).bottom, _viewport.left + (*extentRect).right, _viewport.bottom - (*extentRect).top); FrameArc(&extent, start + 90, start - end); SetClip(clip); /* restore the clip rect */ DisposeRgn(clip); /* dispose of the region */ } /* End of SRGP_ellipseArc */ /* ______________________________________________________________ SRGP_setLineStyle This function sets the global line style attribute. Arguments: value a short, the line style Returns: nothing Side Effects: changes gLineStyle Problems: none */ void SRGP_setLineStyle(short value) { Pattern ourBlack = {255, 255, 255, 255, 255, 255, 255, 255}; Pattern ourGray = {170, 85, 170, 85, 170, 85, 170, 85}; Pattern ourltGray = {136, 0, 34, 0, 136, 0, 34, 0}; gLineStyle = value; switch(gLineStyle) { case CONTINUOUS: PenPat(ourBlack); break; case DASHED: PenPat(ourGray); break; case DOTTED: PenPat(ourltGray); break; default: break; } } /* End of SRGP_setLineStyle */ /* ______________________________________________________________ SRGP_setLineWidth This function sets the global line width attribute. Arguments: value a short, the line width in pixels Returns: nothing Side Effects: changes gLineWidth Problems: none */ void SRGP_setLineWidth(short value) { gLineWidth = value; PenSize(value, value); } /* End of SRGP_setLineWidth */