/*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*/ 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 */ #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 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 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); setpattern(GREYPAT); circfi(x, y, radius); setpattern(SOLIDPAT); #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) { #ifdef V3FISBUGGED 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; polf(3, v); #else 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(); #endif } 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); setpattern(GREYPAT); FillIntQuad(left, (top), left, bottom, (right), bottom, (right), (top)); setpattern(SOLIDPAT); #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 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; concave(TRUE); /*DIK what is this supposed to return to?*/ 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) { #ifdef V3FISBUGGED Coord 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; polf2(4, v); #else 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(); #endif } 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) { #ifdef V3FISBUGGED Coord 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; polf(5, v); #else 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(); #endif } 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) { #ifdef V3FISBUGGED 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; polf(4, v); #else 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(); #endif } 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) { Coord 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; polf2(4, v); /*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; polf2(4, v); /*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; polf2(4, v); /*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; polf2(4, v); } 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 Coord 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; polf2(4, v); /*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; polf2(3, v); } 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 Coord 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; polf2(4, v); /*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; polf2(4, v); #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; #define PIXPERLINE 10 #define SUBSAMPLE 3 width = right - left; height = top - bottom; #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); #ifdef SUBSAMPLE 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"); #else fprintf(psFile, "/imgstr %d string def\n", right - left); fprintf(psFile, "%d %d %d %d %d matrix translate\n", right - left, top - bottom, 8, -left, -bottom); #endif #ifdef SUBSAMPLE /*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"); #else /*Do pixels*/ nPixels = (right - left) * (top - bottom); pixWrap = 0; fprintf(psFile, "{currentfile imgstr readhexstring pop} image\n"); for (k = 0; k < nPixels; ++k) { RGB2YIQ(&y, &dummy, &dummy, imageBuffer[k] . red / 255.0, imageBuffer[k] . green / 255.0, imageBuffer[k] . blue / 255.0); iVal = y * 255.0; fprintf(psFile, "%02X%s", LinToGamma[iVal], (++pixWrap) % PIXPERLINE ? " " : "\n"); } fprintf(psFile, "\n\n"); #endif #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. */ #define WINFRAMEWID 6 #define WINTITLEHT 20 #define WINTITLEFONT "Helvetica-BoldOblique" #ifdef PROTO void BeginDrawing(char *name, int left, int right, int bottom, int top) #else void BeginDrawing(name, left, right, bottom, top) char *name; /*Window title*/ int left, right, bottom, top; /*Coordinates of window INTERIOR*/ #endif { #ifdef GRAPHICS psFile = tmpfile(); if (drawingMode == DRAW_POSTSCRIPT && psFile) { struct timeval date; if (!(selWinInfo->flags & WINNOFRAME)) { right += 2*WINFRAMEWID; top += 2*WINFRAMEWID + WINTITLEHT; } 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) ((right + 1)/2), (int) ((top + 1)/2)); 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\ .5 .5 scale\n\n"); if (!(selWinInfo -> flags & WINNOFRAME)) { /* 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)); fprintf(psFile, "%d %d translate\n", WINFRAMEWID, WINFRAMEWID); RegisterFontUsed(WINTITLEFONT); } } #endif } void EndDrawing() { #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); /* 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() { }