/*ScianDraw.c Drawing routines for various types of objects Eric Pepke March 28, 1990 */ /* JEL added PostScript drawing 4/2/92 */ #include "Scian.h" #include "ScianTypes.h" #include "ScianArrays.h" #include "ScianLists.h" #include "ScianIDs.h" #include "ScianWindows.h" #include "ScianDraw.h" #include "ScianObjWindows.h" #include "ScianColors.h" #include "ScianPictures.h" #include "ScianStyle.h" #include "ScianFontSystem.h" extern short LinToGamma[]; DrawingState drawingStates[NDRAWINGSTATES]; /*Stack of drawing states*/ int curDrawingStateIndex = 0; /*Current drawing state*/ Bool drawMouse = false; /*True iff draw on next mouse*/ extern int curMouse; /*Current mouse button*/ int drawingMode = DRAW_SCREEN; /*Drawing to the screen*/ FILE *drawFile = 0; /*File in which to draw*/ int imageSubSample = 0; /*Subsampling offset for image*/ Bool fullScreen = false; /*True iff drawing to full screen*/ Matrix Identity = {{1.0, 0.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 0.0, 1.0}}; /* globals used for PostScript drawing */ FILE *psFile; /* pointer to temp file */ int iconsUsed[32]; /* maximum number of *different* icons in EPS file is 32 */ int numIconsUsed; /* number used so far = next index to use */ Bool evenOnly = false; Bool oddOnly = false; #ifdef PROTO void BeginTranslucent(void) #else void BeginTranslucent() #endif /*Begins translucent drawing*/ { #ifdef GRAPHICS if (evenOnly) { setpattern(EVENGREYPAT); } else if (oddOnly) { setpattern(ODDGREYPAT); } else { setpattern(GREYPAT); } #endif } #ifdef PROTO void EndTranslucent(void) #else void BeginTranslucent() #endif /*Begins translucent drawing*/ { #ifdef GRAPHICS if (evenOnly) { setpattern(EVENPAT); } else if (oddOnly) { setpattern(ODDPAT); } else { setpattern(SOLIDPAT); } #endif } #ifdef PROTO void BeginEvenOnly(void) #else void BeginEvenOnly() #endif /*Begins drawing on only even lines*/ { evenOnly = true; #ifdef GRAPHICS setpattern(EVENPAT); #endif } #ifdef PROTO void EndEvenOnly(void) #else void EndEvenOnly() #endif /*Ends drawing on only even lines*/ { evenOnly = false; #ifdef GRAPHICS setpattern(SOLIDPAT); #endif } #ifdef PROTO void BeginOddOnly(void) #else void BeginOddOnly() #endif /*Begins drawing on only odd lines*/ { oddOnly = true; #ifdef GRAPHICS setpattern(ODDPAT); #endif } #ifdef PROTO void EndOddOnly(void) #else void EndEvenOnly() #endif /*Ends drawing on only odd lines*/ { oddOnly = false; #ifdef GRAPHICS setpattern(SOLIDPAT); #endif } #if 0 void EchoDraw(s) char *s; { int k; for (k = 0; k < curDrawingStateIndex; ++k) printf(" "); printf("%s\n", s); } #else #define EchoDraw(s) #endif #ifdef PROTO void PushTransformation(void) #else void PushTransformation() #endif /*Pushes the transformation*/ { #ifdef GRAPHICS pushmatrix(); #endif } #ifdef PROTO void PopTransformation(void) #else void PopTransformation() #endif /*Pushes the transformation*/ { #ifdef GRAPHICS popmatrix(); #endif } void PushDrawingState() /*Pushes the drawing state, producing a copy of the top drawing state*/ { int k; ++curDrawingStateIndex; if (curDrawingStateIndex >= NDRAWINGSTATES) { fprintf(stderr, "SciAn: Panic, drawing state overflow\n"); exit(-1); } CURSTATE . window = LASTSTATE . window; CURSTATE . initialWindow = false; for (k = 0; k < 4; ++k) { CURSTATE . screenMask[k] = LASTSTATE . screenMask[k]; CURSTATE . viewport[k] = LASTSTATE . viewport[k]; } for (k = 0; k < 2; ++k) { CURSTATE . origin[k] = LASTSTATE . origin[k]; CURSTATE . translation[k] = LASTSTATE . translation[k]; } } void PopDrawingState() /*Pops the drawing state and sets everything back to what it was. As a side-effect, may set the window*/ { Bool setViewport = false; /*True iff the viewport needs to be set*/ --curDrawingStateIndex; if (curDrawingStateIndex < 0) { fprintf(stderr, "SciAn: Panic, drawing state underflow\n"); exit(-1); } if (!(CURSTATE . window)) { /*No window, do nothing*/ return; } if (NEXTSTATE . initialWindow) { /*New window! Need to set everything*/ SelWindow(CURSTATE . window); #ifdef GRAPHICS shademodel(FLAT); concave(TRUE); backface(FALSE); lmcolor(LMC_COLOR); { float n[3]; n[0] = 0.0; n[1] = 0.0; n[2] = 1.0; N3F(n); } #endif setViewport = true; } if (setViewport || (CURSTATE . viewport[0] != NEXTSTATE . viewport[0]) || (CURSTATE . viewport[1] != NEXTSTATE . viewport[1]) || (CURSTATE . viewport[2] != NEXTSTATE . viewport[2]) || (CURSTATE . viewport[3] != NEXTSTATE . viewport[3])) { /*New viewport. Need to set viewport*/ setViewport = true; #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { /*Set the viewport in pixel-centered coordinates*/ viewport((Screencoord) CURSTATE . viewport[0], (Screencoord) CURSTATE . viewport[1] - 1, (Screencoord) CURSTATE . viewport[2], (Screencoord) CURSTATE . viewport[3] - 1); /*Set up an orthographic perspective setup to map to this viewport*/ MakeOrthoXform(); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%%new viewport\n%d %d translate\n", (int) CURSTATE . translation[0], (int) CURSTATE . translation[1]); } #endif } if (setViewport || (CURSTATE . screenMask[0] != NEXTSTATE . screenMask[0]) || (CURSTATE . screenMask[1] != NEXTSTATE . screenMask[1]) || (CURSTATE . screenMask[2] != NEXTSTATE . screenMask[2]) || (CURSTATE . screenMask[3] != NEXTSTATE . screenMask[3])) { /*New screen mask. Need to set it*/ if (drawingMode == DRAW_SCREEN) { #ifdef GRAPHICS scrmask((Screencoord) CURSTATE . screenMask[0], (Screencoord) CURSTATE . screenMask[1] - 1, (Screencoord) CURSTATE . screenMask[2], (Screencoord) CURSTATE . screenMask[3] - 1); #endif } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { int sl, sr, sb, st; sl = CURSTATE . screenMask[0]; sr = CURSTATE . screenMask[1]; sb = CURSTATE . screenMask[2]; st = CURSTATE . screenMask[3]; fprintf(psFile, "resetclip newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath clip newpath\n", sl, st, sr, st, sr, sb, sl, sb); } } if ((setViewport == false) && (CURSTATE . translation[0] != NEXTSTATE . translation[0] || CURSTATE . translation[1] != NEXTSTATE . translation[1])) { if (drawingMode == DRAW_SCREEN) { #ifdef GRAPHICS /*Translate back, but only if only the translation is different*/ translate( (Coord) (CURSTATE . translation[0] - NEXTSTATE . translation[0]), (Coord) (CURSTATE . translation[1] - NEXTSTATE . translation[1]), (Coord) 0.0); #endif } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%d %d translate\n", (int) (CURSTATE . translation[0] - NEXTSTATE . translation[0]), (int) (CURSTATE . translation[1] - NEXTSTATE . translation[1])); } } } #ifdef PROTO void SetDrawingWindow(WinInfoPtr window) #else void SetDrawingWindow(window) WinInfoPtr window; #endif /*Sets to draw into a new window. Side effect--selects the window*/ { int k; int l, r, b, t, ox, oy; EchoDraw("SetDrawingWindow"); /*Save the current window, etc.*/ PushDrawingState(); /*Select this window and use it*/ SelWindow(window); #ifdef GRAPHICS shademodel(FLAT); concave(TRUE); backface(FALSE); lmcolor(LMC_COLOR); { float n[3]; n[0] = 0.0; n[1] = 0.0; n[2] = 1.0; N3F(n); } #endif CURSTATE . window = window; CURSTATE . initialWindow = true; /*Zero translation*/ for (k = 0; k < 2; ++k) { CURSTATE . translation[k] = 0; } /*Get the bounds of the window, in Mac style coordinates*/ GetWindowBounds(&l, &r, &b, &t); /*Save the bounds as the viewport and mask*/ CURSTATE . screenMask[0] = CURSTATE . viewport[0] = l; CURSTATE . screenMask[1] = CURSTATE . viewport[1] = r; CURSTATE . screenMask[2] = CURSTATE . viewport[2] = b; CURSTATE . screenMask[3] = CURSTATE . viewport[3] = t; /*Get the origin of the window*/ GetWindowOrigin(&ox, &oy); CURSTATE . origin[0] = ox; CURSTATE . origin[1] = oy; #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { /*Set the viewport in pixel-centered coordinates*/ viewport((Screencoord) l, (Screencoord) r - 1, (Screencoord) b, (Screencoord) t - 1); /*Set up an orthographic perspective setup to map to this viewport*/ MakeOrthoXform(); } #endif } void RestoreDrawingWindow() /*Restores the window area to what it was before. Side effect--sets the window*/ { /*Pop the drawing state*/ PopDrawingState(); EchoDraw("RestoreDrawingWIndow"); } #ifdef PROTO void SetSubPort(int l, int r, int b, int t) #else void SetSubPort(l, r, b, t) int l, r, b, t; #endif /*Sets to draw into a subport. Side effect--selects the window*/ { int k; EchoDraw("SetSubPort"); /*Save the current state.*/ PushDrawingState(); /*Pretend its a new window*/ CURSTATE . initialWindow = true; /*Save the bounds as the viewport*/ CURSTATE . viewport[0] = l; CURSTATE . viewport[1] = r; CURSTATE . viewport[2] = b; CURSTATE . viewport[3] = t; /*Shift the mask over by the effective offset*/ CURSTATE . screenMask[0] -= CURSTATE . translation[0]; CURSTATE . screenMask[1] -= CURSTATE . translation[0]; CURSTATE . screenMask[2] -= CURSTATE . translation[1]; CURSTATE . screenMask[3] -= CURSTATE . translation[1]; /*Make a screen mask that is the intersection*/ if (CURSTATE . viewport[0] > CURSTATE . screenMask[0]) CURSTATE . screenMask[0] = CURSTATE . viewport[0]; if (CURSTATE . viewport[1] < CURSTATE . screenMask[1]) CURSTATE . screenMask[1] = CURSTATE . viewport[1]; if (CURSTATE . viewport[2] > CURSTATE . screenMask[2]) CURSTATE . screenMask[2] = CURSTATE . viewport[2]; if (CURSTATE . viewport[3] < CURSTATE . screenMask[3]) CURSTATE . screenMask[3] = CURSTATE . viewport[3]; /*Zero translation*/ for (k = 0; k < 2; ++k) { CURSTATE . translation[k] = 0; } /*Bump up origin*/ CURSTATE . origin[0] += l; CURSTATE . origin[1] += b; /*Save the bounds as the viewport and mask*/ CURSTATE . screenMask[0] = CURSTATE . viewport[0] = l; CURSTATE . screenMask[1] = CURSTATE . viewport[1] = r; CURSTATE . screenMask[2] = CURSTATE . viewport[2] = b; CURSTATE . screenMask[3] = CURSTATE . viewport[3] = t; #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { /*Set the viewport in pixel-centered coordinates*/ viewport((Screencoord) l, (Screencoord) r - 1, (Screencoord) b, (Screencoord) t - 1); /*Set up an orthographic perspective setup to map to this viewport*/ MakeOrthoXform(); /*Set the screen mask*/ scrmask((Screencoord) CURSTATE . screenMask[0], (Screencoord) CURSTATE . screenMask[1] - 1, (Screencoord) CURSTATE . screenMask[2], (Screencoord) CURSTATE . screenMask[3] - 1); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%%Call to SetSubPort!\n"); } #endif } void RestoreSubPort() /*Restores the window area to what it was before. Side effect--sets the window*/ { /*Pop the drawing state*/ PopDrawingState(); EchoDraw("RestoreSubPort"); } #ifdef PROTO void SetOrthoPick(void) #else void SetOrthoPick() #endif /*Sets to do an ortho pick.*/ { int k; EchoDraw("SetOrthoPick"); /*Save the current state.*/ PushDrawingState(); /*Pretend its a new window*/ CURSTATE . initialWindow = true; } #ifdef PROTO void RestoreOrthoPick(void) #else void RestoreOrthoPick() #endif /*Restores the pickiness to what it was before. Side effect--sets the window*/ { /*Pop the drawing state*/ PopDrawingState(); EchoDraw("RestoreOrthoPick"); } void SetOrigin(x, y) int x, y; /*Sets the origin to x, y WITHIN current translation*/ { EchoDraw("SetOrigin"); /*Save drawing state*/ PushDrawingState(); CURSTATE . translation[0] += x; CURSTATE . translation[1] += y; if (drawingMode == DRAW_SCREEN) { #ifdef GRAPHICS translate((Coord) x, (Coord) y, (Coord) 0.0); #endif } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%d %d translate\n", x, y); } } void RestoreOrigin() /*Restores the origin to what it was*/ { PopDrawingState(); EchoDraw("RestoreOrigin"); } #ifdef PROTO void FullScreen(Bool whether) #else void FullScreen(whether) Bool whether; #endif /*Sets full screen mode to whether*/ { if (whether == fullScreen) return; fullScreen = whether; #ifdef GRAPHICS if (fullScreen) { fullscrn(); } else { endfullscrn(); } #endif } void MakeOrthoXform() /*Makes an orthographic transformation based on the current state.*/ { if (drawingMode == DRAW_SCREEN) { #ifdef GRAPHICS mmode(MPROJECTION); ortho2( 0.0, (float) (CURSTATE . viewport[1] - CURSTATE . viewport[0]), 0.0, (float) (CURSTATE . viewport[3] - CURSTATE . viewport[2])); mmode(MVIEWING); loadmatrix(Identity); translate((Coord) CURSTATE . translation[0], (Coord) CURSTATE . translation[1], (Coord) 0.0); #endif } } void MakePickOrthoXform() /*Makes an orthographic transformation based on the current state.*/ { #ifdef GRAPHICS ortho2( 0.0, (float) (CURSTATE . viewport[1] - CURSTATE . viewport[0]), 0.0, (float) (CURSTATE . viewport[3] - CURSTATE . viewport[2])); #endif } #ifdef PROTO void SetClipRect(int left, int right, int bottom, int top) #else void SetClipRect(left, right, bottom, top) int left, right, bottom, top; #endif /*Sets the current clipping rectangle to left, right, bottom, top*/ { int sl, sr, sb, st; EchoDraw("SetClipRect"); /*Save the current state*/ PushDrawingState(); left += CURSTATE . translation[0]; right += CURSTATE . translation[0]; bottom += CURSTATE . translation[1]; top += CURSTATE . translation[1]; sl = CURSTATE . screenMask[0]; sr = CURSTATE . screenMask[1]; sb = CURSTATE . screenMask[2]; st = CURSTATE . screenMask[3]; if (left > sl) sl = MIN(left, sr); if (right < sr) sr = MAX(right, sl); if (bottom > sb) sb = MIN(bottom, st); if (top < st) st = MAX(top, sb); CURSTATE . screenMask[0] = sl; CURSTATE . screenMask[1] = sr; CURSTATE . screenMask[2] = sb; CURSTATE . screenMask[3] = st; if (drawingMode == DRAW_SCREEN) { #ifdef GRAPHICS scrmask(sl, sr - 1, sb, st - 1); #endif } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "resetclip newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath clip newpath\n", sl, st, sr, st, sr, sb, sl, sb); } } void RestoreClipRect() /*Restores the clipping rectangle to what it was before*/ { PopDrawingState(); EchoDraw("RestoreClipRect"); } void CurOffset(x, y) int *x, *y; /*Returns the current offset of the internal mouse coords from global*/ { int ox, oy; *x = CURSTATE . origin[0] + CURSTATE . translation[0]; *y = CURSTATE . origin[1] + CURSTATE . translation[1]; } void UD(void) /*Updated drawing according to belated DrawMe's*/ { #ifdef GRAPHICS if (drawMouse) { IdleAllWindows(); drawMouse = false; } #endif } void UpdateDrawing(void) /*Updates drawing according to belated DrawMe's*/ { UD(); } #ifdef GRAPHICS void DrawObj2(origObj, obj) ObjPtr origObj, obj; /*Draws origObj according to method in obj*/ { FuncTyp DrawFunction; /*Method*/ if (obj) { DrawObj2(origObj, ClassOf(obj)); DrawFunction = Get1Method(obj, DRAW); if (DrawFunction) { (*DrawFunction)(origObj); } } } #endif void DrawObject(obj) ObjPtr obj; /*Draws obj.*/ { #ifdef GRAPHICS ObjPtr picState; if (GetPredicate(obj, INHIBITDRAWING)) { return; } if (GetPredicate(obj, HIDDEN)) { return; } if (GetPredicate(obj, MULTIDRAW)) { DrawObj2(obj, obj); } else { FuncTyp DrawFunction; /*Method*/ DrawFunction = GetMethod(obj, DRAW); if (DrawFunction) { (*DrawFunction)(obj); } } #endif } void ClipToMe(object) ObjPtr object; /*Sets the clipping rectangle to object*/ { int l, r, b, t; Get2DIntBounds(object, &l, &r, &b, &t); SetClipRect(l, r, b, t); } #ifdef INTERACTIVE ObjPtr PressObject(obj, x, y, flags) ObjPtr obj; int x, y; long flags; /*Presses in obj at x, y*/ { FuncTyp PressFunction; PressFunction = GetMethod(obj, PRESS); if (PressFunction) { return (*PressFunction)(obj, x, y, flags); } else { return ObjFalse; } } #endif ObjPtr DropObjects(obj, dropObj, x, y) ObjPtr obj, dropObj; int x, y; /*Drops objects in list dropObj in obj at x, y*/ { FuncTyp method; method = GetMethod(obj, DROPOBJECTS); if (method) { return (*method)(obj, dropObj, x, y); } else { return ObjFalse; } } #ifdef PROTO ObjPtr KeyDownObject(ObjPtr obj, int key, long flags) #else ObjPtr KeyDownObject(obj, key, flags) ObjPtr obj; int key; long flags; #endif /*Does a keydown in obj*/ { FuncTyp method; method = GetMethod(obj, KEYDOWN); if (method) { return (*method)(obj, key, flags); } else { return ObjFalse; } } void FrameUIRect(left, right, bottom, top, uiColor) int left, right, bottom, top, uiColor; /*Frames a user interface rectangle*/ { #ifdef GRAPHICS SetUIColor(uiColor); FrameRect(left, right, bottom, top); #endif } void FrameRect(left, right, bottom, top) int left, right, bottom, top; /*Frames a rectangle*/ { #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { #ifdef V3FISBUGGED move2(left + 0.5, top - 0.5); draw2(left + 0.5, bottom + 0.5); draw2(right - 0.5, bottom + 0.5); draw2(right - 0.5, top - 0.5); draw2(left + 0.5, top - 0.5); #else float v[5][2]; v[0][0] = left + 0.5; v[0][1] = top - 0.5; v[1][0] = left + 0.5; v[1][1] = bottom + 0.5; v[2][0] = right - 0.5; v[2][1] = bottom + 0.5; v[3][0] = right - 0.5; v[3][1] = top - 0.5; v[4][0] = left + 0.5; v[4][1] = top - 0.5; bgnline(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); v2f(v[4]); endline(); #endif } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "%d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath stroke\n", left, top, right, top, right, bottom, left, bottom); } #endif } void FillUIRect(left, right, bottom, top, uiColor) int left, right, bottom, top, uiColor; /*Fills a user interface rectangle*/ { #ifdef GRAPHICS SetUIColor(uiColor); FillRect(left, right, bottom, top); #endif } void FillRect(left, right, bottom, top) int left, right, bottom, top; /*Fills a rectangle*/ { #ifdef GRAPHICS FillIntQuad(left, bottom, (right), bottom, (right), (top), left, (top)); #endif } void FillUIGauzeDisc(x, y, radius, uiColor) int x, y, radius, uiColor; /*Fills a disc in uiColor with gauze pattern*/ { #ifdef GRAPHICS SetUIColor(uiColor); BeginTranslucent(); circfi(x, y, radius); EndTranslucent(); #endif } void FillUIDisc(x, y, radius, uiColor) int x, y, radius, uiColor; /*Fills a disc in uiColor*/ { #ifdef GRAPHICS SetUIColor(uiColor); if (drawingMode == DRAW_SCREEN) { circfi(x, y, radius); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "newpath %d %d %d 0 360 arc fill\n", x, y, radius); } #endif } void FillTri(x1, y1, x2, y2, x3, y3) int x1, y1, x2, y2, x3, y3; /*Fills a triangle*/ { #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { float v[3][2]; v[0][0] = x1; v[0][1] = y1; v[1][0] = x2; v[1][1] = y2; v[2][0] = x3; v[2][1] = y3; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); endpolygon(); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "%d %d moveto %d %d lineto %d %d lineto closepath fill\n", x1, y1, x2, y2, x3, y3); } #endif } void FillUITri(x1, y1, x2, y2, x3, y3, uiColor) int x1, y1, x2, y2, x3, y3, uiColor; /*Fills a triangle in uiColor*/ { #ifdef GRAPHICS SetUIColor(uiColor); FillTri(x1, y1, x2, y2, x3, y3); #endif } void FillUIGauzeRect(left, right, bottom, top, uiColor) int left, right, bottom, top, uiColor; /*Fills a user interface rectangle as if it were gauze*/ { #ifdef GRAPHICS SetUIColor(uiColor); BeginTranslucent(); FillIntQuad(left, (top), left, bottom, (right), bottom, (right), (top)); EndTranslucent(); #endif } void DrawUILine(x1, y1, x2, y2, uiColor) int x1, y1, x2, y2, uiColor; { #ifdef GRAPHICS SetUIColor(uiColor); DrawLine(x1, y1, x2, y2); #endif } void DrawLine(x1, y1, x2, y2) int x1, y1, x2, y2; { #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { #ifdef V3FISBUGGED move2(x1 + 0.5, y1 + 0.5); draw2(x2 + 0.5, y2 + 0.5); #else float v[2][2]; v[0][0] = x1 + 0.5; v[0][1] = y1 + 0.5; v[1][0] = x2 + 0.5; v[1][1] = y2 + 0.5; bgnline(); v2f(v[0]); v2f(v[1]); endline(); #endif } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "%d %d moveto %d %d lineto stroke\n", x1, y1, x2, y2); } #endif } void FillUIWedge(x, y, radius, start, end, uiColor) int x, y, radius, start, end, uiColor; /*Fills a solid wege at x, y with radius from start to end degrees*/ { #ifdef GRAPHICS SetUIColor(uiColor); if (drawingMode == DRAW_SCREEN) { arcfi(x, y, radius, start * 10, end * 10); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "newpath %d %d moveto %d %d %d %d %d arc closepath fill\n", x, y, x, y, radius, start, end); } #endif } void DrawArc(x, y, radius, start, end) int x, y, radius, start, end; /*Draws an arc in the current color. start and end are in degrees.*/ { if (drawingMode == DRAW_SCREEN) { #ifdef GRAPHICS arci(x, y, radius, start * 10, end * 10); #endif } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "newpath %d %d %d %d %d arc stroke\n", x, y, radius, start, end); } } #ifdef PROTO void FillSpaceRect(real x1, real y1, real z1, real x2, real y2, real z2, real x3, real y3, real z3, real x4, real y4, real z4, real nx, real ny, real nz) #else void FillSpaceRect( x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, nx, ny, nz) real x1; real y1; real z1; real x2; real y2; real z2; real x3; real y3; real z3; real x4; real y4; real z4; real nx; real ny; real nz; #endif /*Draws a rectangle in space around [xyz]1 through [xyz]4 using n[xyz] as normal. If n[xyz] is 0, doesn't do a normal*/ { #ifdef GRAPHICS float v[4][3]; float n[3]; v[0][0] = x1; v[0][1] = y1; v[0][2] = z1; v[1][0] = x2; v[1][1] = y2; v[1][2] = z2; v[2][0] = x3; v[2][1] = y3; v[2][2] = z3; v[3][0] = x4; v[3][1] = y4; v[3][2] = z4; if (nx != 0.0 || ny != 0.0 || nz != 0.0) { n[0] = nx; n[1] = ny; n[2] = nz; } bgnpolygon(); N3F(n); v3f(v[0]); v3f(v[1]); v3f(v[2]); v3f(v[3]); endpolygon(); #endif } #ifdef PROTO void FrameSpaceRect(real x1, real y1, real z1, real x2, real y2, real z2, real x3, real y3, real z3, real x4, real y4, real z4) #else void FrameSpaceRect( x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4) real x1; real y1; real z1; real x2; real y2; real z2; real x3; real y3; real z3; real x4; real y4; real z4; #endif /*Frames a rectangle in space around [xyz]1 through [xyz]4*/ { DrawSpaceLine(x1, y1, z1, x2, y2, z2); DrawSpaceLine(x2, y2, z2, x3, y3, z3); DrawSpaceLine(x3, y3, z3, x4, y4, z4); DrawSpaceLine(x4, y4, z4, x1, y1, z1); } #ifdef PROTO void DrawSpaceLine(real x1, real y1, real z1, real x2, real y2, real z2) #else void DrawSpaceLine(x1, y1, z1, x1, y1, z1) real x1; real y1; real z1; real x2; real y2; real z2; #endif /*Draws a line in a space*/ { float v[2][3]; #ifdef GRAPHICS #ifdef V3FISBUGGED move(x1, y1, z1); draw(x2, y2, z2); #else /*Draws a line in a space*/ v[0][0] = x1; v[0][1] = y1; v[0][2] = z1; v[1][0] = x2; v[1][1] = y2; v[1][2] = z2; bgnline(); v3f(v[0]); v3f(v[1]); endline(); #endif #endif } #ifdef PROTO void DrawSpacePanelLine(real x1, real y1, real x2, real y2, real width, int arrow, real arrowParams[4][2]) #else void DrawSpacePanelLine(x1, y1, x2, y2, width, arrow, arrowParams) real x1, y1, x2, y2, width; int arrow; real arrowParams[4][2]; #endif /*Draws a space panel line*/ /* DIK need to make PostScript version */ { #ifdef GRAPHICS if (x1 == y1 && x2 == y2) { /*Just a point*/ long v[2]; bgnpoint(); v[0] = x1; v[1] = y1; v2i(v); endpoint(); } else if (width <= 1 && arrow == AH_NO_ARROW) { /*Plain line*/ long v[2][2]; v[0][0] = x1; v[0][1] = y1; v[1][0] = x2; v[1][1] = y2; bgnline(); v2i(v[0]); v2i(v[1]); endline(); } else { /*Solid line*/ real ax, ay, nx, ny, rr, mx, my; float v[10][2]; /*Calculate the axial unit vector*/ ax = x2 - x1; ay = y2 - y1; rr = 1.0 / sqrt(ax * ax + ay * ay); ax *= rr; ay *= rr; /*Now the normal unit vector*/ nx = -ay; ny = ax; switch(arrow) { case AH_NO_ARROW: v[0][0] = x1 - nx * width * 0.5; v[0][1] = y1 - ny * width * 0.5; v[1][0] = x2 - nx * width * 0.5; v[1][1] = y2 - ny * width * 0.5; v[2][0] = x2 + nx * width * 0.5; v[2][1] = y2 + ny * width * 0.5; v[3][0] = x1 + nx * width * 0.5; v[3][1] = y1 + ny * width * 0.5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); endpolygon(); break; case AH_AT_END: /*Arrow base*/ v[0][0] = x1; v[0][1] = y1; /*Down to fletching*/ v[1][0] = x1 + ax * width * arrowParams[0][0] - nx * width * arrowParams[0][1]; v[1][1] = y1 + ay * width * arrowParams[0][0] - ny * width * arrowParams[0][1]; /*Over to shaft*/ v[2][0] = x2 + ax * width * arrowParams[1][0] - nx * width * arrowParams[1][1]; v[2][1] = y2 + ay * width * arrowParams[1][0] - ny * width * arrowParams[1][1]; /*To first arrowhead tip*/ v[3][0] = x2 + ax * width * arrowParams[2][0] - nx * width * arrowParams[2][1]; v[3][1] = y2 + ay * width * arrowParams[2][0] - ny * width * arrowParams[2][1]; /*To second arrowhead tip*/ v[4][0] = x2 + ax * width * arrowParams[3][0] - nx * width * arrowParams[3][1]; v[4][1] = y2 + ay * width * arrowParams[3][0] - ny * width * arrowParams[3][1]; /*To end of arrow*/ v[5][0] = x2; v[5][1] = y2; /*Up to second arrowhead tip*/ v[6][0] = x2 + ax * width * arrowParams[3][0] + nx * width * arrowParams[3][1]; v[6][1] = y2 + ay * width * arrowParams[3][0] + ny * width * arrowParams[3][1]; /*Back to first arrowhead tip*/ v[7][0] = x2 + ax * width * arrowParams[2][0] + nx * width * arrowParams[2][1]; v[7][1] = y2 + ay * width * arrowParams[2][0] + ny * width * arrowParams[2][1]; /*Down to shaft*/ v[8][0] = x2 + ax * width * arrowParams[1][0] + nx * width * arrowParams[1][1]; v[8][1] = y2 + ay * width * arrowParams[1][0] + ny * width * arrowParams[1][1]; /*Back to fletching*/ v[9][0] = x1 + ax * width * arrowParams[0][0] + nx * width * arrowParams[0][1]; v[9][1] = y1 + ay * width * arrowParams[0][0] + ny * width * arrowParams[0][1]; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); v2f(v[4]); v2f(v[5]); v2f(v[6]); v2f(v[7]); v2f(v[8]); v2f(v[9]); endpolygon(); break; case AH_AT_START: /*Arrow base*/ v[0][0] = x2; v[0][1] = y2; /*Down to fletching*/ v[1][0] = x2 - ax * width * arrowParams[0][0] + nx * width * arrowParams[0][1]; v[1][1] = y2 - ay * width * arrowParams[0][0] + ny * width * arrowParams[0][1]; /*Over to shaft*/ v[2][0] = x1 - ax * width * arrowParams[1][0] + nx * width * arrowParams[1][1]; v[2][1] = y1 - ay * width * arrowParams[1][0] + ny * width * arrowParams[1][1]; /*To first arrowhead tip*/ v[3][0] = x1 - ax * width * arrowParams[2][0] + nx * width * arrowParams[2][1]; v[3][1] = y1 - ay * width * arrowParams[2][0] + ny * width * arrowParams[2][1]; /*To second arrowhead tip*/ v[4][0] = x1 - ax * width * arrowParams[3][0] + nx * width * arrowParams[3][1]; v[4][1] = y1 - ay * width * arrowParams[3][0] + ny * width * arrowParams[3][1]; /*To end of arrow*/ v[5][0] = x1; v[5][1] = y1; /*Up to second arrowhead tip*/ v[6][0] = x1 - ax * width * arrowParams[3][0] - nx * width * arrowParams[3][1]; v[6][1] = y1 - ay * width * arrowParams[3][0] - ny * width * arrowParams[3][1]; /*Back to first arrowhead tip*/ v[7][0] = x1 - ax * width * arrowParams[2][0] - nx * width * arrowParams[2][1]; v[7][1] = y1 - ay * width * arrowParams[2][0] - ny * width * arrowParams[2][1]; /*Down to shaft*/ v[8][0] = x1 - ax * width * arrowParams[1][0] - nx * width * arrowParams[1][1]; v[8][1] = y1 - ay * width * arrowParams[1][0] - ny * width * arrowParams[1][1]; /*Back to fletching*/ v[9][0] = x2 - ax * width * arrowParams[0][0] - nx * width * arrowParams[0][1]; v[9][1] = y2 - ay * width * arrowParams[0][0] - ny * width * arrowParams[0][1]; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); v2f(v[4]); v2f(v[5]); v2f(v[6]); v2f(v[7]); v2f(v[8]); v2f(v[9]); endpolygon(); break; case AH_BOTH_ENDS: /*Calculate midpoints*/ mx = (x1 + x2) * 0.5; my = (y1 + y2) * 0.5; /*Do at end first*/ /*Arrow base*/ v[0][0] = mx; v[0][1] = my; /*Down to fletching*/ v[1][0] = mx + ax * width * arrowParams[0][0] - nx * width * arrowParams[0][1]; v[1][1] = my + ay * width * arrowParams[0][0] - ny * width * arrowParams[0][1]; /*Over to shaft*/ v[2][0] = x2 + ax * width * arrowParams[1][0] - nx * width * arrowParams[1][1]; v[2][1] = y2 + ay * width * arrowParams[1][0] - ny * width * arrowParams[1][1]; /*To first arrowhead tip*/ v[3][0] = x2 + ax * width * arrowParams[2][0] - nx * width * arrowParams[2][1]; v[3][1] = y2 + ay * width * arrowParams[2][0] - ny * width * arrowParams[2][1]; /*To second arrowhead tip*/ v[4][0] = x2 + ax * width * arrowParams[3][0] - nx * width * arrowParams[3][1]; v[4][1] = y2 + ay * width * arrowParams[3][0] - ny * width * arrowParams[3][1]; /*To end of arrow*/ v[5][0] = x2; v[5][1] = y2; /*Up to second arrowhead tip*/ v[6][0] = x2 + ax * width * arrowParams[3][0] + nx * width * arrowParams[3][1]; v[6][1] = y2 + ay * width * arrowParams[3][0] + ny * width * arrowParams[3][1]; /*Back to first arrowhead tip*/ v[7][0] = x2 + ax * width * arrowParams[2][0] + nx * width * arrowParams[2][1]; v[7][1] = y2 + ay * width * arrowParams[2][0] + ny * width * arrowParams[2][1]; /*Down to shaft*/ v[8][0] = x2 + ax * width * arrowParams[1][0] + nx * width * arrowParams[1][1]; v[8][1] = y2 + ay * width * arrowParams[1][0] + ny * width * arrowParams[1][1]; /*Back to fletching*/ v[9][0] = mx + ax * width * arrowParams[0][0] + nx * width * arrowParams[0][1]; v[9][1] = my + ay * width * arrowParams[0][0] + ny * width * arrowParams[0][1]; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); v2f(v[4]); v2f(v[5]); v2f(v[6]); v2f(v[7]); v2f(v[8]); v2f(v[9]); endpolygon(); /*Now do at start*/ bgnpolygon(); /*Arrow base*/ v[0][0] = mx; v[0][1] = my; /*Down to fletching*/ v[1][0] = mx - ax * width * arrowParams[0][0] + nx * width * arrowParams[0][1]; v[1][1] = my - ay * width * arrowParams[0][0] + ny * width * arrowParams[0][1]; /*Over to shaft*/ v[2][0] = x1 - ax * width * arrowParams[1][0] + nx * width * arrowParams[1][1]; v[2][1] = y1 - ay * width * arrowParams[1][0] + ny * width * arrowParams[1][1]; /*To first arrowhead tip*/ v[3][0] = x1 - ax * width * arrowParams[2][0] + nx * width * arrowParams[2][1]; v[3][1] = y1 - ay * width * arrowParams[2][0] + ny * width * arrowParams[2][1]; /*To second arrowhead tip*/ v[4][0] = x1 - ax * width * arrowParams[3][0] + nx * width * arrowParams[3][1]; v[4][1] = y1 - ay * width * arrowParams[3][0] + ny * width * arrowParams[3][1]; /*To end of arrow*/ v[5][0] = x1; v[5][1] = y1; /*Up to second arrowhead tip*/ v[6][0] = x1 - ax * width * arrowParams[3][0] - nx * width * arrowParams[3][1]; v[6][1] = y1 - ay * width * arrowParams[3][0] - ny * width * arrowParams[3][1]; /*Back to first arrowhead tip*/ v[7][0] = x1 - ax * width * arrowParams[2][0] - nx * width * arrowParams[2][1]; v[7][1] = y1 - ay * width * arrowParams[2][0] - ny * width * arrowParams[2][1]; /*Down to shaft*/ v[8][0] = x1 - ax * width * arrowParams[1][0] - nx * width * arrowParams[1][1]; v[8][1] = y1 - ay * width * arrowParams[1][0] - ny * width * arrowParams[1][1]; /*Back to fletching*/ v[9][0] = mx - ax * width * arrowParams[0][0] - nx * width * arrowParams[0][1]; v[9][1] = my - ay * width * arrowParams[0][0] - ny * width * arrowParams[0][1]; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); v2f(v[4]); v2f(v[5]); v2f(v[6]); v2f(v[7]); v2f(v[8]); v2f(v[9]); endpolygon(); break; } } #endif } void DrawVCursor(x, yt, yb) int x, yt, yb; /*Draws a vertical cursor*/ { #ifdef GRAPHICS DrawUILine(x, yt, x, yb, UIRED); DrawUILine(x + 1, yt, x + 1, yb, UIBLACK); #endif } #ifdef GRAPHICS #ifdef FONTS4D extern fmfonthandle currentFontHandle; #endif #endif #ifdef PROTO void DrawSpaceString(real x, real y, real z, char *s) #else void DrawSpaceString(x, y, z, s) real x, y, z; char *s; #endif /*Draws a string beginning at x, y, z in a space*/ /* DIK need PostScript version? */ { #ifdef GRAPHICS cmov((Coord) x, (Coord) y, (Coord) z); #ifdef FONTS4D if (currentFontHandle) { fmprstr(s); } else { charstr(s); } #else charstr(s); #endif #endif } #ifdef PROTO void DrawWFSphere(real x, real y, real z, real radius) #else void DrawWFSphere(x, y, z, radius) real x, y, z, radius; #endif /*Draws a wire frame sphere*/ { #ifdef GRAPHICS pushmatrix(); translate(x, y, z); circ(0.0, 0.0, radius); translate(0.0, 0.0, radius * SQ22); circ(0.0, 0.0, radius * SQ22); translate(0.0, 0.0, -radius * 2.0 * SQ22); circ(0.0, 0.0, radius * SQ22); translate(0.0, 0.0, radius * SQ22); rotate(900, 'y'); circ(0.0, 0.0, radius); rotate(450, 'x'); circ(0.0, 0.0, radius); rotate(450, 'x'); circ(0.0, 0.0, radius); rotate(450, 'x'); circ(0.0, 0.0, radius); popmatrix(); #endif } #ifdef PROTO void FillRealQuad(real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4) #else void FillRealQuad(x1, y1, x2, y2, x3, y3, x4, y4) real x1, y1, x2, y2, x3, y3, x4, y4; #endif /*Fills a quadrilateral given real coordinates*/ { #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { float v[4][2]; v[0][0] = x1; v[0][1] = y1; v[1][0] = x2; v[1][1] = y2; v[2][0] = x3; v[2][1] = y3; v[3][0] = x4; v[3][1] = y4; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); endpolygon(); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "%g %g moveto %g %g lineto %g %g lineto %g %g lineto closepath fill\n", x1, y1, x2, y2, x3, y3, x4, y4); } #endif } #ifdef PROTO void FillIntQuad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) #else void FillIntQuad(x1, y1, x2, y2, x3, y3, x4, y4) int x1, y1, x2, y2, x3, y3, x4, y4; #endif /*Fills a quadrilateral given real coordinates*/ { #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { long v[4][2]; v[0][0] = x1; v[0][1] = y1; v[1][0] = x2; v[1][1] = y2; v[2][0] = x3; v[2][1] = y3; v[3][0] = x4; v[3][1] = y4; bgnpolygon(); v2i(v[0]); v2i(v[1]); v2i(v[2]); v2i(v[3]); endpolygon(); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "%d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath fill\n", x1, y1, x2, y2, x3, y3, x4, y4); } #endif } #ifdef PROTO void FillRealQuint(real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4, real x5, real y5) #else void FillRealQuint(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5) real x1, y1, x2, y2, x3, y3, x4, y4, x5, y5; #endif /*Fills a quintalateral given real coordinates*/ { #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { float v[5][2]; v[0][0] = x1; v[0][1] = y1; v[1][0] = x2; v[1][1] = y2; v[2][0] = x3; v[2][1] = y3; v[3][0] = x4; v[3][1] = y4; v[4][0] = x5; v[4][1] = y5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); v2f(v[4]); endpolygon(); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "%g %g moveto %g %g lineto %g %g lineto %g %g lineto %g %g lineto closepath fill\n", x1, y1, x2, y2, x3, y3, x4, y4, x5, y5); } #endif } #ifdef PROTO void FillRealHex(real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4, real x5, real y5, real x6, real y6) #else void FillRealHex(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6) real x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6; #endif /*Fills a hexalateral given real coordinates*/ { #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { float v[6][2]; v[0][0] = x1; v[0][1] = y1; v[1][0] = x2; v[1][1] = y2; v[2][0] = x3; v[2][1] = y3; v[3][0] = x4; v[3][1] = y4; v[4][0] = x5; v[4][1] = y5; v[5][0] = x6; v[5][1] = y6; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); v2f(v[4]); v2f(v[5]); endpolygon(); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "%g %g moveto %g %g lineto %g %g lineto %g %g lineto %g %g lineto %g %g lineto closepath fill\n", x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6); } #endif } #ifdef PROTO void FillRealRect(real left, real right, real bottom, real top) #else void FillRealRect(left, right, bottom, top) real left, right, bottom, top; #endif /*Fills a rectangle, taking real coordinates*/ { #ifdef GRAPHICS FillRealQuad(left, top, left, bottom, right, bottom, right, top); #endif } #ifdef PROTO void FrameRealWideRect(real left, real right, real bottom, real top, real width) #else void FrameRealWideRect(left, right, bottom, top, width) real left, right, bottom, top, width; #endif /*Frames a wide rectangle taking real variables*/ { #ifdef GRAPHICS FillRealRect(left, right, top - width, top); FillRealRect(left, right, bottom, bottom + width); FillRealRect(left, left + width, bottom, top); FillRealRect(right - width, right, bottom, top); #endif } #ifdef PROTO void FrameWideRect(int left, int right, int bottom, int top, int width) #else void FrameWideRect(left, right, bottom, top, width) int left, right, bottom, top, width; #endif /*Frames a wide rectangle*/ { #ifdef GRAPHICS FillRect(left, right, top - width + 1, top); FillRect(left, right, bottom, bottom + width - 1); FillRect(left, left + width - 1, bottom, top); FillRect(right - width + 1, right, bottom, top); #endif } #ifdef PROTO void FrameUIWideRect(int left, int right, int bottom, int top, int width, int color) #else void FrameUIWideRect(left, right, bottom, top, width, color) int left, right, bottom, top, width, color; #endif /*Frames a wide rectangle in UI color*/ { #ifdef GRAPHICS SetUIColor(color); FrameWideRect(left, right, bottom, top, width); #endif } #ifdef PROTO void DrawHandle(int x, int y) #else void DrawHandle(x, y) int x, y; #endif /* Draws a handle at x,y */ { #ifdef GRAPHICS FillUIRect(x - HANDLESIZE/2, x + HANDLESIZE / 2, y - HANDLESIZE/2, y + HANDLESIZE/2, OUTSIDEFRAMECOLOR); FillUIRect(x - HANDLESIZE/2 + OUTSIDEFRAMEWEIGHT, x + HANDLESIZE/2 - OUTSIDEFRAMEWEIGHT, y - HANDLESIZE/2 + OUTSIDEFRAMEWEIGHT, y + HANDLESIZE/2 - OUTSIDEFRAMEWEIGHT, INSIDEFRAMECOLOR); #endif } #ifdef PROTO Bool PointInHandle(int pointX, int pointY, int handleX, int handleY) #else Bool PointInHandle(pointX, pointY, handleX, handleY) int pointX; int pointY; int handleX; int handleY; #endif /*Returns true if a point is inside a handle*/ { #ifdef INTERACTIVE return (pointX >= handleX - HANDLESIZE / 2 && pointX <= handleX + HANDLESIZE / 2 && pointY >= handleY - HANDLESIZE / 2 && pointY <= handleY + HANDLESIZE / 2) ? true : false; #endif } #ifdef PROTO void DrawRaisedEdge(int left, int right, int bottom, int top) #else void DrawRaisedEdge(left, right, bottom, top) int left; int right; int bottom; int top; #endif /* draws a rectangular raised edge (JEL) */ { #ifdef GRAPHICS /* bottom */ SetUIColor(UIBOTTOMEDGE); FillIntQuad( left, bottom, right, bottom, right - EDGE, bottom + EDGE, left + EDGE, bottom + EDGE); /* left */ SetUIColor(UILEFTEDGE); FillIntQuad( left, bottom, left + EDGE, bottom + EDGE, left + EDGE, top - EDGE, left, top); /* right */ SetUIColor(UIRIGHTEDGE); FillIntQuad( right - EDGE, bottom + EDGE, right, bottom, right, top, right - EDGE, top - EDGE); /* top */ SetUIColor(UITOPEDGE); FillIntQuad( left + EDGE, top - EDGE, right - EDGE, top - EDGE, right, top, left, top); return; #endif } #ifdef PROTO void DrawSunkenEdge(int left, int right, int bottom, int top) #else void DrawSunkenEdge(left, right, bottom, top) int left; int right; int bottom; int top; #endif /* draws a rectanglar sunken edge (JEL) Fixed to be in CCW order (EMP) */ { #ifdef GRAPHICS /* bottom */ SetUIColor(UITOPEDGE); FillIntQuad( left, bottom, right, bottom, right - EDGE, bottom + EDGE, left + EDGE, bottom + EDGE); /* left */ SetUIColor(UIRIGHTEDGE); FillIntQuad( left, bottom, left + EDGE, bottom + EDGE, left + EDGE, top - EDGE, left, top); /* right */ SetUIColor(UILEFTEDGE); FillIntQuad( right - EDGE, bottom + EDGE, right, bottom, right, top, right - EDGE, top - EDGE); /* top */ SetUIColor(UIBOTTOMEDGE); FillIntQuad( left + EDGE, top - EDGE, right - EDGE, top - EDGE, right, top, left, top); return; #endif } #ifdef PROTO void DrawInsetRect(int left, int right, int bottom, int top) #else void DrawInsetRect(left, right, bottom, top) int left; int right; int bottom; int top; #endif /* draws a rectangle filled with uiColor inset by EDGE from the given bounds */ { #ifdef GRAPHICS FillRect(left + EDGE, right - EDGE, bottom + EDGE, top - EDGE); #endif } #ifdef PROTO void DrawInsetWashedRect(int left, int right, int bottom, int top, int washColor) #else void DrawInsetWashedRect(left, right, bottom, top, int washColor) int left; int right; int bottom; int top; int washColor; #endif /* draws a rectangle filled with uiColor inset by EDGE from the given bounds */ { #ifdef GRAPHICS FillUIRect(left + EDGE, right - EDGE, bottom + EDGE, top - EDGE, UIGRAY75); FillUIGauzeRect(left + EDGE, right - EDGE, bottom + EDGE, top - EDGE, washColor); #endif } #ifdef PROTO void DrawRaisedRect(int left, int right, int bottom, int top, int uiColor) #else void DrawRaisedRect(left, right, bottom, top, uiColor) int left; int right; int bottom; int top; int uiColor; #endif /* draws a raised edge with filled rectangle inside */ { #ifdef GRAPHICS SetUIColor(uiColor); DrawInsetRect(left, right, bottom, top); DrawRaisedEdge(left, right, bottom, top); #endif } #ifdef PROTO void DrawSunkenRect(int left, int right, int bottom, int top, int uiColor) #else void DrawSunkenRect(left, right, bottom, top, uiColor) int left; int right; int bottom; int top; int uiColor; #endif /* draws a sunken edge with filled rectangle inside */ { #ifdef GRAPHICS SetUIColor(uiColor); DrawInsetRect(left, right, bottom, top); DrawSunkenEdge(left, right, bottom, top); #endif } void SetLineWidth(width) int width; /*Sets the line width to width*/ { #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { linewidth(width); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%d setlinewidth\n", width); } #endif } void SetPointWidth(width) int width; /*Sets the line width to width*/ { #ifdef GRAPHICS if (drawingMode == DRAW_SCREEN) { #if MACHINE != RS6000 pntsize((short) width); #endif } #endif } void DrawMarkerSplat(left, right, bottom, top) { #ifdef GRAPHICS SetUIColor(UITEXT); if (drawingMode == DRAW_SCREEN) { float v[4][2]; /*Draw part of button '*', the left-bottom to top-right part */ v[0][0] = left + 2.5; v[0][1] = bottom + 3.5; v[1][0] = left + 3.5; v[1][1] = bottom + 2.5; v[2][0] = right - 2.5; v[2][1] = top - 3.5; v[3][0] = right - 3.5; v[3][1] = top - 2.5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); endpolygon(); /*Draw rest of button '*', the left-top to right-bottom part*/ v[0][0] = left + 2.5; v[0][1] = top - 3.5; v[1][0] = left + 3.5; v[1][1] = top - 2.5; v[2][0] = right - 2.5; v[2][1] = bottom + 3.5; v[3][0] = right - 3.5; v[3][1] = bottom + 2.5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); endpolygon(); /*Draw rest of button '*', the left-to-right part*/ v[0][0] = left + 1.5; v[0][1] = (top+bottom)/2.0 - 0.5; v[1][0] = left + 1.5; v[1][1] = (top+bottom)/2.0 + 0.5; v[2][0] = right - 1.5; v[2][1] = (top+bottom)/2.0 + 0.5; v[3][0] = right - 1.5; v[3][1] = (top+bottom)/2.0 - 0.5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); endpolygon(); /*Draw rest of button '*', the top-to-bottom part*/ v[0][0] = (left+right)/2.0 - 0.5; v[0][1] = top - 1.5; v[1][0] = (left+right)/2.0 + 0.5; v[1][1] = top - 1.5; v[2][0] = (left+right)/2.0 + 0.5; v[2][1] = bottom + 1.5; v[3][0] = (left+right)/2.0 - 0.5; v[3][1] = bottom + 1.5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); endpolygon(); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n", left + 2.5, bottom + 3.5, left + 3.5, bottom + 2.5, right - 2.5, top - 3.5, right - 3.5, top - 2.5); fprintf(psFile, "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n", left + 2.5, top - 3.5, left + 3.5, top - 2.5, right - 2.5, bottom + 3.5, right - 3.5, bottom + 2.5); fprintf(psFile, "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n", left + 1.5, (top+bottom)/2.0 - 0.5, left + 1.5, (top+bottom)/2.0 + 0.5, right - 1.5, (top+bottom)/2.0 + 0.5, right - 1.5, (top+bottom)/2.0 - 0.5); fprintf(psFile, "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n", (left+right)/2.0 - 0.5, top - 1.5, (left+right)/2.0 + 0.5, top - 1.5, (left+right)/2.0 + 0.5, bottom + 1.5, (left+right)/2.0 - 0.5, bottom + 1.5); } #endif /* GRAPHICS */ } void DrawMarkerBlot(left, right, bottom, top) int left, right, bottom, top; { #ifdef GRAPHICS SetUIColor(UITEXT); FillRect(left+2.5, right-2.5, bottom+2.5, top-2.5); #endif /*GRAPHICS*/ } void DrawMarkerCheck(left, right, bottom, top) int left, right, bottom, top; { #ifdef GRAPHICS float v[4][2]; SetUIColor(UITEXT); if (drawingMode == DRAW_SCREEN) { /*Draw part of checkmark*/ v[0][0] = left + 1.5; v[0][1] = (top + bottom) / 2 - 0.5; v[1][0] = left + 2.5; v[1][1] = (top + bottom) / 2 + 1.5; v[2][0] = left + (right - left) / 3 + 1.5; v[2][1] = bottom + 1.5; v[3][0] = left + (right - left) / 3 - 0.5; v[3][1] = bottom + 1.5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); endpolygon(); /*Draw rest of checkmark*/ v[0][0] = left + (right - left) / 3 + 1.5; v[0][1] = bottom + 1.5; v[1][0] = left + (right - left) / 3 - 0.5; v[1][1] = bottom + 1.5; v[2][0] = right - 1.5; v[2][1] = top - 1.5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); endpolygon(); } else if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%f setgray\n", PSColor()); fprintf(psFile, "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n", left + 1.5, (top + bottom) / 2 - 0.5, left + 2.5, (top + bottom) / 2 + 1.5, left + (right - left) / 3 + 1.5, bottom + 1.5, left + (right - left) / 3 - 0.5, bottom + 1.5); fprintf(psFile, "%.1f %.1f moveto %.1f %.1f lineto %.1f %.1f lineto closepath fill\n", left + (right - left) / 3 + 1.5, bottom + 1.5, left + (right - left) / 3 - 0.5, bottom + 1.5, right - 1.5, top - 1.5); } #endif /*GRAPHICS */ } void DrawMarkerX(left, right, bottom, top) int left, right, bottom, top; { #ifdef GRAPHICS float v[4][2]; SetUIColor(UITEXT); /*Draw part of button 'X'*/ v[0][0] = left + 1.5; v[0][1] = bottom + 2.5; v[1][0] = left + 2.5; v[1][1] = bottom + 1.5; v[2][0] = right - 1.5; v[2][1] = top - 2.5; v[3][0] = right - 2.5; v[3][1] = top - 1.5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); endpolygon(); /*Draw rest of button 'X'*/ v[0][0] = left + 1.5; v[0][1] = top - 2.5; v[1][0] = left + 2.5; v[1][1] = top - 1.5; v[2][0] = right - 1.5; v[2][1] = bottom + 2.5; v[3][0] = right - 2.5; v[3][1] = bottom + 1.5; bgnpolygon(); v2f(v[0]); v2f(v[1]); v2f(v[2]); v2f(v[3]); endpolygon(); #endif /*GRAPHICS */ } #ifdef PROTO void DrawCtlLeft(int left, int right, int bottom, int top, int uiColor) #else void DrawCtlLeft(left, right, bottom, top, uiColor) int left, right, bottom, top; Bool highlight; #endif { #ifdef GRAPHICS float a, b, c, d; a = left - 0.5 + 1.4142 * EDGE; b = left - 0.5 + 0.4142 * EDGE + (top - bottom) / 2; c = (top + bottom) / 2; d = (top - bottom) / 2; /* bottom */ SetUIColor(UIBOTTOMEDGE); FillRealHex(right, bottom, left + d, bottom, left, c, a, c, b, bottom + EDGE, right - EDGE, bottom + EDGE); /* top */ SetUIColor(UITOPEDGE); FillRealHex(a, c, left, c, left + d, top, right, top, right - EDGE, top - EDGE, b, top - EDGE); /* right */ SetUIColor(UIRIGHTEDGE); FillRealQuad(right, top, right - EDGE, top - EDGE, right - EDGE, bottom + EDGE, right, bottom); /* surface */ SetUIColor(uiColor); FillRealQuint(right - EDGE, bottom + EDGE, b, bottom + EDGE, a, c, b, top - EDGE, right - EDGE, top - EDGE); #endif } #ifdef PROTO void DrawCtlRight(int left, int right, int bottom, int top, int uiColor) #else void DrawCtlRight(left, right, bottom, top, uiColor) int left, right, bottom, top; Bool highlight; #endif { #ifdef GRAPHICS float a, b, c, d; a = right + 0.5 - 1.4142 * EDGE; b = right + 0.5 - 0.4142 * EDGE - (top - bottom) / 2; c = (top + bottom) / 2; d = (top - bottom) / 2; /* bottom */ SetUIColor(UIBOTTOMEDGE); FillRealHex(right, c, right - d, bottom, left, bottom, left + EDGE, bottom + EDGE, b, bottom + EDGE, a, c); /* top */ SetUIColor(UITOPEDGE); FillRealHex(right, c, a, c, b, top - EDGE, left + EDGE, top - EDGE, left, top, right - d, top); /* left */ SetUIColor(UILEFTEDGE); FillRealQuad(left, bottom, left, top, left + EDGE, top - EDGE, left + EDGE, bottom + EDGE); /* surface */ SetUIColor(uiColor); FillRealQuint(a, c, b, bottom + EDGE, left + EDGE, bottom + EDGE, left + EDGE, top - EDGE, b, top - EDGE); #endif } #ifdef PROTO void DrawCtlUp(int left, int right, int bottom, int top, int uiColor) #else void DrawCtlUp(left, right, bottom, top, uiColor) int left, right, bottom, top; Bool highlight; #endif { #ifdef GRAPHICS float a, b, c, d; a = top - 1.4142 * EDGE + 0.5; b = top - 0.4142 * EDGE - (right - left) /2; c = (right + left) / 2; d = (right - left) / 2; /* left */ SetUIColor(UILEFTEDGE); FillRealHex(c, top, c, a, left + EDGE, b, left + EDGE, bottom + EDGE, left, bottom, left, top - d); /* right */ SetUIColor(UIRIGHTEDGE); FillRealHex(c, top, right, top - d, right, bottom, right - EDGE, bottom + EDGE, right - EDGE, b, c, a); /* bottom */ SetUIColor(UIBOTTOMEDGE); FillRealQuad(right, bottom, left, bottom, left + EDGE, bottom + EDGE, right - EDGE, bottom + EDGE); /* surface */ SetUIColor(uiColor); FillRealQuint(c, a, right - EDGE, b, right - EDGE, bottom + EDGE, left + EDGE, bottom + EDGE, left + EDGE, b); #endif } #ifdef PROTO void DrawCtlDown(int left, int right, int bottom, int top, int uiColor) #else void DrawCtlDown(left, right, bottom, top, uiColor) int left, right, bottom, top; Bool highlight; #endif { #ifdef GRAPHICS float a, b, c, d; a = bottom + 1.4142 * EDGE - 0.5; b = bottom + 0.4142 * EDGE - (right - left) /2; c = (right + left) / 2; d = (right - left) / 2; /* left */ SetUIColor(UILEFTEDGE); FillRealHex(c, bottom, left, bottom + d, left, top, left + EDGE, top - EDGE, left + EDGE, b, c, a); /* right */ SetUIColor(UIRIGHTEDGE); FillRealHex(c, bottom, c, a, right - EDGE, b, right - EDGE, top - EDGE, right, top, right, bottom + d); /* top */ SetUIColor(UITOPEDGE); FillRealQuad(right, top, right - EDGE, top - EDGE, left + EDGE, top - EDGE, left, top); /* surface */ SetUIColor(uiColor); FillRealQuint(c, a, left + EDGE, b, left + EDGE, top - EDGE, right - EDGE, top - EDGE, right - EDGE, b); #endif } #ifdef PROTO void SavePSImage(FILE *psFile, Pixel *imageBuffer, int left, int right, int bottom, int top) #else void SavePSImage(psFile, imageBuffer, left, right, bottom, top) FILE *psFile; Pixel *imageBuffer; int left; int right; int bottom; int top; #endif /*Saves an image in imageBuffer within left, right, bottom, top into psFile*/ { real y, dummy; int iVal; long k; int pixWrap; long nPixels; long i, j, ip, jp; long width, height; int subSample; subSample = imageSubSample + 1; width = right - left; height = top - bottom; #define PIXPERLINE 10 #ifdef COLORPOST /*Color image. Do stuff before pixels*/ fprintf(psFile, "%% Color Space image within %d %d %d %d\n", left, right, bottom, top); fprintf(psFile, "%d %d moveto\n", left, bottom); fprintf(psFile, "/imgstr %d string def\n", 3 * width); fprintf(psFile, "%d %d %d matrix \n", right - left, top - bottom, 8); /*Do pixels*/ nPixels = width * height; pixWrap = 0; fprintf(psFile, "{currentfile imgstr readhexstring pop} false 3 colorimage\n"); for (k = 0; k < nPixels; ++k) { fprintf(psFile, "%02X%02X%02X%s", LinToGamma[imageBuffer[k] . red], LinToGamma[imageBuffer[k] . green], LinToGamma[imageBuffer[k] . blue], (++pixWrap) % PIXPERLINE ? " " : "\n"); } fprintf(psFile, "\n\n"); #else /*B/W image. Do stuff before pixels*/ fprintf(psFile, "%% B/W Space image within %d %d %d %d\n", left, right, bottom, top); fprintf(psFile, "/imgstr %d string def\n", width / subSample); fprintf(psFile, "%d %d %d\n", width / subSample, height / subSample, 8); fprintf(psFile, "%d %d matrix translate\n", -left, -bottom); fprintf(psFile, "%lg %lg matrix scale\n", 1.0 / (double) subSample, 1.0 / (double) subSample); fprintf(psFile, " matrix concatmatrix\n"); /*Do pixels*/ nPixels = (right - left) * (top - bottom); pixWrap = 0; fprintf(psFile, "{currentfile imgstr readhexstring pop} image\n"); for (j = 0; j < height; j += subSample) { for (i = 0; i < width; i += subSample) { real avgPixel; avgPixel = 0.0; /*Calculate an average pixel*/ for (jp = j; jp < j + subSample; ++jp) { for (ip = i; ip < i + subSample; ++ip) { k = ip + jp * width; RGB2YIQ(&y, &dummy, &dummy, imageBuffer[k] . red / 255.0, imageBuffer[k] . green / 255.0, imageBuffer[k] . blue / 255.0); avgPixel += y; } } avgPixel /= (real) subSample; avgPixel /= (real) subSample; iVal = avgPixel * 255.0; if (iVal < 0) iVal = 0; if (iVal > 255) iVal = 255; fprintf(psFile, "%02X%s", LinToGamma[iVal], (++pixWrap) % PIXPERLINE ? " " : "\n"); } } fprintf(psFile, "\n\n"); #endif #undef PIXPERLINE } /* * Icons in eps files 10/28/92 * In order to make the eps file of a window self contained, a bit-mapped * font of just the icons used in that window is defined in the file. In PS * drawing mode, RegisterIconUsed keeps a list of the icon numbers used. * It returns the index of the icon in the list. EndDrawing uses the list * to create the font definition. If there are any icons in the window, the * file must be rewritten with the font definition in the header. The font * definition is generated by GenIconDef() in ScianIcons.c. */ #ifdef PROTO void DrawPSFrame(char *name, int left, int right, int bottom, int top) #else void DrawPSFrame(name, left, right, bottom, top) char *name; int left; int right; int bottom; int top; #endif /*Draws a PostScript frame around left, right, bottom, top*/ { left -= WINFRAMEWID; right -= WINFRAMEWID; bottom -= WINFRAMEWID; top -= WINFRAMEWID; { /* draw a generic window frame with title only */ fprintf(psFile, "newpath 0 0 moveto 0 %d lineto %d %d lineto %d 0 lineto closepath stroke\n", top, right, top, right); fprintf(psFile, "newpath %d %d moveto %d %d lineto %d %d lineto %d %d lineto closepath stroke\n", WINFRAMEWID - 1, WINFRAMEWID - 1, WINFRAMEWID - 1, top - WINFRAMEWID + 1, right - WINFRAMEWID + 1, top - WINFRAMEWID + 1, right - WINFRAMEWID + 1, WINFRAMEWID - 1); fprintf(psFile, "newpath %d %d moveto %d %d lineto stroke\n", WINFRAMEWID - 1, top - WINFRAMEWID - WINTITLEHT + 1, right - WINFRAMEWID + 1, top - WINFRAMEWID - WINTITLEHT + 1); SetupFont(WINTITLEFONT, 12); fprintf(psFile, "%d %d moveto (%s) show\n", WINFRAMEWID + 20, top - WINFRAMEWID - WINTITLEHT + 5, show(name)); RegisterFontUsed(WINTITLEFONT); } } #ifdef PROTO void BeginDrawSubscreen(int ox, int oy) #else void BeginDrawSubscreen(ox, oy) int ox, oy; #endif /*Begins a drawing segment offset by ox, oy*/ { if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%d %d translate\n", ox, oy); } } #ifdef PROTO void EndDrawSubscreen(int ox, int oy) #else void EndDrawSubscreen(ox, oy) int ox, oy; #endif /*Begins a drawing segment offset by ox, oy*/ { if (drawingMode == DRAW_POSTSCRIPT && psFile) { fprintf(psFile, "%d %d translate\n", -ox, -oy); } } #ifdef PROTO void BeginDrawing(char *name, int left, int right, int bottom, int top, real scale) #else void BeginDrawing(name, left, right, bottom, top, scale) char *name; /*Window title*/ int left, right, bottom, top; /*Coordinates of window INTERIOR*/ real scale; #endif { #ifdef GRAPHICS psFile = tmpfile(); if (drawingMode == DRAW_POSTSCRIPT && psFile) { struct timeval date; gettimeofday(&date, (struct timezone *)0); /* "normalize" bounds */ right -= left; top -= bottom; /* initialize counters */ numFontsUsed = 0; numIconsUsed = 0; /* write EPS header */ fprintf(psFile, "\ %%!PS-Adobe-2.0 EPSF-2.0\n\ %%%%Title: %s\n\ %%%%Creator: SciAn\n\ %%%%CreationDate: %s\ %%%%For: %s\n\ %%%%DocumentFonts: (atend)\n\ %%%%BoundingBox: 0 0 %d %d\n\ %%%%EndComments\n\ save\n\n", /* NOTE: icon font def is inserted after first blank line of file */ name, ctime(&date.tv_sec), getenv("USER"), (int) (scale * (real) (right + 1)), (int) (scale * (real) (top + 1))); fprintf(psFile, "/resetclip {matrix currentmatrix currentfont currentlinewidth\n\ grestore gsave setlinewidth setfont setmatrix } def\n\ \n\ currentscreen 3 1 roll pop pop 75 0 3 -1 roll setscreen\n\ gsave\n\ 1 setlinewidth\n\ %g %g scale\n\n\n", scale, scale); } #endif } #ifdef PROTO void EndDrawing(Bool showpagep) #else void EndDrawing(showpagep) Bool showpagep; #endif { #ifdef GRAPHICS if (drawingMode == DRAW_POSTSCRIPT && psFile && drawFile) { char buf[256]; int i; /* copy header from temp file (copies to first blank line) */ rewind(psFile); while (fgets(buf, 256, psFile)) { fputs(buf, drawFile); if (*buf == '\n') break; } /* generate font of icons used, if needed */ GenIconDef(drawFile); /* copy the rest of the temp file */ while (fgets(buf, 256, psFile)) { fputs(buf, drawFile); } fclose(psFile); if (showpagep) { fprintf(drawFile, "\nshowpage\n"); } /* write PostScript trailer -- list fonts used */ fprintf(drawFile, "\nrestore\n\n%%%%Trailer\n%%%%DocumentFonts:"); for (i=0; i= 32) { ReportError("RegisterIconUsed","Too many different icons!"); return -1; } iconsUsed[numIconsUsed] = icon; return numIconsUsed++; #else return 0; #endif } void EraseAll() /*Erases everything*/ { SetUIColor(UIBLACK); clear(); } void InitDraw() /*Initializes the drawing system*/ { int k; /*No window at the beginning*/ curDrawingStateIndex = 0; CURSTATE . window = 0; CURSTATE . initialWindow = false; for (k = 0; k < 4; ++k) { CURSTATE . screenMask[k] = 0; CURSTATE . viewport[k] = 0; } for (k = 0; k < 2; ++k) { CURSTATE . origin[k] = 0; CURSTATE . translation[k] = 0; } } void KillDraw() { }