v04i070: xpic -- pic previewer for X11, Part05/15

Dan Heller argv at island.uu.net
Fri Jul 21 05:16:57 AEST 1989


Submitted-by: Mark Moraes <moraes at ai.toronto.edu>
Posting-number: Volume 4, Issue 70
Archive-name: xpic/part05



#! /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 5 (of 15)."
# Contents:  xpic/fonts.alias xpic/obj_box.c xpic/obj_elem.c
#   xpic/obj_text.c xpic/test/test.pic xpic/updown.c xpic/xtypeout.c
# Wrapped by moraes at neat.ai on Thu Jul 13 22:36:07 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'xpic/fonts.alias' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/fonts.alias'\"
else
echo shar: Extracting \"'xpic/fonts.alias'\" \(5867 characters\)
sed "s/^X//" >'xpic/fonts.alias' <<'END_OF_FILE'
Xdevpsc.cd.10.75	-adobe-courier-bold-o-normal--10-100-75-75-m-60-iso8859-1
Xdevpsc.cd.12.75	-adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
Xdevpsc.cd.14.75	-adobe-courier-bold-o-normal--14-140-75-75-m-90-iso8859-1
Xdevpsc.cd.18.75	-adobe-courier-bold-o-normal--18-180-75-75-m-110-iso8859-1
Xdevpsc.cd.24.75	-adobe-courier-bold-o-normal--24-240-75-75-m-150-iso8859-1
Xdevpsc.cd.8.75	-adobe-courier-bold-o-normal--8-80-75-75-m-50-iso8859-1
Xdevpsc.cb.10.75	-adobe-courier-bold-r-normal--10-100-75-75-m-60-iso8859-1
Xdevpsc.cb.12.75	-adobe-courier-bold-r-normal--12-120-75-75-m-70-iso8859-1
Xdevpsc.cb.14.75	-adobe-courier-bold-r-normal--14-140-75-75-m-90-iso8859-1
Xdevpsc.cb.18.75	-adobe-courier-bold-r-normal--18-180-75-75-m-110-iso8859-1
Xdevpsc.cb.24.75	-adobe-courier-bold-r-normal--24-240-75-75-m-150-iso8859-1
Xdevpsc.cb.8.75	-adobe-courier-bold-r-normal--8-80-75-75-m-50-iso8859-1
Xdevpsc.co.10.75	-adobe-courier-medium-o-normal--10-100-75-75-m-60-iso8859-1
Xdevpsc.co.12.75	-adobe-courier-medium-o-normal--12-120-75-75-m-70-iso8859-1
Xdevpsc.co.14.75	-adobe-courier-medium-o-normal--14-140-75-75-m-90-iso8859-1
Xdevpsc.co.18.75	-adobe-courier-medium-o-normal--18-180-75-75-m-110-iso8859-1
Xdevpsc.co.24.75	-adobe-courier-medium-o-normal--24-240-75-75-m-150-iso8859-1
Xdevpsc.co.8.75	-adobe-courier-medium-o-normal--8-80-75-75-m-50-iso8859-1
Xdevpsc.c.10.75	-adobe-courier-medium-r-normal--10-100-75-75-m-60-iso8859-1
Xdevpsc.c.12.75	-adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1
Xdevpsc.c.14.75	-adobe-courier-medium-r-normal--14-140-75-75-m-90-iso8859-1
Xdevpsc.c.18.75	-adobe-courier-medium-r-normal--18-180-75-75-m-110-iso8859-1
Xdevpsc.c.24.75	-adobe-courier-medium-r-normal--24-240-75-75-m-150-iso8859-1
Xdevpsc.c.8.75	-adobe-courier-medium-r-normal--8-80-75-75-m-50-iso8859-1
Xdevpsc.hd.10.75	-adobe-helvetica-bold-o-normal--10-100-75-75-p-60-iso8859-1
Xdevpsc.hd.12.75	-adobe-helvetica-bold-o-normal--12-120-75-75-p-69-iso8859-1
Xdevpsc.hd.14.75	-adobe-helvetica-bold-o-normal--14-140-75-75-p-82-iso8859-1
Xdevpsc.hd.18.75	-adobe-helvetica-bold-o-normal--18-180-75-75-p-104-iso8859-1
Xdevpsc.hd.24.75	-adobe-helvetica-bold-o-normal--24-240-75-75-p-138-iso8859-1
Xdevpsc.hd.8.75	-adobe-helvetica-bold-o-normal--8-80-75-75-p-50-iso8859-1
Xdevpsc.hb.10.75	-adobe-helvetica-bold-r-normal--10-100-75-75-p-60-iso8859-1
Xdevpsc.hb.12.75	-adobe-helvetica-bold-r-normal--12-120-75-75-p-70-iso8859-1
Xdevpsc.hb.14.75	-adobe-helvetica-bold-r-normal--14-140-75-75-p-82-iso8859-1
Xdevpsc.hb.18.75	-adobe-helvetica-bold-r-normal--18-180-75-75-p-103-iso8859-1
Xdevpsc.hb.24.75	-adobe-helvetica-bold-r-normal--24-240-75-75-p-138-iso8859-1
Xdevpsc.hb.8.75	-adobe-helvetica-bold-r-normal--8-80-75-75-p-50-iso8859-1
Xdevpsc.ho.10.75	-adobe-helvetica-medium-o-normal--10-100-75-75-p-57-iso8859-1
Xdevpsc.ho.12.75	-adobe-helvetica-medium-o-normal--12-120-75-75-p-67-iso8859-1
Xdevpsc.ho.14.75	-adobe-helvetica-medium-o-normal--14-140-75-75-p-78-iso8859-1
Xdevpsc.ho.18.75	-adobe-helvetica-medium-o-normal--18-180-75-75-p-98-iso8859-1
Xdevpsc.ho.24.75	-adobe-helvetica-medium-o-normal--24-240-75-75-p-130-iso8859-1
Xdevpsc.ho.8.75	-adobe-helvetica-medium-o-normal--8-80-75-75-p-47-iso8859-1
Xdevpsc.h.10.75	-adobe-helvetica-medium-r-normal--10-100-75-75-p-56-iso8859-1
Xdevpsc.h.12.75	-adobe-helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1
Xdevpsc.h.14.75	-adobe-helvetica-medium-r-normal--14-140-75-75-p-77-iso8859-1
Xdevpsc.h.18.75	-adobe-helvetica-medium-r-normal--18-180-75-75-p-98-iso8859-1
Xdevpsc.h.24.75	-adobe-helvetica-medium-r-normal--24-240-75-75-p-130-iso8859-1
Xdevpsc.h.8.75	-adobe-helvetica-medium-r-normal--8-80-75-75-p-46-iso8859-1
Xdevpsc.bi.10.75	-adobe-times-bold-i-normal--10-100-75-75-p-57-iso8859-1
Xdevpsc.bi.12.75	-adobe-times-bold-i-normal--12-120-75-75-p-68-iso8859-1
Xdevpsc.bi.14.75	-adobe-times-bold-i-normal--14-140-75-75-p-77-iso8859-1
Xdevpsc.bi.18.75	-adobe-times-bold-i-normal--18-180-75-75-p-98-iso8859-1
Xdevpsc.bi.24.75	-adobe-times-bold-i-normal--24-240-75-75-p-128-iso8859-1
Xdevpsc.bi.8.75	-adobe-times-bold-i-normal--8-80-75-75-p-47-iso8859-1
Xdevpsc.b.10.75	-adobe-times-bold-r-normal--10-100-75-75-p-57-iso8859-1
Xdevpsc.b.12.75	-adobe-times-bold-r-normal--12-120-75-75-p-67-iso8859-1
Xdevpsc.b.14.75	-adobe-times-bold-r-normal--14-140-75-75-p-77-iso8859-1
Xdevpsc.b.18.75	-adobe-times-bold-r-normal--18-180-75-75-p-99-iso8859-1
Xdevpsc.b.24.75	-adobe-times-bold-r-normal--24-240-75-75-p-132-iso8859-1
Xdevpsc.b.8.75	-adobe-times-bold-r-normal--8-80-75-75-p-47-iso8859-1
Xdevpsc.i.10.75	-adobe-times-medium-i-normal--10-100-75-75-p-52-iso8859-1
Xdevpsc.i.12.75	-adobe-times-medium-i-normal--12-120-75-75-p-63-iso8859-1
Xdevpsc.i.14.75	-adobe-times-medium-i-normal--14-140-75-75-p-73-iso8859-1
Xdevpsc.i.18.75	-adobe-times-medium-i-normal--18-180-75-75-p-94-iso8859-1
Xdevpsc.i.24.75	-adobe-times-medium-i-normal--24-240-75-75-p-125-iso8859-1
Xdevpsc.i.8.75	-adobe-times-medium-i-normal--8-80-75-75-p-42-iso8859-1
Xdevpsc.r.10.75	-adobe-times-medium-r-normal--10-100-75-75-p-54-iso8859-1
Xdevpsc.r.12.75	-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1
Xdevpsc.r.14.75	-adobe-times-medium-r-normal--14-140-75-75-p-74-iso8859-1
Xdevpsc.r.18.75	-adobe-times-medium-r-normal--18-180-75-75-p-94-iso8859-1
Xdevpsc.r.24.75	-adobe-times-medium-r-normal--24-240-75-75-p-124-iso8859-1
Xdevpsc.r.8.75	-adobe-times-medium-r-normal--8-80-75-75-p-44-iso8859-1
Xdevpsc.s.10.75	dec-adobe-symbol-medium-r-normal--10-100-75-75-p-61-adobe-fontspecific
Xdevpsc.s.12.75	dec-adobe-symbol-medium-r-normal--12-120-75-75-p-74-adobe-fontspecific
Xdevpsc.s.14.75	dec-adobe-symbol-medium-r-normal--14-140-75-75-p-85-adobe-fontspecific
Xdevpsc.s.18.75	dec-adobe-symbol-medium-r-normal--18-180-75-75-p-107-adobe-fontspecific
Xdevpsc.s.24.75	dec-adobe-symbol-medium-r-normal--24-240-75-75-p-142-adobe-fontspecific
Xdevpsc.s.8.75	dec-adobe-symbol-medium-r-normal--8-80-75-75-p-51-adobe-fontspecific
END_OF_FILE
if test 5867 -ne `wc -c <'xpic/fonts.alias'`; then
    echo shar: \"'xpic/fonts.alias'\" unpacked with wrong size!
