william@CS.UCLA.EDU (William Cheng) (03/11/91)
Submitted-by: william@CS.UCLA.EDU (William Cheng) Posting-number: Volume 12, Issue 19 Archive-name: tgif/part03 ---------------------------------> cut here <--------------------------------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 23)." # Contents: drawing.c dup.c edit.c # Wrapped by william@oahu on Wed Mar 6 09:57:03 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'drawing.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'drawing.c'\" else echo shar: Extracting \"'drawing.c'\" \(24657 characters\) sed "s/^X//" >'drawing.c' <<'END_OF_FILE' X/* X * Author: William Chia-Wei Cheng (william@cs.ucla.edu) X * X * Copyright (C) 1990, 1991, William Cheng. X */ X#ifndef lint Xstatic char RCSid[] = X "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/drawing.c,v 2.0 91/03/05 15:26:27 william Exp $"; X#endif X X#include <X11/Xlib.h> X#include <X11/Xutil.h> X#include "const.h" X#include "types.h" X X#include "align.e" X#include "animate.e" X#include "arc.e" X#include "attr.e" X#include "box.e" X#include "choice.e" X#include "copypaste.e" X#include "cursor.e" X#include "dialog.e" X#include "dup.e" X#include "edit.e" X#include "file.e" X#include "font.e" X#include "grid.e" X#include "group.e" X#include "mark.e" X#include "menu.e" X#include "msg.e" X#include "obj.e" X#include "oval.e" X#include "pattern.e" X#include "poly.e" X#include "polygon.e" X#include "raster.e" X#include "rcbox.e" X#include "rect.e" X#include "ruler.e" X#include "scroll.e" X#include "select.e" X#include "setup.e" X#include "special.e" X#include "stk.e" X#include "stretch.e" X#include "text.e" X#include "xbitmap.e" X X#define O_VIS 4 X#define O_INVIS 4 X#define O_GRID (O_VIS+O_INVIS) X Xvoid SetDefaultDrawWinClipRecs () X{ X XRectangle recs[1]; X X SetRecVals (recs[0], 0, 0, drawWinW, drawWinH); X XSetClipRectangles (mainDisplay, drawGC, 0, 0, recs, 1, YXBanded); X} X Xvoid SetDefaultIconWinClipRecs () X{ X XRectangle recs[1]; X X SetRecVals (recs[0], 0, 0, iconWindowW, iconWindowH); X XSetClipRectangles (mainDisplay, drawGC, 0, 0, recs, 1, YXBanded); X} X Xstatic Xvoid DrawHorizOutline (Win, Y, X1, X2, XStart, XEnd, Pixel) X Window Win; X int Y, X1, X2, XStart, XEnd, Pixel; X /* XStart and XEnd are the real place, X1 and X2 are on outline grid */ X{ X register int i; X X if (XStart-X1 < O_VIS) X XDrawLine (mainDisplay, Win, defaultGC, XStart, Y, X1+O_VIS-1, Y); X for (i = X1+O_GRID; i < X2-O_GRID; i+= O_GRID) X XDrawLine (mainDisplay, Win, defaultGC, i, Y, i+O_VIS-1, Y); X if (X2-XEnd < O_VIS) X XDrawLine (mainDisplay, Win, defaultGC, X2-O_GRID, Y, XEnd, Y); X else X XDrawLine (mainDisplay, Win, defaultGC, X2-O_GRID, Y, X2-O_INVIS-1, Y); X} X Xstatic Xvoid DrawVertOutline (Win, X, Y1, Y2, YStart, YEnd, Pixel) X Window Win; X int X, Y1, Y2, YStart, YEnd, Pixel; X /* YStart and YEnd are the real place, Y1 and Y2 are on outline grid */ X{ X register int i; X X if (YStart-Y1 < O_VIS) X XDrawLine (mainDisplay, Win, defaultGC, X, YStart, X, Y1+O_VIS-1); X for (i = Y1+O_GRID; i < Y2-O_GRID; i+= O_GRID) X XDrawLine (mainDisplay, Win, defaultGC, X, i, X, i+O_VIS-1); X if (Y2-YEnd < O_VIS) X XDrawLine (mainDisplay, Win, defaultGC, X, Y2-O_GRID, X, YEnd); X else X XDrawLine (mainDisplay, Win, defaultGC, X, Y2-O_GRID, X, Y2-O_INVIS-1); X} X Xstatic Xvoid DrawSymOutline (Win, XOff, YOff, ObjPtr) X Window Win; X int XOff, YOff; X struct ObjRec * ObjPtr; X{ X int ltx, lty, rbx, rby, x_start, x_end, y_start, y_end, pixel; X X pixel = myFgPixel; X X ltx = ((ObjPtr->obbox.ltx - XOff - QUARTER_INCH) >> zoomScale) + 1; X lty = ((ObjPtr->obbox.lty - YOff - QUARTER_INCH) >> zoomScale) + 1; X rbx = ((ObjPtr->obbox.rbx - XOff + QUARTER_INCH) >> zoomScale) - 1; X rby = ((ObjPtr->obbox.rby - YOff + QUARTER_INCH) >> zoomScale) - 1; X X x_start = (ltx % O_GRID == 0) ? ltx : (int)(ltx / O_GRID) * O_GRID; X x_end = (rbx % O_GRID == 0) ? rbx : ((int)(rbx / O_GRID) + 1) * O_GRID; X DrawHorizOutline (Win, lty, x_start, x_end, ltx, rbx, pixel); X DrawHorizOutline (Win, rby, x_start, x_end, ltx, rbx, pixel); X y_start = (lty % O_GRID == 0) ? lty : (int)(lty / O_GRID) * O_GRID; X y_end = (rby % O_GRID == 0) ? rby : ((int)(rby / O_GRID) + 1) * O_GRID; X DrawVertOutline (Win, ltx, y_start, y_end, lty, rby, pixel); X DrawVertOutline (Win, rbx, y_start, y_end, lty, rby, pixel); X} X Xvoid DrawObj (Win, ObjPtr) X Window Win; X register struct ObjRec * ObjPtr; X{ X register struct ObjRec * obj_ptr; X register struct AttrRec * attr_ptr; X X switch (ObjPtr->type) X { X case OBJ_POLY: X DrawPolyObj (Win, drawOrigX, drawOrigY, ObjPtr); X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr); X break; X case OBJ_BOX: X DrawBoxObj (Win, drawOrigX, drawOrigY, ObjPtr); X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr); X break; X case OBJ_OVAL: X DrawOvalObj (Win, drawOrigX, drawOrigY, ObjPtr); X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr); X break; X case OBJ_TEXT: DrawTextObj (Win, drawOrigX, drawOrigY, ObjPtr); break; X case OBJ_POLYGON: X DrawPolygonObj (Win, drawOrigX, drawOrigY, ObjPtr); X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr); X break; X case OBJ_ARC: X DrawArcObj (Win, drawOrigX, drawOrigY, ObjPtr); X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr); X break; X case OBJ_RCBOX: X DrawRCBoxObj (Win, drawOrigX, drawOrigY, ObjPtr); X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr); X break; X case OBJ_XBM: X DrawXBmObj (Win, drawOrigX, drawOrigY, ObjPtr); X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr); X break; X X case OBJ_SYM: X case OBJ_ICON: X case OBJ_GROUP: X obj_ptr = ObjPtr->detail.r->last; X for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->prev) X if (BBoxIntersect (obj_ptr->bbox, drawWinBBox)) X DrawObj (Win, obj_ptr); X if (ObjPtr->type == OBJ_ICON && ObjPtr->dirty) X { X attr_ptr = ObjPtr->fattr; X for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next) X UpdTextBBox (attr_ptr->obj); X AdjObjBBox (ObjPtr); X UpdSelBBox (); X ObjPtr->dirty = FALSE; X } X DrawAttrs(Win, drawOrigX, drawOrigY, ObjPtr->fattr); X if (ObjPtr->type == OBJ_SYM) DrawSymOutline (Win, drawOrigX, drawOrigY, X ObjPtr); X break; X } X} X Xvoid DrawPaperBoundary () X{ X register int x_end, y_end; X X if (drawOrigX+drawWinW > paperWidth) X { X x_end = OFFSET_X(paperWidth); X if (drawOrigY+drawWinH > paperHeight) X { X y_end = OFFSET_Y(paperHeight); X XDrawLine (mainDisplay, drawWindow, defaultGC, x_end, 0, x_end, y_end); X XDrawLine (mainDisplay, drawWindow, defaultGC, 0, y_end, x_end, y_end); X } X else X XDrawLine (mainDisplay, drawWindow, defaultGC, x_end, 0, x_end, X drawWinH>>zoomScale); X } X else if (drawOrigY+drawWinH > paperHeight) X { X y_end = OFFSET_Y(paperHeight); X XDrawLine (mainDisplay, drawWindow, defaultGC, 0, y_end, X drawWinW>>zoomScale, y_end); X } X} X Xvoid RedrawAnArea (BotObj, LtX, LtY, RbX, RbY) X struct ObjRec * BotObj; X int LtX, LtY, RbX, RbY; X /* LtX, LtY, RbX, RbY are absolute coordinates */ X{ X register struct ObjRec * obj_ptr; X struct BBRec bbox; X XRectangle recs[1]; X X bbox.ltx = LtX; bbox.lty = LtY; X bbox.rbx = min(RbX, paperWidth); X bbox.rby = min(RbY, paperHeight); X X SetRecVals (recs[0], OFFSET_X(LtX), OFFSET_Y(LtY), ((RbX-LtX)>>zoomScale)+1, X ((RbY-LtY)>>zoomScale)+1); X XSetClipRectangles (mainDisplay, drawGC, 0, 0, recs, 1, YXBanded); X X XClearArea (mainDisplay, drawWindow, OFFSET_X(LtX), OFFSET_Y(LtY), X ((RbX-LtX)>>zoomScale)+1, ((RbY-LtY)>>zoomScale)+1, FALSE); X X if (paperWidth >= LtX && paperWidth < RbX || X paperHeight >= LtY && paperHeight < RbY) X DrawPaperBoundary (); X X DrawGridLines (drawWindow, LtX, LtY, RbX+(1<<zoomScale), RbY+(1<<zoomScale)); X X for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) X if (BBoxIntersect (obj_ptr->bbox, bbox) && X BBoxIntersect (obj_ptr->bbox, drawWinBBox)) X DrawObj (drawWindow, obj_ptr); X X SetDefaultDrawWinClipRecs (); X} X Xstatic Xint Inside (BBox1, BBox2) X struct BBRec BBox1, BBox2; X{ X return (BBox1.ltx >= BBox2.ltx && BBox1.lty >= BBox2.lty && X BBox1.rbx <= BBox2.rbx && BBox1.rby <= BBox2.rby); X} X Xvoid RedrawAreas (BotObj, LtX1, LtY1, RbX1, RbY1, LtX2, LtY2, RbX2, RbY2) X struct ObjRec * BotObj; X int LtX1, LtY1, RbX1, RbY1, LtX2, LtY2, RbX2, RbY2; X /* note: these coordinates are absolute */ X{ X register struct ObjRec * obj_ptr; X int ltx, lty, rbx, rby, rec1_slot, num; X struct BBRec bbox1, bbox2; X XRectangle recs[4]; X X bbox1.ltx = LtX1; bbox1.lty = LtY1; X bbox1.rbx = min(RbX1, paperWidth); X bbox1.rby = min(RbY1, paperHeight); X bbox2.ltx = LtX2; bbox2.lty = LtY2; X bbox2.rbx = min(RbX2, paperWidth); X bbox2.rby = min(RbY2, paperHeight); X X if (Inside (bbox1, bbox2)) X { X RedrawAnArea (BotObj, LtX2, LtY2, RbX2, RbY2); X return; X } X else if (Inside (bbox2, bbox1)) X { X RedrawAnArea (BotObj, LtX1, LtY1, RbX1, RbY1); X return; X } X X XClearArea (mainDisplay, drawWindow, OFFSET_X(LtX1), OFFSET_Y(LtY1), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1, FALSE); X X if (BBoxIntersect (bbox1, bbox2)) X { X ltx = min(LtX1,LtX2); lty = min(LtY1,LtY2); X rbx = max(RbX1,RbX2); rby = max(RbY1,RbY2); X RedrawAnArea (BotObj, ltx, lty, rbx, rby); X return; X } X X if (LtY1 == LtY2) X { X rec1_slot = (LtX1 <= LtX2) ? 0 : 1; X SetRecVals (recs[rec1_slot], OFFSET_X(LtX1), OFFSET_Y(LtY1), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1); X SetRecVals (recs[!rec1_slot], OFFSET_X(LtX2), OFFSET_Y(LtY2), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1); X num = 2; X } X else X { X if (LtY1 < LtY2) X { X if (RbY1 <= LtY2) X { /* y-extents do not intersect */ X SetRecVals (recs[0], OFFSET_X(LtX1), OFFSET_Y(LtY1), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1); X SetRecVals (recs[1], OFFSET_X(LtX2), OFFSET_Y(LtY2), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1); X num = 2; X } X else if (RbY1 >= RbY2) X { /* box 2's y-extents is inside box 1's y-extents */ X rec1_slot = (LtX1 < LtX2) ? 0 : 1; X SetRecVals (recs[rec1_slot], OFFSET_X(LtX1), OFFSET_Y(LtY1), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1); X SetRecVals (recs[!rec1_slot], OFFSET_X(LtX2), OFFSET_Y(LtY2), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1); X num = 2; X } X else X { X SetRecVals (recs[0], OFFSET_X(LtX1), OFFSET_Y(LtY1), X ((RbX1-LtX1)>>zoomScale)+1, ((LtY2-LtY1)>>zoomScale)+1); X if (LtX1 < LtX2) X { X SetRecVals (recs[1], OFFSET_X(LtX1), OFFSET_Y(LtY2), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY2)>>zoomScale)+1); X SetRecVals (recs[2], OFFSET_X(LtX2), OFFSET_Y(LtY2), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY1-LtY2)>>zoomScale)+1); X } X else X { X SetRecVals (recs[1], OFFSET_X(LtX2), OFFSET_Y(LtY2), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY1-LtY2)>>zoomScale)+1); X SetRecVals (recs[2], OFFSET_X(LtX1), OFFSET_Y(LtY2), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY2)>>zoomScale)+1); X } X SetRecVals (recs[3], OFFSET_X(LtX2), OFFSET_Y(RbY1), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-RbY1)>>zoomScale)+1); X num = 4; X } X } X else X { X if (RbY2 <= LtY1) X { /* y-extents do not intersect */ X SetRecVals (recs[0], OFFSET_X(LtX2), OFFSET_Y(LtY2), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1); X SetRecVals (recs[1], OFFSET_X(LtX1), OFFSET_Y(LtY1), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1); X num = 2; X } X else if (RbY2 >= RbY1) X { /* box 1's y-extents is inside box 2's y-extents */ X rec1_slot = (LtX1 < LtX2) ? 0 : 1; X SetRecVals (recs[rec1_slot], OFFSET_X(LtX1), OFFSET_Y(LtY1), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-LtY1)>>zoomScale)+1); X SetRecVals (recs[!rec1_slot], OFFSET_X(LtX2), OFFSET_Y(LtY2), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY2)>>zoomScale)+1); X num = 2; X } X else X { X SetRecVals (recs[0], OFFSET_X(LtX2), OFFSET_Y(LtY2), X ((RbX2-LtX2)>>zoomScale)+1, ((LtY1-LtY2)>>zoomScale)+1); X if (LtX1 < LtX2) X { X SetRecVals (recs[1], OFFSET_X(LtX1), OFFSET_Y(LtY1), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY2-LtY1)>>zoomScale)+1); X SetRecVals (recs[2], OFFSET_X(LtX2), OFFSET_Y(LtY1), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY1)>>zoomScale)+1); X } X else X { X SetRecVals (recs[1], OFFSET_X(LtX2), OFFSET_Y(LtY1), X ((RbX2-LtX2)>>zoomScale)+1, ((RbY2-LtY1)>>zoomScale)+1); X SetRecVals (recs[2], OFFSET_X(LtX1), OFFSET_Y(LtY1), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY2-LtY1)>>zoomScale)+1); X } X SetRecVals (recs[3], OFFSET_X(LtX1), OFFSET_Y(RbY2), X ((RbX1-LtX1)>>zoomScale)+1, ((RbY1-RbY2)>>zoomScale)+1); X num = 4; X } X } X } X XSetClipRectangles (mainDisplay, drawGC, 0, 0, recs, num, YXSorted); X X if (paperWidth >= LtX1 && paperWidth < RbX1 || X paperHeight >= LtY1 && paperHeight < RbY1 || X paperWidth >= LtX2 && paperWidth < RbX2 || X paperHeight >= LtY2 && paperHeight < RbY2) X DrawPaperBoundary (); X X DrawGridLines (drawWindow, LtX1, LtY1, RbX1+(1<<zoomScale), X RbY1+(1<<zoomScale)); X DrawGridLines (drawWindow, LtX2, LtY2, RbX2+(1<<zoomScale), X RbY2+(1<<zoomScale)); X X for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) X { X if (BBoxIntersect (obj_ptr->bbox, drawWinBBox) && X (BBoxIntersect (obj_ptr->bbox, bbox1) || X BBoxIntersect (obj_ptr->bbox, bbox2))) X DrawObj (drawWindow, obj_ptr); X } X X SetDefaultDrawWinClipRecs (); X} X XPixmap DrawAllOnPixmap (LtX, LtY, W, H) X int *LtX, *LtY, *W, *H; X{ X register int i; X register struct ObjRec * obj_ptr; X int len, ltx, lty, rbx, rby, w, h; X int saved_draw_orig_x, saved_draw_orig_y; X int saved_draw_win_w, saved_draw_win_h; X int saved_zoom_scale; X char msg[MAXSTRING]; X Pixmap pixmap; X XGCValues values; X X ltx = botObj->bbox.ltx; lty = botObj->bbox.lty; X rbx = botObj->bbox.rbx; rby = botObj->bbox.rby; X for (obj_ptr = botObj->prev; obj_ptr != NULL; obj_ptr = obj_ptr->prev) X { X if (obj_ptr->bbox.ltx < ltx) ltx = obj_ptr->bbox.ltx; X if (obj_ptr->bbox.lty < lty) lty = obj_ptr->bbox.lty; X if (obj_ptr->bbox.rbx > rbx) rbx = obj_ptr->bbox.rbx; X if (obj_ptr->bbox.rby > rby) rby = obj_ptr->bbox.rby; X } X *W = w = rbx - ltx; X *H = h = rby - lty; X *LtX = ltx; X *LtY = lty; X X saved_draw_orig_x = drawOrigX; saved_draw_orig_y = drawOrigY; X saved_draw_win_w = drawWinW; saved_draw_win_h = drawWinH; X saved_zoom_scale = zoomScale; X X drawOrigX = ltx; drawOrigY = lty; X drawWinW = w; drawWinH = h; X zoomScale = 0; X X pixmap = XCreatePixmap (mainDisplay, mainWindow, w, h, mainDepth); X X if (pixmap == None) X { X sprintf (msg, "Can not allocate pixmap of size %1dx%1d.", w, h); X Msg (msg); X return (None); X } X X values.foreground = myBgPixel; X values.function = GXcopy; X values.fill_style = FillSolid; X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle, &values); X XFillRectangle (mainDisplay, pixmap, drawGC, 0, 0, w, h); X X AdjSplineVs (); X X for (obj_ptr = botObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) X DrawObj (pixmap, obj_ptr); X X drawOrigX = saved_draw_orig_x; drawOrigY = saved_draw_orig_y; X drawWinW = saved_draw_win_w; drawWinH = saved_draw_win_h; X zoomScale = saved_zoom_scale; X X AdjSplineVs (); X X return (pixmap); X} X Xvoid RedrawDrawWindow (BotObj) X struct ObjRec * BotObj; X{ X register struct ObjRec * obj_ptr; X X DrawPaperBoundary (); X RedrawGridLines (); X X for (obj_ptr = BotObj; obj_ptr != NULL; obj_ptr = obj_ptr->prev) X if (PointInBBox (obj_ptr->x, obj_ptr->y, drawWinBBox) || X BBoxIntersect (obj_ptr->bbox, drawWinBBox)) X DrawObj (drawWindow, obj_ptr); X} X Xvoid ClearAndRedrawDrawWindow () X{ X XClearWindow (mainDisplay, drawWindow); X RedrawDrawWindow (botObj); X RedrawCurText (); X HighLightForward (); X} X Xvoid CleanUpDrawingWindow () X{ X HighLightReverse (); X RemoveAllSel (); X DelAllObj (); X ClearCurText (); X SetCurChoice (NOTHING); X} X Xint ShortHand (input) X XEvent * input; X /* returns BAD if the character is a <CONTROL> or a <META> character */ X /* returns INVALID if the character is a normal character */ X /* otherwise, returns the value of sub-functions, such as QuitProc () */ X{ X int x, y; X char buf[80]; X KeySym key_sym; X XComposeStatus c_stat; X XKeyEvent * key_ev; X X key_ev = &(input->xkey); X XLookupString (key_ev, buf, 80, &key_sym, &c_stat); X if ((key_sym>='\040' && key_sym<='\177' || X key_sym>='\240' && key_sym<='\377') && X (key_ev->state & (ControlMask | Mod1Mask))) X { X Msg (""); X if ((key_ev->state & ControlMask) && (!(key_ev->state & Mod1Mask))) X { X switch (buf[0]) X { X case '\001': /*^A*/ SelAllObj (); break; X case '\002': /*^B*/ BackProc (); break; X case '\003': /*^C*/ ChangeDomain (); break; X case '\004': /*^D*/ DupSelObj (); break; X case '\005': /*^E*/ break; X case '\006': /*^F*/ FrontProc (); break; X case '\007': /*^G*/ GroupSelObj (); break; X case '\010': /*^H*/ return (INVALID); X case '\011': /*^I*/ Instantiate (); break; X case '\012': /*^J*/ return (INVALID); X case '\013': /*^K*/ PopIcon (); break; X case '\014': /*^L*/ AlignSelObjs (); break; X case '\015': /*^M*/ return (INVALID); X case '\016': /*^N*/ NewProc (); break; X case '\017': /*^O*/ OpenProc (); break; X case '\020': /*^P*/ Dump (FALSE, ""); break; X case '\021': /*^Q*/ return (QuitProc ()); X case '\022': /*^R*/ ClearAndRedrawDrawWindow (); break; X case '\023': /*^S*/ SaveFile (); break; X case '\024': /*^T*/ AlignSelToGrid (); break; X case '\025': /*^U*/ UngroupSelObj (); break; X case '\026': /*^V*/ PushIcon (); break; X case '\027': /*^W*/ SetCurChoice (DRAWTEXT); break; X case '\030': /*^X*/ DelAllSelObj (); break; X case '\031': /*^Y*/ CopyToCutBuffer (); break; X case '\032': /*^Z*/ return (AnimateProc ()); X case ',': /*^,*/ ScrollLeft (); break; X case '.': /*^.*/ ScrollRight (); break; X case '-': /*^-*/ PrintWithCommand (FALSE, ""); break; X } X } X else if ((key_ev->state & Mod1Mask) && (!(key_ev->state & ControlMask))) X { X switch (buf[0]) X { X case 'a': /*#A*/ AddAttrs (); break; X case 'b': /*#B*/ return (ProbeProc ()); X case 'c': /*#C*/ RotateCounter (); break; X case 'd': /*#D*/ DecGrid (); break; X case 'e': /*#E*/ AnimateSel (); break; X case 'f': /*#F*/ FlashSelColor (); break; X case 'g': /*#G*/ ToggleGridShown (); break; X case 'h': /*#H*/ FlipHorizontal (); break; X case 'i': /*#I*/ IncGrid (); break; X case 'j': /*#J*/ HideAllAttrNames (); break; X case 'k': /*#K*/ SetCurChoice (NOTHING); break; X case 'l': /*#L*/ CornerLoop (&x, &y); LineStyleMenu (x, y); break; X case 'm': /*#M*/ MoveAttr (); break; X case 'n': /*#N*/ ShowAllAttrNames (); break; X case 'o': /*#O*/ ZoomOut (); break; X case 'p': /*#P*/ ImportFile (); break; X case 'q': /*#Q*/ SetCurChoice (DRAWPOLY); break; X case 'r': /*#R*/ SetCurChoice (DRAWBOX); break; X case 's': /*#S*/ return (SolveProc ()); X case 't': /*#T*/ DetachAttrs (); break; X case 'u': /*#U*/ UndoDelete (); break; X case 'v': /*#V*/ FlipVertical (); break; X case 'w': /*#W*/ RotateClockWise (); break; X case 'x': /*#X*/ return (EscapeProc ()); X case 'y': /*#Y*/ return (SimulateProc ()); X case 'z': /*#Z*/ ZoomIn (); break; X case '0': /*#0*/ ChangeFontSize (0); break; X case '1': /*#1*/ ChangeFontSize (1); break; X case '2': /*#2*/ ChangeFontSize (2); break; X case '3': /*#3*/ ChangeFontSize (3); break; X case '4': /*#4*/ ChangeFontSize (4); break; X case '5': /*#5*/ ChangeFontSize (5); break; X case ',': /*#,*/ ScrollUp (); break; X case '.': /*#.*/ ScrollDown (); break; X } X } X else if ((key_ev->state & Mod1Mask) && (key_ev->state & ControlMask)) X { X switch (buf[0]) X { X case '\001': /*^#A*/ AddPoint (); break; X case '\002': /*^#B*/ ChangeFontStyle (STYLE_BR); break; X case '\003': /*^#C*/ ChangeFontJust (JUST_C); break; X case '\004': /*^#D*/ DeletePoint (); break; X case '\005': /*^#E*/ SetCurChoice (DRAWRCBOX); break; X case '\006': /*^#F*/ InvertXBitmaps (); break; X case '\007': /*^#G*/ ToggleSnapOn (); break; X case '\010': /*^#H*/ break; X case '\011': /*^#I*/ MakeIconic (); break; X case '\012': /*^#J*/ UnMakeIconic (); break; X case '\013': /*^#K*/ ToggleColorPostScript (); break; X case '\014': /*^#L*/ ChangeFontJust (JUST_L); break; X case '\015': /*^#M*/ MakeSymbolic (); break; X case '\016': /*^#N*/ UnMakeSymbolic (); break; X case '\017': /*^#O*/ ChangeFontStyle (STYLE_NR); break; X case '\020': /*^#P*/ ChangeFontStyle (STYLE_BI); break; X case '\021': /*^#Q*/ SetCurChoice (DRAWPOLYGON); break; X case '\022': /*^#R*/ ChangeFontJust (JUST_R); break; X case '\023': /*^#S*/ SaveNewFile (); break; X case '\024': /*^#T*/ ChangeFontStyle (STYLE_NI); break; X case '\025': /*^#U*/ UpdateSymbols (); break; X case '\026': /*^#V*/ SetCurChoice (DRAWCIRCLE); break; X case '\027': /*^#W*/ ToggleAllSelLineType (); break; X case '\030': /*^#X*/ ToggleWhereToPrint (); break; X case '\031': /*^#Y*/ PasteFromCutBuffer (); break; X case '\032': /*^#Z*/ SetCurChoice (DRAWARC); break; X case '.': /*^#.*/ ImportXBitmapFile (); break; X } X } X return (BAD); X } X return (INVALID); X} X Xstatic Xint SomethingDirty () X{ X register struct ObjRec * obj_ptr = topObj; X X for ( ; obj_ptr != NULL; obj_ptr = obj_ptr->next) X if (obj_ptr->dirty) X return (TRUE); X return (FALSE); X} X Xint DrawingEventHandler (input) X XEvent * input; X{ X int mouse_x, mouse_y, grid_x, grid_y; X XEvent ev; X XButtonEvent * button_ev; X X if (input->type == Expose) X { X XSync (mainDisplay, FALSE); X while (XCheckWindowEvent (mainDisplay, drawWindow, ExposureMask, &ev)) ; X X if (topSel != NULL || SomethingDirty ()) X ClearAndRedrawDrawWindow (); X else X { X RedrawDrawWindow (botObj); X RedrawCurText (); X } X return (INVALID); X } X else if (input->type == MotionNotify) X { X while (XCheckWindowEvent (mainDisplay,drawWindow,PointerMotionMask,&ev)) ; X X mouse_x = (input->xmotion).x; X mouse_y = (input->xmotion).y; X GridXY (mouse_x, mouse_y, &grid_x, &grid_y); X MarkRulers (grid_x, grid_y); X return (INVALID); X } X X if (input->type == ButtonPress) X { X button_ev = &(input->xbutton); X if ((button_ev->button == Button3) && (button_ev->state & ShiftMask)) X { X SetCurChoice (NOTHING); X return (INVALID); X } X else if (button_ev->button == Button3) X return (MainMenu (button_ev)); X } X X Msg (""); X switch(curChoice) X { X case NOTHING: Select (input); break; X case DRAWTEXT: DrawText (input); break; X case DRAWBOX: DrawBox (input); break; X case DRAWCIRCLE: DrawOval (input); break; X case DRAWPOLY: DrawPoly (input); break; X case DRAWPOLYGON: DrawPolygon (input); break; X case DRAWARC: DrawArc (input); break; X case DRAWRCBOX: DrawRCBox (input); break; X } X return (INVALID); X} END_OF_FILE if test 24657 -ne `wc -c <'drawing.c'`; then echo shar: \"'drawing.c'\" unpacked with wrong size! fi # end of 'drawing.c' fi if test -f 'dup.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dup.c'\" else echo shar: Extracting \"'dup.c'\" \(11685 characters\) sed "s/^X//" >'dup.c' <<'END_OF_FILE' X/* X * Author: William Chia-Wei Cheng (william@cs.ucla.edu) X * X * Copyright (C) 1990, 1991, William Cheng. X */ X#ifndef lint Xstatic char RCSid[] = X "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/dup.c,v 2.0 91/03/05 12:47:04 william Exp $"; X#endif X X#include <X11/Xlib.h> X#include "const.h" X#include "types.h" X X#include "attr.e" X#include "drawing.e" X#include "grid.e" X#include "obj.e" X#include "raster.e" X#include "select.e" X#include "setup.e" X#include "xbitmap.e" X Xextern struct ObjRec * DupObj (); X Xint justDupped = FALSE; Xint dupDx = INVALID, dupDy = INVALID; X Xvoid DupObjBasics (FromObjPtr, ToObjPtr) X register struct ObjRec * FromObjPtr, * ToObjPtr; X{ X ToObjPtr->x = FromObjPtr->x; X ToObjPtr->y = FromObjPtr->y; X ToObjPtr->color = FromObjPtr->color; X ToObjPtr->id = objId++; X ToObjPtr->dirty = FALSE; X ToObjPtr->type = FromObjPtr->type; X ToObjPtr->bbox.ltx = FromObjPtr->bbox.ltx; X ToObjPtr->bbox.lty = FromObjPtr->bbox.lty; X ToObjPtr->bbox.rbx = FromObjPtr->bbox.rbx; X ToObjPtr->bbox.rby = FromObjPtr->bbox.rby; X ToObjPtr->obbox.ltx = FromObjPtr->obbox.ltx; X ToObjPtr->obbox.lty = FromObjPtr->obbox.lty; X ToObjPtr->obbox.rbx = FromObjPtr->obbox.rbx; X ToObjPtr->obbox.rby = FromObjPtr->obbox.rby; X} X Xstatic Xvoid DupPolyObj (PolyPtr, ObjPtr) X struct PolyRec * PolyPtr; X struct ObjRec * ObjPtr; X{ X register int i, num_pts; X register struct PolyRec * poly_ptr; X register XPoint * v; X X poly_ptr = (struct PolyRec *) calloc (1, sizeof(struct PolyRec)); X num_pts = poly_ptr->n = PolyPtr->n; X v = (XPoint *) calloc (num_pts+1, sizeof(XPoint)); X for (i = 0; i < num_pts; i++) X { X v[i].x = PolyPtr->vlist[i].x; X v[i].y = PolyPtr->vlist[i].y; X } X poly_ptr->vlist = v; X poly_ptr->style = PolyPtr->style; X poly_ptr->width = PolyPtr->width; X poly_ptr->pen = PolyPtr->pen; X poly_ptr->fill = PolyPtr->fill; X if ((poly_ptr->curved = PolyPtr->curved) == LT_SPLINE) X { X poly_ptr->sn = num_pts = PolyPtr->sn; X v = (XPoint *) calloc (num_pts+1, sizeof(XPoint)); X for (i = 0; i < num_pts; i++) X { X v[i].x = PolyPtr->svlist[i].x; X v[i].y = PolyPtr->svlist[i].y; X } X poly_ptr->svlist = v; X } X poly_ptr->dash = PolyPtr->dash; X X ObjPtr->detail.p = poly_ptr; X} X Xstatic Xvoid DupPolygonObj (PolygonPtr, ObjPtr) X struct PolygonRec * PolygonPtr; X struct ObjRec * ObjPtr; X{ X register int i, num_pts; X register struct PolygonRec * polygon_ptr; X XPoint * v; X X polygon_ptr = (struct PolygonRec *) calloc (1, sizeof(struct PolygonRec)); X num_pts = polygon_ptr->n = PolygonPtr->n; X v = (XPoint *) calloc (num_pts+1, sizeof(XPoint)); X for (i = 0; i < num_pts; i++) X { X v[i].x = PolygonPtr->vlist[i].x; X v[i].y = PolygonPtr->vlist[i].y; X } X polygon_ptr->vlist = v; X polygon_ptr->fill = PolygonPtr->fill; X polygon_ptr->width = PolygonPtr->width; X polygon_ptr->pen = PolygonPtr->pen; X if ((polygon_ptr->curved = PolygonPtr->curved) == LT_SPLINE) X { X polygon_ptr->sn = num_pts = PolygonPtr->sn; X v = (XPoint *) calloc (num_pts, sizeof(XPoint)); X for (i = 0; i < num_pts; i++) X { X v[i].x = PolygonPtr->svlist[i].x; X v[i].y = PolygonPtr->svlist[i].y; X } X polygon_ptr->svlist = v; X } X polygon_ptr->dash = PolygonPtr->dash; X X ObjPtr->detail.g = polygon_ptr; X} X Xstatic Xvoid DupOvalObj (OvalPtr, ObjPtr) X struct OvalRec * OvalPtr; X struct ObjRec * ObjPtr; X{ X register struct OvalRec * oval_ptr; X X oval_ptr = (struct OvalRec *) calloc (1, sizeof(struct OvalRec)); X oval_ptr->fill = OvalPtr->fill; X oval_ptr->width = OvalPtr->width; X oval_ptr->pen = OvalPtr->pen; X oval_ptr->dash = OvalPtr->dash; X X ObjPtr->detail.o = oval_ptr; X} X Xstatic Xvoid DupBoxObj (BoxPtr, ObjPtr) X struct BoxRec * BoxPtr; X struct ObjRec * ObjPtr; X{ X register struct BoxRec * box_ptr; X X box_ptr = (struct BoxRec *) calloc (1, sizeof(struct BoxRec)); X box_ptr->fill = BoxPtr->fill; X box_ptr->width = BoxPtr->width; X box_ptr->pen = BoxPtr->pen; X box_ptr->dash = BoxPtr->dash; X X ObjPtr->detail.b = box_ptr; X} X Xstatic Xvoid DupRCBoxObj (RCBoxPtr, ObjPtr) X struct RCBoxRec * RCBoxPtr; X struct ObjRec * ObjPtr; X{ X register struct RCBoxRec * rcbox_ptr; X X rcbox_ptr = (struct RCBoxRec *) calloc (1, sizeof(struct RCBoxRec)); X rcbox_ptr->fill = RCBoxPtr->fill; X rcbox_ptr->width = RCBoxPtr->width; X rcbox_ptr->pen = RCBoxPtr->pen; X rcbox_ptr->dash = RCBoxPtr->dash; X rcbox_ptr->radius = RCBoxPtr->radius; X X ObjPtr->detail.rcb = rcbox_ptr; X} X Xstatic Xvoid DupArcObj (ArcPtr, ObjPtr) X struct ArcRec * ArcPtr; X struct ObjRec * ObjPtr; X{ X register struct ArcRec * arc_ptr; X X arc_ptr = (struct ArcRec *) calloc (1, sizeof(struct ArcRec)); X arc_ptr->fill = ArcPtr->fill; X arc_ptr->width = ArcPtr->width; X arc_ptr->pen = ArcPtr->pen; X arc_ptr->dash = ArcPtr->dash; X X arc_ptr->xc = ArcPtr->xc; arc_ptr->yc = ArcPtr->yc; X arc_ptr->x1 = ArcPtr->x1; arc_ptr->y1 = ArcPtr->y1; X arc_ptr->x2 = ArcPtr->x2; arc_ptr->y2 = ArcPtr->y2; X arc_ptr->dir = ArcPtr->dir; X arc_ptr->ltx = ArcPtr->ltx; arc_ptr->lty = ArcPtr->lty; X arc_ptr->w = ArcPtr->w; arc_ptr->h = ArcPtr->h; X arc_ptr->angle1 = ArcPtr->angle1; arc_ptr->angle2 = ArcPtr->angle2; X X ObjPtr->detail.a = arc_ptr; X} X Xstatic Xvoid DupXBmObj (XBmPtr, ObjPtr) X struct XBmRec * XBmPtr; X struct ObjRec * ObjPtr; X{ X register struct XBmRec * xbm_ptr; X Pixmap bitmap; X int w, h; X X w = ObjPtr->obbox.rbx - ObjPtr->obbox.ltx; X h = ObjPtr->obbox.rby - ObjPtr->obbox.lty; X X bitmap = XCreatePixmap (mainDisplay, mainWindow, w, h, 1); X XCopyArea (mainDisplay, XBmPtr->bitmap, bitmap, xbmGC, 0, 0, w, h, 0, 0); X X xbm_ptr = (struct XBmRec *) calloc (1, sizeof(struct XBmRec)); X xbm_ptr->bitmap = bitmap; X xbm_ptr->data = NULL; X xbm_ptr->fill = XBmPtr->fill; X ObjPtr->detail.xbm = xbm_ptr; X} X Xvoid DupTextObj (TextPtr, ObjPtr) X struct TextRec * TextPtr; X struct ObjRec * ObjPtr; X{ X register int i, num_lines; X register struct TextRec * text_ptr; X struct StrRec * first_str; X struct StrRec * from_str_ptr, * to_str_ptr; X X text_ptr = (struct TextRec *) calloc (1, sizeof(struct TextRec)); X text_ptr->just = TextPtr->just; X num_lines = text_ptr->lines = TextPtr->lines; X from_str_ptr = TextPtr->last; X first_str = NULL; X for (i = 0; i < num_lines; i++, from_str_ptr = from_str_ptr->prev) X { X to_str_ptr = (struct StrRec *) calloc (1, sizeof(struct StrRec)); X strcpy (to_str_ptr->s, from_str_ptr->s); X to_str_ptr->next = first_str; X if (first_str == NULL) X text_ptr->last = to_str_ptr; X else X first_str->prev = to_str_ptr; X first_str = to_str_ptr; X } X first_str->prev = NULL; X text_ptr->first = first_str; X X text_ptr->font = TextPtr->font; X text_ptr->dpi = TextPtr->dpi; X text_ptr->style = TextPtr->style; X text_ptr->size = TextPtr->size; X text_ptr->rotate = TextPtr->rotate; X text_ptr->pen = TextPtr->pen; X text_ptr->asc = TextPtr->asc; X text_ptr->des = TextPtr->des; X X ObjPtr->detail.t = text_ptr; X} X Xstatic Xvoid DupGroupObj (GroupPtr, ObjPtr) X struct GroupRec * GroupPtr; X struct ObjRec * ObjPtr; X{ X register struct GroupRec * group_ptr; X struct ObjRec * top_obj, * bot_obj; X struct ObjRec * from_obj_ptr, * to_obj_ptr; X X group_ptr = (struct GroupRec *) calloc (1, sizeof(struct GroupRec)); X top_obj = bot_obj = NULL; X from_obj_ptr = GroupPtr->last; X for ( ; from_obj_ptr != NULL; from_obj_ptr = from_obj_ptr->prev) X { X to_obj_ptr = DupObj (from_obj_ptr); X to_obj_ptr->next = top_obj; X if (top_obj == NULL) X group_ptr->last = to_obj_ptr; X else X top_obj->prev = to_obj_ptr; X top_obj = to_obj_ptr; X } X top_obj->prev = NULL; X group_ptr->first = top_obj; X X ObjPtr->detail.r = group_ptr; X} X Xstruct ObjRec * DupObj (ObjPtr) X struct ObjRec * ObjPtr; X{ X struct ObjRec * obj_ptr; X X obj_ptr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec)); X DupObjBasics (ObjPtr, obj_ptr); X X switch (ObjPtr->type) X { X case OBJ_POLY: X DupPolyObj (ObjPtr->detail.p, obj_ptr); X DupAttrs (ObjPtr, obj_ptr); X break; X case OBJ_BOX: X DupBoxObj (ObjPtr->detail.b, obj_ptr); X DupAttrs (ObjPtr, obj_ptr); X break; X case OBJ_OVAL: X DupOvalObj (ObjPtr->detail.o, obj_ptr); X DupAttrs (ObjPtr, obj_ptr); X break; X case OBJ_TEXT: DupTextObj (ObjPtr->detail.t, obj_ptr); break; X case OBJ_POLYGON: X DupPolygonObj (ObjPtr->detail.g, obj_ptr); X DupAttrs (ObjPtr, obj_ptr); X break; X case OBJ_ARC: X DupArcObj (ObjPtr->detail.a, obj_ptr); X DupAttrs (ObjPtr, obj_ptr); X break; X case OBJ_RCBOX: X DupRCBoxObj (ObjPtr->detail.rcb, obj_ptr); X DupAttrs (ObjPtr, obj_ptr); X break; X case OBJ_XBM: X DupXBmObj (ObjPtr->detail.xbm, obj_ptr); X DupAttrs (ObjPtr, obj_ptr); X break; X case OBJ_SYM: X case OBJ_GROUP: X case OBJ_ICON: X DupGroupObj (ObjPtr->detail.r, obj_ptr); X DupAttrs (ObjPtr, obj_ptr); X if (obj_ptr->type == OBJ_ICON) X strcpy (obj_ptr->detail.r->s, ObjPtr->detail.r->s); X break; X } X return (obj_ptr); X} X Xvoid DupSelObj () X{ X struct SelRec * sel_ptr, * sel_ptr1; X struct ObjRec * obj_ptr, * top_obj, * bot_obj; X int dx, dy; X X if (topSel == NULL) return; X X top_obj = bot_obj = NULL; X for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev) X { X obj_ptr = DupObj (sel_ptr->obj); X obj_ptr->next = top_obj; X if (top_obj == NULL) X bot_obj = obj_ptr; X else X top_obj->prev = obj_ptr; X top_obj = obj_ptr; X } X top_obj->prev = NULL; X X HighLightReverse (); X X sel_ptr = botSel; X sel_ptr1 = sel_ptr->prev; X for (obj_ptr = bot_obj; sel_ptr1 != NULL; obj_ptr = obj_ptr->prev) X { X sel_ptr->obj = obj_ptr; X sel_ptr = sel_ptr1; X sel_ptr1 = sel_ptr1->prev; X } X sel_ptr->obj = obj_ptr; X X bot_obj->next = topObj; X topObj->prev = bot_obj; X topObj = top_obj; X X if (justDupped) X { X dx = dupDx; X dy = dupDy; X } X else X { X if (gridOn) X dupDx = dupDy = dx = dy = xyGrid << zoomScale; X else X dupDx = dupDy = dx = dy = DEFAULT_GRID << zoomScale; X justDupped = TRUE; X } X X selLtX += dx; selLtY += dy; selRbX += dx; selRbY += dy; X selObjLtX += dx; selObjLtY += dy; selObjRbX += dx; selObjRbY += dy; X X MoveAllSel (dx, dy); X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale), X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale)); X HighLightForward (); X SetFileModified (TRUE); X} X Xvoid JustDupSelObj (NewTopSel, NewBotSel) X struct SelRec * * NewTopSel, * * NewBotSel; X{ X struct SelRec * sel_ptr, * new_sel_ptr; X struct ObjRec * obj_ptr, * top_obj, * bot_obj; X X *NewTopSel = *NewBotSel = NULL; X if (topSel == NULL) return; X X top_obj = bot_obj = NULL; X for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev) X { X obj_ptr = DupObj (sel_ptr->obj); X obj_ptr->next = top_obj; X new_sel_ptr = (struct SelRec *) calloc (1, sizeof (struct SelRec)); X new_sel_ptr->next = *NewTopSel; X new_sel_ptr->obj = obj_ptr; X if (top_obj == NULL) X { X bot_obj = obj_ptr; X *NewBotSel = new_sel_ptr; X } X else X { X top_obj->prev = obj_ptr; X (*NewTopSel)->prev = new_sel_ptr; X } X top_obj = obj_ptr; X *NewTopSel = new_sel_ptr; X } X top_obj->prev = NULL; X (*NewTopSel)->prev = NULL; X} END_OF_FILE if test 11685 -ne `wc -c <'dup.c'`; then echo shar: \"'dup.c'\" unpacked with wrong size! fi # end of 'dup.c' fi if test -f 'edit.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'edit.c'\" else echo shar: Extracting \"'edit.c'\" \(29266 characters\) sed "s/^X//" >'edit.c' <<'END_OF_FILE' X/* X * Author: William Chia-Wei Cheng (william@cs.ucla.edu) X * X * Copyright (C) 1990, 1991, William Cheng. X */ X#ifndef lint Xstatic char RCSid[] = X "@(#)$Header: /tmp_mnt/n/kona/tangram/u/william/X11/TGIF2/RCS/edit.c,v 2.0 91/03/05 12:47:06 william Exp $"; X#endif X X#include <stdio.h> X#include <math.h> X#include <X11/Xlib.h> X#include "const.h" X#include "types.h" X X#include "align.e" X#include "color.e" X#include "copypaste.e" X#include "cursor.e" X#include "drawing.e" X#include "dup.e" X#include "font.e" X#include "group.e" X#include "mark.e" X#include "obj.e" X#include "poly.e" X#include "raster.e" X#include "select.e" X#include "setup.e" X#include "special.e" X#include "spline.e" X#include "stretch.e" X#include "xbitmap.e" X X#ifndef M_PI X#define M_PI 3.14159265358979323846 X#endif X X#define MARK(X,Y) \ X XFillRectangle(mainDisplay,drawWindow,revDefaultGC,(X)-2,(Y)-2,5,5) X#define MyDashedLine(W,GC,V,N) XDrawLines (mainDisplay, W, GC, V, N, \ X CoordModeOrigin) X X#define EDIT_REDRAW 0 X#define EDIT_DUP 1 X#define EDIT_DELETE 2 X#define EDIT_SELALL 3 X#define EDIT_UNDODEL 4 X#define EDIT_DEL_POINT 5 X#define EDIT_ADD_POINT 6 X#define EDIT_COPY 7 X#define EDIT_PASTE 8 X#define EDIT_INV_XBM 9 X X#define MAXEDITMENUS 10 X Xstatic char * editMenuStr[] = X { "Redraw ^R", X "Duplicate ^D", X "Delete ^X", X "SelectAll ^A", X "UndoDelete #U", X "DeletePoint ^#D", X "AddPoint ^#A", X "Copy ^Y", X "Paste ^#Y", X "InvertXBitmap ^#F" X }; X Xvoid DeletePoint () X{ X register int i; X register struct ObjRec * obj_ptr; X struct PolyRec * poly_ptr = NULL; X struct PolygonRec * polygon_ptr = NULL; X int index, n, point_deleted, deleting = TRUE; X int root_x, root_y, old_x, old_y; X unsigned int status; X Window root_win, child_win; X XEvent input, ev; X X if (!(topSel != NULL && topSel == botSel && X (topSel->obj->type == OBJ_POLY || topSel->obj->type == OBJ_POLYGON))) X { X Msg ("Please select only one POLY or POLYGON object."); X return; X } X X obj_ptr = topSel->obj; X switch (obj_ptr->type) X { X case OBJ_POLY: poly_ptr = obj_ptr->detail.p; break; X case OBJ_POLYGON: polygon_ptr = obj_ptr->detail.g; break; X } X TwoLineMsg ("Click left mouse button to DELETE points.", X "Click other buttons to quit."); X X XGrabPointer (mainDisplay, drawWindow, False, X PointerMotionMask | ButtonPressMask, X GrabModeAsync, GrabModeAsync, None, defaultCursor, CurrentTime); X XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win, X &root_x, &root_y, &old_x, &old_y, &status); X XSetFont (mainDisplay, revDefaultGC, defaultFontPtr->fid); X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "DEL", 3); X MarkRulers (old_x, old_y); X X while (deleting) X { X XNextEvent (mainDisplay, &input); X if (input.type == ButtonPress) X { X if (input.xbutton.button == Button1) X { X point_deleted = FALSE; X if (obj_ptr->type == OBJ_POLY && X PtInPolyMark (input.xbutton.x, input.xbutton.y, X poly_ptr->n, poly_ptr->vlist, &index) || X obj_ptr->type == OBJ_POLYGON && X PtInPolyMark (input.xbutton.x, input.xbutton.y, X polygon_ptr->n-1, polygon_ptr->vlist, &index)) X { X point_deleted = TRUE; X HighLightReverse (); X if (obj_ptr->type == OBJ_POLY && poly_ptr->n == 2 || X obj_ptr->type == OBJ_POLYGON && polygon_ptr->n == 4) X { X CopySelToCut (); X DelObj (obj_ptr); X deleting = FALSE; X obj_ptr = NULL; X cfree (topSel); X topSel = botSel = NULL; X } X else X { X switch (obj_ptr->type) X { X case OBJ_POLY: X n = poly_ptr->n; X for (i = index+1; i < n; i++) X poly_ptr->vlist[i-1] = poly_ptr->vlist[i]; X poly_ptr->n--; X if (poly_ptr->curved) X { X cfree (poly_ptr->svlist); X poly_ptr->svlist = MakeSplinePolyVertex ( X &(poly_ptr->sn), drawOrigX, drawOrigY, X poly_ptr->n, poly_ptr->vlist); X } X UpdPolyBBox (obj_ptr, poly_ptr->n, poly_ptr->vlist); X break; X case OBJ_POLYGON: X n = polygon_ptr->n; X for (i = index+1; i < n; i++) X polygon_ptr->vlist[i-1] = polygon_ptr->vlist[i]; X polygon_ptr->n--; X n--; X if (index == 0) X polygon_ptr->vlist[n-1] = polygon_ptr->vlist[0]; X if (polygon_ptr->curved) X { X cfree (polygon_ptr->svlist); X polygon_ptr->svlist = MakeSplinePolygonVertex ( X &(polygon_ptr->sn), drawOrigX, drawOrigY, X polygon_ptr->n, polygon_ptr->vlist); X } X UpdPolyBBox (obj_ptr, polygon_ptr->n, X polygon_ptr->vlist); X break; X } X AdjObjBBox (obj_ptr); X } X } X if (point_deleted) X { X XDrawString (mainDisplay, drawWindow, revDefaultGC, old_x+4, X old_y+defaultFontAsc, "DEL", 3); X old_x = input.xbutton.x; X old_y = input.xbutton.y; X RedrawAnArea (botObj, X selLtX-(1<<zoomScale), selLtY-(1<<zoomScale), X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale)); X HighLightForward (); X if (obj_ptr != NULL) X XDrawString (mainDisplay, drawWindow, revDefaultGC, old_x+4, X old_y+defaultFontAsc, "DEL", 3); X UpdSelBBox (); X SetFileModified (TRUE); X } X } X else X { X deleting = FALSE; X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "DEL", 3); X } X } X else if (input.type == MotionNotify) X { X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "DEL", 3); X old_x = input.xmotion.x; X old_y = input.xmotion.y; X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "DEL", 3); X MarkRulers (old_x, old_y); X while (XCheckMaskEvent (mainDisplay, PointerMotionMask, &ev)) ; X } X } X XUngrabPointer (mainDisplay, CurrentTime); X Msg (""); X} X Xstatic Xvoid ContinueAddPolyPoint (ObjPtr, MouseX, MouseY, Index, PolyPtr, X LastMouseX, LastMouseY) X struct ObjRec * ObjPtr; X int MouseX, MouseY, Index; X struct PolyRec * PolyPtr; X int * LastMouseX, * LastMouseY; X /* (MouseX,MouseY) is the mouse's origin in screen offsets */ X{ X int n = PolyPtr->n; X int already_moved = FALSE, done = FALSE, before = FALSE; X XPoint * vs = PolyPtr->vlist, v[3]; X int prev_x, prev_y, x, y, next_x, next_y, new_x, new_y; X int orig_x, orig_y, grid_x, grid_y, new_mouse_x, new_mouse_y; X int sel_ltx, sel_lty, sel_rbx, sel_rby, num = 0, i; X double prev_angle, next_angle, new_angle, theta_1, theta_2; X XEvent input, ev; X X MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y)); X X sel_ltx = selLtX; sel_lty = selLtY; X sel_rbx = selRbX; sel_rby = selRbY; X X x = vs[Index].x; X y = vs[Index].y; X X if (Index == 0) X { X next_x = vs[1].x; next_y = vs[1].y; X prev_x = 2*x-next_x; prev_y = 2*y-next_y; X } X else if (Index == n-1) X { X prev_x = vs[n-2].x; prev_y = vs[n-2].y; X next_x = 2*x-prev_x; next_y = 2*y-prev_y; X } X else X { X prev_x = vs[Index-1].x; prev_y = vs[Index-1].y; X next_x = vs[Index+1].x; next_y = vs[Index+1].y; X } X prev_angle = atan2 ((double)(prev_y-y), (double)(prev_x-x)); X next_angle = atan2 ((double)(next_y-y), (double)(next_x-x)); X X GridXY (MouseX, MouseY, &orig_x, &orig_y); X new_mouse_x = MouseX; new_mouse_y = MouseY; X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4, X new_mouse_y+defaultFontAsc, "ADD", 3); X X while (!done) X { X XNextEvent (mainDisplay, &input); X if (input.type == MotionNotify) X { X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4, X new_mouse_y+defaultFontAsc, "ADD", 3); X new_mouse_x = input.xmotion.x; X new_mouse_y = input.xmotion.y; X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4, X new_mouse_y+defaultFontAsc, "ADD", 3); X X GridXY (new_mouse_x, new_mouse_y, &grid_x, &grid_y); X new_x = ((new_mouse_x-MouseX)<<zoomScale) + x; X new_y = ((new_mouse_y-MouseY)<<zoomScale) + y; X if (!already_moved) X { X already_moved = TRUE; X X new_angle = atan2 ((double)(new_y-y), (double)(new_x-x)); X theta_1 = fabs (prev_angle - new_angle); X theta_2 = fabs (next_angle - new_angle); X if (theta_1 > M_PI) theta_1 = 2*M_PI-theta_1; X if (theta_2 > M_PI) theta_2 = 2*M_PI-theta_2; X before = (theta_1 <= theta_2); X X if (before) X { /* Add a point between the current and the previous point */ X if (Index == 0) X { X num = 2; X v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y); X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y); X } X else X { X num = 3; X v[0].x = OFFSET_X(prev_x); v[0].y = OFFSET_Y(prev_y); X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y); X v[2].x = OFFSET_X(x); v[2].y = OFFSET_Y(y); X } X } X else X { /* Add a point between the current and the next point */ X if (Index == n-1) X { X num = 2; X v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y); X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y); X } X else X { X num = 3; X v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y); X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y); X v[2].x = OFFSET_X(next_x); v[2].y = OFFSET_Y(next_y); X } X } X MyDashedLine (drawWindow, revDefaultGC, v, num); X } X else X { X MyDashedLine (drawWindow, revDefaultGC, v, num); X v[1].x = OFFSET_X(x) + grid_x - orig_x; X v[1].y = OFFSET_Y(y) + grid_y - orig_y; X MyDashedLine (drawWindow, revDefaultGC, v, num); X MarkRulers (grid_x, grid_y); X } X while (XCheckMaskEvent (mainDisplay, PointerMotionMask, &ev)) ; X } X else if (input.type == ButtonRelease) X { X done = TRUE; X *LastMouseX = new_mouse_x; *LastMouseY = new_mouse_y; X MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y)); X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4, X new_mouse_y+defaultFontAsc, "ADD", 3); X X if (!already_moved) X continue; X else X { X MyDashedLine (drawWindow, revDefaultGC, v, num); X if (grid_x == orig_x && grid_y == orig_y) X continue; X } X X HighLightReverse (); X vs = (XPoint *) realloc (vs, (n+2)*sizeof(XPoint)); X if (vs == NULL) X { X printf ("Can not realloc () in ContinueAddPolyPoint ().\n"); X exit (-1); X } X PolyPtr->vlist = vs; X if (before) X { X for (i = n-1; i >= Index; i--) vs[i+1] = vs[i]; X vs[Index].x = x + ((grid_x-orig_x)<<zoomScale); X vs[Index].y = y + ((grid_y-orig_y)<<zoomScale); X } X else X { X for (i = n-1; i > Index; i--) vs[i+1] = vs[i]; X vs[Index+1].x = x + ((grid_x-orig_x)<<zoomScale); X vs[Index+1].y = y + ((grid_y-orig_y)<<zoomScale); X } X PolyPtr->n++; X n++; X if (PolyPtr->curved) X { X cfree (PolyPtr->svlist); X PolyPtr->svlist = MakeSplinePolyVertex (&(PolyPtr->sn), X drawOrigX, drawOrigY, PolyPtr->n, PolyPtr->vlist); X } X UpdPolyBBox (ObjPtr, PolyPtr->n, PolyPtr->vlist); X AdjObjBBox (ObjPtr); X X UpdSelBBox (); X RedrawAreas (botObj, X sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale), X sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale), X selLtX-(1<<zoomScale), selLtY-(1<<zoomScale), X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale)); X HighLightForward (); X SetFileModified (TRUE); X } X } X} X Xstatic Xvoid ContinueAddPolygonPoint (ObjPtr, MouseX, MouseY, Index, PolygonPtr, X LastMouseX, LastMouseY) X struct ObjRec * ObjPtr; X int MouseX, MouseY, Index; X struct PolygonRec * PolygonPtr; X int * LastMouseX, * LastMouseY; X /* (MouseX,MouseY) is the mouse's origin in screen offsets */ X{ X int n = PolygonPtr->n; X int already_moved = FALSE, done = FALSE, before = FALSE; X XPoint * vs = PolygonPtr->vlist, v[3]; X int prev_x, prev_y, x, y, next_x, next_y, new_x, new_y; X int orig_x, orig_y, grid_x, grid_y, new_mouse_x, new_mouse_y; X int sel_ltx, sel_lty, sel_rbx, sel_rby, i; X double prev_angle, next_angle, new_angle, theta_1, theta_2; X XEvent input, ev; X X MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y)); X X sel_ltx = selLtX; sel_lty = selLtY; X sel_rbx = selRbX; sel_rby = selRbY; X X x = vs[Index].x; X y = vs[Index].y; X X if (Index == 0 || Index == n-1) X { X next_x = vs[1].x; next_y = vs[1].y; X prev_x = vs[n-2].x; prev_y = vs[n-2].y; X } X else X { X prev_x = vs[Index-1].x; prev_y = vs[Index-1].y; X next_x = vs[Index+1].x; next_y = vs[Index+1].y; X } X prev_angle = atan2 ((double)(prev_y-y), (double)(prev_x-x)); X next_angle = atan2 ((double)(next_y-y), (double)(next_x-x)); X X GridXY (MouseX, MouseY, &orig_x, &orig_y); X new_mouse_x = MouseX; new_mouse_y = MouseY; X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4, X new_mouse_y+defaultFontAsc, "ADD", 3); X X while (!done) X { X XNextEvent (mainDisplay, &input); X if (input.type == MotionNotify) X { X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4, X new_mouse_y+defaultFontAsc, "ADD", 3); X new_mouse_x = input.xmotion.x; X new_mouse_y = input.xmotion.y; X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4, X new_mouse_y+defaultFontAsc, "ADD", 3); X X GridXY (new_mouse_x, new_mouse_y, &grid_x, &grid_y); X new_x = ((new_mouse_x-MouseX)<<zoomScale) + x; X new_y = ((new_mouse_y-MouseY)<<zoomScale) + y; X if (!already_moved) X { X already_moved = TRUE; X X new_angle = atan2 ((double)(new_y-y), (double)(new_x-x)); X theta_1 = fabs (prev_angle - new_angle); X theta_2 = fabs (next_angle - new_angle); X if (theta_1 > M_PI) theta_1 = 2*M_PI-theta_1; X if (theta_2 > M_PI) theta_2 = 2*M_PI-theta_2; X before = (theta_1 <= theta_2); X X if (before) X { /* Add a point between the current and the previous point */ X v[0].x = OFFSET_X(prev_x); v[0].y = OFFSET_Y(prev_y); X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y); X v[2].x = OFFSET_X(x); v[2].y = OFFSET_Y(y); X } X else X { /* Add a point between the current and the next point */ X v[0].x = OFFSET_X(x); v[0].y = OFFSET_Y(y); X v[1].x = OFFSET_X(x); v[1].y = OFFSET_Y(y); X v[2].x = OFFSET_X(next_x); v[2].y = OFFSET_Y(next_y); X } X MyDashedLine (drawWindow, revDefaultGC, v, 3); X } X else X { X MyDashedLine (drawWindow, revDefaultGC, v, 3); X v[1].x = OFFSET_X(x) + grid_x - orig_x; X v[1].y = OFFSET_Y(y) + grid_y - orig_y; X MyDashedLine (drawWindow, revDefaultGC, v, 3); X MarkRulers (grid_x, grid_y); X } X while (XCheckMaskEvent (mainDisplay, PointerMotionMask, &ev)) ; X } X else if (input.type == ButtonRelease) X { X done = TRUE; X *LastMouseX = new_mouse_x; *LastMouseY = new_mouse_y; X MARK(OFFSET_X(vs[Index].x), OFFSET_Y(vs[Index].y)); X XDrawString (mainDisplay, drawWindow, revDefaultGC, new_mouse_x+4, X new_mouse_y+defaultFontAsc, "ADD", 3); X X if (!already_moved) X continue; X else X { X MyDashedLine (drawWindow, revDefaultGC, v, 3); X if (grid_x == orig_x && grid_y == orig_y) X continue; X } X X HighLightReverse (); X vs = (XPoint *) realloc (vs, (n+2)*sizeof(XPoint)); X if (vs == NULL) X { X printf ("Can not realloc () in ContinueAddPolygonPoint ().\n"); X exit (-1); X } X PolygonPtr->vlist = vs; X if (Index == 0 || Index == n-1) X { X if (before) X { X vs[n].x = vs[n-1].x; X vs[n].y = vs[n-1].y; X vs[n-1].x = x + ((grid_x-orig_x)<<zoomScale); X vs[n-1].y = y + ((grid_y-orig_y)<<zoomScale); X } X else X { X for (i = n-1; i > 0; i--) vs[i+1] = vs[i]; X vs[1].x = x + ((grid_x-orig_x)<<zoomScale); X vs[1].y = y + ((grid_y-orig_y)<<zoomScale); X } X } X else X { X if (before) X { X for (i = n-1; i >= Index; i--) vs[i+1] = vs[i]; X vs[Index].x = x + ((grid_x-orig_x)<<zoomScale); X vs[Index].y = y + ((grid_y-orig_y)<<zoomScale); X } X else X { X for (i = n-1; i > Index; i--) vs[i+1] = vs[i]; X vs[Index+1].x = x + ((grid_x-orig_x)<<zoomScale); X vs[Index+1].y = y + ((grid_y-orig_y)<<zoomScale); X } X } X PolygonPtr->n++; X n++; X if (PolygonPtr->curved) X { X cfree (PolygonPtr->svlist); X PolygonPtr->svlist = MakeSplinePolygonVertex (&(PolygonPtr->sn), X drawOrigX, drawOrigY, PolygonPtr->n, PolygonPtr->vlist); X } X UpdPolyBBox (ObjPtr, PolygonPtr->n, PolygonPtr->vlist); X AdjObjBBox (ObjPtr); X X UpdSelBBox (); X RedrawAreas (botObj, X sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale), X sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale), X selLtX-(1<<zoomScale), selLtY-(1<<zoomScale), X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale)); X HighLightForward (); X SetFileModified (TRUE); X } X } X} X Xvoid AddPoint () X{ X register struct ObjRec * obj_ptr; X struct PolyRec * poly_ptr = NULL; X struct PolygonRec * polygon_ptr = NULL; X int index, adding = TRUE; X int root_x, root_y, old_x, old_y; X unsigned int status; X Window root_win, child_win; X XEvent input, ev; X X if (!(topSel != NULL && topSel == botSel && X (topSel->obj->type == OBJ_POLY || topSel->obj->type == OBJ_POLYGON))) X { X Msg ("Please select only one POLY or POLYGON object."); X return; X } X X obj_ptr = topSel->obj; X switch (obj_ptr->type) X { X case OBJ_POLY: poly_ptr = obj_ptr->detail.p; break; X case OBJ_POLYGON: polygon_ptr = obj_ptr->detail.g; break; X } X TwoLineMsg ("Drag left mouse button to ADD points.", X "Click other buttons to quit."); X X XGrabPointer (mainDisplay, drawWindow, False, X PointerMotionMask | ButtonPressMask | ButtonReleaseMask, X GrabModeAsync, GrabModeAsync, None, defaultCursor, CurrentTime); X XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win, X &root_x, &root_y, &old_x, &old_y, &status); X XSetFont (mainDisplay, revDefaultGC, defaultFontPtr->fid); X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "ADD", 3); X MarkRulers (old_x, old_y); X X while (adding) X { X XNextEvent (mainDisplay, &input); X if (input.type == ButtonPress) X { X if (input.xbutton.button == Button1) X { X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "ADD", 3); X if (obj_ptr->type == OBJ_POLY && X PtInPolyMark (input.xbutton.x, input.xbutton.y, X poly_ptr->n, poly_ptr->vlist, &index)) X ContinueAddPolyPoint (obj_ptr, input.xbutton.x, input.xbutton.y, X index, poly_ptr, &old_x, &old_y); X else if (obj_ptr->type == OBJ_POLYGON && X PtInPolyMark (input.xbutton.x, input.xbutton.y, X polygon_ptr->n-1, polygon_ptr->vlist, &index)) X ContinueAddPolygonPoint (obj_ptr, input.xbutton.x, X input.xbutton.y, index, polygon_ptr, &old_x, &old_y); X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "ADD", 3); X } X else X { X adding = FALSE; X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "ADD", 3); X } X } X else if (input.type == MotionNotify) X { X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "ADD", 3); X old_x = input.xmotion.x; X old_y = input.xmotion.y; X XDrawString (mainDisplay, drawWindow, revDefaultGC, X old_x+4, old_y+defaultFontAsc, "ADD", 3); X MarkRulers (old_x, old_y); X while (XCheckMaskEvent (mainDisplay, PointerMotionMask, &ev)) ; X } X } X XUngrabPointer (mainDisplay, CurrentTime); X Msg (""); X} X Xvoid EditMenu (X, Y) X int X, Y; X{ X int index, * fore_colors, * valid; X X DefaultColorArrays (MAXEDITMENUS, &fore_colors, &valid); X index = TextMenuLoop (X, Y, editMenuStr, MAXEDITMENUS, fore_colors, valid, X SINGLECOLOR); X X switch (index) X { X case EDIT_REDRAW: ClearAndRedrawDrawWindow (); break; X case EDIT_DUP: DupSelObj (); break; X case EDIT_DELETE: DelAllSelObj (); break; X case EDIT_SELALL: SelAllObj (); break; X case EDIT_UNDODEL: UndoDelete (); break; X case EDIT_DEL_POINT: DeletePoint (); break; X case EDIT_ADD_POINT: AddPoint (); break; X case EDIT_COPY: CopyToCutBuffer (); break; X case EDIT_PASTE: PasteFromCutBuffer (); break; X case EDIT_INV_XBM: InvertXBitmaps (); break; X } X} X Xvoid FrontProc () X{ X if (topSel != NULL) X { X HighLightReverse (); X MoveSelToTop (); X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale), X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale)); X HighLightForward (); X SetFileModified (TRUE); X } X} X Xvoid BackProc () X{ X if (topSel != NULL) X { X HighLightReverse (); X MoveSelToBot (); X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale), X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale)); X HighLightForward (); X SetFileModified (TRUE); X } X} X X#define ARRANGE_FRONT 0 X#define ARRANGE_BACK 1 X#define ARRANGE_GROUP 2 X#define ARRANGE_UNGROUP 3 X#define ARRANGE_ALIGNOBJ 4 X#define ARRANGE_ALIGNGRID 5 X#define FLIP_HORIZONTAL 6 X#define FLIP_VERTICAL 7 X#define ROTATE_CLOCKWISE 8 X#define ROTATE_COUNTER 9 X#define MAXARRANGEMENUS 10 X Xstatic char * arrangeMenuStr[] = X { "Front ^F", X "Back ^B", X "Group ^G", X "UnGroup ^U", X "AlignObjs ^L", X "AlignToGrid ^T", X "FlipHorizontal #H", X "FlipVertical #V", X "RotateClockWise #W", X "RotateCounter #C", X }; X Xvoid ArrangeMenu (X, Y) X int X, Y; X{ X int index, * fore_colors, * valid; X X DefaultColorArrays (MAXARRANGEMENUS, &fore_colors, &valid); X index = TextMenuLoop (X, Y, arrangeMenuStr, MAXARRANGEMENUS, fore_colors, X valid, SINGLECOLOR); X switch (index) X { X case ARRANGE_FRONT: FrontProc (); break; X case ARRANGE_BACK: BackProc (); break; X case ARRANGE_GROUP: GroupSelObj (); break; X case ARRANGE_UNGROUP: UngroupSelObj (); break; X case ARRANGE_ALIGNOBJ: AlignSelObjs (); break; X case ARRANGE_ALIGNGRID: AlignSelToGrid (); break; X case FLIP_HORIZONTAL: FlipHorizontal (); break; X case FLIP_VERTICAL: FlipVertical (); break; X case ROTATE_CLOCKWISE: RotateClockWise (); break; X case ROTATE_COUNTER: RotateCounter (); break; X } X} X Xstatic struct ObjRec * tmpTopObj, * tmpBotObj; Xstatic struct SelRec * tmpTopSel, * tmpBotSel; X Xstatic Xvoid PushTmpSel (ObjPtr) X struct ObjRec * ObjPtr; X{ X struct SelRec * sel_ptr; X X ObjPtr->next = tmpTopObj; X ObjPtr->prev = NULL; X X sel_ptr = (struct SelRec *) calloc (1, sizeof (struct SelRec)); X sel_ptr->next = tmpTopSel; X sel_ptr->prev = NULL; X sel_ptr->obj = ObjPtr; X X if (tmpTopObj == NULL) X { X tmpBotObj = ObjPtr; X tmpBotSel = sel_ptr; X } X else X { X tmpTopObj->prev = ObjPtr; X tmpTopSel->prev = sel_ptr; X } X tmpTopObj = ObjPtr; X tmpTopSel = sel_ptr; X} X Xvoid UpdateSymbols () X{ X int dx = 0, dy = 0, changed = FALSE; X char path_name[MAXPATHLENGTH], sym_name[MAXPATHLENGTH]; X struct ObjRec * obj_ptr, * new_obj_ptr; X struct SelRec * sel_ptr; X X if (topSel == NULL) return; X X tmpTopObj = tmpBotObj = NULL; X tmpTopSel = tmpBotSel = NULL; X X HighLightReverse (); X X for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev) X { X obj_ptr = sel_ptr->obj; X if (obj_ptr->type != OBJ_ICON) continue; X X strcpy (sym_name, obj_ptr->detail.r->s); X if (GetSymbolPath (obj_ptr->detail.r->s, path_name)) X { X if ((new_obj_ptr = GetObjRepresentation (path_name, sym_name)) != NULL) X { X switch (horiAlign) X { X case ALIGN_L: X dx = obj_ptr->obbox.ltx - new_obj_ptr->obbox.ltx; X break; X case ALIGN_N: X case ALIGN_C: X dx = (int)(((obj_ptr->obbox.ltx+obj_ptr->obbox.rbx) - X (new_obj_ptr->obbox.ltx+new_obj_ptr->obbox.rbx))/2); X break; X case ALIGN_R: X dx = obj_ptr->obbox.rbx - new_obj_ptr->obbox.rbx; X break; X } X switch (vertAlign) X { X case ALIGN_T: X dy = obj_ptr->obbox.lty - new_obj_ptr->obbox.lty; X break; X case ALIGN_N: X case ALIGN_M: X dy = (int)(((obj_ptr->obbox.lty+obj_ptr->obbox.rby) - X (new_obj_ptr->obbox.lty+new_obj_ptr->obbox.rby))/2); X break; X case ALIGN_B: X dy = obj_ptr->obbox.rby - new_obj_ptr->obbox.rby; X break; X } X MoveObj (new_obj_ptr, dx, dy); X X changed = TRUE; X X UnlinkObj (obj_ptr); X PushTmpSel (obj_ptr); X CopyAndUpdateAttrs (new_obj_ptr, obj_ptr); X X if (new_obj_ptr->bbox.ltx < selLtX) selLtX = new_obj_ptr->bbox.ltx; X if (new_obj_ptr->bbox.lty < selLtY) selLtY = new_obj_ptr->bbox.lty; X if (new_obj_ptr->bbox.rbx < selRbX) selRbX = new_obj_ptr->bbox.rbx; X if (new_obj_ptr->bbox.rby < selRbY) selRbY = new_obj_ptr->bbox.rby; X if (new_obj_ptr->obbox.ltx < selObjLtX) X selObjLtX = new_obj_ptr->obbox.ltx; X if (new_obj_ptr->obbox.lty < selObjLtY) X selObjLtY = new_obj_ptr->obbox.lty; X if (new_obj_ptr->obbox.rbx < selObjRbX) X selObjRbX = new_obj_ptr->obbox.rbx; X if (new_obj_ptr->obbox.rby < selObjRbY) X selObjRbY = new_obj_ptr->obbox.rby; X X sel_ptr->obj = new_obj_ptr; X AddObj (NULL, topObj, new_obj_ptr); X } X } X } X X PushToCutBuffer (tmpTopSel, tmpBotSel); X X if (changed) X { X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale), X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale)); X UpdSelBBox (); X SetFileModified (TRUE); X justDupped = FALSE; X } X HighLightForward (); X} END_OF_FILE if test 29266 -ne `wc -c <'edit.c'`; then echo shar: \"'edit.c'\" unpacked with wrong size! fi # end of 'edit.c' fi echo shar: End of archive 3 \(of 23\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 23 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 ---------------------------------> cut here <--------------------------------- -- Bill Cheng // UCLA Computer Science Department // (213) 206-7135 3277 Boelter Hall // Los Angeles, California 90024 // USA william@CS.UCLA.EDU ...!{uunet|ucbvax}!cs.ucla.edu!william