[comp.sources.x] v12i026: tgif, Part10/23

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, &ltx, &lty, &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