fi
# end of 'xpic/fonts.alias'
fi
if test -f 'xpic/obj_box.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/obj_box.c'\"
else
echo shar: Extracting \"'xpic/obj_box.c'\" \(6147 characters\)
sed "s/^X//" >'xpic/obj_box.c' <<'END_OF_FILE'
X/* $Header: obj_box.c,v 1.3 89/02/23 02:47:53 xwindows Exp $ */
X/*
X *  The box object routines
X */
X#include <math.h>
X
X#include "xpic.h"
X#include "windows.h"
X#include "gels.h"
X#include "draw.h"
X#include "assert.h"
X
Xstatic int x_1, y_1, x_2, y_2;			/* Corners of box, ellipse, ends of line */
Xstatic int xmin, xmax, ymin, ymax;	/* Bounding box */
X
Xbox_event(evtype, mx, my)
X{
X	switch(evtype) {
X	case MOTION | START_MODE:
X	case RIGHT  | START_MODE:
X	case MIDDLE | START_MODE:
X	case REDRAW | START_MODE:
X	case RIGHT  | END_MODE:
X		break;
X	case MOTION | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcInvert);
X		x_2 = mx;
X		y_2 = my;
X		box(picWin, x_1, y_1, x_2, y_2, gcInvert);
X		break;
X	case LEFT | START_MODE:
X		x_1 = x_2 = mx;
X		y_1 = y_2 = my;
X		drawingMode = END_MODE;
X		box(picWin, x_1, y_1, x_2, y_2, gcInvert);
X		break;
X	case LEFT | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcInvert);
X		x_2 = mx;
X		y_2 = my;
X		xmin = MIN(x_1, mx);
X		xmax = MAX(x_1, mx);
X		ymin = MIN(y_1, my);
X		ymax = MAX(y_1, my);
X		box(picWin, x_1, y_1, x_2, y_2, gcNormal);
X		AddBoxGel(&(CurrentCell->gelList), xmin, ymin, xmax, ymax,
X		 line_type | fill_type, lineThickness);
X		FreeGel(CurrentCell->undoList);
X		CurrentCell->undoList = NULL;
X		CurrentCell->undo = 1;
X		CurrentCell->saved |= MODIFIED;
X		drawingMode = START_MODE;
X		break;
X	case MIDDLE | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcInvert);
X		drawingMode = START_MODE;
X		break;
X	case REDRAW | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, gcInvert);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Hey! Unknown BOX mode %d", drawingMode);
X		message(errstring);
X#endif
X		break;
X	}
X	ASSERT(allock(), "box_event");
X}
X
X
Xbox_abort()
X{
X	box_event((MIDDLE | drawingMode), 0, 0);
X}
X	
X
Xbox_adj(evtype, gel, mx, my)
Xint evtype;
XGel *gel;
Xint mx, my;
X{
X	static Gel *boxgel;
X	/*
X	 *  Will not need to process MOTION|START_MODE, RIGHT|START_MODE,
X	 *  REDRAW|START_MODE - these are taken care of in
X	 *  the adj_element routine.
X	 */
X	switch(evtype) {
X	case MOTION | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, tmpGcInvert);
X		x_2 = mx;
X		y_2 = my;
X		box(picWin, x_1, y_1, x_2, y_2, tmpGcInvert);
X		break;
X	case LEFT | START_MODE:
X		GetBoxCorners(&x_1, &y_1, &x_2, &y_2, &gel->b_box, mx, my);
X		boxgel = gel;
X		drawingMode = END_MODE;
X		setwidth(tmpGcNormal, boxgel->linewidth);
X		setwidth(tmpGcInvert, boxgel->linewidth);
X		SETDASHES(tmpGcNormal, getlinestyle(boxgel->attributes))
X		SETDASHES(tmpGcInvert, getlinestyle(boxgel->attributes))
X		box(picWin, x_1, y_1, x_2, y_2, tmpGcInvert);
X		break;
X	case LEFT | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, tmpGcInvert);
X		x_2 = mx;
X		y_2 = my;
X		xmin = MIN(x_1, mx);
X		xmax = MAX(x_1, mx);
X		ymin = MIN(y_1, my);
X		ymax = MAX(y_1, my);
X		box(picWin, x_1, y_1, x_2, y_2, tmpGcNormal);
X		AddBoxGel(&(CurrentCell->gelList), xmin, ymin, xmax, ymax,
X		 boxgel->attributes, boxgel->linewidth);
X		FreeGel(CurrentCell->undoList);
X		CurrentCell->undoList = boxgel;
X		boxgel = NULL;
X		CurrentCell->undo = 1;
X		CurrentCell->saved |= MODIFIED;
X		drawingMode = START_MODE;
X		break;
X	case RIGHT | END_MODE:
X	case MIDDLE | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, tmpGcInvert);
X		GelDraw(boxgel, DRAW);
X		(void) PushUnderUndo(&(CurrentCell->gelList), boxgel,
X		 CurrentCell->undo);
X		boxgel = NULL;
X		if (evtype == (MIDDLE | END_MODE))
X			ClearGelFlags(CurrentCell->gelList);
X		drawingMode = START_MODE;
X		break;
X	case MIDDLE | START_MODE:
X		ClearGelFlags(CurrentCell->gelList);
X		break;
X	case REDRAW | END_MODE:
X		box(picWin, x_1, y_1, x_2, y_2, tmpGcInvert);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Hey! Unknown mode %d in box_adj", 
X		 evtype);
X		message(errstring);
X#endif
X		break;
X	}
X	ASSERT(allock(), "box_adj");
X}
X
X/*
X *  Puts box the corner of b that is farthest from mx, my in x_1, y_1, and
X *  closer corner in x_2, y_2 (which will get moved)
X */
XGetBoxCorners(x_1, y_1, x_2, y_2, b, mx, my)
Xint *x_1, *x_2, *y_1, *y_2;
XBox *b;
Xint mx, my;
X{
X	int d1, d2, tmp;
X	
X	*x_1 = b->ll.x;
X	*y_1 = b->ll.y;
X	*x_2 = b->ur.x;
X	*y_2 = b->ur.y;
X	/* Make sure x_1, y_1 is farthest point in box from mouse coords */
X	d1 = ABS(*x_1 - mx);
X	d2 = ABS(*x_2 - mx);
X	if (d1 < d2) {
X		tmp = *x_1;
X		*x_1 = *x_2;
X		*x_2 = tmp;
X	}
X	d1 = ABS(*y_1 - my);
X	d2 = ABS(*y_2 - my);
X	if (d1 < d2) {
X		tmp = *y_1;
X		*y_1 = *y_2;
X		*y_2 = tmp;
X	}
X}
X
X
X/*
X * Finds distance of point from a box. This is the distance of the closest
X * edge of the box to the point. We compute it by using the four logical
X * conditions to determine which region of the box the point lies in.
X */
X/*
X *       6             7             5
X *
X *               +------------+
X *               |            |
X *      14       |    15      |     13
X *               |            |
X *               +------------+
X *
X *      10            11             9
X */
X/*
X * In regions 5, 6, 9, 10, the distance is from the nearest corner. For
X * regions 7, 11, 13, 14, the distance is from the nearest edge, and for
X * region 15, the distance is the minimum of the distance from all the edges
X */
Xint
Xbox_distance(gel, xp, yp)
XGel *gel;
Xint xp, yp;
X{
X	int region = 0;
X	int dist;
X	Box *b = &gel->b_box;
X	int dx_1 = xp - b->ll.x;
X	int dy_1 = yp - b->ll.y;
X	int dx_2 = b->ur.x - xp;
X	int dy_2 = b->ur.y - yp;
X
X	if (dx_1 >= 0)
X		region += 1;
X	if (dx_2 >= 0)
X		region += 2;
X	if (dy_1 >= 0)
X		region += 4;
X	if (dy_2 >= 0)
X		region += 8;
X
X	switch(region) {
X	case 0:
X	case 1:
X	case 2:
X	case 3:
X	case 4:
X		ASSERT(0, "Impossible region in box");
X		break;
X	case 5:
X		dist = sqrt((double) (dx_2 * dx_2 + dy_2 * dy_2));
X		break;
X	case 6:
X		dist = sqrt((double) (dx_1 * dx_1 + dy_2 * dy_2));
X		break;
X	case 7:
X		dist = -dy_2;
X		break;
X	case 8:
X		ASSERT(0, "Impossible region in box");
X		break;
X	case 9:
X		dist = sqrt((double) (dx_2 * dx_2 + dy_1 * dy_1));
X		break;
X	case 10:
X		dist = sqrt((double) (dx_1 * dx_1 + dy_1 * dy_1));
X		break;
X	case 11:
X		dist = -dy_1;
X		break;
X	case 12:
X		ASSERT(0, "Impossible region in box");
X		break;
X	case 13:
X		dist = -dx_2;
X		break;
X	case 14:
X		dist = -dx_1;
X		break;
X	case 15:
X		dist = MIN(dx_1, dx_2);
X		dist = MIN(dist, dy_1);
X		dist = MIN(dist, dy_2);
X		break;
X	}
X	return(dist);
X}
END_OF_FILE
if test 6147 -ne `wc -c <'xpic/obj_box.c'`; then
    echo shar: \"'xpic/obj_box.c'\" unpacked with wrong size!
