v12i017: tgif, Part01/23
William Cheng
william at CS.UCLA.EDU
Mon Mar 11 08:37:04 AEST 1991
Submitted-by: william at CS.UCLA.EDU (William Cheng)
Posting-number: Volume 12, Issue 17
Archive-name: tgif/part01
Tgif is a Xlib base 2-D drawing facility under X11. It also supports
hierarchical construction of drawings.
The README is in part 19 -- stay tuned :-}
Here's a short list of added features/bug fixes.
........................... tgif-1.23 => tgif-2.0 ...........................
1) Can import X11 bitmaps as new primitive objects.
2) Output X11 bitmap (xbm) or X11 pixmap (xpm) files.
3) Fix color PostScript output. There are still some problem
with printing to Apple LaserWriter. Please read the BUGS
section in tgif.man.
4) Scrollable message window (no scrollbars, just clicks).
5) Comment line (starts with %) are allowed in .obj and .sym files.
6) Handle more X defaults to setup initial fonts, styles, etc.
7) Keeping track of importing directory, and better handling
of the popup window that enquires about file names.
8) The directory 'bitmaps' is renamed to 'xbm'.
........................... tgif-2.0 => tgif-2.1 ...........................
1) Fix small bugs in Makefile.noimake
---------------------------------> 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 1 (of 23)."
# Contents: align.c animate.c arc.c attr.c
# Wrapped by william at oahu on Wed Mar 6 09:56:55 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'align.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'align.c'\"
else
echo shar: Extracting \"'align.c'\" \(3897 characters\)
sed "s/^X//" >'align.c' <<'END_OF_FILE'
X/*
X * Author: William Chia-Wei Cheng (william at 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/align.c,v 2.0 91/03/05 12:46:11 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 "drawing.e" /* RedrawAreas () */
X#include "dup.e" /* justDupped */
X#include "grid.e" /* GridXY () */
X#include "mark.e" /* HighLightForward (), HighLightReverse () */
X#include "move.e" /* MoveObj () */
X#include "obj.e" /* botObj */
X#include "select.e" /* topSel */
X#include "setup.e" /* fileModified */
X
Xint horiAlign = ALIGN_L;
Xint vertAlign = ALIGN_T;
X
Xvoid AlignSelObjs ()
X{
X register struct SelRec * sel_ptr;
X register struct ObjRec * obj_ptr;
X register int x = 0, y = 0;
X int pivot_x = 0, pivot_y = 0;
X int dx, dy, ltx, lty, rbx, rby;
X
X if (topSel == NULL) return;
X
X HighLightReverse ();
X switch (horiAlign)
X {
X case ALIGN_L : pivot_x = selObjLtX; break;
X case ALIGN_C : pivot_x = (selObjLtX + selObjRbX) / 2; break;
X case ALIGN_R : pivot_x = selObjRbX; break;
X }
X switch (vertAlign)
X {
X case ALIGN_T : pivot_y = selObjLtY; break;
X case ALIGN_M : pivot_y = (selObjLtY + selObjRbY) / 2; break;
X case ALIGN_B : pivot_y = selObjRbY; break;
X }
X
X for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
X {
X obj_ptr = sel_ptr->obj;
X switch (horiAlign)
X {
X case ALIGN_L : x = obj_ptr->obbox.ltx; break;
X case ALIGN_C : x = (obj_ptr->obbox.ltx+obj_ptr->obbox.rbx) / 2; break;
X case ALIGN_R : x = obj_ptr->obbox.rbx; break;
X }
X switch (vertAlign)
X {
X case ALIGN_T : y = obj_ptr->obbox.lty; break;
X case ALIGN_M : y = (obj_ptr->obbox.lty+obj_ptr->obbox.rby) / 2; break;
X case ALIGN_B : y = obj_ptr->obbox.rby; break;
X }
X if (horiAlign == ALIGN_N) x = pivot_x;
X if (vertAlign == ALIGN_N) y = pivot_y;
X
X dx = pivot_x - x;
X dy = pivot_y - y;
X
X MoveObj (obj_ptr, dx, dy);
X }
X ltx = selLtX; lty = selLtY; rbx = selRbX, rby = selRbY;
X UpdSelBBox ();
X RedrawAreas (botObj, ltx-(1<<zoomScale), lty-(1<<zoomScale),
X rbx+(1<<zoomScale), rby+(1<<zoomScale), selLtX-(1<<zoomScale),
X selLtY-(1<<zoomScale), selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X SetFileModified (TRUE);
X justDupped = FALSE;
X}
X
Xvoid AlignSelToGrid ()
X{
X register struct SelRec * sel_ptr;
X register struct ObjRec * obj_ptr;
X register int x = 0, y = 0;
X int grid_x, grid_y, dx, dy, ltx, lty, rbx, rby;
X
X if (topSel == NULL) return;
X
X HighLightReverse ();
X for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
X {
X obj_ptr = sel_ptr->obj;
X switch (horiAlign)
X {
X case ALIGN_L : x = obj_ptr->obbox.ltx; break;
X case ALIGN_C : x = (obj_ptr->obbox.ltx+obj_ptr->obbox.rbx) / 2; break;
X case ALIGN_R : x = obj_ptr->obbox.rbx; break;
X }
X switch (vertAlign)
X {
X case ALIGN_T : y = obj_ptr->obbox.lty; break;
X case ALIGN_M : y = (obj_ptr->obbox.lty+obj_ptr->obbox.rby) / 2; break;
X case ALIGN_B : y = obj_ptr->obbox.rby; break;
X }
X GridXY (x, y, &grid_x, &grid_y);
X if (horiAlign == ALIGN_N) x = grid_x;
X if (vertAlign == ALIGN_N) y = grid_y;
X
X dx = (grid_x - x) << zoomScale;
X dy = (grid_y - y) << zoomScale;
X
X MoveObj (obj_ptr, dx, dy);
X }
X ltx = selLtX; lty = selLtY; rbx = selRbX, rby = selRbY;
X UpdSelBBox ();
X RedrawAreas (botObj, ltx-(1<<zoomScale), lty-(1<<zoomScale),
X rbx+(1<<zoomScale), rby+(1<<zoomScale), selLtX-(1<<zoomScale),
X selLtY-(1<<zoomScale), selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X SetFileModified (TRUE);
X justDupped = FALSE;
X}
END_OF_FILE
if test 3897 -ne `wc -c <'align.c'`; then
echo shar: \"'align.c'\" unpacked with wrong size!
fi
# end of 'align.c'
fi
if test -f 'animate.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'animate.c'\"
else
echo shar: Extracting \"'animate.c'\" \(8049 characters\)
sed "s/^X//" >'animate.c' <<'END_OF_FILE'
X/*
X * Author: William Chia-Wei Cheng (william at 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/animate.c,v 2.0 91/03/05 12:46:35 william Exp $";
X#endif
X
X#include <X11/Xlib.h>
X#include "const.h"
X#include "types.h"
X
X#include "color.e"
X#include "raster.e"
X#include "select.e"
X#include "setup.e"
X
X#define SEND_SPEED 8
X
X#define TOKEN_R 8
X
Xstatic XPoint savedToken[5];
X
Xvoid AnimateSend (PolyPtr, Speed, Pixel)
X struct PolyRec * PolyPtr;
X int Speed, Pixel;
X{
X register int delta, i;
X register XPoint * token;
X int x, y, num_pts, j, x_dist, y_dist;
X XPoint * v;
X struct BBRec bbox;
X double slope, delta_x, delta_y;
X XGCValues values;
X
X values.foreground = Pixel;
X values.function = GXxor;
X values.line_style = FillSolid;
X values.line_width = 0;
X XChangeGC (mainDisplay, drawGC,
X GCForeground | GCFunction | GCLineStyle | GCLineWidth, &values);
X
X bbox.ltx = 0; bbox.lty = 0; bbox.rbx = 2*TOKEN_R; bbox.rby = 2*TOKEN_R;
X
X num_pts = PolyPtr->n;
X v = PolyPtr->vlist;
X token = (XPoint *) calloc (5, sizeof(XPoint));
X
X for (j = 0; j < num_pts-1; j++)
X {
X x = OFFSET_X(v[j].x);
X y = OFFSET_Y(v[j].y);
X token[0].x = (short)(x - TOKEN_R); token[0].y = (short)(y - TOKEN_R);
X token[1].x = (short)(x + TOKEN_R); token[1].y = (short)(y - TOKEN_R);
X token[2].x = (short)(x + TOKEN_R); token[2].y = (short)(y + TOKEN_R);
X token[3].x = (short)(x - TOKEN_R); token[3].y = (short)(y + TOKEN_R);
X token[4].x = (short)(x - TOKEN_R); token[4].y = (short)(y - TOKEN_R);
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X if (v[j].x == v[j+1].x)
X { /* moving vertical */
X if ((y_dist = (v[j+1].y-v[j].y)>>zoomScale) > 0)
X { /* moving down */
X for (delta = 0; delta < y_dist; delta += Speed)
X {
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X for (i = 0; i < 5; i++) token[i].y += Speed;
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X }
X }
X else
X { /* moving up */
X for (delta = y_dist; delta < 0; delta += Speed)
X {
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X for (i = 0; i < 5; i++) token[i].y -= Speed;
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X }
X }
X }
X else if (v[j].y == v[j+1].y)
X { /* moving horizontal */
X if ((x_dist = (v[j+1].x-v[j].x)>>zoomScale) > 0)
X { /* moving right */
X for (delta = 0; delta < x_dist; delta += Speed)
X {
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X for (i = 0; i < 5; i++) token[i].x += Speed;
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X }
X }
X else
X { /* moving left */
X for (delta = x_dist; delta < 0; delta += Speed)
X {
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X for (i = 0; i < 5; i++) token[i].x -= Speed;
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X }
X }
X }
X else
X { /* moving diagonally */
X x_dist = (v[j+1].x-v[j].x)>>zoomScale;
X y_dist = (v[j+1].y-v[j].y)>>zoomScale;
X for (i = 0; i < 5; i++)
X {
X savedToken[i].x = token[i].x;
X savedToken[i].y = token[i].y;
X }
X if (abs (x_dist) > abs (y_dist))
X { /* moving in the x direction */
X slope = (double)y_dist / (double)x_dist;
X if (x_dist > 0)
X { /* moving right */
X for (delta = 0; delta < x_dist; delta += Speed)
X {
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5,
X Convex, CoordModeOrigin);
X delta_y = slope * (double)delta;
X for (i = 0; i < 5; i++)
X {
X token[i].x = savedToken[i].x + delta;
X token[i].y = savedToken[i].y + delta_y;
X }
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5,
X Convex, CoordModeOrigin);
X }
X }
X else
X { /* moving left */
X for (delta = 0; delta > x_dist; delta -= Speed)
X {
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5,
X Convex, CoordModeOrigin);
X delta_y = slope * (double)delta;
X for (i = 0; i < 5; i++)
X {
X token[i].x = savedToken[i].x + delta;
X token[i].y = savedToken[i].y + delta_y;
X }
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5,
X Convex, CoordModeOrigin);
X }
X }
X }
X else
X { /* moving in the y direction */
X slope = (double)x_dist / (double)y_dist;
X if (y_dist > 0)
X { /* moving down */
X for (delta = 0; delta < y_dist; delta += Speed)
X {
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5,
X Convex, CoordModeOrigin);
X delta_x = slope * (double)delta;
X for (i = 0; i < 5; i++)
X {
X token[i].x = savedToken[i].x + delta_x;
X token[i].y = savedToken[i].y + delta;
X }
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5,
X Convex, CoordModeOrigin);
X }
X }
X else
X { /* moving up */
X for (delta = 0; delta > y_dist; delta -= Speed)
X {
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5,
X Convex, CoordModeOrigin);
X delta_x = slope * (double)delta;
X for (i = 0; i < 5; i++)
X {
X token[i].x = savedToken[i].x + delta_x;
X token[i].y = savedToken[i].y + delta;
X }
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5,
X Convex, CoordModeOrigin);
X }
X }
X }
X }
X XFillPolygon (mainDisplay, drawWindow, drawGC, token, 5, Convex,
X CoordModeOrigin);
X }
X cfree (token);
X}
X
Xvoid AnimateSel ()
X{
X if (topSel != botSel || topSel == NULL || topSel->obj->type != OBJ_POLY)
X {
X Msg ("Please select only one POLY object.");
X return;
X }
X AnimateSend (topSel->obj->detail.p, SEND_SPEED,
X xorColorPixels[topSel->obj->color]);
X}
X
Xvoid AnimateFlashColor(ObjPtr, ColorIndex)
X struct ObjRec * ObjPtr;
X int ColorIndex;
X{
X int saved_color_index = ObjPtr->color;
X
X ObjPtr->color = ColorIndex;
X DrawPolyObj (drawWindow, drawOrigX, drawOrigY, ObjPtr);
X ObjPtr->color = saved_color_index;
X DrawPolyObj (drawWindow, drawOrigX, drawOrigY, ObjPtr);
X}
X
Xvoid FlashSelColor ()
X{
X register int i;
X
X if (topSel != botSel || topSel == NULL || topSel->obj->type != OBJ_POLY)
X {
X Msg ("Please select only one POLY object.");
X return;
X }
X for (i = 0; i < maxColors; i++)
X if (strcmp ("white", colorMenuItems[i]) == 0)
X break;
X AnimateFlashColor (topSel->obj, i);
X}
END_OF_FILE
if test 8049 -ne `wc -c <'animate.c'`; then
echo shar: \"'animate.c'\" unpacked with wrong size!
fi
# end of 'animate.c'
fi
if test -f 'arc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'arc.c'\"
else
echo shar: Extracting \"'arc.c'\" \(19449 characters\)
sed "s/^X//" >'arc.c' <<'END_OF_FILE'
X/*
X * Author: William Chia-Wei Cheng (william at 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/arc.c,v 2.0 91/03/05 12:46:37 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 "color.e"
X#include "cursor.e"
X#include "file.e"
X#include "grid.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
X#ifndef M_PI
X#define M_PI 3.14159265358979323846
X#endif
X
X#define EXPAND_BBOX(bbox,x,y) \
X if ((x)<(bbox)->ltx) (bbox)->ltx=(x); if ((y)<(bbox)->lty) (bbox)->lty=(y); \
X if ((x)>(bbox)->rbx) (bbox)->rbx=(x); if ((y)>(bbox)->rby) (bbox)->rby=(y)
X
Xint arcDrawn = FALSE;
X
Xstatic
Xint ArcDirection (xc, yc, x1, y1, x2, y2)
X int xc, yc, x1, y1, x2, y2;
X{
X register int dx, dy, radius;
X register double theta1, theta2;
X
X dx = x1-xc; dy = y1-yc;
X radius = (int)sqrt((double)(dx*dx+dy*dy));
X theta1 = atan2 ((double)(dy), (double)(dx));
X theta2 = atan2 ((double)(y2-yc), (double)(x2-xc));
X if (theta1 < 0) theta1 += 2*M_PI;
X if (theta2 < 0) theta2 += 2*M_PI;
X
X if (theta2 > theta1)
X {
X if (theta2-theta1 >= 2*M_PI-theta2+theta1)
X return (ARC_CCW);
X else
X return (ARC_CW);
X }
X else if (theta1 > theta2)
X {
X if (theta1-theta2 >= 2*M_PI-theta1+theta2)
X return (ARC_CW);
X else
X return (ARC_CCW);
X }
X else
X return (ARC_CCW);
X}
X
Xvoid PointsToArc (xc, yc, x1, y1, x2, y2, dir, ltx, lty, w, h, angle1, angle2)
X int xc, yc, x1, y1, x2, y2, dir;
X int * ltx, * lty, * w, * h, * angle1, * angle2;
X{
X register int dx, dy, radius, theta1, theta2, d_theta;
X
X dx = x1-xc; dy = y1-yc;
X radius = (int)sqrt((double)(dx*dx+dy*dy));
X *ltx = xc-radius; *lty = yc-radius;
X *w = *h = 2*radius;
X theta1 = (int)(atan2 ((double)(dy),(double)(dx))/M_PI*(-180));
X theta2 = (y2-yc == 0 && x2-xc == 0) ?
X 0 : (int)(atan2 ((double)(y2-yc),(double)(x2-xc))/M_PI*(-180));
X /* NOTE: *angle1 must be between -180 degrees and +180 degrees */
X *angle1 = theta1*64;
X d_theta = theta2-theta1;
X switch (dir)
X {
X case ARC_CCW: if (d_theta < 0) d_theta = 360 + d_theta; break;
X case ARC_CW: if (d_theta > 0) d_theta = d_theta - 360; break;
X }
X *angle2 = d_theta * 64;
X}
X
Xvoid ArcRealX2Y2 (ArcPtr, RealX2, RealY2)
X register struct ArcRec * ArcPtr;
X int * RealX2, * RealY2;
X{
X register double angle_in_radian;
X int w = ArcPtr->w, h = ArcPtr->h;
X
X angle_in_radian = (ArcPtr->angle1+ArcPtr->angle2)*M_PI/180/64;
X *RealX2 = ArcPtr->xc + round((w/2)*cos(angle_in_radian));
X *RealY2 = ArcPtr->yc - round((h/2)*sin(angle_in_radian));
X}
X
Xvoid CalcArcBBox (ArcPtr, bbox)
X struct ArcRec * ArcPtr;
X register struct BBRec * bbox;
X{
X register int theta1, theta2;
X int real_x2, real_y2, dir = ArcPtr->dir;
X int ltx = ArcPtr->ltx, lty = ArcPtr->lty;
X int w = ArcPtr->w, h = ArcPtr->h;
X int pass_theta1 = FALSE, coverage = 0, angle;
X
X theta1 = (ArcPtr->angle1)/64;
X theta2 = theta1 + (ArcPtr->angle2)/64;
X
X ArcRealX2Y2 (ArcPtr, &real_x2, &real_y2);
X
X if (ArcPtr->fill == NONEPAT)
X { /* don't counter the center of the arc */
X bbox->ltx = min(ArcPtr->x1,real_x2);
X bbox->lty = min(ArcPtr->y1,real_y2);
X bbox->rbx = max(ArcPtr->x1,real_x2);
X bbox->rby = max(ArcPtr->y1,real_y2);
X }
X else
X {
X bbox->ltx = min(ArcPtr->xc,min(ArcPtr->x1,real_x2));
X bbox->lty = min(ArcPtr->yc,min(ArcPtr->y1,real_y2));
X bbox->rbx = max(ArcPtr->xc,max(ArcPtr->x1,real_x2));
X bbox->rby = max(ArcPtr->yc,max(ArcPtr->y1,real_y2));
X }
X
X if (theta2 < -180) theta2 += 360;
X if (theta2 > 180) theta2 -= 360;
X
X if (theta1 < 0) theta1 += 360;
X if (theta2 < 0) theta2 += 360;
X
X if (dir == ARC_CCW)
X {
X angle = 0;
X while (angle < theta2 || !pass_theta1)
X {
X if (angle >= theta1 && !pass_theta1)
X {
X pass_theta1 = TRUE;
X if (theta2 > theta1 && angle >= theta2) break;
X if (theta2 < theta1) angle -= 360;
X }
X if (pass_theta1) coverage |= 1 << (((angle+360)/90) % 4);
X angle = (angle == 360) ? 0 : (angle+90);
X }
X }
X else
X {
X angle = 360;
X while (angle > theta2 || !pass_theta1)
X {
X if (angle <= theta1 && !pass_theta1)
X {
X pass_theta1 = TRUE;
X if (theta2 < theta1 && angle <= theta2) break;
X if (theta2 > theta1) angle += 360;
X }
X if (pass_theta1) coverage |= 1 << ((angle/90) % 4);
X angle = (angle == 0) ? 360 : (angle-90);
X }
X }
X if (coverage & 0x1) { EXPAND_BBOX(bbox,(int)(ltx+w),(int)(lty+h/2)); }
X if (coverage & 0x2) { EXPAND_BBOX(bbox,(int)(ltx+w/2),lty); }
X if (coverage & 0x4) { EXPAND_BBOX(bbox,ltx,(int)(lty+h/2)); }
X if (coverage & 0x8) { EXPAND_BBOX(bbox,(int)(ltx+w/2),(int)(lty+h)); }
X}
X
Xstatic
Xvoid DumpArcPSPath (FP, xc, yc, xr, yr, dir, a1, a2, outline, blank1, blank2)
X FILE * FP;
X int xc, yc, xr, yr, dir, a1, a2, outline;
X char * blank1, * blank2;
X{
X fprintf (FP, "%snewpath\n", blank1);
X if (outline) fprintf (FP, "%s%1d %1d moveto\n", blank2, xc, yc);
X switch (dir)
X {
X case ARC_CCW:
X fprintf (FP, "%s%1d %1d %1d %1d %1d %1d tgifarc\n", blank2,
X xc, yc, xr, yr, a1, a2);
X break;
X case ARC_CW:
X fprintf (FP, "%s%1d %1d %1d %1d %1d %1d tgifarcn\n", blank2,
X xc, yc, xr, yr, a1, a2);
X break;
X }
X if (outline) fprintf (FP, "%s%1d %1d lineto ", blank2, xc, yc);
X}
X
Xvoid DumpArcObj (FP, ObjPtr)
X FILE * FP;
X struct ObjRec * ObjPtr;
X{
X register struct ArcRec * arc_ptr = ObjPtr->detail.a;
X int i;
X int fill, width, pen, dash, color_index;
X int xc, yc, xr, yr, dir, angle1, angle2;
X
X fill = arc_ptr->fill;
X width = arc_ptr->width;
X pen = arc_ptr->pen;
X dash = arc_ptr->dash;
X xc = arc_ptr->xc; yc = arc_ptr->yc;
X xr = (int)(arc_ptr->w/2); yr = (int)(arc_ptr->h/2);
X dir = arc_ptr->dir;
X angle1 = -(int)(arc_ptr->angle1/64);
X angle2 = -(int)(arc_ptr->angle2/64) + angle1;
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 switch (fill)
X {
X case NONEPAT: break;
X case SOLIDPAT:
X DumpArcPSPath (FP,xc,yc,xr,yr,dir,angle1,angle2,TRUE,""," ");
X fprintf (FP, " fill\n");
X break;
X case BACKPAT:
X DumpArcPSPath (FP,xc,yc,xr,yr,dir,angle1,angle2,TRUE,""," ");
X fprintf (FP, " closepath 1 setgray fill\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",fill);
X DumpArcPSPath (FP,xc,yc,xr,yr,dir,angle1,angle2,TRUE," "," ");
X if (colorDump)
X {
X fprintf (FP, " closepath clip\n");
X DumpPatFill (FP, fill, 8, ObjPtr->bbox, " ");
X }
X else
X fprintf (FP, " fill\n");
X fprintf (FP, "grestore\n");
X break;
X }
X
X fprintf (FP, "%1d setlinewidth\n", 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
X switch (pen)
X {
X case NONEPAT: break;
X case SOLIDPAT:
X DumpArcPSPath (FP,xc,yc,xr,yr,dir,angle1,angle2,FALSE,""," ");
X fprintf (FP, "stroke\n");
X break;
X case BACKPAT:
X DumpArcPSPath (FP,xc,yc,xr,yr,dir,angle1,angle2,FALSE,""," ");
X fprintf (FP, "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", pen);
X DumpArcPSPath (FP,xc,yc,xr,yr,dir,angle1,angle2,FALSE," "," ");
X if (colorDump)
X {
X fprintf (FP, " strokepath clip\n");
X DumpPatFill (FP, pen, 8, ObjPtr->bbox, " ");
X }
X else
X fprintf (FP, " stroke\n");
X fprintf (FP, "grestore\n");
X break;
X }
X if (dash != 0) fprintf (FP, "[] 0 setdash\n");
X fprintf (FP, "1 setlinewidth\n\n");
X}
X
Xvoid DrawArcObj (window, XOff, YOff, ObjPtr)
X Window window;
X int XOff, YOff;
X struct ObjRec * ObjPtr;
X{
X struct ArcRec * arc_ptr = ObjPtr->detail.a;
X int fill, width, pen, dash, pixel, real_x_off, real_y_off;
X int ltx, lty, w, h, angle1, angle2;
X XGCValues values;
X
X real_x_off = (XOff >> zoomScale) << zoomScale;
X real_y_off = (YOff >> zoomScale) << zoomScale;
X
X ltx = (arc_ptr->ltx - real_x_off) >> zoomScale;
X lty = (arc_ptr->lty - real_y_off) >> zoomScale;
X w = (arc_ptr->w) >> zoomScale;
X h = (arc_ptr->h) >> zoomScale;
X angle1 = arc_ptr->angle1;
X angle2 = arc_ptr->angle2;
X
X fill = ObjPtr->detail.a->fill;
X width = ObjPtr->detail.a->width;
X pen = ObjPtr->detail.a->pen;
X dash = ObjPtr->detail.a->dash;
X pixel = colorPixels[ObjPtr->color];
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 XFillArc (mainDisplay, window, drawGC, ltx, lty, w, h, angle1, angle2);
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 XDrawArc (mainDisplay, window, drawGC, ltx, lty, w, h, angle1, angle2);
X }
X}
X
Xvoid UpdArcBBox (ObjPtr)
X struct ObjRec * ObjPtr;
X{
X struct ArcRec * arc_ptr = ObjPtr->detail.a;
X struct BBRec bbox;
X int w;
X
X ObjPtr->x = arc_ptr->xc;
X ObjPtr->y = arc_ptr->yc;
X
X CalcArcBBox (arc_ptr, &bbox);
X
X ObjPtr->bbox.ltx = ObjPtr->obbox.ltx = bbox.ltx;
X ObjPtr->bbox.lty = ObjPtr->obbox.lty = bbox.lty;
X ObjPtr->bbox.rbx = ObjPtr->obbox.rbx = bbox.rbx;
X ObjPtr->bbox.rby = ObjPtr->obbox.rby = bbox.rby;
X
X w = widthOfLine[arc_ptr->width];
X
X ObjPtr->bbox.ltx -= w;
X ObjPtr->bbox.lty -= w;
X ObjPtr->bbox.rbx += w;
X ObjPtr->bbox.rby += w;
X}
X
Xstatic
Xvoid CreateArcObj (xc, yc, x1, y1, x2, y2, dir, ltx, lty, w, h, angle1, angle2)
X int xc, yc, x1, y1, x2, y2, dir, ltx, lty, w, h, angle1, angle2;
X{
X struct ArcRec * arc_ptr;
X struct ObjRec * obj_ptr;
X
X arc_ptr = (struct ArcRec *) calloc (1, sizeof(struct ArcRec));
X arc_ptr->fill = objFill;
X arc_ptr->width = lineWidth;
X arc_ptr->pen = penPat;
X arc_ptr->dash = curDash;
X
X arc_ptr->xc = (xc<<zoomScale)+drawOrigX;
X arc_ptr->yc = (yc<<zoomScale)+drawOrigY;
X arc_ptr->x1 = (x1<<zoomScale)+drawOrigX;
X arc_ptr->y1 = (y1<<zoomScale)+drawOrigY;
X arc_ptr->x2 = (x2<<zoomScale)+drawOrigX;
X arc_ptr->y2 = (y2<<zoomScale)+drawOrigY;
X arc_ptr->dir = dir;
X arc_ptr->ltx = (ltx<<zoomScale)+drawOrigX;
X arc_ptr->lty = (lty<<zoomScale)+drawOrigY;
X arc_ptr->w = w<<zoomScale;
X arc_ptr->h = h<<zoomScale;
X arc_ptr->angle1 = angle1; arc_ptr->angle2 = angle2;
X
X obj_ptr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec));
X obj_ptr->detail.a = arc_ptr;
X
X UpdArcBBox (obj_ptr);
X
X obj_ptr->type = OBJ_ARC;
X obj_ptr->color = colorIndex;
X obj_ptr->id = objId++;
X obj_ptr->dirty = FALSE;
X obj_ptr->fattr = obj_ptr->lattr = NULL;
X AddObj (NULL, topObj, obj_ptr);
X}
X
Xstatic
Xvoid ContinueArc (OrigX, OrigY)
X int OrigX, OrigY;
X{
X int grid_x, grid_y, first_x = 0, first_y = 0;
X int end_x, end_y, saved_x, saved_y;
X int done = FALSE, drawing_arc = FALSE;
X int dir = INVALID, ltx, lty, w, h, angle1, angle2;
X char msg[80];
X XGCValues values;
X XEvent input;
X XMotionEvent * motion_ev;
X
X values.foreground = xorColorPixels[colorIndex];
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 grid_x = saved_x = OrigX;
X grid_y = saved_y = OrigY;
X XDrawLine (mainDisplay, drawWindow, drawGC, OrigX, OrigY, saved_x, saved_y);
X
X XGrabPointer (mainDisplay, drawWindow, FALSE,
X PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
X GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime);
X
X Msg ("Please specify the start of an arc.");
X while (!done)
X {
X XNextEvent (mainDisplay, &input);
X if (input.type == ButtonPress)
X {
X if (drawing_arc)
X {
X XUngrabPointer (mainDisplay, CurrentTime);
X XDrawArc (mainDisplay, drawWindow, drawGC, ltx, lty, w, h,
X angle1, angle2);
X done = TRUE;
X Msg ("");
X }
X else
X {
X XDrawLine (mainDisplay, drawWindow, drawGC, OrigX, OrigY,
X saved_x, saved_y);
X first_x = saved_x;
X first_y = saved_y;
X drawing_arc = TRUE;
X if (OrigX == grid_x && OrigY == grid_y)
X { /* fake it as if the 1st point is ok but the 2nd point is bad */
X XUngrabPointer (mainDisplay, CurrentTime);
X grid_x = first_x;
X grid_y = first_y;
X done = TRUE;
X }
X Msg ("Please specify the end of the arc.");
X }
X }
X else if (input.type == MotionNotify)
X {
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 if (grid_x != saved_x || grid_y != saved_y)
X {
X if (drawing_arc)
X { /* finished with the center and the first point on the arc */
X if (dir == INVALID)
X {
X dir = ArcDirection (OrigX, OrigY, first_x, first_y,
X grid_x, grid_y);
X ltx = OrigX; lty = OrigY; w = 0; h = 0; angle1 = angle2 = 0;
X if (dir == ARC_CW)
X sprintf (msg, "Please specify the end of the arc. (%s).",
X "clockwise");
X else
X sprintf (msg, "Please specify the end of the arc. (%s).",
X "counter-clockwise");
X Msg (msg);
X }
X XDrawArc (mainDisplay, drawWindow, drawGC, ltx, lty, w, h,
X angle1, angle2);
X saved_x = grid_x;
X saved_y = grid_y;
X PointsToArc (OrigX, OrigY, first_x, first_y, saved_x, saved_y,
X dir, <x, <y, &w, &h, &angle1, &angle2);
X XDrawArc (mainDisplay, drawWindow, drawGC, ltx, lty, w, h,
X angle1, angle2);
X }
X else
X { /* looking for the first point on the arc */
X XDrawLine (mainDisplay, drawWindow, drawGC, OrigX, OrigY,
X saved_x, saved_y);
X saved_x = grid_x;
X saved_y = grid_y;
X XDrawLine (mainDisplay, drawWindow, drawGC, OrigX, OrigY,
X saved_x, saved_y);
X }
X }
X MarkRulers (grid_x, grid_y);
X }
X }
X if (first_x != grid_x || first_y != grid_y)
X {
X CreateArcObj (OrigX, OrigY, first_x, first_y, saved_x, saved_y, dir,
X ltx, lty, w, h, angle1, angle2);
X DrawArcObj (drawWindow, drawOrigX, drawOrigY, topObj);
X arcDrawn = TRUE;
X SetFileModified (TRUE);
X }
X}
X
Xvoid DrawArc (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 ContinueArc (grid_x, grid_y);
X }
X}
X
Xvoid SaveArcObj (FP, ObjPtr)
X FILE * FP;
X register struct ObjRec * ObjPtr;
X{
X register struct ArcRec * arc_ptr = ObjPtr->detail.a;
X
X fprintf (FP, "arc('%s',", colorMenuItems[ObjPtr->color]);
X fprintf (FP, "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,\
X %1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,",
X arc_ptr->fill, arc_ptr->width, arc_ptr->pen, arc_ptr->dash,
X arc_ptr->ltx, arc_ptr->lty, arc_ptr->xc, arc_ptr->yc,
X arc_ptr->x1, arc_ptr->y1, arc_ptr->x2, arc_ptr->y2,
X arc_ptr->dir, arc_ptr->w, arc_ptr->h, arc_ptr->angle1, arc_ptr->angle2,
X ObjPtr->id);
X SaveAttrs (FP, ObjPtr->lattr);
X fprintf (FP, ")");
X}
X
Xvoid ReadArcObj (Inbuf, ObjPtr)
X char * Inbuf;
X struct ObjRec * * ObjPtr;
X{
X register struct ArcRec * arc_ptr;
X char color_str[20], * s;
X int fill, width, pen, dash, ltx, lty, w, h;
X int xc, yc, x1, y1, x2, y2, dir, angle1, angle2;
X
X * ObjPtr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec));
X s = FindChar ('(', Inbuf);
X s = ParseStr (s, ',', color_str);
X arc_ptr = (struct ArcRec *) calloc (1, sizeof(struct ArcRec));
X
X if (fileVersion > 8)
X {
X sscanf (s, "%d , %d , %d , %d , %d , %d , %d , %d , %d , \
X %d, %d , %d , %d , %d , %d , %d , %d , %d",
X &fill, &width, &pen, &dash, <x, <y, &xc, &yc, &x1, &y1,
X &x2, &y2, &dir, &w, &h, &angle1, &angle2, &((*ObjPtr)->id));
X if ((*ObjPtr)->id >= objId) objId = (*ObjPtr)->id + 1;
X }
X
X arc_ptr->fill = fill;
X arc_ptr->width = width;
X arc_ptr->pen = pen;
X arc_ptr->dash = dash;
X
X arc_ptr->xc = xc; arc_ptr->yc = yc;
X arc_ptr->x1 = x1; arc_ptr->y1 = y1;
X arc_ptr->x2 = x2; arc_ptr->y2 = y2;
X arc_ptr->dir = dir;
X arc_ptr->ltx = ltx; arc_ptr->lty = lty;
X arc_ptr->w = w; arc_ptr->h = h;
X arc_ptr->angle1 = angle1; arc_ptr->angle2 = angle2;
X
X (*ObjPtr)->detail.a = arc_ptr;
X UpdArcBBox (*ObjPtr);
X
X (*ObjPtr)->type = OBJ_ARC;
X (*ObjPtr)->color = FindColorIndex (color_str);
X (*ObjPtr)->dirty = FALSE;
X}
X
Xvoid FreeArcObj (ObjPtr)
X struct ObjRec * ObjPtr;
X{
X cfree (ObjPtr->detail.a);
X cfree (ObjPtr);
X}
END_OF_FILE
if test 19449 -ne `wc -c <'arc.c'`; then
echo shar: \"'arc.c'\" unpacked with wrong size!
fi
# end of 'arc.c'
fi
if test -f 'attr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'attr.c'\"
else
echo shar: Extracting \"'attr.c'\" \(28217 characters\)
sed "s/^X//" >'attr.c' <<'END_OF_FILE'
X/*
X * Author: William Chia-Wei Cheng (william at 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/attr.c,v 2.0 91/03/05 12:46:41 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 "choice.e"
X#include "color.e"
X#include "cursor.e"
X#include "dialog.e"
X#include "drawing.e"
X#include "dup.e"
X#include "file.e"
X#include "font.e"
X#include "mainloop.e"
X#include "mark.e"
X#include "menu.e"
X#include "msg.e"
X#include "obj.e"
X#include "raster.e"
X#include "select.e"
X#include "setup.e"
X#include "text.e"
X
X#define PAINT 0
X#define ERASE 1
X
Xstatic struct AttrRec * topAttr = NULL, * botAttr = NULL;
X
Xvoid LinkInAttr (PrevPtr, NextPtr, AttrPtr)
X struct AttrRec * PrevPtr, * NextPtr, * AttrPtr;
X /* add AttrPtr between PrevPtr and NextPtr */
X{
X AttrPtr->prev = PrevPtr;
X AttrPtr->next = NextPtr;
X
X if (PrevPtr == NULL)
X topAttr = AttrPtr;
X else
X PrevPtr->next = AttrPtr;
X
X if (NextPtr == NULL)
X botAttr = AttrPtr;
X else
X NextPtr->prev = AttrPtr;
X}
X
Xvoid FreeAttr (AttrPtr)
X struct AttrRec * AttrPtr;
X /* This routine only frees the attribute record, not */
X /* the text record, which must be freed explicitly. */
X{
X cfree (AttrPtr);
X}
X
Xvoid UnlinkAttr (AttrPtr)
X struct AttrRec * AttrPtr;
X{
X struct ObjRec * own_ptr;
X struct AttrRec * * top_attr_ad;
X struct AttrRec * * bot_attr_ad;
X
X own_ptr = AttrPtr->owner;
X
X top_attr_ad = &(own_ptr->fattr);
X bot_attr_ad = &(own_ptr->lattr);
X
X if (*top_attr_ad == AttrPtr)
X *top_attr_ad = AttrPtr->next;
X else
X AttrPtr->prev->next = AttrPtr->next;
X
X if (*bot_attr_ad == AttrPtr)
X *bot_attr_ad = AttrPtr->prev;
X else
X AttrPtr->next->prev = AttrPtr->prev;
X}
X
Xstatic
Xchar * FindEqual(s)
X register char * s;
X{
X while (*s != '=' && *s != '\0') s++;
X return ((*s == '=') ? (s) : (char *)NULL);
X}
X
Xstatic
Xvoid ParseAttrStr(Str, name, s)
X char * Str, * name, * s;
X{
X char * eq_ptr, * str_ptr, * ptr;
X
X if ((eq_ptr = FindEqual(Str)) != NULL)
X {
X eq_ptr++;
X ptr = name;
X str_ptr = Str;
X do
X {
X *ptr = *str_ptr;
X ptr++;
X str_ptr++;
X } while (str_ptr != eq_ptr);
X
X *ptr = '\0';
X
X ptr = s;
X do
X {
X *ptr = *str_ptr;
X ptr++;
X str_ptr++;
X } while (*str_ptr != '\0');
X
X *ptr = '\0';
X }
X else
X {
X *name = '\0';
X strcpy (s, Str);
X }
X}
X
Xvoid UpdateAttr (TextPtr, AttrPtr)
X struct TextRec * TextPtr;
X struct AttrRec * AttrPtr;
X /* This routine updates the name and value in the AttrRec */
X /* and its ObjRec after an attribute was edited. */
X{
X char s[MAXSTRING+1], name[MAXSTRING+1];
X
X if (AttrPtr->nameshown)
X {
X ParseAttrStr (TextPtr->first->s, name, s);
X strcpy (AttrPtr->s, s);
X strcpy (AttrPtr->name, name);
X }
X else
X {
X strcpy (s, TextPtr->first->s);
X strcpy (AttrPtr->s, s);
X }
X
X if (!(AttrPtr->shown))
X TextPtr->first->s[0] = '\0';
X else
X {
X if (AttrPtr->nameshown)
X {
X strcat (name, s);
X strcpy (TextPtr->first->s, name);
X }
X else
X strcpy (TextPtr->first->s, s);
X }
X UpdTextBBox (AttrPtr->obj);
X}
X
Xvoid DrawAttrs (Win, XOff, YOff, AttrPtr)
X Window Win;
X int XOff, YOff;
X struct AttrRec * AttrPtr;
X{
X struct AttrRec * ptr;
X
X for (ptr = AttrPtr; ptr != NULL; ptr = ptr->next)
X if (ptr->shown)
X DrawTextObj(Win, XOff, YOff, ptr->obj);
X}
X
Xvoid MoveAttrs (AttrPtr, Dx, Dy)
X int Dx, Dy;
X struct AttrRec * AttrPtr;
X{
X struct AttrRec * ptr;
X
X for (ptr = AttrPtr; ptr != NULL; ptr = ptr->next)
X {
X ptr->obj->x += Dx;
X ptr->obj->y += Dy;
X ptr->obj->bbox.ltx += Dx;
X ptr->obj->bbox.lty += Dy;
X ptr->obj->bbox.rbx += Dx;
X ptr->obj->bbox.rby += Dy;
X ptr->obj->obbox.ltx += Dx;
X ptr->obj->obbox.lty += Dy;
X ptr->obj->obbox.rbx += Dx;
X ptr->obj->obbox.rby += Dy;
X }
X}
X
Xvoid DelAllAttrs (AttrPtr)
X struct AttrRec * AttrPtr;
X{
X struct AttrRec * ptr;
X
X for (ptr = AttrPtr; ptr != NULL; ptr = ptr->next)
X {
X FreeTextObj(ptr->obj);
X FreeAttr(ptr);
X }
X}
X
Xstatic
Xstruct AttrRec * NewAttr (OwnerObjPtr, ObjPtr, Inherited)
X struct ObjRec * ObjPtr;
X struct ObjRec * OwnerObjPtr;
X short Inherited;
X{
X struct AttrRec * attr_ptr;
X
X attr_ptr = (struct AttrRec *) calloc (1, sizeof(struct AttrRec));
X attr_ptr->shown = TRUE;
X attr_ptr->nameshown = TRUE;
X attr_ptr->inherited = Inherited;
X attr_ptr->obj = ObjPtr;
X attr_ptr->next= attr_ptr->prev = NULL;
X attr_ptr->owner = OwnerObjPtr;
X ObjPtr->detail.t->attr = attr_ptr;
X
X return attr_ptr;
X}
X
Xstatic
Xvoid DupAnAttr (FromAttrPtr, ToAttrPtr)
X register struct AttrRec * FromAttrPtr, * ToAttrPtr;
X{
X struct ObjRec * text_obj_ptr;
X
X text_obj_ptr = (struct ObjRec *) calloc (1, sizeof(struct ObjRec));
X DupObjBasics (FromAttrPtr->obj, text_obj_ptr);
X DupTextObj (FromAttrPtr->obj->detail.t, text_obj_ptr);
X
X strcpy(ToAttrPtr->name, FromAttrPtr->name);
X strcpy(ToAttrPtr->s, FromAttrPtr->s);
X ToAttrPtr->shown = FromAttrPtr->shown;
X ToAttrPtr->nameshown = FromAttrPtr->nameshown;
X ToAttrPtr->inherited = FromAttrPtr->inherited;
X ToAttrPtr->obj = text_obj_ptr;
X ToAttrPtr->next= ToAttrPtr->prev = NULL;
X text_obj_ptr->detail.t->attr = ToAttrPtr;
X}
X
Xvoid DupAttrs (FromObjPtr, ToObjPtr)
X register struct ObjRec * FromObjPtr, * ToObjPtr;
X{
X register struct AttrRec * to_attr_ptr, * from_attr_ptr;
X
X topAttr = botAttr = NULL;
X from_attr_ptr = FromObjPtr->fattr;
X for ( ; from_attr_ptr != NULL; from_attr_ptr = from_attr_ptr->next)
X {
X to_attr_ptr = (struct AttrRec *) calloc (1, sizeof(struct AttrRec));
X to_attr_ptr->owner = ToObjPtr;
X DupAnAttr (from_attr_ptr, to_attr_ptr);
X LinkInAttr (NULL, topAttr, to_attr_ptr);
X }
X ToObjPtr->fattr = topAttr;
X ToObjPtr->lattr = botAttr;
X}
X
Xstatic
Xvoid AddAttr(ObjPtr, TextObjPtr)
X struct ObjRec * ObjPtr, * TextObjPtr;
X{
X struct AttrRec * attr_ptr;
X struct TextRec * text_ptr;
X char name[MAXSTRING+1], value[MAXSTRING+1];
X
X text_ptr = TextObjPtr->detail.t;
X
X ParseAttrStr(text_ptr->first->s, name, value);
X topAttr = ObjPtr->fattr;
X botAttr = ObjPtr->lattr;
X
X UnlinkObj (TextObjPtr);
X TextObjPtr->next = TextObjPtr->prev = NULL;
X attr_ptr = NewAttr (ObjPtr, TextObjPtr, FALSE);
X UpdateAttr (text_ptr, attr_ptr);
X LinkInAttr (NULL, topAttr, attr_ptr);
X
X ObjPtr->fattr = topAttr;
X ObjPtr->lattr = botAttr;
X}
X
Xvoid AddAttrs ()
X{
X struct ObjRec * owner_ptr = NULL;
X struct SelRec * sel_ptr;
X int text_count = 0, sel_ltx, sel_lty, sel_rbx, sel_rby;
X
X for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
X switch (sel_ptr->obj->type)
X {
X case OBJ_TEXT: text_count++; break;
X
X case OBJ_BOX:
X case OBJ_OVAL:
X case OBJ_POLYGON:
X case OBJ_POLY:
X case OBJ_SYM:
X case OBJ_GROUP:
X case OBJ_ICON:
X case OBJ_ARC:
X case OBJ_RCBOX:
X case OBJ_XBM:
X if (owner_ptr != NULL)
X {
X Msg("Two non-text objects selected.");
X return;
X }
X owner_ptr = sel_ptr->obj;
X break;
X }
X
X if (text_count == 0)
X {
X Msg("No text objects selected to add as attributes.");
X return;
X }
X if (owner_ptr == NULL)
X {
X Msg("No objects (other than TEXT objects) selected.");
X return;
X }
X
X HighLightReverse ();
X sel_ltx = selLtX; sel_lty = selLtY;
X sel_rbx = selRbX; sel_rby = selRbY;
X
X for (sel_ptr = botSel; sel_ptr != NULL; sel_ptr = sel_ptr->prev)
X if (sel_ptr->obj->type == OBJ_TEXT)
X AddAttr(owner_ptr, sel_ptr->obj);
X
X RemoveAllSel ();
X UnlinkObj (owner_ptr);
X AddObj (NULL, topObj, owner_ptr);
X topSel = botSel = (struct SelRec *) calloc (1, sizeof(struct SelRec));
X topSel->obj = owner_ptr;
X topSel->prev = NULL;
X botSel->next = NULL;
X AdjObjBBox (owner_ptr);
X UpdSelBBox ();
X RedrawAreas (botObj, sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
X sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
X selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X justDupped = FALSE;
X}
X
Xstatic
Xvoid SaveAttr (FP, AttrPtr)
X FILE * FP;
X struct AttrRec * AttrPtr;
X{
X fprintf (FP, "attr(\"");
X SaveString (FP, AttrPtr->name);
X fprintf (FP, "\", \"");
X SaveString (FP, AttrPtr->s);
X fprintf (FP, "\", %1d, %1d, %1d,\n",
X AttrPtr->shown, AttrPtr->nameshown, AttrPtr->inherited);
X
X SaveTextObj (FP, AttrPtr->obj);
X fprintf (FP, ")");
X}
X
Xvoid SaveAttrs (FP, BotAttrPtr)
X FILE * FP;
X struct AttrRec * BotAttrPtr;
X{
X
X struct AttrRec * ptr;
X
X fprintf (FP, "[\n");
X
X for (ptr = BotAttrPtr; ptr != NULL; ptr = ptr->prev)
X {
X SaveAttr (FP, ptr);
X if (ptr->prev != NULL)
X fprintf (FP, ",\n");
X }
X
X if (BotAttrPtr == NULL)
X fprintf (FP, "]");
X else
X fprintf (FP, "\n]");
X}
X
Xstatic
Xchar * ReadAttrString (Str)
X char * Str;
X{
X register char * s = Str;
X
X for (s = Str; *s != '\0' && *s != '"'; s++)
X if (*s == '\\')
X s++;
X
X if (*s == '"') s++;
X return (s);
X}
X
Xint ReadAttr (FP, AttrPtr, PRTGIF)
X FILE * FP;
X struct AttrRec * * AttrPtr;
X int PRTGIF;
X{
X struct ObjRec * TextObj;
X char inbuf[MAXSTRING+1], * s;
X char name[MAXSTRING+1], value[MAXSTRING+1];
X int len, shown, nameshown, inherited;
X
X fgets (inbuf, MAXSTRING, FP);
X
X if (inbuf[0] == ']') return (FALSE);
X
X *AttrPtr = (struct AttrRec *) calloc (1, sizeof(struct AttrRec));
X
X len = strlen(inbuf) - 1;
X inbuf[len] = '\0';
X
X strcpy(name, FindChar ('"', inbuf));
X s = ReadAttrString (inbuf);
X s = FindChar (',', s);
X strcpy(value, FindChar ('"', s));
X s = ReadAttrString (value);
X s = FindChar (',', s);
X sscanf (s, "%d, %d, %d", &shown, &nameshown, &inherited);
X
X s = ReadString (name);
X *(--s) = '\0';
X strcpy ((*AttrPtr)->name, name);
X s = ReadString (value);
X *(--s) = '\0';
X strcpy ((*AttrPtr)->s, value);
X
X (*AttrPtr)->shown = shown;
X (*AttrPtr)->nameshown = nameshown;
X (*AttrPtr)->inherited = inherited;
X
X ReadObj (FP, &TextObj, PRTGIF);
X TextObj->detail.t->attr = *AttrPtr;
X (*AttrPtr)->obj = TextObj;
X
X return (TRUE);
X}
X
Xstatic
Xint ShowAndUpdAttrNames (Force)
X int Force;
X /* Force will force attribute name to be shown whether the attribute */
X /* is inherited or not. */
X /* returns TRUE if any attribute names are updated */
X /* This routine concatinate the 'name' and 's' first of every */
X /* attribute of the selected object and assign that to the */
X /* first line of the text object the attribute pointer points to. */
X{
X struct SelRec * sel_ptr;
X struct ObjRec * obj_ptr;
X struct AttrRec * attr_ptr;
X int picture_changed = FALSE, obj_changed;
X int len1, len2;
X char * s, msg[80];
X
X for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
X {
X obj_ptr = sel_ptr->obj;
X attr_ptr = obj_ptr->fattr;
X if (attr_ptr != NULL)
X {
X obj_changed = FALSE;
X for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
X {
X if (!(attr_ptr->nameshown) && (Force || !(attr_ptr->inherited)))
X {
X s = attr_ptr->obj->detail.t->first->s;
X strcpy (s, attr_ptr->name);
X
X len1 = strlen (attr_ptr->name);
X len2 = strlen (attr_ptr->s);
X if (len1+len2 >= MAXSTRING)
X {
X sprintf (msg, "String length exceeds %1d. String truncated.",
X MAXSTRING);
X Msg (msg);
X attr_ptr->s[MAXSTRING-len1] = '\0';
X }
X
X strcat (s, attr_ptr->s);
X attr_ptr->nameshown = TRUE;
X UpdTextBBox (attr_ptr->obj);
X if (attr_ptr->shown) obj_changed = picture_changed = TRUE;
X }
X }
X if (obj_changed) AdjObjBBox (obj_ptr);
X }
X }
X return (picture_changed);
X}
X
Xvoid ShowAllAttrNames ()
X{
X if (ShowAndUpdAttrNames (TRUE))
X {
X HighLightReverse ();
X UpdSelBBox ();
X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X HighLightForward ();
X SetFileModified (TRUE);
X }
X}
X
Xstatic
Xint HideAndUpdAttrNames ()
X /* returns TRUE if any attribute names are updated */
X /* For all the first line of the selected object's attributes, */
X /* this routine change them to the 's' field of the attribute. */
X{
X struct SelRec * sel_ptr;
X struct ObjRec * obj_ptr;
X struct AttrRec * attr_ptr;
X int picture_changed = FALSE, obj_changed;
X char * s;
X
X for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
X {
X obj_ptr = sel_ptr->obj;
X attr_ptr = obj_ptr->fattr;
X if (attr_ptr != NULL)
X {
X obj_changed = FALSE;
X for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
X {
X if (attr_ptr->nameshown && *(attr_ptr->name) != '\0')
X {
X attr_ptr->nameshown = FALSE;
X s = attr_ptr->obj->detail.t->first->s;
X strcpy (s, attr_ptr->s);
X UpdTextBBox (attr_ptr->obj);
X if (attr_ptr->shown) obj_changed = picture_changed = TRUE;
X }
X }
X if (obj_changed) AdjObjBBox (obj_ptr);
X }
X }
X return (picture_changed);
X}
X
Xvoid HideAllAttrNames ()
X{
X int sel_ltx, sel_lty, sel_rbx, sel_rby;
X
X sel_ltx = selLtX; sel_lty = selLtY; sel_rbx = selRbX; sel_rby = selRbY;
X
X if (HideAndUpdAttrNames ())
X {
X HighLightReverse ();
X UpdSelBBox ();
X RedrawAnArea (botObj, sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
X sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale));
X HighLightForward ();
X SetFileModified (TRUE);
X }
X}
X
Xvoid DetachGroupAttrs (ObjPtr, TopSelPtr, BotSelPtr)
X struct ObjRec * ObjPtr;
X struct SelRec * * TopSelPtr, * * BotSelPtr;
X{
X struct AttrRec * attr_ptr = ObjPtr->fattr;
X struct SelRec * new_sel_ptr;
X int len1, len2;
X char * s, msg[80];
X
X for ( ; attr_ptr != NULL; attr_ptr = attr_ptr->next)
X {
X if (!(attr_ptr->nameshown))
X {
X s = attr_ptr->obj->detail.t->first->s;
X strcpy (s, attr_ptr->name);
X
X len1 = strlen (attr_ptr->name);
X len2 = strlen (attr_ptr->s);
X if (len1+len2 >= MAXSTRING)
X {
X sprintf (msg, "String length exceeds %1d. String truncated.",
X MAXSTRING);
X Msg (msg);
X attr_ptr->s[MAXSTRING-len1] = '\0';
X }
X
X strcat (s, attr_ptr->s);
X UpdTextBBox (attr_ptr->obj);
X }
X
X attr_ptr->obj->detail.t->attr = NULL;
X
X attr_ptr->obj->prev = NULL;
X attr_ptr->obj->next = ObjPtr->detail.r->first;
X
X if (attr_ptr->obj->next == NULL)
X ObjPtr->detail.r->last = attr_ptr->obj;
X else
X attr_ptr->obj->next->prev = attr_ptr->obj;
X ObjPtr->detail.r->first = attr_ptr->obj;
X
X new_sel_ptr = (struct SelRec *) calloc (1, sizeof(struct SelRec));
X new_sel_ptr->obj = attr_ptr->obj;
X
X new_sel_ptr->prev = NULL;
X new_sel_ptr->next = *TopSelPtr;
X
X if (new_sel_ptr->next == NULL)
X *BotSelPtr = new_sel_ptr;
X else
X (*TopSelPtr)->prev = new_sel_ptr;
X *TopSelPtr = new_sel_ptr;
X
X cfree (attr_ptr);
X }
X}
X
Xvoid DetachAttrs ()
X{
X struct SelRec * sel_ptr, * new_sel_ptr;
X struct ObjRec * obj_ptr;
X struct AttrRec * attr_ptr, * attr_ptr_next;
X int picture_changed, obj_changed;
X
X HighLightReverse ();
X picture_changed = ShowAndUpdAttrNames (FALSE);
X
X for (sel_ptr = topSel; sel_ptr != NULL; sel_ptr = sel_ptr->next)
X {
X obj_ptr = sel_ptr->obj;
X attr_ptr = obj_ptr->fattr;
X if (attr_ptr != NULL)
X {
X topAttr = botAttr = NULL;
X for ( ; attr_ptr != NULL; attr_ptr = attr_ptr_next)
X {
X attr_ptr_next = attr_ptr->next;
X if (obj_ptr->type == OBJ_ICON && attr_ptr->inherited)
X {
X LinkInAttr (NULL, topAttr, attr_ptr);
X continue;
X }
X
X if (!(attr_ptr->shown)) obj_changed = picture_changed = TRUE;
X attr_ptr->obj->detail.t->attr = NULL;
X AddObj (obj_ptr->prev, obj_ptr, attr_ptr->obj);
X new_sel_ptr = (struct SelRec *) calloc (1, sizeof(struct SelRec));
X new_sel_ptr->obj = obj_ptr->prev;
X AddSel (sel_ptr->prev, sel_ptr, new_sel_ptr);
X cfree (attr_ptr);
X }
X obj_ptr->fattr = topAttr;
X obj_ptr->lattr = botAttr;
X AdjObjBBox (obj_ptr);
X }
X }
X if (picture_changed)
X {
X UpdSelBBox ();
X RedrawAnArea (botObj, selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X SetFileModified (TRUE);
X }
X HighLightForward ();
X}
X
Xvoid UpdAttr (AttrPtr)
X struct AttrRec * AttrPtr;
X /* Update the text object's string value associated with AttrPtr */
X{
X int len1, len2;
X char msg[80];
X
X if (AttrPtr->nameshown)
X {
X strcpy (AttrPtr->obj->detail.t->first->s, AttrPtr->name);
X
X len1 = strlen (AttrPtr->name);
X len2 = strlen (AttrPtr->s);
X if (len1+len2 >= MAXSTRING)
X {
X sprintf (msg, "String length exceeds %1d. String truncated.",
X MAXSTRING);
X Msg (msg);
X AttrPtr->s[MAXSTRING-len1] = '\0';
X }
X
X strcat (AttrPtr->obj->detail.t->first->s, AttrPtr->s);
X }
X else
X strcpy (AttrPtr->obj->detail.t->first->s, AttrPtr->s);
X UpdTextBBox(AttrPtr->obj);
X}
X
Xstatic
Xint MoveOneAttr (ObjPtr, AttrPtr)
X struct ObjRec * ObjPtr;
X struct AttrRec * AttrPtr;
X{
X struct ObjRec * text_obj_ptr;
X int x, y, grid_x, grid_y, dx, dy, placing = TRUE;
X int ltx, lty, rbx, rby, changed = FALSE, moved = FALSE;
X int orig_x, orig_y, grid_orig_x, grid_orig_y;
X XEvent input;
X
X text_obj_ptr = AttrPtr->obj;
X Msg ("LEFT--show and move. MIDDLE--toggle name shown. RIGHT--hide attr.");
X
X orig_x = OFFSET_X(text_obj_ptr->x);
X orig_y = OFFSET_Y(text_obj_ptr->y);
X GridXY (orig_x, orig_y, &grid_orig_x, &grid_orig_y);
X ltx = OFFSET_X(text_obj_ptr->bbox.ltx);
X lty = OFFSET_Y(text_obj_ptr->bbox.lty);
X rbx = OFFSET_X(text_obj_ptr->bbox.rbx)+1;
X rby = OFFSET_Y(text_obj_ptr->bbox.rby)+1;
X SelBox (drawWindow, revDefaultGC, ltx, lty, rbx, rby);
X
X XGrabPointer (mainDisplay, drawWindow, FALSE,
X PointerMotionMask | ButtonPressMask,
X GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime);
X XWarpPointer (mainDisplay, None, drawWindow, 0, 0, 0, 0, orig_x, orig_y);
X
X dx = dy = 0;
X grid_x = grid_orig_x; grid_y = grid_orig_y;
X
X while (placing)
X {
X XNextEvent (mainDisplay, &input);
X if (input.type == MotionNotify)
X {
X x = input.xmotion.x;
X y = input.xmotion.y;
X GridXY (x, y, &grid_x, &grid_y);
X
X if (moved = (grid_x != grid_orig_x+dx || grid_y != grid_orig_y+dy))
X {
X SelBox (drawWindow, revDefaultGC, ltx+dx, lty+dy, rbx+dx, rby+dy);
X MarkRulers (grid_x, grid_y);
X }
X
X dx = grid_x - grid_orig_x;
X dy = grid_y - grid_orig_y;
X
X if (moved)
X SelBox (drawWindow, revDefaultGC, ltx+dx, lty+dy, rbx+dx, rby+dy);
X }
X else if (input.type == ButtonPress)
X {
X XUngrabPointer (mainDisplay, CurrentTime);
X placing = FALSE;
X SelBox (drawWindow, revDefaultGC, ltx+dx, lty+dy, rbx+dx, rby+dy);
X Msg ("");
X switch (input.xbutton.button)
X {
X case Button1:
X if (!(AttrPtr->shown))
X {
X changed = TRUE;
X AttrPtr->shown = TRUE;
X }
X if (dx != 0 || dy != 0)
X {
X MoveObj (text_obj_ptr, dx<<zoomScale, dy<<zoomScale);
X AdjObjBBox (ObjPtr);
X return (TRUE);
X }
X else
X {
X if (changed) AdjObjBBox (ObjPtr);
X return (changed);
X }
X break;
X case Button2:
X if (!(AttrPtr->nameshown) || *(AttrPtr->name) != '\0')
X AttrPtr->nameshown = !AttrPtr->nameshown;
X UpdAttr (AttrPtr);
X if (AttrPtr->shown)
X {
X AdjObjBBox (ObjPtr);
X return (TRUE);
X }
X return (FALSE);
X case Button3:
X if (AttrPtr->shown)
X {
X AttrPtr->shown = FALSE;
X AdjObjBBox (ObjPtr);
X return (TRUE);
X }
X return (FALSE);
X }
X }
X }
X}
X
Xstatic
Xint ChangeAttrJust (ObjPtr, AttrPtr)
X struct ObjRec * ObjPtr;
X struct AttrRec * AttrPtr;
X{
X struct ObjRec * text_obj_ptr;
X int x, y, grid_x, grid_y, dx, dy, placing = TRUE;
X int ltx, lty, rbx, rby, moved = FALSE;
X int orig_x, orig_y, grid_orig_x, grid_orig_y;
X int old_just = 0, new_just = 0;
X XEvent input;
X
X text_obj_ptr = AttrPtr->obj;
X Msg ("LEFT--left, MIDDLE--center, RIGHT--right justified.");
X
X orig_x = OFFSET_X(text_obj_ptr->x);
X orig_y = OFFSET_Y(text_obj_ptr->y);
X GridXY (orig_x, orig_y, &grid_orig_x, &grid_orig_y);
X ltx = OFFSET_X(text_obj_ptr->bbox.ltx);
X lty = OFFSET_Y(text_obj_ptr->bbox.lty);
X rbx = OFFSET_X(text_obj_ptr->bbox.rbx)+1;
X rby = OFFSET_Y(text_obj_ptr->bbox.rby)+1;
X SelBox (drawWindow, revDefaultGC, ltx, lty, rbx, rby);
X
X XGrabPointer (mainDisplay, drawWindow, FALSE,
X PointerMotionMask | ButtonPressMask,
X GrabModeAsync, GrabModeAsync, None, handCursor, CurrentTime);
X XWarpPointer (mainDisplay, None, drawWindow, 0, 0, 0, 0, orig_x, orig_y);
X
X dx = dy = 0;
X grid_x = grid_orig_x; grid_y = grid_orig_y;
X
X while (placing)
X {
X XNextEvent (mainDisplay, &input);
X if (input.type == MotionNotify)
X {
X x = input.xmotion.x;
X y = input.xmotion.y;
X GridXY (x, y, &grid_x, &grid_y);
X
X if (moved = (grid_x != grid_orig_x+dx || grid_y != grid_orig_y+dy))
X {
X SelBox (drawWindow, revDefaultGC, ltx+dx, lty+dy, rbx+dx, rby+dy);
X MarkRulers (grid_x, grid_y);
X }
X
X dx = grid_x - grid_orig_x;
X dy = grid_y - grid_orig_y;
X
X if (moved)
X SelBox (drawWindow, revDefaultGC, ltx+dx, lty+dy, rbx+dx, rby+dy);
X }
X else if (input.type == ButtonPress)
X {
X XUngrabPointer (mainDisplay, CurrentTime);
X placing = FALSE;
X SelBox (drawWindow, revDefaultGC, ltx+dx, lty+dy, rbx+dx, rby+dy);
X Msg ("");
X old_just = text_obj_ptr->detail.t->just;
X switch (input.xbutton.button)
X {
X case Button1: new_just = JUST_L; break;
X case Button2: new_just = JUST_C; break;
X case Button3: new_just = JUST_R; break;
X }
X if (old_just != new_just)
X {
X text_obj_ptr->detail.t->just = new_just;
X UpdTextBBox (text_obj_ptr);
X AdjObjBBox (ObjPtr);
X return (TRUE);
X }
X return (FALSE);
X }
X }
X}
X
Xvoid MoveAttr ()
X{
X struct ObjRec * obj_ptr;
X struct AttrRec * attr_ptr, * attr_ptr1;
X int num_attrs = 0, i, index, x, y;
X int picture_changed, sel_ltx, sel_lty, sel_rbx, sel_rby;
X int * fore_colors, * pixel_ptr, * valid, * flag_ptr;
X int len1, len2;
X char * * attrStrs, * s, buf[MAXSTRING], msg[80];
X unsigned int button;
X
X if (topSel != botSel || topSel == NULL)
X { Msg ("Please select only ONE object."); return; }
X
X obj_ptr = topSel->obj;
X attr_ptr1 = attr_ptr = obj_ptr->fattr;
X
X for ( ; attr_ptr1 != NULL; attr_ptr1 = attr_ptr1->next, num_attrs++) ;
X
X if (num_attrs == 0)
X { Msg ("Selected object currently has NO attributes."); return; }
X
X attrStrs = (char * *) calloc (num_attrs, sizeof(char *));
X fore_colors = pixel_ptr = (int *) calloc (num_attrs, sizeof(int));
X valid = flag_ptr = (int *) calloc (num_attrs, sizeof(int));
X
X attr_ptr1 = attr_ptr;
X for (i = 0; i < num_attrs; i++, attr_ptr1 = attr_ptr1->next)
X {
X s = (char *) calloc (MAXSTRING, sizeof(char));
X attrStrs[i] = s;
X strcpy (s, attr_ptr1->name);
X
X len1 = strlen (attr_ptr1->name);
X len2 = strlen (attr_ptr1->s);
X if (len1+len2 >= MAXSTRING)
X {
X sprintf (msg, "String length exceeds %1d. String truncated.",
X MAXSTRING);
X Msg (msg);
X attr_ptr1->s[MAXSTRING-len1] = '\0';
X }
X
X strcat (s, attr_ptr1->s);
X *pixel_ptr++ = colorPixels[attr_ptr1->obj->color];
X *flag_ptr++ = TRUE;
X }
X
X Msg ("Hold down left button to see attributes.");
X strcpy (buf, "Left button move/see attributes. ");
X strcat (buf, "Middle button change attribute justifications.");
X Msg (buf);
X button = CornerLoop (&x, &y);
X index = TextMenuLoop (x, y, attrStrs, num_attrs, fore_colors, valid, True);
X if (index != INVALID)
X {
X attr_ptr1 = attr_ptr;
X for (i = 0; i < index; i++, attr_ptr1 = attr_ptr1->next) ;
X sel_ltx = selLtX; sel_lty = selLtY; sel_rbx = selRbX; sel_rby = selRbY;
X if (button == Button1)
X {
X if (picture_changed = MoveOneAttr (obj_ptr, attr_ptr1))
X {
X HighLightReverse ();
X UpdSelBBox ();
X RedrawAreas (botObj, sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
X sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
X selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X SetFileModified (TRUE);
X HighLightForward ();
X }
X }
X else if (button == Button2)
X {
X if (picture_changed = ChangeAttrJust (obj_ptr, attr_ptr1))
X {
X HighLightReverse ();
X UpdSelBBox ();
X RedrawAreas (botObj, sel_ltx-(1<<zoomScale), sel_lty-(1<<zoomScale),
X sel_rbx+(1<<zoomScale), sel_rby+(1<<zoomScale),
X selLtX-(1<<zoomScale), selLtY-(1<<zoomScale),
X selRbX+(1<<zoomScale), selRbY+(1<<zoomScale));
X SetFileModified (TRUE);
X HighLightForward ();
X }
X }
X }
X
X for (i = 0; i < num_attrs; i++) cfree (attrStrs[i]);
X cfree (attrStrs);
X justDupped = FALSE;
X}
X
Xvoid CopyAndUpdateAttrs (ToObjPtr, FromObjPtr)
X struct ObjRec * ToObjPtr, * FromObjPtr;
X{
X register struct AttrRec * to_attr_ptr, * from_attr_ptr;
X
X topAttr = botAttr = NULL;
X from_attr_ptr = FromObjPtr->fattr;
X for ( ; from_attr_ptr != NULL; from_attr_ptr = from_attr_ptr->next)
X {
X to_attr_ptr = ToObjPtr->fattr;
X for ( ; to_attr_ptr != NULL; to_attr_ptr = to_attr_ptr->next)
X {
X if (from_attr_ptr->obj->color == to_attr_ptr->obj->color &&
X strcmp (from_attr_ptr->name, to_attr_ptr->name) == 0)
X {
X if (*(from_attr_ptr->s) != '\0')
X {
X strcpy (to_attr_ptr->s, from_attr_ptr->s);
X UpdAttr (to_attr_ptr);
X }
X break;
X }
X }
X if (to_attr_ptr == NULL)
X { /* new attribute */
X to_attr_ptr = (struct AttrRec *) calloc (1, sizeof(struct AttrRec));
X to_attr_ptr->owner = ToObjPtr;
X DupAnAttr (from_attr_ptr, to_attr_ptr);
X LinkInAttr (NULL, topAttr, to_attr_ptr);
X }
X }
X if (topAttr != NULL)
X {
X topAttr->prev = NULL;
X botAttr->next = ToObjPtr->fattr;
X
X if (ToObjPtr->fattr != NULL) ToObjPtr->fattr->prev = botAttr;
X ToObjPtr->fattr = topAttr;
X if (ToObjPtr->lattr == NULL) ToObjPtr->lattr = botAttr;
X AdjObjBBox (ToObjPtr);
X }
X}
END_OF_FILE
if test 28217 -ne `wc -c <'attr.c'`; then
echo shar: \"'attr.c'\" unpacked with wrong size!
fi
# end of 'attr.c'
fi
echo shar: End of archive 1 \(of 23\).
cp /dev/null ark1isdone
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 at CS.UCLA.EDU ...!{uunet|ucbvax}!cs.ucla.edu!william
More information about the Comp.sources.x
mailing list