[comp.sources.x] v12i030: tgif, Part14/23

william@CS.UCLA.EDU (William Cheng) (03/14/91)

Submitted-by: william@CS.UCLA.EDU (William Cheng)
Posting-number: Volume 12, Issue 30
Archive-name: tgif/part14

---------------------------------> 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 14 (of 23)."
# Contents:  special.c spline.c
# Wrapped by william@oahu on Wed Mar  6 09:57:44 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'special.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'special.c'\"
else
echo shar: Extracting \"'special.c'\" \(12418 characters\)
sed "s/^X//" >'special.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/special.c,v 2.0 91/03/05 12:48:26 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 "animate.e"
X#include "attr.e"
X#include "choice.e"
X#include "color.e"
X#include "cursor.e"
X#include "dialog.e"
X#include "drawing.e"
X#include "dup.e"
X#include "edit.e"
X#include "file.e"
X#include "grid.e"
X#include "group.e"
X#include "mark.e"
X#include "msg.e"
X#include "move.e"
X#include "names.e"
X#include "obj.e"
X#include "raster.e"
X#include "select.e"
X#include "setup.e"
X#include "stk.e"
X
X#define SPECIAL_SYM 0
X#define SPECIAL_UNSYM 1
X#define SPECIAL_INST 2
X#define SPECIAL_ICON 3
X#define SPECIAL_UNICON 4
X#define SPECIAL_PUSH 5
X#define SPECIAL_POP 6
X#define SPECIAL_ADDATTR 7
X#define SPECIAL_DETACHATTR 8
X#define SPECIAL_SHOWATTRNAME 9
X#define SPECIAL_HIDEATTRNAME 10
X#define SPECIAL_MOVEATTR 11
X#define SPECIAL_ANIMATESEND 12
X#define SPECIAL_ANIMATEFLASH 13
X#define SPECIAL_UPDATESYMS 14
X
X#define MAXSPECIALMENUS 15
Xstatic char * specialMenuStr[] =
X{
X   "MakeSymbolic   ^#M",
X   "UnMakeSymbolic ^#N",
X   "Instantiate     ^I",
X   "MakeIconic     ^#I",
X   "UnMakeIconic   ^#J",
X   "Push            ^V",
X   "Pop             ^K",
X   "AddAttr         #A",
X   "DetachAttrs     #T",
X   "ShowAttrName    #N",
X   "HideAttrName    #J",
X   "MoveAttr        #M",
X   "AnimateSend     #E",
X   "AnimateFlash    #F",
X   "UpdateSymbols  ^#U"
X};
X
Xstruct ObjRec * ReadSymbol (FP)
X   FILE	* FP;
X{
X   register struct AttrRec	* attr_ptr;
X   struct ObjRec		* obj_ptr;
X
X   importingFile = TRUE; /* ignore 'state' info but set fileVersion */
X   while (ReadObj (FP, &obj_ptr, FALSE))
X      if (obj_ptr != NULL)
X      {
X         if (obj_ptr->type == OBJ_SYM)
X         {
X            obj_ptr->type = OBJ_ICON;
X            attr_ptr = obj_ptr->lattr;
X            for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->prev)
X               attr_ptr->inherited = TRUE;
X            importingFile = FALSE;
X            return (obj_ptr);
X         }
X         else
X            FreeObj (obj_ptr);
X      }
X   importingFile = FALSE;
X   return (NULL);
X}
X
Xstruct ObjRec * GetObjRepresentation (PathName, SymName)
X   char	* PathName, * SymName;
X{
X   char			file_name[MAXPATHLENGTH];
X   struct ObjRec	* obj_ptr;
X   FILE			* fp;
X
X   sprintf (file_name, "%s/%s.sym", PathName, SymName);
X   if ((fp = fopen (file_name, "r")) == NULL)
X   { printf ("Can not open '%s'\n", file_name); return (NULL); }
X
X   if ((obj_ptr = ReadSymbol (fp)) != NULL)
X   {
X      obj_ptr->id = objId++;
X      obj_ptr->dirty = FALSE;
X      strcpy (obj_ptr->detail.r->s, SymName);
X      AdjObjBBox (obj_ptr);
X   }
X   fclose (fp);
X   return (obj_ptr);
X}
X
Xvoid PlaceTopObj ()
X{
X   int		x, y, grid_x, grid_y, dx, dy, placing = TRUE;
X   int		cursor_x, cursor_y, orig_x, orig_y;
X   int		obj_ltx, obj_lty, obj_rbx, obj_rby;
X   int		grid_obj_ltx, grid_obj_lty, grid_dx, grid_dy;
X   Window	root_win, child_win;
X   int		root_x, root_y;
X   unsigned int	status;
X   XEvent	input;
X
X   while (TRUE)
X   {
X      XQueryPointer (mainDisplay, drawWindow, &root_win, &child_win,
X            &root_x, &root_y, &cursor_x, &cursor_y, &status);
X      if (!(status & (Button1Mask | Button2Mask | Button3Mask))) break;
X   }
X
X   GridXY (cursor_x, cursor_y, &orig_x, &orig_y);
X   obj_ltx = OFFSET_X(topObj->obbox.ltx); obj_lty = OFFSET_Y(topObj->obbox.lty);
X   obj_rbx = OFFSET_X(topObj->obbox.rbx); obj_rby = OFFSET_Y(topObj->obbox.rby);
X   GridXY (obj_ltx, obj_lty, &grid_obj_ltx, &grid_obj_lty);
X   grid_dx = orig_x-grid_obj_ltx; grid_dy = orig_y-grid_obj_lty;
X   SelBox (drawWindow, revDefaultGC, obj_ltx+grid_dx, obj_lty+grid_dy,
X         obj_rbx+grid_dx, obj_rby+grid_dy);
X
X   dx = dy = 0;
X   XGrabPointer (mainDisplay, drawWindow, FALSE,
X         PointerMotionMask | ButtonPressMask,
X         GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime);
X
X   while (placing)
X   {
X      XNextEvent (mainDisplay, &input);
X      if (input.type == ButtonPress)
X      {
X         XUngrabPointer (mainDisplay, CurrentTime);
X         placing = FALSE;
X         SelBox (drawWindow, revDefaultGC, obj_ltx+grid_dx+dx,
X               obj_lty+grid_dy+dy, obj_rbx+grid_dx+dx, obj_rby+grid_dy+dy);
X         grid_dx = (grid_dx+dx)<<zoomScale;
X         grid_dy = (grid_dy+dy)<<zoomScale;
X         MoveObj (topObj, grid_dx, grid_dy);
X         DrawObj (drawWindow, topObj);
X      }
X      else if (input.type == MotionNotify)
X      {
X         x = input.xmotion.x;
X         y = input.xmotion.y;
X         GridXY (x, y, &grid_x, &grid_y);
X         SelBox (drawWindow, revDefaultGC, obj_ltx+grid_dx+dx,
X               obj_lty+grid_dy+dy, obj_rbx+grid_dx+dx, obj_rby+grid_dy+dy);
X         dx = grid_x - orig_x;
X         dy = grid_y - orig_y;
X         SelBox (drawWindow, revDefaultGC, obj_ltx+grid_dx+dx,
X               obj_lty+grid_dy+dy, obj_rbx+grid_dx+dx, obj_rby+grid_dy+dy);
X         MarkRulers (grid_x, grid_y);
X      }
X   }
X   XSync (mainDisplay, True);
X}
X
Xvoid Instantiate ()
X{
X   char			file_name[MAXPATHLENGTH];
X   char			sym_name[MAXPATHLENGTH], path_name[MAXPATHLENGTH];
X   struct ObjRec	* obj_ptr;
X   FILE			* fp;
X
X   if (SelectSymbolName (sym_name, path_name) == INVALID) return;
X
X   TieLooseEnds ();
X   SetCurChoice (NOTHING);
X
X   sprintf (file_name, "%s/%s.sym", path_name, sym_name);
X   if ((fp = fopen (file_name, "r")) == NULL)
X   { printf ("Can not open %s\n", file_name); return; }
X
X   if ((obj_ptr = ReadSymbol (fp)) != NULL)
X   {
X      if (topSel != NULL)
X      {
X         HighLightReverse ();
X         RemoveAllSel ();
X      }
X      SetNullCursor (drawWindow);
X
X      obj_ptr->id = objId++;
X      obj_ptr->dirty = FALSE;
X      strcpy (obj_ptr->detail.r->s, sym_name);
X      AddObj (NULL, topObj, obj_ptr);
X      AdjObjBBox (obj_ptr);
X
X      PlaceTopObj ();
X      SelectTopObj ();
X      SetFileModified (TRUE);
X      justDupped = FALSE;
X      ShowCursor ();
X   }
X   fclose (fp);
X}
X
Xvoid MakeSymbolic ()
X{
X   if (topSel!=NULL && topSel==botSel &&
X      (topSel->obj->type==OBJ_GROUP || topSel->obj->type==OBJ_ICON))
X   {
X      HighLightReverse ();
X      topSel->obj->type = OBJ_SYM;
X      Msg ("Selected GROUP object is now SYMBOLIC.");
X      SetFileModified (TRUE);
X      AdjObjBBox (topSel->obj);
X      UpdSelBBox ();
X      RedrawAnArea (botObj,
X            botSel->obj->obbox.ltx-QUARTER_INCH-(1<<zoomScale),
X            botSel->obj->obbox.lty-QUARTER_INCH-(1<<zoomScale),
X            botSel->obj->obbox.rbx+QUARTER_INCH+(1<<zoomScale),
X            botSel->obj->obbox.rby+QUARTER_INCH+(1<<zoomScale));
X      HighLightForward ();
X   }
X   else
X      Msg ("Please select one GROUP or ICON object to make it Symbolic.");
X}
X
Xvoid UnMakeSymbolic ()
X{
X   register struct ObjRec	* obj_ptr;
X   register int			ltx = 0, lty = 0, rbx = 0, rby = 0;
X   struct SelRec		* sel_ptr = topSel;
X   int				modified = FALSE;
X
X   for ( ; sel_ptr != NULL; sel_ptr = sel_ptr->next)
X   {
X      obj_ptr = sel_ptr->obj;
X      if (obj_ptr->type == OBJ_SYM)
X      {
X         obj_ptr->type = OBJ_GROUP;
X         AdjObjBBox (obj_ptr);
X         if (modified)
X         {
X            if (ltx < obj_ptr->bbox.ltx) ltx = obj_ptr->bbox.ltx;
X            if (lty < obj_ptr->bbox.lty) lty = obj_ptr->bbox.lty;
X            if (rbx > obj_ptr->bbox.rbx) rbx = obj_ptr->bbox.rbx;
X            if (rby > obj_ptr->bbox.rby) rby = obj_ptr->bbox.rby;
X         }
X         else
X         {
X            ltx = obj_ptr->bbox.ltx; lty = obj_ptr->bbox.lty;
X            rbx = obj_ptr->bbox.rbx; rby = obj_ptr->bbox.rby;
X            modified = TRUE;
X         }
X      }
X   }
X   if (modified)
X   {
X      HighLightReverse ();
X      SetFileModified (TRUE);
X      UpdSelBBox ();
X      RedrawAnArea (botObj,
X            ltx-QUARTER_INCH-(1<<zoomScale), lty-QUARTER_INCH-(1<<zoomScale),
X            rbx+QUARTER_INCH+(1<<zoomScale), rby+QUARTER_INCH+(1<<zoomScale));
X      HighLightForward ();
X   }
X}
X
Xvoid MakeIconic ()
X{
X   char 		icon_name[MAXPATHLENGTH], file_name[MAXPATHLENGTH];
X   char 		s[MAXPATHLENGTH], icon_full_name[MAXPATHLENGTH];
X   FILE			* fp;
X   struct ObjRec	* saved_obj_ptr;
X   int			len;
X
X   if (topSel!=NULL && topSel==botSel && topSel->obj->type==OBJ_GROUP)
X   {
X      Dialog ("Please Enter Name of the Icon:", icon_name);
X      len = strlen (icon_name);
X      if (*icon_name == '\0')
X      {
X         Msg ("Name not specified, icon not created.");
X         return;
X      }
X
X      if (strlen (icon_name) >= 4)
X      {
X         if (strcmp (&icon_name[len-4], ".obj") == 0)
X         {
X            Msg ("Can not save as a .obj file, icon not created.");
X            return;
X         }
X         else if (strcmp (&icon_name[len-4], ".sym") != 0)
X         {
X            strcpy (icon_full_name, icon_name);
X            strcat (icon_full_name, ".sym");
X         }
X
X         if (strlen (icon_full_name) == 4)
X         {
X            Msg ("No file name specified.  File not saved.");
X            return;
X         }
X      }
X      else
X      {
X         strcpy (icon_full_name, icon_name);
X         strcat (icon_full_name, ".sym");
X      }
X
X      if (*curDomainName != '\0')
X         sprintf (file_name, "%s/%s", curDomainName, icon_full_name);
X      else
X         sprintf (file_name, "%s", icon_full_name);
X      if (!OkayToCreateFile (file_name)) return;
X      if ((fp = fopen (file_name, "w")) == NULL)
X      {
X         sprintf (s, "Can not create '%s', icon not created.", file_name);
X         Msg (s);
X         return;
X      }
X      sprintf (s, "Creating '%s' ...", file_name);
X      Msg (s);
X      topSel->obj->type = OBJ_SYM;
X      strcpy (topSel->obj->detail.r->s, icon_name);
X
X      saved_obj_ptr = topSel->obj->prev;
X      topSel->obj->prev = NULL;
X      Save (fp, topSel->obj, 0);
X      topSel->obj->prev = saved_obj_ptr;
X
X      sprintf (s, "File '%s' created.", file_name);
X      Msg (s);
X      fclose (fp);
X
X      HighLightReverse ();
X      topSel->obj->type = OBJ_ICON;
X      topSel->obj->id = objId++;
X      Msg ("Selected GROUP object is now ICONIC.");
X      SetFileModified (TRUE);
X      AdjObjBBox (topSel->obj);
X      UpdSelBBox ();
X      RedrawAnArea (botObj,
X            botSel->obj->bbox.ltx-(1<<zoomScale),
X            botSel->obj->bbox.lty-(1<<zoomScale),
X            botSel->obj->bbox.rbx+(1<<zoomScale),
X            botSel->obj->bbox.rby+(1<<zoomScale));
X      HighLightForward ();
X   }
X   else
X      Msg ("Please select one GROUP object to make it ICONIC.");
X}
X
Xvoid UnMakeIconic ()
X{
X   register struct ObjRec	* obj_ptr;
X   struct SelRec		* sel_ptr;
X   struct AttrRec		* attr_ptr;
X   int				modified = FALSE;
X
X   HighLightReverse ();
X   for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
X   {
X      obj_ptr = sel_ptr->obj;
X      if (obj_ptr->type == OBJ_ICON)
X      {
X         obj_ptr->type = OBJ_GROUP;
X         AdjObjBBox (obj_ptr);
X         modified = TRUE;
X         attr_ptr = obj_ptr->fattr;
X         for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
X            attr_ptr->inherited = FALSE;
X      }
X   }
X   if (modified)
X   {
X      Msg ("Selected ICONIC objects are GROUP objects now.");
X      SetFileModified (TRUE);
X      UpdSelBBox ();
X      RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X            selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X   }
X   HighLightForward ();
X}
X
Xvoid SpecialMenu (X, Y)
X   int	X, Y;
X{
X   register int	index;
X   int		* fore_colors, * valid;
X
X   DefaultColorArrays (MAXSPECIALMENUS, &fore_colors, &valid);
X   index = TextMenuLoop (X, Y, specialMenuStr, MAXSPECIALMENUS, fore_colors,
X         valid, SINGLECOLOR);
X   switch (index)
X   {
X      case SPECIAL_SYM: MakeSymbolic (); break;
X      case SPECIAL_UNSYM: UnMakeSymbolic (); break;
X      case SPECIAL_INST: Instantiate (); break;
X      case SPECIAL_ICON: MakeIconic (); break;
X      case SPECIAL_UNICON: UnMakeIconic (); break;
X      case SPECIAL_PUSH: PushIcon (); break;
X      case SPECIAL_POP: PopIcon (); break;
X      case SPECIAL_ADDATTR: AddAttrs (); break;
X      case SPECIAL_SHOWATTRNAME: ShowAllAttrNames (); break;
X      case SPECIAL_HIDEATTRNAME: HideAllAttrNames (); break;
X      case SPECIAL_DETACHATTR: DetachAttrs (); break;
X      case SPECIAL_MOVEATTR: MoveAttr (); break;
X      case SPECIAL_ANIMATESEND: AnimateSel (); break;
X      case SPECIAL_ANIMATEFLASH: FlashSelColor (); break;
X      case SPECIAL_UPDATESYMS: UpdateSymbols (); break;
X   }
X}
END_OF_FILE
if test 12418 -ne `wc -c <'special.c'`; then
    echo shar: \"'special.c'\" unpacked with wrong size!