fi
# end of 'xpic/obj_box.c'
fi
if test -f 'xpic/obj_elem.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/obj_elem.c'\"
else
echo shar: Extracting \"'xpic/obj_elem.c'\" \(8859 characters\)
sed "s/^X//" >'xpic/obj_elem.c' <<'END_OF_FILE'
X/* $Header: obj_elem.c,v 1.5 89/04/20 22:50:25 xwindows Exp $ */
X/*
X *  The element editing routines.
X */
X#include "xpic.h"
X#include "windows.h"
X#include "spline.h"
X#include "gels.h"
X#include "input.h"
X#include "newfonts.h"
X#include "assert.h"
X
Xstatic Gel *gel;
Xstatic int origX, origY;
Xstatic int lastX, lastY;
X
X/* 
X *  Basic rationale: START_MODE means wandering around with the mouse, a
X *  LEFT click means selecting the nearest object. It gets attached to
X *  the mouse, and goes into END_MODE. A right click puts it back where
X *  it was, and marks it so that the next LEFT click won't select it,
X *  but will instead select the next-nearest object. A MIDDLE button
X *  aborts, restoring the object to its old position, and back to
X *  START_MODE. If DELETE is desired, the object gets highlighted
X *  instead of attached to the mouse, and the user is asked to confirm
X *  the delete with a mouse click. Adjust puts you in an appropriate
X *  mode - for circles, ellipses, boxes and text it is as if you are
X *  creating the object again - for lines, splines, it selects the
X *  nearest point and rubber-bands it. You can move it anywhere you
X *  like. Scale and rotate are a bit more complicated - later.
X */
Xelement_event(evtype, mx, my)
X{
X	switch (editType) {
X	case COPY:
X	case MOVE:
X		move_element(evtype, mx, my);
X		break;
X	case CHANGE_ATTRIBUTE:
X	case DELETE:
X		delete_element(evtype, mx, my);
X		break;
X	case ADJUST:
X		adjust_element(evtype, mx, my);
X		break;
X	case ROTATE:
X		rotate_element(evtype, mx, my);
X		break;
X	case SCALE:
X		scale_element(evtype, mx, my);
X		break;
X	case PASTE:
X		move_element(evtype, mx, my);
X		break;
X	case PUT:
X	case GET:
X		message("Get/Put only allowed in BLOCK mode");
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Unknown ELEMENT editType - %d", editType);
X		message(errstring);
X#endif
X		break;
X	}
X	ASSERT(allock(), "element_event");
X}
X
X
Xelement_abort()
X{
X	element_event((MIDDLE | drawingMode), 0, 0);
X}
X	
X
X/*
X *  This is called from element_event if the editType is MOVE, COPY, or
X *  PASTE. We do slightly different things for each
X */
Xmove_element(evtype, mx, my)
X{
X	int remove_old_gel = (editType == MOVE);
X	
X	switch(evtype) {
X	case MOTION | START_MODE:
X	case RIGHT  | START_MODE:
X	case REDRAW | START_MODE:
X		break;
X	case MIDDLE | START_MODE:
X		ClearGelFlags(CurrentCell->gelList);
X		break;
X	case MOTION | END_MODE:
X		GelDraw(gel, INVERT);
X		MoveGel(gel, mx - lastX, my - lastY);
X		lastX = mx;
X		lastY = my;
X		GelDraw(gel, INVERT);
X		break;
X	case LEFT | START_MODE:
X		origX = lastX = mx;
X		origY = lastY = my;
X		if (editType == PASTE) {
X			if (KillBuffer == NULL) {
X				message("Nothing to paste. Delete something first");
X				return;
X			}
X			gel = CopyGel(KillBuffer, 1);
X			MoveGel(gel, mx - KillX, my - KillY);
X		} else { /* MOVE, COPY */
X			if ((gel = SelectGel(CurrentCell->gelList, mx, my)) == NULL)
X				return;
X			if (remove_old_gel) {
X				GelDraw(gel, ERASE);
X				gel = RemoveGel(&(CurrentCell->gelList), gel);
X			} else {
X				gel = CopyGel(gel, 1);
X			}
X		}
X		GelDraw(gel, INVERT);
X		drawingMode = END_MODE;
X		break;
X	case LEFT | END_MODE:
X		GelDraw(gel, INVERT);
X		MoveGel(gel, mx - lastX, my - lastY);
X		lastX = mx;
X		lastY = my;
X		GelDraw(gel, DRAW);
X		FreeGel(KillBuffer);
X		KillBuffer = CopyGel(gel, 1);
X		KillX = mx;
X		KillY = my;
X		(void) PushGel(&(CurrentCell->gelList), gel);
X		FreeGel(CurrentCell->undoList);
X		if (editType == MOVE) {
X			/*
X			 *  To undo a move, we need to clobber the new
X			 *  gel (in its moved position), and put the old
X			 *  gel back
X			 */
X			CurrentCell->undoList = CopyGel(gel, 1);
X			MoveGel(CurrentCell->undoList, 
X			 origX - lastX, origY - lastY);
X		} else {/* COPY, PASTE */
X			/*
X			 *  For Copy or Paste, we only need to zonk the
X			 *  new gel
X			 */
X			CurrentCell->undoList = NULL;
X		}
X		gel = NULL;
X		CurrentCell->undo = 1;
X		CurrentCell->saved |= MODIFIED;
X		ClearGelFlags(CurrentCell->gelList);
X		drawingMode = START_MODE;
X		break;
X	case RIGHT | END_MODE:
X	case MIDDLE | END_MODE:
X		GelDraw(gel, INVERT);
X		if (editType == PASTE || editType == COPY) {
X			FreeGel(gel);
X			gel = NULL;
X		} else if (editType == MOVE) {
X			MoveGel(gel, origX - lastX, origY - lastY);
X			GelDraw(gel, DRAW);
X			(void) PushUnderUndo(&(CurrentCell->gelList), gel,
X			 CurrentCell->undo);
X		} 
X#ifdef DEBUG
X		else {
X			(void) sprintf(errstring, "move_element: RIGHT editType = %d",
X			 editType);
X			message(errstring);
X		}
X#endif
X		if (evtype == (MIDDLE | END_MODE))
X			ClearGelFlags(CurrentCell->gelList);
X		drawingMode = START_MODE;
X		break;
X	case REDRAW | END_MODE:
X		GelDraw(gel, INVERT);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Hey! Unknown mode %d in move_element", 
X		 evtype);
X		message(errstring);
X#endif
X		break;
X	}
X}
X
X
X/*
X *  This should actually be called ClearSelectedGels since that's what
X *  it does - it does not affect the HILITED flag, for instance
X */
XClearGelFlags(g)
Xregister Gel *g;
X{
X#ifdef DEBUG
X	int cleared = 0;
X#endif
X
X	for(;g != NULL; g= g->next) {
X#ifdef DEBUG
X		if (g->int_flags & SELECTED) cleared++;
X#endif
X		g->int_flags &= ~SELECTED;
X	}
X	
X#ifdef DEBUG
X	(void) sprintf(errstring, "Cleared %d elements which had been selected",
X	 cleared);
X	message(errstring);
X#endif
X}
X
X
X/*
X *  This is called with editTypes of DELETE or CHANGE_ATTRIBUTE. The
X *  first simply deletes the selected gel after confirmation, the latter
X *  changes the gel's attributes to the current ones after confirmation.
X *  END_MODE simply means wait to confirm.
X */
Xdelete_element(evtype, mx, my)
X{
X	switch(evtype) {
X	case MOTION | START_MODE:
X	case RIGHT  | START_MODE:
X	case REDRAW | START_MODE:
X	case MOTION | END_MODE:
X		break;
X	case MIDDLE | START_MODE:
X		ClearGelFlags(CurrentCell->gelList);
X		break;
X	case LEFT | START_MODE:
X		if ((gel = SelectGel(CurrentCell->gelList, mx, my)) == NULL)
X			return;
X		origX = mx;
X		origY = my;
X		gel = RemoveGel(&(CurrentCell->gelList), gel);
X		GelDraw(gel, ERASE);
X		GelHilite(gel);
X		(void) sprintf(errstring, "Click Left button to confirm %s", 
X		 (editType == DELETE) ? "Delete" : "Change");
X		message(errstring);
X		drawingMode = END_MODE;
X		break;
X	case LEFT | END_MODE:
X		GelUnHilite(gel);
X		GelDraw(gel, ERASE);
X		FreeGel(CurrentCell->undoList);
X		CurrentCell->undoList = gel;
X		if (editType == DELETE) {
X			CurrentCell->undo = 0;
X			FreeGel(KillBuffer);
X			KillBuffer = CopyGel(gel, 1);
X			KillX = origX;
X			KillY = origY;
X		} else { /* editType == CHANGE_ATTRIBUTE */
X			CurrentCell->undo = 1;
X			gel = CopyGel(gel, 1);
X			ChangeAttrib(gel, line_type, line_arrow, lineThickness,
X			 fill_type, 
X			 textVertAlign | textHorizAlign, fontType, textSize);
X			GelDraw(gel, DRAW);
X			(void) PushGel(&(CurrentCell->gelList), gel);
X			gel = NULL;
X		}
X		CurrentCell->saved |= MODIFIED;
X		ClearGelFlags(CurrentCell->gelList);
X		drawingMode = START_MODE;
X		break;
X	case RIGHT | END_MODE:
X	case MIDDLE | END_MODE:
X		GelUnHilite(gel);
X		GelDraw(gel, DRAW);
X		(void) PushUnderUndo(&(CurrentCell->gelList), gel, CurrentCell->undo);
X		if (evtype == (MIDDLE | END_MODE))
X			ClearGelFlags(CurrentCell->gelList);
X		drawingMode = START_MODE;
X		break;
X	case REDRAW | END_MODE:
X		GelHilite(gel);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Hey! Unknown mode %d in delete_element", 
X		 evtype);
X		message(errstring);
X#endif
X		break;
X	}
X}
X
X
X/*
X *  This is not as symmetric as the others because we first want to
X *  select the gel, and then, depending on the type of gel, we need to
X *  process the events differently. Each object should have an xxx_adj
X *  call which will be called by this routine.
X */
Xadjust_element(evtype, mx, my)
X{
X	/* Need to select the Gel first */
X	switch (evtype) {
X	case MOTION | START_MODE:
X	case RIGHT | START_MODE:
X	case MIDDLE | START_MODE:
X	case REDRAW | START_MODE:
X	 	/* Do nothing */
X	 	return;
X 	case LEFT | START_MODE:
X		if ((gel = SelectGel(CurrentCell->gelList, mx, my)) == NULL)
X			return;
X		origX = lastX = mx;
X		origY = lastY = my;
X		GelDraw(gel, ERASE);
X		gel = RemoveGel(&(CurrentCell->gelList), gel);
X		break;
X	default:
X		/* This must be processed individually for each type of gel */
X		break;
X	}
X
X	/*
X	 *  we get here after selecting a gel - or with a gel already
X	 *  selected. So we now call the appropriate xxx_adj to do the work.
X	 */
X	switch(gel->type) {
X	case TEXT:
X		text_adj(evtype, gel, mx, my);
X		break;
X	case BOX:
X		box_adj(evtype, gel, mx, my);
X		break;
X	case ELLIPSE:
X		ellipse_adj(evtype, gel, mx, my);
X		break;
X	case CIRCLE:
X		circle_adj(evtype, gel, mx, my);
X		break;
X	case LINE:
X		line_adj(evtype, gel, mx, my);
X		break;
X	case SPLINE:
X		spline_adj(evtype, gel, mx, my);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Unknown gel->type %d in adjust_element", 
X		 gel->type);
X		message(errstring);
X#endif
X		break;
X	}
X}
X
X
X/*ARGSUSED*/
Xscale_element(evtype, mx, my)
X{
X}
X
X
X/*ARGSUSED*/
Xrotate_element(ev_type, mx, my)
X{
X}
END_OF_FILE
if test 8859 -ne `wc -c <'xpic/obj_elem.c'`; then
    echo shar: \"'xpic/obj_elem.c'\" unpacked with wrong size!
