[comp.sources.x] v08i101: pic support for xditview, Part01/01

amana@yetti.cs.yorku.ca (John Amanatides) (08/28/90)

Submitted-by: amana@yetti.cs.yorku.ca (John Amanatides)
Posting-number: Volume 8, Issue 101
Archive-name: xditv.patch/part01

[ Note: this is not an "official" patch to the program since it was
never submitted to this newsgroup. --dan ]

The X11R4 release of xditview does not have support for pic commands.
Below is the replacement for draw.c with the added support.
Note: you have to include the math library (-lm) now.

-----------------------------------------------------------------------
/*
 * draw.c
 *
 * accept dvi function calls and translate to X
 *
 * added pic support, John Amanatides, August 1990
 */

#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <stdio.h>
#include <ctype.h>
#include "DviP.h"

extern double sqrt(), atan2();
extern long strtol();

HorizontalMove(dw, delta)
	DviWidget	dw;
	int		delta;
{
	dw->dvi.state->x += delta;
}

HorizontalGoto(dw, NewPosition)
	DviWidget	dw;
	int		NewPosition;
{
	dw->dvi.state->x = NewPosition;
}

VerticalMove(dw, delta)
	DviWidget	dw;
	int		delta;
{
	dw->dvi.state->y += delta;
}

VerticalGoto(dw, NewPosition)
	DviWidget	dw;
	int		NewPosition;
{
	dw->dvi.state->y = NewPosition;
}

FlushCharCache (dw)
	DviWidget	dw;
{
	if (dw->dvi.cache.char_index != 0)
	    XDrawText (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
			dw->dvi.cache.start_x, dw->dvi.cache.start_y,
 			dw->dvi.cache.cache, dw->dvi.cache.index + 1);
	dw->dvi.cache.index = 0;
	dw->dvi.cache.max = DVI_TEXT_CACHE_SIZE;
	if (dw->dvi.noPolyText)
	    dw->dvi.cache.max = 1;
	dw->dvi.cache.char_index = 0;
	dw->dvi.cache.cache[0].nchars = 0;
	dw->dvi.cache.start_x = dw->dvi.cache.x = dw->dvi.state->x;
	dw->dvi.cache.start_y = dw->dvi.cache.y = dw->dvi.state->y;
}

ClearPage (dw)
	DviWidget	dw;
{
	XClearWindow (XtDisplay (dw), XtWindow (dw));
}

static void setGC (dw)
	DviWidget	dw;
{
	if (dw->dvi.state->line_style != dw->dvi.line_style ||
	    dw->dvi.state->line_width != dw->dvi.line_width)
	{
		XSetLineAttributes (XtDisplay (dw), dw->dvi.normal_GC,
				    dw->dvi.state->line_width,
				    LineSolid,
				    CapButt,
				    JoinMiter
				    );
		dw->dvi.line_style = dw->dvi.state->line_style;
		dw->dvi.line_width = dw->dvi.state->line_width;
	}
}

DrawLine (dw, x, y)
	DviWidget	dw;
	int		x, y;
{
	x += dw->dvi.state->x;
	y += dw->dvi.state->y;
	XDrawLine (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
		dw->dvi.state->x, dw->dvi.state->y, x, y);
	dw->dvi.state->x = x;
	dw->dvi.state->y = y;
}

DrawCircle (dw, diameter)
	DviWidget	dw;
	int		diameter;
{
	XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
		dw->dvi.state->x, dw->dvi.state->y - diameter/2,
		diameter, diameter, 0, 360*64);
}

DrawEllipse (dw, a, b)
	DviWidget	dw;
	int		a, b;
{
	XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
		dw->dvi.state->x, dw->dvi.state->y - b/2,
		a, b, 0, 360*64);
}

#define RAD2DEG	(57.29577951308232)

DrawArc (dw, x0, y0, x1, y1)
	DviWidget	dw;
	int		x0, y0, x1, y1;
{
	int radius, angle0, angle1;

	radius= sqrt((double) (x0*x0 + y0*y0));
	angle0= -64.0*RAD2DEG*atan2((double) -y0, (double) -x0);
	if(angle0 < 0)
		angle0 += 360*64;
	angle1= -64.0*RAD2DEG*atan2((double) y1, (double) x1);
	if(angle1 < 0)
		angle1 += 360*64;
	angle1 -= angle0;
	if(angle1 < 0)
		angle1 += 360*64;
	XDrawArc (XtDisplay (dw), XtWindow (dw), dw->dvi.normal_GC,
		dw->dvi.state->x + x0 - radius, dw->dvi.state->y + y0 - radius,
		2*radius, 2*radius, angle0, angle1);
	dw->dvi.state->x += x0 + x1;
	dw->dvi.state->y += y0 + y1;
}

#define MAX_KNOTS	256

DrawSpline (dw, s, len)
	DviWidget	dw;
	char		*s;
	int		len;
{
	XPoint knots[MAX_KNOTS];
	XPoint *points, *ComputeSpline();
	int numKnots, numPoints;

	/* read knots, duplicate first and last, convert relative to absolute */
	knots[0].x= dw->dvi.state->x;
	knots[0].y= dw->dvi.state->y;
	knots[1]= knots[0];
	numKnots= 2;
	while(getpoint(&s, &knots[numKnots]) && numKnots < MAX_KNOTS-1) {
		knots[numKnots].x += knots[numKnots-1].x;
		knots[numKnots].y += knots[numKnots-1].y;
		numKnots++;
	}
	knots[numKnots]= knots[numKnots-1];
	numKnots++;

	points= ComputeSpline(knots, numKnots, &numPoints);
	XDrawLines (XtDisplay (dw),  XtWindow (dw), dw->dvi.normal_GC,
			points, numPoints, CoordModeOrigin);
	dw->dvi.state->x= points[numPoints-1].x;
	dw->dvi.state->y= points[numPoints-1].y;
}

static
int getpoint(buffer, point)
char	**buffer;
XPoint	*point;
{
	char *end;

	if(*buffer == 0 || **buffer == '\0')
		return 0;
	point->x= (short) strtol(*buffer, &end, 10);
	if(end == *buffer)
		return 0;
	*buffer= end;
	point->y= (short) strtol(*buffer, &end, 10);
	*buffer= end;
	return 1;
}

#define SUBDIV	4

static
XPoint *ComputeSpline(knots, numKnots, numPoints)
register XPoint	knots[];
int	numKnots, *numPoints;
{
	static XPoint spline[SUBDIV*MAX_KNOTS];
	register int i, j, n;
	double w, t1, t2, t3;

	n= 0;
	for(i=0;i < numKnots-2; i++)
		for(j=0; j < SUBDIV; j++) {
			w= (1.0/SUBDIV) * j;
			t1= 0.5*w*w;
			w -= 0.5;
			t2= 0.75-w*w;
			w -= 0.5;
			t3= 0.5*w*w;
			spline[n].x= t1*knots[i+2].x + t2*knots[i+1].x +
							t3*knots[i].x + 0.5;
			spline[n].y= t1*knots[i+2].y + t2*knots[i+1].y +
							t3*knots[i].y + 0.5;
			if(n == 0 || spline[n].x != spline[n-1].x ||
					spline[n].y != spline[n-1].y)
				n++;
		}
	spline[n++]= knots[numKnots-1];
	*numPoints= n;
	return spline;
}

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.