fi
# end of 'special.c'
fi
if test -f 'spline.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'spline.c'\"
else
echo shar: Extracting \"'spline.c'\" \(18843 characters\)
sed "s/^X//" >'spline.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/spline.c,v 2.0 91/03/05 12:48:28 william Exp $";
X#endif
X
X#include <math.h>
X#include <stdio.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include "const.h"
X#include "types.h"
X
X#include "poly.e"
X#include "raster.e"
X#include "rect.e"
X#include "setup.e"
X
X#define SPLINE_TOL 9
X
Xvoid Spline (Win, Pixel, Func, X1, Y1, X2, Y2, X3, Y3, X4, Y4)
X   Window	Win;
X   int		Pixel, Func;
X   double	X1, Y1, X2, Y2, X3, Y3, X4, Y4;
X   /* X1, Y1, X2, Y2, X3, Y3, X4, Y4 are screen offsets */
X{
X   double	x, y;
X
X   x = (X2 + X3) / 2.0;
X   y = (Y2 + Y3) / 2.0;
X   if (fabs (X1 - x) < SPLINE_TOL && fabs (Y1 - y) < SPLINE_TOL)
X      XDrawLine (mainDisplay, Win, drawGC, round(X1), round(Y1), round(x),
X            round(y));
X   else
X      Spline (Win, Pixel, Func, X1, Y1, ((X1+X2)/2.0), ((Y1+Y2)/2.0),
X            ((3.0*X2+X3)/4.0), ((3.0*Y2+Y3)/4.0), x, y);
X
X   if (fabs (x - X4) < SPLINE_TOL && fabs (y - Y4) < SPLINE_TOL)
X      XDrawLine (mainDisplay, Win, drawGC, round(x), round(y), round(X4),
X            round(Y4));
X   else
X      Spline (Win, Pixel, Func, x, y, ((X2+3.0*X3)/4.0), ((Y2+3.0*Y3)/4.0),
X            ((X3+X4)/2.0), ((Y3+Y4)/2.0), X4, Y4);
X}
X
Xstatic XPoint	* splineVs;
X
Xint AddSplinePt(N, MaxN, X, Y)
X   int		* N, * MaxN, X, Y;
X{
X   if (*N == *MaxN)
X   {
X      splineVs = (XPoint *) realloc (splineVs, (*MaxN)*2*sizeof(XPoint));
X      if (splineVs == NULL)
X      {
X         printf ("Can not realloc() in AddSplinePt ()\n");
X         return (FALSE);
X      }
X      *MaxN = (*MaxN) * 2;
X   }
X   splineVs[*N].x = X;
X   splineVs[*N].y = Y;
X   (*N)++;
X}
X
Xstatic
Xvoid SetSplineVs (N, MaxN, X1, Y1, X2, Y2, X3, Y3, X4, Y4)
X   int		* N, * MaxN;
X   double	X1, Y1, X2, Y2, X3, Y3, X4, Y4;
X   /* X1, Y1, X2, Y2, X3, Y3, X4, Y4 are screen offsets */
X{
X   double	x, y;
X
X   x = (X2 + X3) / 2.0;
X   y = (Y2 + Y3) / 2.0;
X   if (fabs (X1 - x) < SPLINE_TOL && fabs (Y1 - y) < SPLINE_TOL)
X      AddSplinePt (N, MaxN, round(x), round(y));
X   else
X      SetSplineVs (N, MaxN, X1, Y1, ((X1+X2)/2.0), ((Y1+Y2)/2.0),
X            ((3.0*X2+X3)/4.0), ((3.0*Y2+Y3)/4.0), x, y);
X
X   if (fabs (x - X4) < SPLINE_TOL && fabs (y - Y4) < SPLINE_TOL)
X      AddSplinePt (N, MaxN, round(X4), round(Y4));
X   else
X      SetSplineVs (N, MaxN, x, y, ((X2+3.0*X3)/4.0), ((Y2+3.0*Y3)/4.0),
X            ((X3+X4)/2.0), ((Y3+Y4)/2.0), X4, Y4);
X}
X
XXPoint * MakeSplinePolyVertex (N, XOff, YOff, NumVs, Vs)
X   int		* N, XOff, YOff, NumVs;
X   XPoint	* Vs;
X{
X   double	mx1, my1, mx2, my2, mx3, my3, mx4, my4, x1, y1, x2, y2;
X   int		i, x_off, y_off, max_n;
X
X   x_off = (XOff >> zoomScale) << zoomScale;
X   y_off = (YOff >> zoomScale) << zoomScale;
X
X   switch (NumVs)
X   {
X      case 0:
X      case 1:
X         break;
X      case 2:
X         splineVs = (XPoint *) calloc (3, sizeof (XPoint));
X         splineVs[0].x = (Vs[0].x-x_off)>>zoomScale;
X         splineVs[0].y = (Vs[0].y-y_off)>>zoomScale;
X         splineVs[1].x = (Vs[1].x-x_off)>>zoomScale;
X         splineVs[1].y = (Vs[1].y-y_off)>>zoomScale;
X         *N = 2;
X         break;
X      case 3:
X         mx1 = (Vs->x-x_off)>>zoomScale; my1 = ((Vs++)->y-y_off)>>zoomScale;
X         x1 = (Vs->x-x_off)>>zoomScale;  y1 = ((Vs++)->y-y_off)>>zoomScale;
X         mx2 = (mx1+x1)/2.0;            my2 = (my1+y1)/2.0;
X         mx4 = (Vs->x-x_off)>>zoomScale; my4 = (Vs->y-y_off)>>zoomScale;
X         mx3 = (x1+mx4)/2.0;            my3 = (y1+my4)/2.0;
X         max_n = 100;
X         splineVs = (XPoint *) calloc (max_n, sizeof (XPoint));
X         splineVs[0].x = mx1;
X         splineVs[0].y = my1;
X         *N = 1;
X         SetSplineVs (N, &max_n, mx1, my1, mx2, my2, mx3, my3, mx4, my4);
X         break;
X      default:
X         mx1 = (Vs->x-x_off)>>zoomScale; my1 = ((Vs++)->y-y_off)>>zoomScale;
X         x1 = (Vs->x-x_off)>>zoomScale;  y1 = ((Vs++)->y-y_off)>>zoomScale;
X         x2 = (Vs->x-x_off)>>zoomScale;  y2 = ((Vs++)->y-y_off)>>zoomScale;
X         mx2 = (mx1+x1)/2.0;            my2 = (my1+y1)/2.0;
X         mx3 = (3.0*x1+x2)/4.0;         my3 = (3.0*y1+y2)/4.0;
X         mx4 = (x1+x2)/2.0;             my4 = (y1+y2)/2.0;
X         max_n = 100;
X         splineVs = (XPoint *) calloc (max_n, sizeof (XPoint));
X         splineVs[0].x = mx1;
X         splineVs[0].y = my1;
X         *N = 1;
X         SetSplineVs (N, &max_n, mx1, my1, mx2, my2, mx3, my3, mx4, my4);
X      
X         for (i = 2; i < NumVs-2; i++, Vs++)
X         {
X            mx1 = mx4;                    my1 = my4;
X            mx2 = (x1 + 3.0*x2) / 4.0;    my2 = (y1 + 3.0*y2) / 4.0;
X            x1 = x2;                      y1 = y2;
X            x2 = (Vs->x-x_off)>>zoomScale; y2 = (Vs->y-y_off)>>zoomScale;
X            mx3 = (3.0*x1 + x2) / 4.0;    my3 = (3.0*y1 + y2) / 4.0;
X            mx4 = (x1 + x2) / 2.0;        my4 = (y1 + y2) / 2.0;
X            SetSplineVs (N, &max_n, mx1, my1, mx2, my2, mx3, my3, mx4, my4);
X         }
X         mx1 = mx4;                     my1 = my4;
X         mx2 = (x1 + 3.0*x2) / 4.0;     my2 = (y1 + 3.0*y2) / 4.0;
X         x1 = x2;                       y1 = y2;
X         mx4 = (Vs->x-x_off)>>zoomScale; my4 = (Vs->y-y_off)>>zoomScale;
X         mx3 = (x1 + mx4) / 2.0;        my3 = (y1 + my4) / 2.0;
X         SetSplineVs (N, &max_n, mx1, my1, mx2, my2, mx3, my3, mx4, my4);
X         break;
X   }
X   return (splineVs);
X}
X
Xstatic XPoint arrow_v[4];
X
Xvoid DrawSplinePolyObj (Win, XOff, YOff, Fill, Width, Pen, Dash, Pixel, PolyPtr)
X   Window		Win;
X   int			XOff, YOff, Fill, Width, Pen, Dash, Pixel;
X   struct PolyRec	* PolyPtr;
X{
X   XPoint	* sv = PolyPtr->svlist, * v;
X   double	dx, dy, len, sin, cos;
X   int		ah, aw, x_off, y_off, sn = PolyPtr->sn;
X   XGCValues	values;
X
X   x_off = (XOff >> zoomScale) << zoomScale;
X   y_off = (YOff >> zoomScale) << zoomScale;
X
X   if (Fill != 0)
X   {
X      sv[sn].x = sv[0].x; sv[sn].y = sv[0].y;
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
X      XFillPolygon (mainDisplay, Win, drawGC, sv, sn+1, 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 | GCLineWidth |
X            GCLineStyle, &values);
X
X      XDrawLines (mainDisplay, Win, drawGC, sv, sn, CoordModeOrigin);
X
X      ah = arrowHeadH[Width] >> zoomScale; if (ah == 0) ah = 1;
X      aw = arrowHeadW[Width] >> zoomScale; if (aw == 0) aw = 1;
X      if (PolyPtr->style & LS_LEFT)
X      {
X         v = PolyPtr->vlist;
X         arrow_v[0].x = arrow_v[3].x = (v->x-x_off)>>zoomScale;
X         arrow_v[0].y = arrow_v[3].y = (v->y-y_off)>>zoomScale;
X         dx = (double)(v[1].x - v[0].x);
X         dy = (double)(v[1].y - v[0].y);
X         len = (double) sqrt (dx * dx + dy * dy);
X         sin = dy / len;
X         cos = dx / len;
X         arrow_v[1].x = round(((int)(v->x-x_off)>>zoomScale)+aw*cos-ah*sin);
X         arrow_v[1].y = round(((int)(v->y-y_off)>>zoomScale)+aw*sin+ah*cos);
X         arrow_v[2].x = round(((int)(v->x-x_off)>>zoomScale)+aw*cos+ah*sin);
X         arrow_v[2].y = round(((int)(v->y-y_off)>>zoomScale)+aw*sin-ah*cos);
X
X         XFillPolygon (mainDisplay, Win, drawGC, arrow_v, 4, Convex,
X               CoordModeOrigin);
X      }
X      if (PolyPtr->style & LS_RIGHT)
X      {
X         v = &(PolyPtr->vlist[PolyPtr->n-2]);
X         arrow_v[0].x = arrow_v[3].x = (v[1].x-x_off)>>zoomScale;
X         arrow_v[0].y = arrow_v[3].y = (v[1].y-y_off)>>zoomScale;
X         dx = (double)(v[1].x - v[0].x);
X         dy = (double)(v[1].y - v[0].y);
X         len = (double) sqrt (dx * dx + dy * dy);
X         sin = dy / len;
X         cos = dx / len;
X         arrow_v[1].x = round(((int)(v[1].x-x_off)>>zoomScale)-aw*cos+ah*sin);
X         arrow_v[1].y = round(((int)(v[1].y-y_off)>>zoomScale)-aw*sin-ah*cos);
X         arrow_v[2].x = round(((int)(v[1].x-x_off)>>zoomScale)-aw*cos-ah*sin);
X         arrow_v[2].y = round(((int)(v[1].y-y_off)>>zoomScale)-aw*sin+ah*cos);
X
X         XFillPolygon (mainDisplay, Win, drawGC, arrow_v, 4, Convex,
X               CoordModeOrigin);
X      }
X   }
X}
X
XXPoint * MakeSplinePolygonVertex (N, XOff, YOff, NumVs, Vs)
X   int		* N, XOff, YOff, NumVs;
X   XPoint	* Vs;
X{
X   double	mx1, my1, mx2, my2, mx3, my3, mx4, my4, x1, y1, x2, y2;
X   int		i, max_n, x_off, y_off;
X
X   x_off = (XOff >> zoomScale) << zoomScale;
X   y_off = (YOff >> zoomScale) << zoomScale;
X
X   Vs[NumVs].x = Vs[1].x; Vs[NumVs].y = Vs[1].y;
X   x1 = (Vs->x-x_off)>>zoomScale; y1 = ((Vs++)->y-y_off)>>zoomScale;
X   x2 = (Vs->x-x_off)>>zoomScale; y2 = ((Vs++)->y-y_off)>>zoomScale;
X   mx4 = (x1 + x2) / 2.0;         my4 = (y1 + y2) / 2.0;
X
X   max_n = 100;
X   splineVs = (XPoint *) calloc (max_n, sizeof (XPoint));
X   splineVs[0].x = mx4;
X   splineVs[0].y = my4;
X   *N = 1;
X
X   for (i = 1; i < NumVs; i++, Vs++)
X   {
X      mx1 = mx4;                     my1 = my4;
X      mx2 = (x1+3.0*x2)/4.0;         my2 = (y1+3.0*y2)/4.0;
X      x1 = x2;                       y1 = y2;
X      x2 = (Vs->x-x_off)>>zoomScale; y2 = (Vs->y-y_off)>>zoomScale;
X      mx3 = (3.0*x1+x2)/4.0;         my3 = (3.0*y1+y2)/4.0;
X      mx4 = (x1+x2)/2.0;             my4 = (y1+y2)/2.0;
X      SetSplineVs (N, &max_n, mx1, my1, mx2, my2, mx3, my3, mx4, my4);
X   }
X   return (splineVs);
X}
X
Xvoid DrawSplinePolygonObj (Win,XOff,YOff,Fill,Width,Pen,Dash,Pixel,PolygonPtr)
X   Window		Win;
X   int			XOff, YOff, Fill, Width, Pen, Dash, Pixel;
X   struct PolygonRec	* PolygonPtr;
X{
X   XPoint	* sv = PolygonPtr->svlist;
X   int		sn = PolygonPtr->sn;
X   XGCValues	values;
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
X      XFillPolygon (mainDisplay, Win, drawGC, sv, sn, Complex, CoordModeOrigin);
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 | GCLineWidth |
X            GCLineStyle, &values);
X
X      XDrawLines (mainDisplay, Win, drawGC, sv, sn, CoordModeOrigin);
X   }
X}
X
Xvoid DumpCurvedPolyPoints (FP, NumPts, V, Indent)
X   FILE			* FP;
X   int			NumPts, Indent;
X   register XPoint	* V;
X{
X   register int	j, i;
X   double	x1, y1, x2, y2;
X   double	mx1, my1, mx2, my2, mx3, my3, mx4, my4;
X
X   switch (NumPts)
X   {
X      case 0:
X      case 1:
X      case 2:
X         break;
X      case 3:
X         mx1 = V->x; my1 = (V++)->y;
X         x1 = V->x; y1 = (V++)->y;
X         x2 = V->x; y2 = (V++)->y;
X         mx2 = (mx1 + 2.0*x1) / 3.0; my2 = (my1 + 2.0*y1) / 3.0;
X         mx3 = (2.0*x1 + x2) / 3.0; my3 = (2.0*y1 + y2) / 3.0;
X         for (j = 0; j < Indent; j++) fprintf (FP, " ");
X         fprintf (FP, "%.2f %.2f %.2f %.2f\n", mx2, my2, mx3, my3);
X         break;
X      default:
X         mx1 = V->x; my1 = (V++)->y;
X         x1 = V->x; y1 = (V++)->y;
X         x2 = V->x; y2 = (V++)->y;
X         mx2 = (mx1 + 2.0*x1) / 3.0; my2 = (my1 + 2.0*y1) / 3.0;
X         mx3 = (5.0*x1 + x2) / 6.0; my3 = (5.0*y1 + y2) / 6.0;
X         mx4 = (x1 + x2) / 2.0; my4 = (y1 + y2) / 2.0;
X         for (j = 0; j < Indent; j++) fprintf (FP, " ");
X         fprintf (FP, "%.2f %.2f %.2f %.2f %.2f %.2f curveto\n",
X               mx2, my2, mx3, my3, mx4, my4);
X      
X         for (i = 2; i < NumPts-2; i++, V++)
X         {
X            mx1 = mx4; my1 = my4;
X            mx2 = (x1 + 5.0*x2) / 6.0; my2 = (y1 + 5.0*y2) / 6.0;
X            x1 = x2; y1 = y2;
X            x2 = V->x; y2 = V->y;
X            mx3 = (5.0*x1 + x2) / 6.0; my3 = (5.0*y1 + y2) / 6.0;
X            mx4 = (x1 + x2) / 2.0; my4 = (y1 + y2) / 2.0;
X            for (j = 0; j < Indent; j++) fprintf (FP, " ");
X            fprintf (FP, "%.2f %.2f %.2f %.2f %.2f %.2f curveto\n",
X                  mx2, my2, mx3, my3, mx4, my4);
X         }
X         mx1 = mx4; my1 = my4;
X         mx2 = (x1 + 5.0*x2) / 6.0; my2 = (y1 + 5.0*y2) / 6.0;
X         x1 = x2; y1 = y2;
X         mx3 = (2.0*x1 + V->x) / 3.0; my3 = (2.0*y1 + V->y) / 3.0;
X         for (j = 0; j < Indent; j++) fprintf (FP, " ");
X         fprintf (FP, "%.2f %.2f %.2f %.2f\n", mx2, my2, mx3, my3);
X         break;
X   }
X}
X
Xvoid DumpCurvedPolygonPoints (FP, NumPts, V, Indent)
X   FILE			* FP;
X   int			NumPts, Indent;
X   register XPoint	* V;
X{
X   register int	j;
X   double	mx1, my1, mx2, my2, mx3, my3, mx4, my4, x1, y1, x2, y2;
X   int		i;
X
X   V[NumPts].x = V[1].x; V[NumPts].y = V[1].y;
X   x1 = V->x;             y1 = (V++)->y;
X   x2 = V->x;             y2 = (V++)->y;
X   mx4 = (x1 + x2) / 2.0; my4 = (y1 + y2) / 2.0;
X   for (j = 0; j < Indent; j++) fprintf (FP, " ");
X   fprintf (FP, "%.2f %.2f moveto\n", mx4, my4);
X
X   for (i = 1; i < NumPts; i++, V++)
X   {
X      mx1 = mx4;             my1 = my4;
X      mx2 = (x1+5.0*x2)/6.0; my2 = (y1+5.0*y2)/6.0;
X      x1 = x2;               y1 = y2;
X      x2 = V->x;             y2 = V->y;
X      mx3 = (5.0*x1+x2)/6.0; my3 = (5.0*y1+y2)/6.0;
X      mx4 = (x1+x2)/2.0;     my4 = (y1+y2)/2.0;
X      for (j = 0; j < Indent; j++) fprintf (FP, " ");
X      fprintf (FP, "%.2f %.2f %.2f %.2f %.2f %.2f curveto\n",
X            mx2, my2, mx3, my3, mx4, my4);
X   }
X}
X
Xstatic
Xint PointInSpline (PX, PY, W, X1, Y1, X2, Y2, X3, Y3, X4, Y4)
X   int		PX, PY, W;
X   double	X1, Y1, X2, Y2, X3, Y3, X4, Y4;
X   /* X and Y are absolute coordinates */
X{
X   register double	x, y;
X
X   x = (X2 + X3) / 2.0;
X   y = (Y2 + Y3) / 2.0;
X   if (fabs (X1 - x) < SPLINE_TOL && fabs (Y1 - y) < SPLINE_TOL)
X      return (PX > min(X1,x)-W && PX < max(X1,x)+W &&
X            PY > min(Y1,y)-W && PY < max(Y1,y)+W);
X   else
X      if (PointInSpline  (PX, PY, W, X1, Y1, (X1+X2)/2.0, (Y1+Y2)/2.0,
X            (3.0*X2+X3)/4.0, (3.0*Y2+Y3)/4.0, x, y))
X         return (TRUE);
X
X   if (fabs (x - X4) < SPLINE_TOL && fabs (y - Y4) < SPLINE_TOL)
X      return (PX > min(X4,x)-W && PX < max(X4,x)+W &&
X            PY > min(Y4,y)-W && PY < max(Y4,y)+W);
X   else
X      return (PointInSpline (PX, PY, W, x, y, (X2+3.0*X3)/4.0, (Y2+3.0*Y3)/4.0,
X            (X3+X4)/2.0, (Y3+Y4)/2.0, X4, Y4));
X}
X
Xint PointInSplinePoly (X, Y, PolyPtr, W)
X   int			X, Y, W;
X   struct PolyRec	* PolyPtr;
X   /* X and Y are absolute coordinates */
X{
X   double	mx1, my1, mx2, my2, mx3, my3, mx4, my4, x1, y1, x2, y2;
X   int		i, in_region, sn, num_pts = PolyPtr->n;
X   XPoint	* v = PolyPtr->vlist, * sv;
X   Region	region;
X
X   if (PolyPtr->fill != NONEPAT)
X   {
X      sv = PolyPtr->svlist;
X      sn = PolyPtr->sn;
X      sv[sn].x = sv[0].x; sv[sn].y = sv[0].y;
X      region = XPolygonRegion (sv, sn+1, EvenOddRule);
X      in_region = XPointInRegion (region, (X-drawOrigX)>>zoomScale,
X            (Y-drawOrigY)>>zoomScale);
X      XDestroyRegion (region);
X      if (in_region) return (TRUE);
X   }
X
X   switch (num_pts)
X   {
X      case 2:
X         return (PointInPoly (X, Y, num_pts, v, W));
X      case 3:
X         mx1 = v->x;             my1 = (v++)->y;
X         x1 = v->x;              y1 = (v++)->y;
X         mx4 = v->x;             my4 = v->y;
X         mx2 = (mx1 + x1) / 2.0; my2 = (my1 + y1) / 2.0;
X         mx3 = (x1 + mx4) / 2.0; my3 = (y1 + my4) / 2.0;
X         return (PointInSpline (X, Y, W, mx1, my1, mx2, my2, mx3, my3, mx4, my4));
X      default:
X         mx1 = v->x;            my1 = (v++)->y;
X         x1 = v->x;             y1 = (v++)->y;
X         x2 = v->x;             y2 = (v++)->y;
X         mx2 = (mx1+x1)/2.0;    my2 = (my1+y1)/2.0;
X         mx3 = (3.0*x1+x2)/4.0; my3 = (3.0*y1+y2)/4.0;
X         mx4 = (x1+x2)/2.0;     my4 = (y1+y2)/2.0;
X         if (PointInSpline (X, Y, W, mx1, my1, mx2, my2, mx3, my3, mx4, my4))
X            return (TRUE);
X      
X         for (i = 2; i < num_pts-2; i++, v++)
X         {
X            mx1 = mx4;             my1 = my4;
X            mx2 = (x1+3.0*x2)/4.0; my2 = (y1+3.0*y2)/4.0;
X            x1 = x2;               y1 = y2;
X            x2 = v->x;             y2 = v->y;
X            mx3 = (3.0*x1+x2)/4.0; my3 = (3.0*y1+y2)/4.0;
X            mx4 = (x1+x2)/2.0;     my4 = (y1+y2)/2.0;
X            if (PointInSpline (X, Y, W, mx1, my1, mx2, my2, mx3, my3, mx4, my4))
X               return (TRUE);
X         }
X         mx1 = mx4;             my1 = my4;
X         mx2 = (x1+3.0*x2)/4.0; my2 = (y1+3.0*y2)/4.0;
X         x1 = x2;               y1 = y2;
X         mx4 = v->x;            my4 = v->y;
X         mx3 = (x1+mx4)/2.0;    my3 = (y1+my4)/2.0;
X         return (PointInSpline (X, Y, W, mx1, my1, mx2, my2, mx3, my3, mx4, my4));
X   }
X}
X
Xint PointInSplinePolygon (X, Y, PolygonPtr, W)
X   int			X, Y, W;
X   struct PolygonRec	* PolygonPtr;
X   /* X and Y are absolute coordinates */
X{
X   double	mx1, my1, mx2, my2, mx3, my3, mx4, my4, x1, y1, x2, y2;
X   int		i, in_region, num_pts = PolygonPtr->n;
X   XPoint	* v = PolygonPtr->vlist;
X   Region	region;
X
X   if (PolygonPtr->fill != NONEPAT)
X   {
X      region = XPolygonRegion (PolygonPtr->svlist, PolygonPtr->sn, EvenOddRule);
X      in_region = XPointInRegion (region, (X-drawOrigX)>>zoomScale,
X            (Y-drawOrigY)>>zoomScale);
X      XDestroyRegion (region);
X      if (in_region) return (TRUE);
X   }
X
X   v[num_pts].x = v[1].x; v[num_pts].y = v[1].y;
X   x1 = v->x;             y1 = (v++)->y;
X   x2 = v->x;             y2 = (v++)->y;
X   mx4 = (x1+x2)/2.0;     my4 = (y1+y2)/2.0;
X
X   for (i = 1; i < num_pts; i++, v++)
X   {
X      mx1 = mx4;             my1 = my4;
X      mx2 = (x1+3.0*x2)/4.0; my2 = (y1+3.0*y2)/4.0;
X      x1 = x2;               y1 = y2;
X      x2 = v->x;             y2 = v->y;
X      mx3 = (3.0*x1+x2)/4.0; my3 = (3.0*y1+y2)/4.0;
X      mx4 = (x1+x2)/2.0;     my4 = (y1+y2)/2.0;
X      if (PointInSpline (X, Y, W, mx1, my1, mx2, my2, mx3, my3, mx4, my4))
X         return (TRUE);
X   }
X   return (FALSE);
X}
END_OF_FILE
if test 18843 -ne `wc -c <'spline.c'`; then
    echo shar: \"'spline.c'\" unpacked with wrong size!
fi
# end of 'spline.c'
fi
echo shar: End of archive 14 \(of 23\).
cp /dev/null ark14isdone
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