fi
# end of 'xpic/obj_elem.c'
fi
if test -f 'xpic/obj_text.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/obj_text.c'\"
else
echo shar: Extracting \"'xpic/obj_text.c'\" \(6337 characters\)
sed "s/^X//" >'xpic/obj_text.c' <<'END_OF_FILE'
X/* $Header: obj_text.c,v 1.4 89/02/23 02:48:15 xwindows Exp $ */
X/*
X *  The text object routines. It calls the minibuf to input the text
X */
X#include "xpic.h"
X#include "windows.h"
X#include "gels.h"
X#include "input.h"
X#include "newfonts.h"
X#include "draw.h"
X#include "assert.h"
X
Xstatic int textWidth, textHeight;
Xstatic char *textString;
Xstatic int textLen;
Xstatic int deltaX, deltaY;
Xstatic int textX, textY;
X
Xtext_event(evtype, mx, my)
X{
X	switch (evtype) {
X	case MOTION | START_MODE:
X	case RIGHT  | START_MODE:
X	case MIDDLE | START_MODE:
X	case REDRAW | START_MODE:
X	case RIGHT  | END_MODE:
X		break;
X	case MOTION | END_MODE:
X		drawtext(picWin, textX, textY, textString, textLen, gcInvert, spacePad);
X		textX = mx + deltaX;
X		textY = my + deltaY;
X		drawtext(picWin, textX, textY, textString, textLen, gcInvert, spacePad);
X		break;
X	case LEFT | START_MODE:
X		if ((textString = get_input("? ", "", FALSE)) == NULL)
X			break;
X		if (fontChanged) {
X			changefont();
X		}
X		textLen = strlen(textString);
X		drawingMode = END_MODE;
X		/* Put the text on the mouse */
X		ComputeTextPosition(textString, textLen, textFont, &deltaX, &deltaY,
X		 &textWidth, &textHeight, textHorizAlign, textVertAlign, spacePad);
X		textX = mx + deltaX;
X		textY = my + deltaY;
X		drawtext(picWin, textX, textY, textString, textLen, gcInvert, spacePad);
X		break;
X	case LEFT | END_MODE:
X		drawtext(picWin, textX, textY, textString, textLen, gcInvert, spacePad);
X		textX = mx + deltaX;
X		textY = my + deltaY;
X		drawtext(picWin, textX, textY, textString, textLen, gcNormal, spacePad);
X		/* !! The calculation of the bounding box is sloppy */
X		AddTextGel(&(CurrentCell->gelList), textString, textLen, 
X		 fontType, fontType->cursize, fontType->name, textSize, 
X		 textVertAlign | textHorizAlign, 
X		 mx, my, textX, textY - textHeight, textX + textWidth, textY);
X		FreeGel(CurrentCell->undoList);
X		CurrentCell->undoList = NULL;
X		CurrentCell->undo = 1;
X		CurrentCell->saved |= MODIFIED;
X		drawingMode = START_MODE;
X		break;
X	case MIDDLE | END_MODE:
X		drawtext(picWin, textX, textY, textString, textLen, gcInvert, spacePad);
X		drawingMode = START_MODE;
X		break;
X	case REDRAW | END_MODE:
X		drawtext(picWin, textX, textY, textString, textLen, gcInvert, spacePad);
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Hey! Unknown TEXT mode %d", drawingMode);
X		message(errstring);
X#endif
X		break;
X	}
X	ASSERT(allock(), "text_event");
X}
X
X
Xtext_abort()
X{
X	text_event((MIDDLE  | drawingMode), 0, 0);
X}
X	
X/*
X *  Computes the position of a given string, in a given font, relative to
X *  the current mouse position. This is computed from 'vertalign'
X *  'horizalign', which are global variables, set by the user from
X *  buttons.
X */
XComputeTextPosition(s, len, font, dx, dy, width, height, halign, valign, pad)
Xchar *s;
Xint len;
XXFontStruct *font;
Xint *dx, *dy;
Xint *width, *height;
Xint halign, valign, pad;
X{
X	*dx = *dy = 0;
X	*width = XTextWidth(font, s, len);
X	while (*s != '\0')
X		if (*s++ == ' ')
X			*width += pad;
X	*height = font->ascent + font->descent;
X	if (halign != LJUST) {
X		if (halign == RJUST)
X			*dx -= *width;
X		else
X			*dx -= *width / 2;
X	}
X	if (valign == TOPLINE)
X		*dy += font->ascent;
X	else if (valign == BOTLINE)
X		*dy -= font->descent;
X	else
X		*dy += (font->ascent - font->descent) / 2 ;
X
X}
X
X
X/*
X *  Adjusting text simply puts the text in the minibuffer - if the user
X *  aborts the minibuffer, the text is left alone, otherwise, the new
X *  text is put in its place. I suppose the user could also be allowed
X *  to move the text as well, but I'd rather keep the actions orthogonal
X *  for now. All the action takes place in START_MODE, therefore this
X *  should never be in END_MODE.
X */
X/*ARGSUSED*/ /* We don't use the mouse positions for this one */
Xtext_adj(evtype, gel, mx, my)
Xint evtype;
XGel *gel;
Xint mx, my;
X{
X	static Gel *textgel;
X	TextString *text;
X	char *s;
X	XFontStruct *font;
X	int pad;
X	/*
X	 *  Will not need to process MOTION|START_MODE, RIGHT|START_MODE,
X	 *  REDRAW|START_MODE - these are taken care of in
X	 *  the adj_element routine.
X	 */
X	switch(evtype) {
X	case MOTION | END_MODE:
X		break;
X	case LEFT | START_MODE:
X		textgel = gel;
X		GelHilite(textgel);
X		message("Click Left Button to confirm selection");
X		drawingMode = END_MODE;
X		break;
X	case LEFT | END_MODE:
X		GelUnHilite(textgel);
X		GelDraw(textgel, ERASE);
X		text = (TextString *) textgel->data;
X		textString = text->str;
X		if ((s = get_input("? ", textString, FALSE)) == NULL) {
X			GelDraw(textgel, DRAW);
X			(void) PushUnderUndo(&(CurrentCell->gelList), textgel,
X			 CurrentCell->undo);
X			textgel = NULL;
X			drawingMode = START_MODE;
X			break;
X		}
X		textLen = strlen(s);
X		textString = s;
X		font = ChangeFont(&text->font->sizes[text->sizeindex], &pad);
X		setfont(tmpGcNormal, font->fid);
X		setfont(tmpGcInvert, font->fid);
X		ComputeTextPosition(textString, textLen, font, &deltaX, &deltaY,
X		 &textWidth, &textHeight, textgel->attributes & HALIGN, 
X		 textgel->attributes & VALIGN, pad);
X		textX = text->x + deltaX;
X		textY = text->y + deltaY;
X		AddTextGel(&(CurrentCell->gelList), textString, textLen, 
X		 text->font, text->sizeindex, text->fontname, text->fontsize, 
X		 textgel->attributes, text->x, text->y, 
X		 textX, textY - textHeight, textX + textWidth, textY);
X		drawtext(picWin, textX, textY, textString, textLen, tmpGcNormal, pad);
X		FreeGel(CurrentCell->undoList);
X		CurrentCell->undoList = textgel;
X		CurrentCell->undo = 1;
X		CurrentCell->saved |= MODIFIED;
X		drawingMode = START_MODE;
X		textString = NULL;
X		textgel = NULL;
X		break;
X	case RIGHT | END_MODE:
X	case MIDDLE | END_MODE:
X		GelUnHilite(textgel);
X		GelDraw(textgel, DRAW);
X		(void) PushUnderUndo(&(CurrentCell->gelList), textgel,
X		 CurrentCell->undo);
X		textgel = NULL;
X		drawingMode = START_MODE;
X		if (evtype == (MIDDLE | END_MODE))
X			ClearGelFlags(CurrentCell->gelList);
X		break;
X	case MIDDLE | START_MODE:
X		break;
X	case REDRAW | END_MODE:
X		break;
X	default:
X#ifdef DEBUG
X		(void) sprintf(errstring, "Hey! Unknown mode %d in text_adj", 
X		 evtype);
X		message(errstring);
X#endif
X		break;
X	}
X	ASSERT(allock(), "text_adj");
X}
X
X/*
X * Finds distance of point from a text object. This is the distance of the
X * point from the text bounding box - we just call box_distance()
X */
Xint
Xtext_distance(gel, xp, yp)
XGel *gel;
Xint xp, yp;
X{
X	extern int box_distance();
X	
X	return(box_distance(gel, xp, yp));
X}
END_OF_FILE
if test 6337 -ne `wc -c <'xpic/obj_text.c'`; then
    echo shar: \"'xpic/obj_text.c'\" unpacked with wrong size!
