william@CS.UCLA.EDU (William Cheng) (03/14/91)
Submitted-by: william@CS.UCLA.EDU (William Cheng) Posting-number: Volume 12, Issue 26 Archive-name: tgif/part10 ---------------------------------> 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 10 (of 23)." # Contents: poly.c polygon.c # Wrapped by william@oahu on Wed Mar 6 09:57:29 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'poly.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'poly.c'\" else echo shar: Extracting \"'poly.c'\" \(30629 characters\) sed "s/^X//" >'poly.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/poly.c,v 2.0 91/03/05 12:47:54 william Exp $"; X#endif X X#include <math.h> X#include <stdio.h> X#include <X11/Xlib.h> X#include "const.h" X#include "types.h" X X#include "attr.e" X#include "color.e" X#include "cursor.e" X#include "drawing.e" X#include "file.e" X#include "grid.e" X#include "obj.e" X#include "pattern.e" X#include "raster.e" X#include "rect.e" X#include "ruler.e" X#include "select.e" X#include "setup.e" X#include "spline.e" X Xint polyDrawn = FALSE; X X/* short widthOfLine[] = { 0, 3, 6, 0 }; */ X/* short arrowHeadH[] = { 3, 5, 10, 3 }; */ X/* short arrowHeadW[] = { 8, 12, 22, 8 }; */ X Xshort widthOfLine[] = { 1, 2, 3, 4, 5, 6, 7 }; Xshort arrowHeadH[] = { 3, 4, 5, 6, 7, 8, 9 }; Xshort arrowHeadW[] = { 8, 10, 12, 14, 18, 20, 22 }; X Xdouble penGrayScale[] = { 1.0, 0.0, 1.0, 0.9, 0.85, 0.8, 0.7, 0.5 }; X Xstatic struct PtRec * lastPtPtr = NULL; Xstatic XPoint pv[11]; X Xvoid UpdPolyBBox (ObjPtr, NumPts, V) X struct ObjRec * ObjPtr; X int NumPts; X XPoint * V; X{ X register int i; X int ltx, lty, rbx, rby, w = 0; X X ltx = rbx = V[0].x; X lty = rby = V[0].y; X X for (i = 1; i < NumPts; i++) X { X if (V[i].x < ltx) ltx = V[i].x; if (V[i].y < lty) lty = V[i].y; X if (V[i].x > rbx) rbx = V[i].x; if (V[i].y > rby) rby = V[i].y; X } X X switch (ObjPtr->type) X { X case OBJ_POLY: w = arrowHeadH[ObjPtr->detail.p->width]; break; X case OBJ_POLYGON: w = widthOfLine[ObjPtr->detail.g->width]; break; X } X X ObjPtr->x = ltx; X ObjPtr->y = lty; X ObjPtr->bbox.ltx = ltx - w; X ObjPtr->bbox.lty = lty - w; X ObjPtr->bbox.rbx = rbx + w; X ObjPtr->bbox.rby = rby + w; X ObjPtr->obbox.ltx = ltx; X ObjPtr->obbox.lty = lty; X ObjPtr->obbox.rbx = rbx; X ObjPtr->obbox.rby = rby; X if (ObjPtr->type == OBJ_POLY) AdjObjBBox (ObjPtr); /* adjust for attrs */ X} X Xstatic Xvoid CreatePolyObj (NumPts) X int NumPts; X{ X struct PtRec * pt_ptr; X struct PolyRec * poly_ptr; X struct ObjRec * obj_ptr; X register int i; X XPoint * v; X int ltx, lty, rbx, rby, w; X X poly_ptr = (struct PolyRec *) calloc (1, sizeof(struct PolyRec)); X poly_ptr->n = NumPts; X v = (XPoint *) calloc (NumPts+1, sizeof(XPoint)); X pt_ptr = lastPtPtr; X ltx = rbx = pt_ptr->x; X lty = rby = pt_ptr->y; X for (i = NumPts-1; i >= 0; i--, lastPtPtr = lastPtPtr->next) X { X v[i].x = (lastPtPtr->x << zoomScale) + drawOrigX; X v[i].y = (lastPtPtr->y << zoomScale) + drawOrigY; X if (lastPtPtr->x < ltx) ltx = lastPtPtr->x; X if (lastPtPtr->y < lty) lty = lastPtPtr->y; X if (lastPtPtr->x > rbx) rbx = lastPtPtr->x; X if (lastPtPtr->y > rby) rby = lastPtPtr->y; X cfree (lastPtPtr); X } X poly_ptr->vlist = v; X if (curSpline == LT_SPLINE) X poly_ptr->svlist = MakeSplinePolyVertex (&(poly_ptr->sn), drawOrigX, X drawOrigY, NumPts, v); X poly_ptr->style = lineStyle; X poly_ptr->width = lineWidth; X poly_ptr->pen = penPat; X poly_ptr->curved = curSpline; X poly_ptr->fill = objFill; X poly_ptr->dash = curDash; X obj_ptr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec)); X obj_ptr->color = colorIndex; X obj_ptr->type = OBJ_POLY; X obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = X (ltx << zoomScale) + drawOrigX; X obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = X (lty << zoomScale) + drawOrigY; X obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = (rbx << zoomScale) + drawOrigX; X obj_ptr->bbox.rby = obj_ptr->obbox.rby = (rby << zoomScale) + drawOrigY; X w = arrowHeadH[lineWidth]; X obj_ptr->bbox.ltx -= w; X obj_ptr->bbox.lty -= w; X obj_ptr->bbox.rbx += w; X obj_ptr->bbox.rby += w; X obj_ptr->id = objId++; X obj_ptr->dirty = FALSE; X obj_ptr->detail.p = poly_ptr; X obj_ptr->fattr = obj_ptr->lattr = NULL; X AddObj (NULL, topObj, obj_ptr); X} X X/* line shapes: */ X/* 0 |---| */ X/* 1 -|---| */ X/* 2 |---|- */ X/* 3 -|---|- */ X/* 4 |<--| */ X/* 5 |<--|- */ X/* 6 |-->| */ X/* 7 -|-->| */ X/* 8 |<->| */ X X/* X * Cont == 0 X * X * || || || || || X * || Rb == 1 || Rb == 0 || Rb == 1 || Rb == 0 || X * || Pt == 1 || Pt == 1 || Pt == 0 || Pt == 0 || X * || || || || || X * --- || |---| || |---| || -|---| || -|---| || X * <-- || |<--| || |<--| || -|---| || -|---| || X * --> || |-->| || |-->| || -|-->| || -|-->| || X * <-> || |<->| || |<->| || -|-->| || -|-->| || X * || || || || || X * X * Cont == 1 X * X * || || || || || X * || Rb == 1 || Rb == 0 || Rb == 1 || Rb == 0 || X * || Pt == 1 || Pt == 1 || Pt == 0 || Pt == 0 || X * || || || || || X * --- || |---| || |---|- || -|---| || -|---|- || X * <-- || |<--| || |<--|- || -|---| || -|---|- || X * --> || |-->| || |---|- || -|-->| || -|---|- || X * <-> || |<->| || |<--|- || -|-->| || -|---|- || X * || || || || || X */ X Xvoid MyLine (Win,Cont,Rb,N,StartX,StartY,EndX,EndY,W,S,P,Pix,Dash) X Window Win; X int Cont, Rb, N, StartX, StartY, EndX, EndY, W, S, P, Pix, Dash; X /* 'Cont' means continue */ X /* 'Rb' means rubber-band */ X /* StartX, StartY, EndX, EndY are screen coordinates within Win, */ X /* that is, scaled and translated. */ X{ X int shape = 0, aw, ah, x1, y1, x2, y2; X double dx, dy, len, sin, cos; X XGCValues values; X X if (StartX == EndX && StartY == EndY) return; X X if (Cont) X if (Rb) X if (N == 1) X switch (S) X { X case LS_PLAIN: shape = 0; break; X case LS_LEFT: shape = 4; break; X case LS_RIGHT: shape = 6; break; X case LS_DOUBLE: shape = 8; break; X } X else /* Cont && Rb && N != 1 */ X switch (S) X { X case LS_PLAIN: shape = 1; break; X case LS_LEFT: shape = 1; break; X case LS_RIGHT: shape = 7; break; X case LS_DOUBLE: shape = 7; break; X } X else /* Cont && !Rb */ X if (N == 1) X switch (S) X { X case LS_PLAIN: shape = 2; break; X case LS_LEFT: shape = 5; break; X case LS_RIGHT: shape = 2; break; X case LS_DOUBLE: shape = 5; break; X } X else /* Cont && !Rb && N != 1 */ X shape = 3; X else X if (N == 1) X switch (S) X { X case LS_PLAIN: shape = 0; break; X case LS_LEFT: shape = 4; break; X case LS_RIGHT: shape = 6; break; X case LS_DOUBLE: shape = 8; break; X } X else /* !Cont && N != 1 */ X switch (S) X { X case LS_PLAIN: shape = 1; break; X case LS_LEFT: shape = 1; break; X case LS_RIGHT: shape = 7; break; X case LS_DOUBLE: shape = 7; break; X } X X ah = arrowHeadH[W] >> zoomScale; if (ah == 0) ah = 1; X aw = arrowHeadW[W] >> zoomScale; if (aw == 0) aw = 1; X X if (Rb) X { X values.foreground = Pix; X values.function = GXxor; X values.fill_style = FillSolid; X values.line_width = 0; X values.line_style = LineSolid; X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCLineWidth | GCLineStyle, X &values); X } X else if (P != 0) X { X values.foreground = (P == 2) ? myBgPixel : Pix; X values.function = GXcopy; X values.fill_style = FillOpaqueStippled; X values.stipple = patPixmap[P]; X values.line_width = widthOfLine[W] >> zoomScale; X if (Dash != 0) X { X XSetDashes (mainDisplay, drawGC, 0, dashList[Dash], X dashListLength[Dash]); X values.line_style = LineOnOffDash; X } X else X values.line_style = LineSolid; X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCStipple | GCLineWidth | X GCLineStyle, &values); X } X else X return; X X dx = (double)(EndX - StartX); X dy = (double)(EndY - StartY); X len = (double) sqrt((double)(dx * dx + dy * dy)); X sin = dy / len; X cos = dx / len; X X switch (shape) X { X case 0: X case 1: X case 2: X case 3: X XDrawLine (mainDisplay, Win, drawGC, StartX, StartY, EndX, EndY); X break; X case 4: X case 5: X x1 = round(StartX+aw*cos); X y1 = round(StartY+aw*sin); X XDrawLine (mainDisplay, Win, drawGC, x1, y1, EndX, EndY); X break; X case 6: X case 7: X x2 = round(EndX-aw*cos); X y2 = round(EndY-aw*sin); X XDrawLine (mainDisplay, Win, drawGC, StartX, StartY, x2, y2); X break; X case 8: X x1 = round(StartX+aw*cos); X y1 = round(StartY+aw*sin); X x2 = round(EndX-aw*cos); X y2 = round(EndY-aw*sin); X XDrawLine (mainDisplay, Win, drawGC, x1, y1, x2, y2); X break; X } X if (shape==4 || shape==5 || shape==8) X { X pv[0].x = pv[3].x = StartX; X pv[0].y = pv[3].y = StartY; X pv[1].x = round(StartX + aw*cos - ah*sin); X pv[1].y = round(StartY + aw*sin + ah*cos); X pv[2].x = round(StartX + aw*cos + ah*sin); X pv[2].y = round(StartY + aw*sin - ah*cos); X XFillPolygon (mainDisplay, Win, drawGC, pv, 4, Convex, CoordModeOrigin); X } X if (shape==6 || shape==7 || shape==8) X { X pv[0].x = pv[3].x = EndX; X pv[0].y = pv[3].y = EndY; X pv[1].x = round(EndX - aw*cos + ah*sin); X pv[1].y = round(EndY - aw*sin - ah*cos); X pv[2].x = round(EndX - aw*cos - ah*sin); X pv[2].y = round(EndY - aw*sin + ah*cos); X XFillPolygon (mainDisplay, Win, drawGC, pv, 4, Convex, CoordModeOrigin); X } X} X Xstatic Xvoid ContinuePoly (OrigX, OrigY) X int OrigX, OrigY; X /* OrigX and OrigY are screen coordinates (scaled and translated). */ X /* OrigX and OrigY are also on grid. */ X{ X XGCValues values; X XEvent input, ev; X XButtonEvent * button_ev; X XMotionEvent * motion_ev; X int pixel, xor_pixel; X int end_x, end_y, grid_x, grid_y, done = FALSE, num_pts = 1; X int last_x = OrigX, last_y = OrigY; X struct PtRec * pt_ptr; X X pixel = colorPixels[colorIndex]; X xor_pixel = xorColorPixels[colorIndex]; X X values.foreground = xor_pixel; X values.function = GXxor; X values.fill_style = FillSolid; X values.line_width = 0; X values.line_style = LineSolid; X X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCLineWidth | GCLineStyle, X &values); X X grid_x = end_x = OrigX; X grid_y = end_y = OrigY; X XGrabPointer (mainDisplay, drawWindow, FALSE, X PointerMotionMask | ButtonPressMask, X GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime); X X while (!done) X { X XNextEvent (mainDisplay, &input); X if (input.type == MotionNotify) X { X motion_ev = &(input.xmotion); X MyLine (drawWindow, CONT, RB, num_pts, OrigX, OrigY, grid_x, X grid_y, lineWidth, lineStyle, penPat, xor_pixel,0); X X end_x = motion_ev->x; X end_y = motion_ev->y; X GridXY (end_x, end_y, &grid_x, &grid_y); X MarkRulers (grid_x, grid_y); X MyLine (drawWindow, CONT, RB, num_pts, OrigX, OrigY, grid_x, X grid_y, lineWidth, lineStyle, penPat, xor_pixel,0); X while (XCheckMaskEvent (mainDisplay, PointerMotionMask, &ev)) ; X } X else if (input.type == ButtonPress) X { X button_ev = &(input.xbutton); X MyLine (drawWindow, CONT, RB, num_pts, OrigX, OrigY, grid_x, X grid_y, lineWidth, lineStyle, penPat, xor_pixel,0); X X GridXY (end_x, end_y, &grid_x, &grid_y); X if (grid_x != last_x || grid_y != last_y) X { X num_pts++; X pt_ptr = (struct PtRec *) calloc (1, sizeof(struct PtRec)); X pt_ptr->next = lastPtPtr; X lastPtPtr = pt_ptr; X pt_ptr->x = last_x = grid_x; X pt_ptr->y = last_y = grid_y; X } X switch (button_ev->button) X { X case Button1 : X if (penPat != 0) X MyLine (drawWindow, CONT, NORB, num_pts-1, OrigX, OrigY, X grid_x, grid_y, lineWidth, lineStyle, penPat, X pixel,0); X OrigX = grid_x; X OrigY = grid_y; X break; X case Button2 : X case Button3 : X if (penPat != 0 || (OrigX == grid_x && OrigY == grid_y && X (lineStyle & LS_RIGHT))) X MyLine (drawWindow, NOCONT, NORB, num_pts-1, OrigX, X OrigY, grid_x, grid_y, lineWidth, lineStyle, X penPat, pixel,0); X X done = TRUE; X break; X } X } X } X XUngrabPointer (mainDisplay, CurrentTime); X X if (num_pts > 1) X { X CreatePolyObj (num_pts); X RedrawAnArea (botObj, topObj->bbox.ltx-(1<<zoomScale), X topObj->bbox.lty-(1<<zoomScale), topObj->bbox.rbx+(1<<zoomScale), X topObj->bbox.rby+(1<<zoomScale)); X polyDrawn = TRUE; X SetFileModified (TRUE); X } X} X Xvoid DrawPoly (input) X XEvent * input; X{ X int mouse_x, mouse_y, grid_x, grid_y; X XButtonEvent * button_ev; X X if (input->type != ButtonPress) return; X X button_ev = &(input->xbutton); X if (button_ev->button == Button1) X { X mouse_x = input->xbutton.x; X mouse_y = input->xbutton.y; X GridXY (mouse_x, mouse_y, &grid_x, &grid_y); X lastPtPtr = (struct PtRec *) calloc (1, sizeof(struct PtRec)); X lastPtPtr->x = grid_x; X lastPtPtr->y = grid_y; X lastPtPtr->next = NULL; X ContinuePoly (grid_x, grid_y); X } X} X Xstatic Xvoid DumpArrow (FP, TailV, HeadV, ArrowW, ArrowH, Pen) X FILE * FP; X XPoint TailV, HeadV; X int ArrowW, ArrowH, Pen; X{ X int i, dx, dy; X struct BBRec bbox; X XPoint v[2]; X double len, sin, cos; X X dx = HeadV.x - TailV.x; X dy = HeadV.y - TailV.y; X X fprintf (FP, "gsave\n"); X X if (colorDump) X { X len = (double) sqrt ((double)(dx*dx + dy*dy)); X sin = ((double)dy) / len; X cos = ((double)dx) / len; X X v[0].x = round(HeadV.x - ArrowW*cos + ArrowH*sin); X v[0].y = round(HeadV.y - ArrowW*sin - ArrowH*cos); X v[1].x = round(HeadV.x - ArrowW*cos - ArrowH*sin); X v[1].y = round(HeadV.y - ArrowW*sin + ArrowH*cos); X X bbox.ltx = bbox.rbx = HeadV.x; X bbox.lty = bbox.rby = HeadV.y; X X for (i = 0; i < 2; i++) X { X if (v[i].x < bbox.ltx) bbox.ltx = v[i].x; X if (v[i].y < bbox.lty) bbox.lty = v[i].y; X if (v[i].x > bbox.rbx) bbox.rbx = v[i].x; X if (v[i].y > bbox.rby) bbox.rby = v[i].y; X } X } X else X fprintf (FP, " pat%1d 8 1 0 72 300 32 div div setpattern\n", Pen); X X fprintf (FP, " newpath\n"); X fprintf (FP, " %1d %1d %1d %1d %1d %1d arrowtip\n", HeadV.x, HeadV.y, X ArrowW, ArrowH, dx, dy); X switch (Pen) X { X case NONEPAT: break; X case SOLIDPAT: X case BACKPAT: fprintf (FP, " closepath fill\n"); break; X default: X if (colorDump) X { X fprintf (FP, " closepath eoclip\n"); X DumpPatFill (FP, Pen, 8, bbox, " "); X } X else X fprintf (FP, " closepath fill\n"); X break; X } X fprintf (FP, "grestore\n"); X} X Xvoid DumpPolyObj (FP, ObjPtr) X FILE * FP; X register struct ObjRec * ObjPtr; X{ X XPoint * v; X int i, num_pts, fill, pen, width, curved, dash, color_index; X int w, aw, ah, dy, dx; X X fill = ObjPtr->detail.p->fill; X width = ObjPtr->detail.p->width; X pen = ObjPtr->detail.p->pen; X curved = ObjPtr->detail.p->curved; X dash = ObjPtr->detail.p->dash; X v = ObjPtr->detail.p->vlist; X num_pts = ObjPtr->detail.p->n; X X if (fill == NONEPAT && pen == NONEPAT) return; X X color_index = ObjPtr->color; X if (colorDump) X fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n", X ((float)tgifColors[color_index].red/maxRGB), X ((float)tgifColors[color_index].green/maxRGB), X ((float)tgifColors[color_index].blue/maxRGB)); X X if (fill != NONEPAT && num_pts > 2) X { X switch (curved) X { X case LT_STRAIGHT: X switch (fill) X { X case SOLIDPAT: X fprintf (FP, "newpath\n"); X fprintf (FP, " %1d %1d moveto\n", v[0].x, v[0].y); X DumpPoints (FP, num_pts, v, 3); X fprintf (FP, "closepath eofill\n"); X break; X case BACKPAT: X fprintf (FP, "newpath\n"); X fprintf (FP, " %1d %1d moveto\n", v[0].x, v[0].y); X DumpPoints (FP, num_pts, v, 3); X fprintf (FP, "closepath 1 setgray eofill\n"); X if (colorDump) X fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n", X ((float)tgifColors[color_index].red/maxRGB), X ((float)tgifColors[color_index].green/maxRGB), X ((float)tgifColors[color_index].blue/maxRGB)); X else X fprintf (FP, "0 setgray\n"); X break; X default: /* patterned */ X fprintf (FP, "gsave\n"); X if (!colorDump) X fprintf (FP, X " pat%1d 8 1 0 72 300 32 div div setpattern\n", X fill); X fprintf (FP, " newpath\n"); X fprintf (FP, " %1d %1d moveto\n", v[0].x,v[0].y); X DumpPoints (FP, num_pts, v, 6); X if (colorDump) X { X fprintf (FP, " closepath eoclip\n"); X DumpPatFill (FP, fill, 8, ObjPtr->bbox, " "); X } X else X fprintf (FP, " closepath eofill\n"); X fprintf (FP, "grestore\n"); X break; X } X break; X case LT_SPLINE: X switch (fill) X { X case SOLIDPAT: X fprintf (FP, "newpath\n"); X fprintf (FP, " %1d %1d moveto\n", v[0].x, v[0].y); X DumpCurvedPolyPoints (FP, num_pts, v, 3); X fprintf (FP, " %1d %1d curveto\n", X v[num_pts-1].x, v[num_pts-1].y); X fprintf (FP, "closepath eofill\n"); X break; X case BACKPAT: X fprintf (FP, "newpath\n"); X fprintf (FP, " %1d %1d moveto\n", v[0].x, v[0].y); X DumpCurvedPolyPoints (FP, num_pts, v, 3); X fprintf (FP, " %1d %1d curveto\n", X v[num_pts-1].x, v[num_pts-1].y); X fprintf (FP, "closepath 1 setgray eofill\n"); X if (colorDump) X fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n", X ((float)tgifColors[color_index].red/maxRGB), X ((float)tgifColors[color_index].green/maxRGB), X ((float)tgifColors[color_index].blue/maxRGB)); X else X fprintf (FP, "0 setgray\n"); X break; X default: /* patterned */ X fprintf (FP, "gsave\n"); X if (!colorDump) X fprintf (FP, X " pat%1d 8 1 0 72 300 32 div div setpattern\n", X fill); X fprintf (FP, " newpath\n"); X fprintf (FP, " %1d %1d moveto\n", v[0].x,v[0].y); X DumpCurvedPolyPoints (FP, num_pts, v, 6); X fprintf (FP, " %1d %1d curveto\n", X v[num_pts-1].x, v[num_pts-1].y); X if (colorDump) X { X fprintf (FP, " closepath eoclip\n"); X DumpPatFill (FP, fill, 8, ObjPtr->bbox, " "); X } X else X fprintf (FP, " closepath eofill\n"); X fprintf (FP, "grestore\n"); X break; X } X break; X } X } X X if (pen == NONEPAT) { fprintf (FP, "\n"); return; } X X fprintf (FP, "gsave\n"); X X w = widthOfLine[width]; X aw = arrowHeadW[width]; X ah = arrowHeadH[width]; X X fprintf (FP, " %1d setlinewidth", w); X if (dash != 0) X { X fprintf (FP, " ["); X for (i = 0; i < dashListLength[dash]-1; i++) X fprintf (FP, "%1d ", (int)(dashList[dash][i])); X fprintf (FP, "%1d] 0 setdash\n", X (int)(dashList[dash][dashListLength[dash]-1])); X } X else X fprintf (FP, "\n"); X X fprintf (FP, " newpath\n %1d %1d moveto\n", v[0].x, v[0].y); X if (ObjPtr->detail.p->style & LS_LEFT) X { X dx = v[1].x - v[0].x; X dy = v[1].y - v[0].y; X fprintf (FP, " %1d %1d atan dup cos %1d mul exch sin %1d mul rmoveto\n", X dy, dx, aw, aw); X } X if (ObjPtr->detail.p->style & LS_RIGHT) X { X if (curved == LT_SPLINE && num_pts != 2) X DumpCurvedPolyPoints (FP, num_pts, v, 6); X else X DumpPoints (FP, num_pts-1, v, 6); X X dx = v[num_pts-1].x - v[num_pts-2].x; X dy = v[num_pts-1].y - v[num_pts-2].y; X fprintf (FP, " %1d %1d atan dup cos %1d mul %1d exch sub\n", X dy, dx, aw, v[num_pts-1].x); X fprintf (FP, " exch sin %1d mul %1d exch sub", X aw, v[num_pts-1].y); X X if (curved == LT_SPLINE && num_pts != 2) X fprintf (FP, " curveto\n"); X else X fprintf (FP, " lineto\n"); X } X else X if (curved == LT_SPLINE && num_pts != 2) X { X DumpCurvedPolyPoints (FP, num_pts, v, 6); X fprintf (FP, " %1d %1d curveto\n",v[num_pts-1].x,v[num_pts-1].y); X } X else X DumpPoints (FP, num_pts, v, 6); X X switch (pen) X { X case SOLIDPAT: fprintf (FP, " stroke\n"); break; X case BACKPAT: fprintf (FP, " 1 setgray stroke\n"); break; X default: X if (colorDump) X { X fprintf (FP, " strokepath clip\n"); X DumpPatFill (FP, pen, 8, ObjPtr->bbox, " "); X } X else X { X fprintf (FP, " pat%1d 8 1 0 72 300 32 div div setpattern\n", pen); X fprintf (FP, " stroke\n"); X } X break; X } X X fprintf (FP, "grestore\n"); X X switch (ObjPtr->detail.p->style) X { X case LS_PLAIN: break; X case LS_LEFT: DumpArrow (FP, v[1], v[0], aw, ah, pen); break; X case LS_RIGHT: X DumpArrow (FP, v[num_pts-2], v[num_pts-1], aw, ah, pen); X break; X case LS_DOUBLE: X DumpArrow (FP, v[1], v[0], aw, ah, pen); X DumpArrow (FP, v[num_pts-2], v[num_pts-1], aw, ah, pen); X break; X } X fprintf (FP, "\n"); X} X Xvoid DrawPolyObj (Win, XOff, YOff, ObjPtr) X Window Win; X int XOff, YOff; X struct ObjRec * ObjPtr; X{ X register int i; X register struct PolyRec * poly_ptr = ObjPtr->detail.p; X XPoint * pv = poly_ptr->vlist, * v; X int pen, width, pixel, fill, curved, n, dash; X int x1, y1, x2, y2, real_x_off, real_y_off; X XGCValues values; X X n = poly_ptr->n; X fill = poly_ptr->fill; X width = poly_ptr->width; X pen = poly_ptr->pen; X curved = poly_ptr->curved; X dash = poly_ptr->dash; X pixel = colorPixels[ObjPtr->color]; X X if (curved == LT_SPLINE) X DrawSplinePolyObj (Win, XOff, YOff, fill, width, pen, dash, pixel, X poly_ptr); X else X { X real_x_off = (XOff >> zoomScale) << zoomScale; X real_y_off = (YOff >> zoomScale) << zoomScale; X X if (fill != NONEPAT) X { X v = (XPoint *) calloc (n+1, sizeof(XPoint)); X for (i = 0; i < n; i++) X { X v[i].x = (pv[i].x - real_x_off) >> zoomScale; X v[i].y = (pv[i].y - real_y_off) >> zoomScale; X } X v[n].x = v[0].x; v[n].y = v[0].y; X values.foreground = (fill == BACKPAT) ? myBgPixel : pixel; X values.function = GXcopy; X values.fill_style = FillOpaqueStippled; X values.stipple = patPixmap[fill]; X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCStipple, &values); X XFillPolygon (mainDisplay, Win, drawGC, v, n+1, Complex, X CoordModeOrigin); X cfree (v); X } X X if (pen == NONEPAT) return; X X for (i = 0; i < poly_ptr->n-2; i++) X { X x1 = (pv[i].x-real_x_off)>>zoomScale; X y1 = (pv[i].y-real_y_off)>>zoomScale; X x2 = (pv[i+1].x-real_x_off)>>zoomScale; X y2 = (pv[i+1].y-real_y_off)>>zoomScale; X X MyLine (Win, CONT, NORB, i+1, x1, y1, x2, y2, poly_ptr->width, X poly_ptr->style, pen, pixel, dash); X } X x1 = (pv[i].x-real_x_off)>>zoomScale; X y1 = (pv[i].y-real_y_off)>>zoomScale; X x2 = (pv[i+1].x-real_x_off)>>zoomScale; X y2 = (pv[i+1].y-real_y_off)>>zoomScale; X X MyLine (Win, NOCONT, NORB, i+1, x1, y1, x2, y2, poly_ptr->width, X poly_ptr->style, pen, pixel, dash); X } X} X Xvoid SavePolyObj (FP, ObjPtr) X FILE * FP; X struct ObjRec * ObjPtr; X{ X register int i, n; X struct PolyRec * poly_ptr = ObjPtr->detail.p; X X n = poly_ptr->n; X fprintf (FP, "poly('%s',%1d,[", colorMenuItems[ObjPtr->color], poly_ptr->n); X for (i = 0; i < n-1; i++) X { X fprintf (FP, "%1d,%1d,", poly_ptr->vlist[i].x, poly_ptr->vlist[i].y); X } X fprintf (FP, "%1d,%1d", poly_ptr->vlist[n-1].x, poly_ptr->vlist[n-1].y); X fprintf (FP, "],%1d,%1d,%1d,%1d,%1d,%1d,%1d,", poly_ptr->style, poly_ptr->width, X poly_ptr->pen, ObjPtr->id, poly_ptr->curved, poly_ptr->fill, poly_ptr->dash); X SaveAttrs (FP, ObjPtr->lattr); X fprintf (FP, ")"); X} X Xvoid ReadPolyObj (Inbuf, ObjPtr) X char * Inbuf; X struct ObjRec * * ObjPtr; X{ X register int i; X struct PolyRec * poly_ptr; X XPoint * v; X char color_str[20], * s; X int num_pts, ltx, lty, rbx, rby, x, y, w; X X * ObjPtr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec)); X s = FindChar ('(', Inbuf); X s = ParseStr (s, ',', color_str); X sscanf (s, "%d,", &num_pts); X poly_ptr = (struct PolyRec *) calloc (1, sizeof(struct PolyRec)); X poly_ptr->n = num_pts; X v = (XPoint *) calloc (num_pts+1, sizeof(XPoint)); X ltx = 20 * PIX_PER_INCH; rbx = 0; X lty = 20 * PIX_PER_INCH; rby = 0; X s = FindChar ('[', s); X for (i = 0; i < num_pts; i++) X { X sscanf (s, "%d , %d", &x, &y); X v[i].x = x; X v[i].y = y; X if (x < ltx) ltx = x; X if (y < lty) lty = y; X if (x > rbx) rbx = x; X if (y > rby) rby = y; X s = FindChar (',',s); X s = FindChar (',',s); X } X X if (fileVersion == INVALID) X { X sscanf (s, "%d , %d , %d", &(poly_ptr->style), &(poly_ptr->width), X &(poly_ptr->pen)); X (*ObjPtr)->id = objId++; X poly_ptr->fill = NONEPAT; X if (poly_ptr->width == LINE_CURVED) X { X poly_ptr->width = 0; X poly_ptr->curved = TRUE; X } X else X poly_ptr->curved = FALSE; X switch (poly_ptr->width) X { X case 1: poly_ptr->width = 3; break; X case 2: poly_ptr->width = 6; break; X } X poly_ptr->dash = 0; X } X else if (fileVersion <= 3) X { X sscanf (s, "%d , %d , %d , %d", &(poly_ptr->style), &(poly_ptr->width), X &(poly_ptr->pen), &((*ObjPtr)->id)); X if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1; X poly_ptr->fill = NONEPAT; X if (poly_ptr->width == LINE_CURVED) X { X poly_ptr->width = 0; X poly_ptr->curved = TRUE; X } X else X poly_ptr->curved = FALSE; X switch (poly_ptr->width) X { X case 1: poly_ptr->width = 3; break; X case 2: poly_ptr->width = 6; break; X } X poly_ptr->dash = 0; X } X else if (fileVersion <= 4) X { X sscanf (s, "%d , %d , %d , %d, %d", &(poly_ptr->style), X &(poly_ptr->width), &(poly_ptr->pen), &((*ObjPtr)->id), X &(poly_ptr->curved)); X if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1; X poly_ptr->fill = NONEPAT; X switch (poly_ptr->width) X { X case 1: poly_ptr->width = 3; break; X case 2: poly_ptr->width = 6; break; X } X poly_ptr->dash = 0; X } X else if (fileVersion <= 5) X { X sscanf (s, "%d , %d , %d , %d, %d, %d", &(poly_ptr->style), X &(poly_ptr->width), &(poly_ptr->pen), &((*ObjPtr)->id), X &(poly_ptr->curved), &(poly_ptr->fill)); X if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1; X switch (poly_ptr->width) X { X case 1: poly_ptr->width = 3; break; X case 2: poly_ptr->width = 6; break; X } X poly_ptr->dash = 0; X } X else if (fileVersion <= 8) X { X sscanf (s, "%d , %d , %d , %d, %d, %d", &(poly_ptr->style), X &(poly_ptr->width), &(poly_ptr->pen), &((*ObjPtr)->id), X &(poly_ptr->curved), &(poly_ptr->fill)); X if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1; X poly_ptr->dash = 0; X } X else X { X sscanf (s, "%d , %d , %d , %d , %d , %d , %d", &(poly_ptr->style), X &(poly_ptr->width), &(poly_ptr->pen), &((*ObjPtr)->id), X &(poly_ptr->curved), &(poly_ptr->fill), &(poly_ptr->dash)); X if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1; X } X X poly_ptr->vlist = v; X if (poly_ptr->curved == LT_SPLINE) X poly_ptr->svlist = MakeSplinePolyVertex (&(poly_ptr->sn), drawOrigX, X drawOrigY, num_pts, v); X w = arrowHeadH[poly_ptr->width]; X (*ObjPtr)->x = ltx; X (*ObjPtr)->y = lty; X (*ObjPtr)->color = FindColorIndex (color_str); X (*ObjPtr)->type = OBJ_POLY; X (*ObjPtr)->bbox.ltx = ltx - w; X (*ObjPtr)->bbox.lty = lty - w; X (*ObjPtr)->bbox.rbx = rbx + w; X (*ObjPtr)->bbox.rby = rby + w; X (*ObjPtr)->obbox.ltx = ltx; X (*ObjPtr)->obbox.lty = lty; X (*ObjPtr)->obbox.rbx = rbx; X (*ObjPtr)->obbox.rby = rby; X (*ObjPtr)->detail.p = poly_ptr; X} X Xvoid FreePolyObj (ObjPtr) X struct ObjRec * ObjPtr; X{ X if (ObjPtr->detail.p->curved) cfree (ObjPtr->detail.p->svlist); X cfree (ObjPtr->detail.p->vlist); X cfree (ObjPtr->detail.p); X cfree (ObjPtr); X} END_OF_FILE if test 30629 -ne `wc -c <'poly.c'`; then echo shar: \"'poly.c'\" unpacked with wrong size! fi # end of 'poly.c' fi if test -f 'polygon.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'polygon.c'\" else echo shar: Extracting \"'polygon.c'\" \(23195 characters\) sed "s/^X//" >'polygon.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/polygon.c,v 2.0 91/03/05 12:47:59 william Exp $"; X#endif X X#include <stdio.h> X#include <X11/Xlib.h> X#include "const.h" X#include "types.h" X X#include "color.e" X#include "cursor.e" X#include "dialog.e" X#include "grid.e" X#include "file.e" X#include "obj.e" X#include "pattern.e" X#include "poly.e" X#include "raster.e" X#include "ruler.e" X#include "select.e" X#include "setup.e" X#include "spline.e" X Xint polygonDrawn = FALSE; X Xstatic struct PtRec * lastPtPtr = NULL; Xstatic int startPolygonX, startPolygonY; X Xvoid DumpPoints (FP, NumPts, V, Indent) X FILE * FP; X int NumPts, Indent; X XPoint * V; X{ X register int i, j; X X for (i = 1; i < NumPts; i++) X { X for (j = 0; j < Indent; j++) fprintf (FP, " "); X fprintf (FP, "%1d %1d lineto\n", V[i].x, V[i].y); X } X} X Xvoid DumpPolygonObj (FP, ObjPtr) X FILE * FP; X struct ObjRec * ObjPtr; X{ X XPoint * v = ObjPtr->detail.g->vlist; X int num_pts = ObjPtr->detail.g->n, i; X int fill, width, pen, curved, dash, color_index; X X fill = ObjPtr->detail.g->fill; X width = ObjPtr->detail.g->width; X pen = ObjPtr->detail.g->pen; X curved = ObjPtr->detail.g->curved; X dash = ObjPtr->detail.g->dash; X X if (fill == NONEPAT && pen == NONEPAT) return; X X color_index = ObjPtr->color; X if (colorDump) X fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n", X ((float)tgifColors[color_index].red/maxRGB), X ((float)tgifColors[color_index].green/maxRGB), X ((float)tgifColors[color_index].blue/maxRGB)); X X if (fill != NONEPAT) X { X switch (curved) X { X case LT_STRAIGHT: X switch (fill) X { X case SOLIDPAT: /* solid black polygon */ X fprintf (FP, "newpath\n %1d %1d moveto\n", v[0].x, v[0].y); X DumpPoints (FP, num_pts-1, v, 3); X fprintf (FP, "closepath eofill\n"); X break; X case BACKPAT: /* solid white polygon */ X fprintf (FP, "newpath\n %1d %1d moveto\n", v[0].x, v[0].y); X DumpPoints (FP, num_pts-1, v, 3); X fprintf (FP, "closepath 1 setgray eofill\n"); X if (colorDump) X fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n", X ((float)tgifColors[color_index].red/maxRGB), X ((float)tgifColors[color_index].green/maxRGB), X ((float)tgifColors[color_index].blue/maxRGB)); X else X fprintf (FP, "0 setgray\n"); X break; X default: /* patterned */ X fprintf (FP, "gsave\n"); X if (!colorDump) X fprintf (FP, X " pat%1d 8 1 0 72 300 32 div div setpattern\n", X fill); X fprintf (FP, " newpath\n"); X fprintf (FP, " %1d %1d moveto\n", v[0].x, v[0].y); X DumpPoints (FP, num_pts-1, v, 6); X if (colorDump) X { X fprintf (FP, " closepath eoclip\n"); X DumpPatFill (FP, fill, 8, ObjPtr->bbox, " "); X } X else X fprintf (FP, " closepath eofill\n"); X fprintf (FP, "grestore\n"); X break; X } X break; X case LT_SPLINE: X switch (fill) X { X case SOLIDPAT: /* solid black polygon */ X fprintf (FP, "newpath\n"); X DumpCurvedPolygonPoints (FP, num_pts, v, 3); X fprintf (FP, "closepath eofill\n"); X break; X case BACKPAT: /* solid white polygon */ X fprintf (FP, "newpath\n"); X DumpCurvedPolygonPoints (FP, num_pts, v, 3); X fprintf (FP, "closepath 1 setgray eofill\n"); X if (colorDump) X fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n", X ((float)tgifColors[color_index].red/maxRGB), X ((float)tgifColors[color_index].green/maxRGB), X ((float)tgifColors[color_index].blue/maxRGB)); X else X fprintf (FP, "0 setgray\n"); X break; X default: /* patterned */ X fprintf (FP, "gsave\n"); X if (!colorDump) X fprintf (FP, X " pat%1d 8 1 0 72 300 32 div div setpattern\n", X fill); X fprintf (FP, " newpath\n"); X DumpCurvedPolygonPoints (FP, num_pts, v, 6); X if (colorDump) X { X fprintf (FP, " closepath eoclip\n"); X DumpPatFill (FP, fill, 8, ObjPtr->bbox, " "); X } X else X fprintf (FP, " closepath eofill\n"); X fprintf (FP, "grestore\n"); X break; X } X break; X } X } X X if (pen == NONEPAT) { fprintf (FP, "\n"); return; } X X fprintf (FP, "%1d setlinewidth", widthOfLine[width]); X if (dash != 0) X { X fprintf (FP, " ["); X for (i = 0; i < dashListLength[dash]-1; i++) X fprintf (FP, "%1d ", (int)(dashList[dash][i])); X fprintf (FP, "%1d] 0 setdash\n", X (int)(dashList[dash][dashListLength[dash]-1])); X } X else X fprintf (FP, "\n"); X X switch (curved) X { X case LT_STRAIGHT: X switch (pen) X { X case SOLIDPAT: X fprintf (FP, "newpath\n %1d %1d moveto\n", v[0].x, v[0].y); X DumpPoints (FP, num_pts-1, v, 3); X fprintf (FP, "closepath stroke\n"); X break; X case BACKPAT: X fprintf (FP, "newpath\n %1d %1d moveto\n", v[0].x, v[0].y); X DumpPoints (FP, num_pts-1, v, 3); X fprintf (FP, "closepath 1 setgray stroke\n"); X if (colorDump) X fprintf (FP, "%.3f %.3f %.3f setrgbcolor\n", X ((float)tgifColors[color_index].red/maxRGB), X ((float)tgifColors[color_index].green/maxRGB), X ((float)tgifColors[color_index].blue/maxRGB)); X else X fprintf (FP, "0 setgray\n"); X break; X default: X fprintf (FP, "gsave\n"); X if (!colorDump) X fprintf (FP, " pat%1d 8 1 0 72 300 32 div div setpattern\n", X pen); X fprintf (FP, " newpath\n"); X fprintf (FP, " %1d %1d moveto\n", v[0].x, v[0].y); X DumpPoints (FP, num_pts-1, v, 6); X if (colorDump) X { X fprintf (FP, " closepath strokepath clip\n"); X DumpPatFill (FP, pen, 8, ObjPtr->bbox, " "); X } X else X fprintf (FP, " closepath stroke\n"); X fprintf (FP, "grestore\n"); X break; X } X break; X case LT_SPLINE: X switch (pen) X { X case SOLIDPAT: X fprintf (FP, "newpath\n"); X DumpCurvedPolygonPoints (FP, num_pts, v, 3); X fprintf (FP, "closepath stroke\n"); X break; X case BACKPAT: X fprintf (FP, "newpath\n"); X DumpCurvedPolygonPoints (FP, num_pts, v, 3); X fprintf (FP, "closepath 1 setgray stroke 0 setgray\n"); X break; X default: X fprintf (FP, "gsave\n"); X if (!colorDump) X fprintf (FP, " pat%1d 8 1 0 72 300 32 div div setpattern\n", X pen); X fprintf (FP, " newpath\n"); X DumpCurvedPolygonPoints (FP, num_pts, v, 6); X if (colorDump) X { X fprintf (FP, " closepath strokepath clip\n"); X DumpPatFill (FP, pen, 8, ObjPtr->bbox, " "); X } X else X fprintf (FP, " closepath stroke\n"); X fprintf (FP, "grestore\n"); X break; X } X break; X } X if (dash != 0) fprintf (FP, "[] 0 setdash\n"); X fprintf (FP, "1 setlinewidth\n\n"); X} X Xvoid DrawPolygonObj (Win, XOff, YOff, ObjPtr) X Window Win; X int XOff, YOff; X struct ObjRec * ObjPtr; X{ X register int i; X XPoint * v; X struct PolygonRec * polygon_ptr = ObjPtr->detail.g; X int fill, width, pen, curved, dash, pixel; X int real_x_off, real_y_off; X XGCValues values; X X fill = polygon_ptr->fill; X width = polygon_ptr->width; X pen = polygon_ptr->pen; X curved = polygon_ptr->curved; X dash = polygon_ptr->dash; X pixel = colorPixels[ObjPtr->color]; X X if (curved == LT_SPLINE) X DrawSplinePolygonObj (Win, XOff, YOff, fill, width, pen, dash, pixel, X polygon_ptr); X else X { X real_x_off = (XOff >> zoomScale) << zoomScale; X real_y_off = (YOff >> zoomScale) << zoomScale; X X v = (XPoint *) calloc (polygon_ptr->n+1, sizeof(XPoint)); X for (i = 0; i < polygon_ptr->n; i++) X { X v[i].x = (polygon_ptr->vlist[i].x - real_x_off) >> zoomScale; X v[i].y = (polygon_ptr->vlist[i].y - real_y_off) >> zoomScale; X } X X if (fill != 0) X { X values.foreground = (fill == 2) ? myBgPixel : pixel; X values.function = GXcopy; X values.fill_style = FillOpaqueStippled; X values.stipple = patPixmap[fill]; X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCStipple, &values); X XFillPolygon (mainDisplay, Win, drawGC, v, polygon_ptr->n, Complex, X CoordModeOrigin); X } X X if (pen != 0) X { X values.foreground = (pen == 2) ? myBgPixel : pixel; X values.function = GXcopy; X values.fill_style = FillOpaqueStippled; X values.stipple = patPixmap[pen]; X values.line_width = widthOfLine[width] >> zoomScale; X if (dash != 0) X { X XSetDashes (mainDisplay, drawGC, 0, dashList[dash], X dashListLength[dash]); X values.line_style = LineOnOffDash; X } X else X values.line_style = LineSolid; X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCStipple | X GCLineWidth | GCLineStyle, &values); X X XDrawLines (mainDisplay, Win, drawGC, v, polygon_ptr->n, X CoordModeOrigin); X } X cfree (v); X } X} X Xstatic Xvoid CreatePolygonObj (NumPts) X int NumPts; X{ X register int i; X struct PtRec * pt_ptr; X struct PolygonRec * polygon_ptr; X struct ObjRec * obj_ptr; X XPoint * v; X int ltx, lty, rbx, rby, w; X X polygon_ptr = (struct PolygonRec *) calloc (1, sizeof(struct PolygonRec)); X polygon_ptr->n = NumPts; X v = (XPoint *) calloc (NumPts+1, sizeof(XPoint)); X pt_ptr = lastPtPtr; X ltx = rbx = pt_ptr->x; X lty = rby = pt_ptr->y; X for (i = NumPts-1; i >= 0; i--, lastPtPtr = lastPtPtr->next) X { X v[i].x = (lastPtPtr->x << zoomScale) + drawOrigX; X v[i].y = (lastPtPtr->y << zoomScale) + drawOrigY; X if (lastPtPtr->x < ltx) ltx = lastPtPtr->x; X if (lastPtPtr->y < lty) lty = lastPtPtr->y; X if (lastPtPtr->x > rbx) rbx = lastPtPtr->x; X if (lastPtPtr->y > rby) rby = lastPtPtr->y; X cfree (lastPtPtr); X } X polygon_ptr->vlist = v; X if (curSpline == LT_SPLINE) X polygon_ptr->svlist = MakeSplinePolygonVertex (&(polygon_ptr->sn), X drawOrigX, drawOrigY, NumPts, v); X polygon_ptr->fill = objFill; X polygon_ptr->width = lineWidth; X polygon_ptr->pen = penPat; X polygon_ptr->curved = curSpline; X polygon_ptr->dash = curDash; X obj_ptr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec)); X obj_ptr->color = colorIndex; X obj_ptr->type = OBJ_POLYGON; X obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = X (ltx << zoomScale) + drawOrigX; X obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = X (lty << zoomScale) + drawOrigY; X obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = (rbx << zoomScale) + drawOrigX; X obj_ptr->bbox.rby = obj_ptr->obbox.rby = (rby << zoomScale) + drawOrigY; X w = widthOfLine[lineWidth]; X obj_ptr->bbox.ltx -= w; X obj_ptr->bbox.lty -= w; X obj_ptr->bbox.rbx += w; X obj_ptr->bbox.rby += w; X obj_ptr->id = objId++; X obj_ptr->dirty = FALSE; X obj_ptr->detail.g = polygon_ptr; X obj_ptr->fattr = obj_ptr->lattr = NULL; X AddObj (NULL, topObj, obj_ptr); X} X Xstatic Xvoid ContinuePolygon (OrigX, OrigY) X int OrigX, OrigY; X /* OrigX and OrigY are screen coordinates (scaled and translated). */ X{ X XGCValues values; X XEvent input; X XButtonEvent * button_ev; X XMotionEvent * motion_ev; X int end_x, end_y, grid_x, grid_y, done = FALSE; X int ltx, lty, rbx, rby; X int pixel, xor_pixel, num_pts = 1; X struct PtRec * pt_ptr; X X pixel = colorPixels[colorIndex]; X xor_pixel = xorColorPixels[colorIndex]; X X values.foreground = xor_pixel; X values.function = GXxor; X values.fill_style = FillSolid; X values.line_width = 0; X values.line_style = LineSolid; X X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCLineWidth | GCLineStyle, X &values); X X grid_x = end_x = OrigX; X grid_y = end_y = OrigY; X XGrabPointer (mainDisplay, drawWindow, FALSE, X PointerMotionMask | ButtonPressMask, X GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime); X X while (!done) X { X XNextEvent (mainDisplay, &input); X if (input.type == MotionNotify) X { X XDrawLine (mainDisplay, drawWindow, drawGC, OrigX, OrigY, grid_x, X grid_y); X motion_ev = &(input.xmotion); X end_x = motion_ev->x; X end_y = motion_ev->y; X GridXY (end_x, end_y, &grid_x, &grid_y); X MarkRulers (grid_x, grid_y); X XDrawLine (mainDisplay, drawWindow, drawGC, OrigX, OrigY, grid_x, X grid_y); X } X else if (input.type == ButtonPress) X { X button_ev = &(input.xbutton); X XDrawLine (mainDisplay, drawWindow, drawGC, OrigX, OrigY, grid_x, X grid_y); X end_x = button_ev->x; X end_y = button_ev->y; X GridXY (end_x, end_y, &grid_x, &grid_y); X X if (penPat != 0 && (button_ev->button == Button1 || num_pts != 1)) X { X values.foreground = (penPat == 2) ? myBgPixel : pixel; X values.function = GXcopy; X values.fill_style = FillOpaqueStippled; X values.line_width = widthOfLine[lineWidth] >> zoomScale; X values.stipple = patPixmap[penPat]; X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCLineWidth | X GCStipple, &values); X X XDrawLine (mainDisplay, drawWindow, drawGC, OrigX, OrigY, grid_x, X grid_y); X X values.foreground = xor_pixel; X values.function = GXxor; X values.fill_style = FillSolid; X values.line_width = 0; X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCLineWidth, X &values); X } X X if ((grid_x != OrigX || grid_y != OrigY) && X (button_ev->button == Button1 || num_pts != 1)) X { X num_pts++; X pt_ptr = (struct PtRec *) calloc (1, sizeof(struct PtRec)); X pt_ptr->next = lastPtPtr; X lastPtPtr = pt_ptr; X pt_ptr->x = grid_x; X pt_ptr->y = grid_y; X } X X if (grid_x == startPolygonX && grid_y == startPolygonY) X done = TRUE; X else X { X switch(button_ev->button) X { X case Button1 : OrigX = grid_x; OrigY = grid_y; break; X case Button2 : X case Button3 : X if (num_pts == 1) X { X done = TRUE; X break; X } X X values.foreground = (penPat == 2) ? myBgPixel : pixel; X values.function = GXcopy; X values.fill_style = FillOpaqueStippled; X values.line_width = widthOfLine[lineWidth] >> zoomScale; X values.stipple = patPixmap[penPat]; X XChangeGC (mainDisplay, drawGC, X GCForeground | GCFunction | GCFillStyle | GCLineWidth | X GCStipple, &values); X X XDrawLine (mainDisplay, drawWindow, drawGC, grid_x, grid_y, X startPolygonX, startPolygonY); X X num_pts++; X pt_ptr = (struct PtRec *) calloc (1, sizeof(struct PtRec)); X pt_ptr->next = lastPtPtr; X lastPtPtr = pt_ptr; X pt_ptr->x = startPolygonX; X pt_ptr->y = startPolygonY; X done = TRUE; X break; X } X } X } X } X XUngrabPointer (mainDisplay, CurrentTime); X X switch (num_pts) X { X case 1: X RedrawAnArea (botObj, (OrigX+drawOrigX)-(1<<zoomScale), X (OrigY+drawOrigY)-(1<<zoomScale), X (OrigX+drawOrigX)+(1<<zoomScale), X (OrigY+drawOrigY)+(1<<zoomScale)); X cfree (lastPtPtr); X break; X case 2: X CalcBBox (lastPtPtr->x, lastPtPtr->y, lastPtPtr->next->x, X lastPtPtr->next->y, <x, <y, &rbx, &rby); X RedrawAnArea (botObj, (ltx+drawOrigX)-(1<<zoomScale), X (lty+drawOrigY)-(1<<zoomScale), (rbx+drawOrigX)+(1<<zoomScale), X (rby+drawOrigY)+(1<<zoomScale)); X cfree (lastPtPtr->next); X cfree (lastPtPtr); X break; X default: X CreatePolygonObj (num_pts); X RedrawAnArea (botObj, topObj->bbox.ltx-(1<<zoomScale), X topObj->bbox.lty-(1<<zoomScale), X topObj->bbox.rbx+(1<<zoomScale), X topObj->bbox.rby+(1<<zoomScale)); X polygonDrawn = TRUE; X SetFileModified (TRUE); X break; X } X} X Xvoid DrawPolygon (input) X XEvent * input; X{ X XButtonEvent * button_ev; X int mouse_x, mouse_y, grid_x, grid_y; X X if (input->type != ButtonPress) return; X X button_ev = &(input->xbutton); X if (button_ev->button == Button1) X { X mouse_x = button_ev->x; X mouse_y = button_ev->y; X GridXY (mouse_x, mouse_y, &grid_x, &grid_y); X lastPtPtr = (struct PtRec *) calloc (1, sizeof(struct PtRec)); X lastPtPtr->x = startPolygonX = grid_x; X lastPtPtr->y = startPolygonY = grid_y; X lastPtPtr->next = NULL; X ContinuePolygon (grid_x, grid_y); X } X} X Xvoid SavePolygonObj (FP, ObjPtr) X FILE * FP; X struct ObjRec * ObjPtr; X{ X register int i, n; X struct PolygonRec * polygon_ptr = ObjPtr->detail.g; X X n = polygon_ptr->n; X fprintf (FP, "polygon('%s',%1d,[", colorMenuItems[ObjPtr->color], X polygon_ptr->n); X for (i = 0; i < n-1; i++) X fprintf (FP, "%1d,%1d,", polygon_ptr->vlist[i].x, polygon_ptr->vlist[i].y); X X fprintf (FP, "%1d,%1d],%1d,%1d,%1d,%1d,%1d,%1d,", polygon_ptr->vlist[n-1].x, X polygon_ptr->vlist[n-1].y, polygon_ptr->fill, polygon_ptr->width, X polygon_ptr->pen, polygon_ptr->curved, ObjPtr->id, polygon_ptr->dash); X SaveAttrs (FP, ObjPtr->lattr); X fprintf (FP, ")"); X} X Xvoid ReadPolygonObj (Inbuf, ObjPtr) X char * Inbuf; X struct ObjRec * * ObjPtr; X{ X register int i; X struct PolygonRec * polygon_ptr; X XPoint * v; X char color_str[20], * s; X int num_pts, ltx, lty, rbx, rby, x, y, fill, width, pen, w; X int curved, dash; X X * ObjPtr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec)); X s = FindChar ('(', Inbuf); X s = ParseStr (s, ',', color_str); X sscanf (s, "%d,", &num_pts); X polygon_ptr = (struct PolygonRec *) calloc (1, sizeof(struct PolygonRec)); X polygon_ptr->n = num_pts; X v = (XPoint *) calloc (num_pts+1, sizeof(XPoint)); X ltx = 20 * PIX_PER_INCH; rbx = 0; X lty = 20 * PIX_PER_INCH; rby = 0; X s = FindChar ('[', s); X for (i = 0; i < num_pts; i++) X { X sscanf (s, "%d , %d", &x, &y); X v[i].x = x; X v[i].y = y; X if (x < ltx) ltx = x; X if (y < lty) lty = y; X if (x > rbx) rbx = x; X if (y > rby) rby = y; X s = FindChar (',',s); X s = FindChar (',',s); X } X X if (fileVersion <= 3) X { X sscanf (s, "%d , %d , %d", &fill, &width, &pen); X if (width == LINE_CURVED) X { X width = 0; X curved = TRUE; X } X else X curved = FALSE; X switch (width) X { X case 1: width = 3; break; X case 2: width = 6; break; X } X (*ObjPtr)->id = objId++; X dash = 0; X } X else if (fileVersion <= 5) X { X sscanf (s, "%d , %d , %d , %d", &fill, &width, &pen, &curved); X switch (width) X { X case 1: width = 3; break; X case 2: width = 6; break; X } X (*ObjPtr)->id = objId++; X dash = 0; X } X else if (fileVersion <= 7) X { X sscanf (s, "%d , %d , %d , %d", &fill, &width, &pen, &curved); X (*ObjPtr)->id = objId++; X dash = 0; X } X else if (fileVersion <= 8) X { X sscanf (s, "%d , %d , %d , %d , %d", &fill, &width, &pen, &curved, X &((*ObjPtr)->id)); X if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1; X dash = 0; X } X else X { X sscanf (s, "%d , %d , %d , %d , %d , %d", &fill, &width, &pen, &curved, X &((*ObjPtr)->id), &dash); X if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1; X } X X polygon_ptr->vlist = v; X if (curved == LT_SPLINE) X polygon_ptr->svlist = MakeSplinePolygonVertex (&(polygon_ptr->sn), X drawOrigX, drawOrigY, num_pts, v); X polygon_ptr->fill = fill; X polygon_ptr->width = width; X polygon_ptr->pen = pen; X polygon_ptr->curved = curved; X polygon_ptr->dash = dash; X (*ObjPtr)->x = ltx; X (*ObjPtr)->y = lty; X (*ObjPtr)->color = FindColorIndex (color_str); X (*ObjPtr)->dirty = FALSE; X (*ObjPtr)->type = OBJ_POLYGON; X (*ObjPtr)->obbox.ltx = ltx; X (*ObjPtr)->obbox.lty = lty; X (*ObjPtr)->obbox.rbx = rbx; X (*ObjPtr)->obbox.rby = rby; X if (width == 0) X { X (*ObjPtr)->bbox.ltx = ltx; X (*ObjPtr)->bbox.lty = lty; X (*ObjPtr)->bbox.rbx = rbx; X (*ObjPtr)->bbox.rby = rby; X } X else X { X w = widthOfLine[width]; X (*ObjPtr)->bbox.ltx = ltx - w; X (*ObjPtr)->bbox.lty = lty - w; X (*ObjPtr)->bbox.rbx = rbx + w; X (*ObjPtr)->bbox.rby = rby + w; X } X (*ObjPtr)->detail.g = polygon_ptr; X} X Xvoid FreePolygonObj (ObjPtr) X struct ObjRec * ObjPtr; X{ X if (ObjPtr->detail.g->curved) cfree (ObjPtr->detail.g->svlist); X cfree (ObjPtr->detail.g->vlist); X cfree (ObjPtr->detail.g); X cfree (ObjPtr); X} END_OF_FILE if test 23195 -ne `wc -c <'polygon.c'`; then echo shar: \"'polygon.c'\" unpacked with wrong size! fi # end of 'polygon.c' fi echo shar: End of archive 10 \(of 23\). cp /dev/null ark10isdone 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 -- Dan Heller ------------------------------------------------ O'Reilly && Associates Z-Code Software Senior Writer President argv@ora.com argv@zipcode.com ------------------------------------------------ General Email: argv@sun.com Comp-sources-x stuff: comp-sources.x@uunet.uu.net