fi
# end of 'xpic/obj_text.c'
fi
if test -f 'xpic/test/test.pic' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/test/test.pic'\"
else
echo shar: Extracting \"'xpic/test/test.pic'\" \(7139 characters\)
sed "s/^X//" >'xpic/test/test.pic' <<'END_OF_FILE'
X.PS
Xscale = 80
X"\fR\s12lj top (moved)\s0\fP" ljust at 416.000000, 281.000000
X"\fR\s18hello world\s0\fP" ljust at 456.000000, 315.000000
Xellipse wid 88.000000 ht 56.000000 at 540.000000, 364.000000
X"\fR\s12top center\s0\fP"  at 336.000000, 321.000000
X"\fR\s12bottom center\s0\fP"  at 336.000000, 295.000000
Xbox  wid 96.000000 ht 72.000000 at 80.000000, 756.000000
Xbox  wid 160.000000 ht 32.000000 at 240.000000, 728.000000
Xbox dotted wid 96.000000 ht 32.000000 at 248.000000, 784.000000
Xbox dashed wid 136.000000 ht 72.000000 at 412.000000, 748.000000
Xbox dashed 0.1 * scale wid 104.000000 ht 40.000000 at 412.000000, 748.000000
Xbox dashed 0.15 * scale wid 72.000000 ht 24.000000 at 412.000000, 748.000000
Xline   from 512.000000, 792.000000 \
X	to 512.000000, 712.000000 \
X	to 552.000000, 712.000000 \
X	to 552.000000, 792.000000 
Xline  dotted from 576.000000, 792.000000 \
X	to 576.000000, 712.000000 \
X	to 616.000000, 712.000000 \
X	to 616.000000, 792.000000 
Xline  dashed from 32.000000, 672.000000 \
X	to 32.000000, 592.000000 \
X	to 72.000000, 672.000000 \
X	to 72.000000, 592.000000 
Xline  dashed 0.1 * scale from 88.000000, 592.000000 \
X	to 88.000000, 672.000000 \
X	to 128.000000, 592.000000 \
X	to 128.000000, 672.000000 
Xline  dashed 0.15 * scale from 152.000000, 592.000000 \
X	to 152.000000, 672.000000 \
X	to 192.000000, 592.000000 \
X	to 192.000000, 672.000000 
Xline <-  from 216.000000, 672.000000 \
X	to 216.000000, 592.000000 \
X	to 240.000000, 672.000000 \
X	to 240.000000, 592.000000 \
X	to 256.000000, 672.000000 
Xline ->  from 272.000000, 672.000000 \
X	to 280.000000, 608.000000 \
X	to 288.000000, 664.000000 \
X	to 296.000000, 592.000000 
Xline <->  from 312.000000, 672.000000 \
X	to 352.000000, 592.000000 \
X	to 312.000000, 592.000000 \
X	to 352.000000, 672.000000 \
X	to 352.000000, 632.000000 
Xline <- dotted from 368.000000, 592.000000 \
X	to 368.000000, 664.000000 \
X	to 392.000000, 592.000000 \
X	to 392.000000, 672.000000 \
X	to 432.000000, 592.000000 
Xline -> dotted from 448.000000, 592.000000 \
X	to 448.000000, 672.000000 \
X	to 472.000000, 592.000000 \
X	to 472.000000, 672.000000 
Xline <-> dotted from 488.000000, 592.000000 \
X	to 488.000000, 672.000000 \
X	to 512.000000, 592.000000 \
X	to 512.000000, 672.000000 
Xline <- dashed from 536.000000, 592.000000 \
X	to 536.000000, 672.000000 \
X	to 560.000000, 592.000000 \
X	to 560.000000, 672.000000 \
X	to 536.000000, 688.000000 
Xline -> dashed from 576.000000, 672.000000 \
X	to 576.000000, 592.000000 \
X	to 608.000000, 672.000000 \
X	to 608.000000, 592.000000 \
X	to 576.000000, 576.000000 
Xline <-> dashed from 32.000000, 552.000000 \
X	to 80.000000, 552.000000 \
X	to 32.000000, 512.000000 \
X	to 80.000000, 512.000000 \
X	to 24.000000, 472.000000 
Xline <- dashed 0.1 * scale from 112.000000, 552.000000 \
X	to 112.000000, 472.000000 \
X	to 152.000000, 552.000000 \
X	to 152.000000, 472.000000 \
X	to 192.000000, 512.000000 
Xline -> dashed 0.1 * scale from 192.000000, 552.000000 \
X	to 272.000000, 552.000000 \
X	to 192.000000, 472.000000 \
X	to 272.000000, 472.000000 
Xline <-> dashed 0.1 * scale from 312.000000, 552.000000 \
X	to 272.000000, 512.000000 \
X	to 312.000000, 512.000000 \
X	to 312.000000, 472.000000 \
X	to 352.000000, 512.000000 \
X	to 344.000000, 472.000000 \
X	to 392.000000, 472.000000 \
X	to 344.000000, 552.000000 
Xline <-> dashed 0.15 * scale from 392.000000, 552.000000 \
X	to 432.000000, 472.000000 \
X	to 432.000000, 552.000000 \
X	to 472.000000, 472.000000 \
X	to 472.000000, 512.000000 
Xline <- dashed 0.15 * scale from 496.000000, 472.000000 \
X	to 496.000000, 552.000000 \
X	to 528.000000, 472.000000 \
X	to 528.000000, 552.000000 
Xline -> dashed 0.15 * scale from 552.000000, 472.000000 \
X	to 552.000000, 552.000000 \
X	to 592.000000, 472.000000 \
X	to 592.000000, 552.000000 \
X	to 560.000000, 464.000000 
Xcircle radius 32 at 32.000000, 432.000000
Xcircle radius 32 at 104.000000, 424.000000
Xcircle radius 32 at 168.000000, 424.000000
Xcircle radius 32 at 248.000000, 424.000000
Xcircle radius 48 at 328.000000, 416.000000
Xellipse wid 64.000000 ht 32.000000 at 424.000000, 432.000000
Xellipse wid 96.000000 ht 32.000000 at 440.000000, 376.000000
Xellipse wid 104.000000 ht 64.000000 at 60.000000, 344.000000
X"\fR\s12hello world\s0\fP"  at 168.000000, 368.000000
X"\fI\s12hello world\s0\fP"  at 168.000000, 336.000000
X"\fB\s12hello world\s0\fP"  at 168.000000, 312.000000
X"\fS\s12hello world\s0\fP"  at 168.000000, 288.000000
Xbox dashed 0.15 * scale wid 64.000000 ht 16.000000 at 168.000000, 368.000000
Xbox dashed 0.15 * scale wid 64.000000 ht 16.000000 at 168.000000, 336.000000
Xbox dashed 0.15 * scale wid 64.000000 ht 16.000000 at 168.000000, 312.000000
Xbox dashed 0.15 * scale wid 80.000000 ht 16.000000 at 168.000000, 288.000000
Xbox dashed 0.15 * scale wid 152.000000 ht 40.000000 at 340.000000, 308.000000
X"\fR\s12hello world\s0\fP" rjust at 128.000000, 273.000000
Xellipse wid 120.000000 ht 16.000000 at 532.000000, 424.000000
X"\fR\s12hello world\s0\fP" rjust at 128.000000, 303.000000
Xspline ->  from 56.000000, 240.000000 \
X	to 8.000000, 208.000000 \
X	to 88.000000, 216.000000 \
X	to 152.000000, 232.000000 \
X	to 160.000000, 192.000000 \
X	to 72.000000, 152.000000 \
X	to 40.000000, 184.000000 \
X	to 8.000000, 192.000000 \
X	to 88.000000, 192.000000 \
X	to 216.000000, 200.000000 \
X	to 184.000000, 232.000000 
Xspline <-  from 200.000000, 256.000000 \
X	to 272.000000, 256.000000 \
X	to 288.000000, 208.000000 \
X	to 232.000000, 192.000000 \
X	to 232.000000, 216.000000 \
X	to 288.000000, 200.000000 \
X	to 328.000000, 184.000000 \
X	to 336.000000, 232.000000 \
X	to 320.000000, 248.000000 \
X	to 272.000000, 184.000000 \
X	to 264.000000, 160.000000 \
X	to 232.000000, 160.000000 
Xspline <->  from 328.000000, 256.000000 \
X	to 392.000000, 256.000000 \
X	to 360.000000, 216.000000 \
X	to 384.000000, 208.000000 \
X	to 432.000000, 208.000000 \
X	to 368.000000, 160.000000 \
X	to 344.000000, 160.000000 
Xspline <->  from 512.000000, 256.000000 \
X	to 544.000000, 264.000000 \
X	to 544.000000, 232.000000 \
X	to 552.000000, 232.000000 \
X	to 576.000000, 240.000000 \
X	to 592.000000, 264.000000 \
X	to 600.000000, 200.000000 \
X	to 592.000000, 184.000000 \
X	to 568.000000, 184.000000 \
X	to 568.000000, 200.000000 \
X	to 536.000000, 176.000000 \
X	to 536.000000, 160.000000 \
X	to 576.000000, 160.000000 
Xspline <->  from 32.000000, 104.000000 \
X	to 80.000000, 120.000000 \
X	to 80.000000, 40.000000 \
X	to 24.000000, 56.000000 \
X	to 24.000000, 64.000000 \
X	to 80.000000, 64.000000 \
X	to 184.000000, 88.000000 \
X	to 160.000000, 112.000000 \
X	to 120.000000, 88.000000 \
X	to 152.000000, 32.000000 
Xspline <->  from 208.000000, 120.000000 \
X	to 280.000000, 136.000000 \
X	to 256.000000, 64.000000 \
X	to 224.000000, 72.000000 \
X	to 224.000000, 88.000000 \
X	to 312.000000, 64.000000 \
X	to 320.000000, 32.000000 \
X	to 232.000000, 0.000000 \
X	to 192.000000, 32.000000 \
X	to 192.000000, 40.000000 \
X	to 208.000000, 40.000000 \
X	to 248.000000, 24.000000 \
X	to 288.000000, 88.000000 
Xspline <->  from 432.000000, 232.000000 \
X	to 496.000000, 240.000000 \
X	to 456.000000, 168.000000 \
X	to 456.000000, 208.000000 \
X	to 504.000000, 208.000000 \
X	to 520.000000, 192.000000 \
X	to 456.000000, 120.000000 \
X	to 392.000000, 120.000000 
X.PE
END_OF_FILE
if test 7139 -ne `wc -c <'xpic/test/test.pic'`; then
    echo shar: \"'xpic/test/test.pic'\" unpacked with wrong size!
fi
# end of 'xpic/test/test.pic'
fi
if test -f 'xpic/updown.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/updown.c'\"
else
echo shar: Extracting \"'xpic/updown.c'\" \(7306 characters\)
sed "s/^X//" >'xpic/updown.c' <<'END_OF_FILE'
X#include "xpic.h"
X#include "windows.h"
X#include "newfonts.h"
X#include "draw.h"
X
Xextern void CleanUpMode();
X
X/*
X *  If a PushButton has been pressed in a mode other than START_MODE,
X *  there's probably rubber-banded stuff on teh screen that we'll have
X *  to clean up
X */
X#define RESETMODE()	if(drawingMode != START_MODE) CleanUpMode(); else
X
X/*
X *  A new style of button - in the pure world, this would be a nifty
X *  widget - I've got a zillion and one things to do, so for now it's a
X *  quick kludge
X */
X
X
Xstatic FontFamily *curFont;
Xstatic FontFamily *availFonts;
Xstatic int nAvailFonts;
Xstatic int initialized = FALSE;
Xstatic Buf *fontBuf, *sizeBuf;
Xstatic char *sizestr;
X
XFontFamily *defaultFontFamily;
Xint fontChanged = 0;
X
X#define changelabel(w, s, buf) \
X	XtSetArg(args[0], XtNlabel, UpDownLabel(s, buf)),\
X	XtSetValues(w, args, 1)
X
Xvoid changefont()
X{
X	textFont = ChangeFont(&curFont->sizes[curFont->cursize], &spacePad);
X	setfont(gcNormal, textFont->fid);
X	setfont(gcInvert, textFont->fid);
X	fontChanged = 0;
X}
X
Xstatic char *UpDownLabel(s, buf) 
Xchar *s;
XBuf *buf;
X{
X	while (strlen(s) + 5>= buf->size) {
X		buf->size += BUF_CHUNK;
X		buf->buf = XtRealloc(buf->buf, (unsigned) buf->size);
X	}
X	(void) sprintf(buf->buf, "+ %s -", s);
X	return(buf->buf);
X}
X
X/*ARGSUSED*/
Xvoid donothing(w, tag, calldata)
XWidget w;
Xcaddr_t tag;
Xcaddr_t calldata;
X{
X}
X
X/*ARGSUSED*/
Xstatic int initializefonts(label)
Xchar *label;
X{
X	register int i, j;
X	char *default_fontname;
X	int default_fontsize;
X	static int status;
X
X	if (initialized)
X		return(status);
X	initialized = TRUE;
X	availFonts = InitFonts(&default_fontname, &default_fontsize, &nAvailFonts);
X	/*
X	 *  Delete font names for which we didn't find any X fonts - saves
X	 *  pain later because we are guaranteed that there'll always be one
X	 *  font, and that every font in the table will have at least one
X	 *  size. Work backward because its faster.
X	 */
X#ifdef DEBUG
X	printf("Fonts found are:\n");
X#endif
X	for(i = nAvailFonts - 1; i >= 0; i--) {
X		if(availFonts[i].nsizes == 0 && (nAvailFonts - i) > 0) {
X			/* 
X			 *  drat! This is a bad font, and there's fonts after it, so
X			 *  we're going to have to delete it. And deleting things in
X			 *  arrays is such fun......
X			 */
X			bcopy((char *) &availFonts[i+1], (char *) &availFonts[i],
X			 (nAvailFonts - i) * sizeof(FontFamily));
X			nAvailFonts--;
X		}
X#ifdef DEBUG
X		else {
X			register int j;
X			
X			printf("\t%s:", availFonts[i].name);
X			for(j = 0; j < availFonts[i].nsizes; j++) {
X				printf(" %d", availFonts[i].sizes[j].pointsize);
X			}
X			printf("\n");
X		}
X#endif
X	}
X	if (nAvailFonts == 0) {
X		/* Urk! */
X#ifdef DEBUG
X		printf("\tNone\n");
X#endif
X		status = FALSE;
X		return(status);
X	};
X	
X	if (default_fontname == NULL || 
X	 (curFont = findfont(default_fontname, TRUE)) == NULL) {
X		curFont = availFonts;
X	}
X
X	/*
X	 *  Now we have to find the closest font size to default_fontsize
X	 *  for all fonts.
X	 */
X	if (default_fontsize <= 0) {
X		for(j = 0; j < nAvailFonts; j++)
X			availFonts[j].cursize = 0;
X	} else {
X		for(j = 0; j < nAvailFonts; j++) {
X			availFonts[j].cursize = default_fontsize;
X			for (i = 0; i < availFonts[j].nsizes; i++) {
X				if (availFonts[j].sizes[i].pointsize > availFonts[j].cursize) {
X					break;
X				}
X			}
X			if (i == 0 || 
X			 availFonts[j].cursize - availFonts[j].sizes[i-1].pointsize >
X			 availFonts[j].sizes[i].pointsize - availFonts[j].cursize) {
X				/*
X				 *  i == 0, in which case we have to use the i'th font, or
X				 *  sizes[i].pointsize is closer to availFonts[j].cursize than
X				 *  sizes[i-1].pointsize
X				 */
X				availFonts[j].cursize = i;
X			} else {
X				/*
X				 *  i == availFonts[j].nsizes, in which case we have to use
X				 *  i-1'th font, or sizes[i-1].pointsize is closer to
X				 *  availFonts[j].cursize than sizes[i].pointsize
X				 */
X				availFonts[j].cursize = i-1;
X			}
X		}
X	}
X	defaultFontFamily = curFont;
X	status = TRUE;
X	return(status);
X}
X
Xstatic FontSizes defaultfontsizes[] = {
X	{0, DEFAULT_FONT, NULL},
X};
X
Xstatic FontFamily defaultfontfamily[] = {
X	{"default", defaultfontsizes, 1, 1, 0},
X};
X
Xvoid textfont(label, updowninfo, posthandler)
Xchar *label;
XButtonInfo *updowninfo;
XButtonInfo *posthandler;
X{
X	void textfont_updown();
X	
X	posthandler->name = NULL;
X	fontBuf = (Buf *) XtMalloc(sizeof(Buf));
X	fontBuf->buf = XtMalloc(BUF_CHUNK);
X	fontBuf->size = BUF_CHUNK;
X	fontChanged = 1;
X	if (initializefonts(label)) {
X		updowninfo->name = UpDownLabel(curFont->name, fontBuf);
X		fontType = curFont;
X		textSize = curFont->cursize;
X		updowninfo->handler = textfont_updown;
X	} else {
X		updowninfo->name = "No Fonts Available";
X		fontType = defaultFontFamily = curFont = defaultfontfamily;
X		textSize = 0;
X		updowninfo->handler = donothing;
X	}
X	return;
X}
X
X/*
X *  The posthandler is solely because we need the Widget type for the
X *  textsize button, since we'll need to change it when we change the
X *  textfont button - YAK (Yet another kludge)
X */
Xstatic Widget sizeWidget;
X
Xvoid textsize_posthandler(w)
XWidget w;
X{
X	sizeWidget = w;
X}
X
X
Xvoid textsize(label, updowninfo, posthandler)
Xchar *label;
XButtonInfo *updowninfo;
XButtonInfo *posthandler;
X{
X	void textsize_updown();
X	
X	sizeBuf = (Buf *) XtMalloc(sizeof(Buf));
X	sizeBuf->buf = XtMalloc(BUF_CHUNK);
X	sizeBuf->size = BUF_CHUNK;
X	sizestr = XtMalloc(5);
X	fontChanged = 1;
X	if (initializefonts(label)) {
X		(void) sprintf(sizestr, "%4d",
X		 curFont->sizes[curFont->cursize].pointsize);
X		updowninfo->name = UpDownLabel(sizestr, sizeBuf);
X		fontType = curFont;
X		textSize = curFont->sizes[curFont->cursize].pointsize;
X		updowninfo->handler = textsize_updown;
X		posthandler->handler = textsize_posthandler;
X		posthandler->name = "ok";	/* Anything non-null, just as a flag */
X	} else {
X		updowninfo->name = "No Fonts Available";
X		fontType = defaultFontFamily = curFont = defaultfontfamily;
X		textSize = 0;
X		updowninfo->handler = donothing;
X		posthandler->name = NULL;
X	}
X	return;
X}
X
Xstatic int up;	/* are we incrementing or decrementing */
X
X/*ARGSUSED*/
Xvoid textfont_updown(w, tag, calldata)
XWidget w;
Xcaddr_t tag;
Xcaddr_t calldata;
X{
X	Arg args[1];
X	
X	RESETMODE();
X	if (up) {
X		if (++curFont - availFonts == nAvailFonts)
X			curFont = availFonts;
X	} else {
X		if (curFont == availFonts)
X			curFont = curFont + nAvailFonts - 1;
X		else
X			--curFont;
X	}
X	fontChanged = 1;
X	changelabel(w, curFont->name, fontBuf);
X	(void) sprintf(sizestr, "%4d", curFont->sizes[curFont->cursize].pointsize);
X	changelabel(sizeWidget, sizestr, sizeBuf);
X	fontType = curFont;
X	textSize = curFont->sizes[curFont->cursize].pointsize;
X}
X
X
X/*ARGSUSED*/
Xvoid textsize_updown(w, tag, calldata)
XWidget w;
Xcaddr_t tag;
Xcaddr_t calldata;
X{
X	Arg args[1];
X	
X	RESETMODE();
X	if (up) {
X		if (++curFont->cursize == curFont->nsizes)
X			curFont->cursize = 0;
X	} else {
X		if (curFont->cursize == 0)
X			curFont->cursize = curFont->nsizes - 1;
X		else
X			curFont->cursize--;
X	}
X	fontChanged = 1;
X	(void) sprintf(sizestr, "%4d", curFont->sizes[curFont->cursize].pointsize);
X	changelabel(w, sizestr, sizeBuf);
X	textSize = curFont->sizes[curFont->cursize].pointsize;
X}
X
X
X/*ARGSUSED*/
Xvoid Increment(w, event, params, num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X	up = TRUE;
X}
X
X
X/*ARGSUSED*/
Xvoid Decrement(w, event, params, num_params)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *num_params;
X{
X	up = FALSE;
X}
END_OF_FILE
if test 7306 -ne `wc -c <'xpic/updown.c'`; then
    echo shar: \"'xpic/updown.c'\" unpacked with wrong size!
fi
# end of 'xpic/updown.c'
fi
if test -f 'xpic/xtypeout.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xpic/xtypeout.c'\"
else
echo shar: Extracting \"'xpic/xtypeout.c'\" \(6169 characters\)
sed "s/^X//" >'xpic/xtypeout.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <varargs.h>
X
X#include <X11/Intrinsic.h>
X#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X#include <X11/Shell.h>
X#include <Xw/Xw.h>
X#include <Xw/XwP.h>
X/*
X * Yechh!! The only way I know of to extract the size of the text widget in
X * rows is to call the sink's maxLines procedure. So we need the Private
X * headers TextEditP, and therefore, XwP and IntrinsicP. There must be a
X * cleaner way
X */
X#include <Xw/TextEdit.h>
X#include <Xw/TextEditP.h>
X
X#ifdef TYPEOUT
X/*
X *  Typeout routines - The typeout widget is created and passed to the
X *  minibuf as an arg. Minibuf typeout is only enabled if the typeout
X *  widget is passed in. The typeout widget is a asciiString of some
X *  specific size, with a string of size rows*cols, enclosed in a popup
X *  shell. TOstart pops it up, sets a grab on it, and starts printing
X *  stuff to the string. When the string is full, (i.e. ready to
X *  scroll),or the typeout is done, it calls redisplay, and waits for a
X *  mouse click or keypress. So the typeout widget has a translation
X *  table of "<Key>: done()\n <BtnUp>: done()\n". done() actually does
X *  the paging, or exits.
X */
X
X#define DEFAULT_FONT	"9x15"
X#define DEFAULT_ROWS	24
X#define DEFAULT_COLS	80
X
Xstatic Widget shell = NULL;
Xstatic Widget typeout = NULL;
Xstatic char *outString = NULL;
Xstatic int len = 0;
Xstatic char *cp = NULL;
Xstatic int notOver;
Xstatic Dimension internalMargin = 2;
Xstatic int nLines = 0;
Xstatic int nRows = 0;
Xstatic int nCols = 0;
X
Xstatic Arg text_args[16];
Xstatic char defaultTranslations[] = 
X	"<Key>:		done()\n";
X
Xstatic void Done();
Xstatic XtActionsRec actionsList [] = {
X	{"done", 	Done},
X};
X
X#define setarg(name, value)	(XtSetArg(text_args[i], name, value), i++)
X#define fontwidth(x)	((x)->max_bounds.rbearing - (x)->min_bounds.lbearing)
X#define fontheight(x)	((x)->max_bounds.ascent + (x)->max_bounds.descent)
X
X/*
X * !! This is a lousy kludge - for starteds, it should use the normal widget
X * hierarchy mechanism to get the font, we should then find out the font,
X * compute the size and request a resize. Also, we should probbaly use a
X * TransientShell - except that the window managers don't do that right, mostly
X */
XWidget CreateTypeout(parent, cols, rows, x, y, font)
XWidget parent;
Xchar *font;
X{
X	XFontStruct *finfo;
X	int i, pixelwidth, pixelheight;
X	XtTranslations defTranslations;
X	
X	if (shell) 
X		return typeout;
X	shell = XtCreateWidget("typeoutshell", overrideShellWidgetClass,
X	 parent, (ArgList) NULL, (Cardinal) 0);
X	if (!font) {
X		finfo = XLoadQueryFont(XtDisplay(shell), DEFAULT_FONT);
X	} else {
X		finfo = XLoadQueryFont(XtDisplay(shell), font);
X		if (finfo == NULL)
X			finfo = XLoadQueryFont(XtDisplay(shell), DEFAULT_FONT);
X	}
X	if (finfo == NULL) {
X		(void) fprintf(stderr, "Can't load default font \"%s\" - quitting\n",
X		 DEFAULT_FONT);
X		exit(-1);
X	}
X	if (cols == 0)
X		cols = DEFAULT_COLS;
X	if (rows == 0)
X		rows = DEFAULT_ROWS;
X	nCols = cols;
X	pixelwidth = cols * fontwidth(finfo) + 2 * internalMargin;
X	pixelheight = rows * fontheight(finfo) + 2 * internalMargin;
X	XtAddActions(actionsList, XtNumber(actionsList));
X	defTranslations = XtParseTranslationTable(defaultTranslations);
X	len = cols *rows + 1;
X	outString = XtMalloc((unsigned) len);
X	bzero(outString, len);
X	i = 0;
X	setarg(XtNwidth, (Dimension) pixelwidth);
X	setarg(XtNheight, (Dimension) pixelheight);
X	setarg(XtNfont, finfo);
X	setarg(XtNx, (Position) x);
X	setarg(XtNy, (Position) y);
X	setarg(XtNtranslations, defTranslations);
X	setarg(XtNstring, outString);
X	setarg(XtNlength, 0);
X	setarg(XtNmaximumSize, len);
X	setarg(XtNeditType, XwtextEdit);
X	setarg(XtNleftMargin, internalMargin);
X	setarg(XtNrightMargin, internalMargin);
X	setarg(XtNtopMargin, internalMargin);
X	setarg(XtNbottomMargin, internalMargin);
X	typeout = XtCreateManagedWidget("typeout", XwtexteditWidgetClass,
X	 shell, text_args, (Cardinal) i);
X	return typeout;
X}
X
X/*ARGSUSED*/
Xstatic void Done(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X	notOver = FALSE;
X}
X
Xmore(s)
Xchar *s;
X{
X	XEvent ev;
X
X	if (s) {
X		(void) strcpy(cp, s);
X		cp += strlen(s);
X	}
X	XwTextInsert((XwTextEditWidget) typeout, (unsigned char *) outString);
X	notOver = TRUE;
X	while(notOver) {
X		XtNextEvent(&ev);
X		XtDispatchEvent(&ev);
X	}
X}
X
Xreset()
X{
X	cp = outString;
X	/*
X	 * Extract number of rows in textEdit widget - there must be a better
X	 * way!
X	 */
X	nRows = (*(((XwTextEditWidget)typeout)->text.sink->maxLines))(typeout);
X	nLines = 1;
X	bzero(outString, len);
X}
X
Xxputs(s)
Xchar *s;
X{
X	while(*s) {
X		*cp++ = *s;
X		if (*s == '\n') {
X			nLines++;
X			if (nLines == nRows) {
X				more("Press any key to continue");
X				reset();
X				XwTextClearBuffer((XwTextEditWidget) typeout);
X			}
X		}
X		s++;
X	}
X}
X		
X/* TOstart(s) char *s;
X *	Starts the typeout, and prints 's' as a title. Typeout is some 
X *	sort of overlay 'window' or something, for temporary output, 
X *	which can popup, and vanish after the user has read it. 
X */
XTOstart(s)
Xchar *s;
X{
X	reset();
X	XwTextClearBuffer((XwTextEditWidget) typeout);
X	XtPopup(shell, XtGrabNonexclusive);
X	XtAddGrab(typeout, False, False);
X	AcquireFocus(typeout);
X	/* title */
X	xputs(s);
X	xputs("\n----------\n");
X}
X
X
X/* Typeout(fmt, args) char *fmt; va_dcl args;
X *	Is like printf() - prints args according to format 'fmt'. 
X *	Is a <varargs> routine. If fmt is NULL, it prints a newline.
X */
X/*VARARGS1*/
XTypeout(va_alist)
Xva_dcl
X{
X	va_list args;
X	char *fmt;
X	char buf[128];
X
X	va_start(args);
X	fmt = va_arg(args, char *);
X	if (!fmt) {
X		xputs("\n");
X	} else {
X		(void) vsprintf(buf, fmt, args);
X		xputs(buf);
X	}
X	va_end(args);
X}
X
X
X/* TOstop()
X *	End of typeout - this of waits for a keypress.
X *	It should then clean up the typeout and return. It only returns.
X */
XTOstop()
X{
X	more("---Press any key or click a button to quit----");
X	ReleaseFocus(typeout);
X	XtRemoveGrab(typeout);
X	XtPopdown(shell);
X	return;
X}
X#else TYPEOUT
X/*ARGSUSED*/
XWidget CreateTypeout(parent, cols, rows, x, y, font)
XWidget parent;
Xchar *font;
X{
X	return(NULL);
X}
X
X/*ARGSUSED*/
XTOstart(s)
X{
X}
X
X/*VARARGS0*/
X/*ARGSUSED*/
XTypeout(va_alist)
Xva_dcl
X{
X}
X
XTOstop()
X{
X}
X#endif TYPEOUT
X/* Don't add anything after the #endif TYPEOUT */
END_OF_FILE
if test 6169 -ne `wc -c <'xpic/xtypeout.c'`; then
    echo shar: \"'xpic/xtypeout.c'\" unpacked with wrong size!
fi
# end of 'xpic/xtypeout.c'
fi
echo shar: End of archive 5 \(of 15\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 15 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



More information about the Comp.sources.x mailing list