ftp.nice.ch/pub/next/text/tex/library/TeX.fonts.d.tar.gz#/tex-font/xhershey/xhershey.c

This is xhershey.c in view mode; [Download] [Up]

#include	<stdio.h>

#ifndef	NO_X_WINDOW
#include	<X11/Xlib.h>
#include	<X11/Xatom.h>
#endif	NO_X_WINDOW

#include	"font.h"
#include	"parse.h"

#define		MAXPIXEL	25
#define		NORMALVOFF	9	/* Normal baseline for Hershey fonts */
#define		CTOI(c)		((c)-'R')

static char	copyright[]	= "Copyright (C) Ken Yap 1988";

static char	*progname;
static char	mfcode		= 1;	/* generate METAFONT code */
static char	xwin		= 1;	/* plot in X window */
static char	nums		= 0;	/* 0: none , 1: end points, 2: all */
static char	*fontlib	= "occidental";
static int	mag		= 2;
static int	xorg, yorg;
#ifndef	NO_X_WINDOW
Display 		*d;
Window			w;
XSetWindowAttributes	xswa;
Visual			visual;
GC			gc;
XGCValues		xgcv;
#endif	NO_X_WINDOW

main(argc, argv)
	int		argc;
	char		*argv[];
{
	register int	i;
	extern int	optind;
	extern char	*optarg;
	char		*rindex();

	if ((progname = rindex(argv[0], '/')) != NULL)
		++progname;
	else
		progname = argv[0];

	while ((i = getopt(argc, argv, "f:m:n:MX")) != EOF)
		switch (i)
		{
		case 'f':		/* different Hershey database */
			fontlib = optarg;
			break;
		case 'm':		/* magnification in window */
			mag = atoi(optarg);
			if (mag <= 0 || mag > 10)
				mag = 2;
			break;
		case 'n':		/* put numbers on points */
			nums = atoi(optarg);
			if (nums <= 0 || nums > 2)
				nums = 0;
			break;
		case 'M':		/* no METAFONT code */
			mfcode = 0;
			break;
		case 'X':		/* no X window */
			xwin = 0;
			break;
		default:
			usage();
			break;
		}

	argc -= optind;
	argv += optind;
	if (argc > 0)
	{
		if (freopen(argv[0], "r", stdin) == NULL)
		{
			perror(argv[0]);
			exit(1);
		}
	}

	xhershey(fontlib);
	exit(0);
}

static usage()
{
	(void)fprintf(stderr, "Usage: xhershey [-f fontlib] [-m mag] [-n annotelevel] [-M] [-X]\n");
	exit(1);
}

static xhershey(fontfilename)
	char		*fontfilename;
/*
**	Main loop, get user input, plot char, output code
*/
{
	register FILE	*fontfile;
	char		line[512];
	int		parsespecs();
	Window		makewindow();

	if ((fontfile = fopen(fontfilename, "r")) == NULL)
	{
		perror(fontfilename);
		return;
	}
#ifndef	NO_X_WINDOW
	if (xwin)
	{
		if ((w = makewindow(progname)) == (Window)0)
		{
			fprintf(stderr, "Can't make X11 window\n");
			exit(1);
		}
	}
#endif
	scanfont(fontfile);
	(void)fprintf(stderr, "Font file ready...\n");
	while (fgets(line, sizeof(line), stdin) != NULL)
	{
		if (parsespecs(line))
		{
			if (getline(fontfile, perchar.hersheyindex, line, sizeof(line)))
			{
#ifdef	PRINTDATA		/* see raw data */
				fputs(line, stderr);
#endif	PRINTDATA
				if (mfcode)
					genchar(line);
#ifndef	NO_X_WINDOW
				if (xwin)
					displaychar(line);
#endif	NO_X_WINDOW
			}
			else
				(void)fprintf(stderr, "Char %d not in font\n",
					perchar.hersheyindex);
		}
	}
	(void)fclose(fontfile);
}

#ifndef	NO_X_WINDOW
Window makewindow(title)
	char		*title;
{
	Window		w;
	register int		width, height;
	XEvent		event;

	xorg = MAXPIXEL * mag;
	yorg = MAXPIXEL * mag;
	width = xorg * 2;
	height = yorg * 2;

	if (!(d = XOpenDisplay((char *)0)))
		return ((Window)0);

	xswa.event_mask = ExposureMask | ButtonPressMask;
	xswa.background_pixel = WhitePixel(d, DefaultScreen(d));
	xswa.border_pixel = BlackPixel(d, DefaultScreen(d));
	visual.visualid = CopyFromParent;

	if ((w = XCreateWindow(d, RootWindow(d, DefaultScreen(d)),
		0, 0,
		width, height,
		1, 1,
		InputOutput, &visual,
		CWEventMask | CWBorderPixel | CWBackPixel,
		&xswa)) == (Window)0)
		return (0);

	XChangeProperty(d, w, XA_WM_NAME, XA_STRING, 8,
		PropModeReplace, title, strlen(title));

	XMapWindow(d, w);

	xgcv.foreground = BlackPixel(d, DefaultScreen(d));
	xgcv.background = WhitePixel(d, DefaultScreen(d));
	gc = XCreateGC(d, w, GCForeground | GCBackground, &xgcv);

	XNextEvent(d, &event);
	switch (event.type)
	{
	case Expose:
		while (XCheckTypedEvent(d, Expose, &event))
			;
		break;
	default:
		(void)fprintf(stderr, "Unknown event type %d\n", event.type);
		break;
	}
	return (w);
}

static displaychar(buf)
	char		*buf;
/*
**	Plot char in window
*/
{
	register int	i, npoints, oxpos, oypos, xpos, ypos, xmin, xmax;
	register char	*p;
	char		spoints[4];
	XEvent		event;

	XClearWindow(d, w);
	spoints[3] = '\0';
	(void)strncpy(spoints, &buf[5], 3);
	p = &buf[8];

	/* first point fixes origin of char */
	xmin = CTOI(*p++) * mag + xorg;
	xmax = CTOI(*p++) * mag + xorg;
	ypos = NORMALVOFF * mag + yorg;
	XDrawLine(d, w, gc, 0, ypos, xorg*2-1, ypos);
	XDrawLine(d, w, gc, xmin, 0, xmin, yorg*2-1);
	XDrawLine(d, w, gc, xmax, 0, xmax, yorg*2-1);

	npoints = atoi(spoints) - 1;
	/* get first point */
	oxpos = CTOI(*p++) * mag + xorg;
	oypos = CTOI(*p++) * mag + yorg;
	if (nums > 0)
		XDrawString(d, w, gc, oxpos + 2, oypos, "0", 1);
	for (i = 1; i < npoints; ++i)
	{
		/* lift pen */
		if (*p == ' ')
		{
			p += 2;
			++i;
			oxpos = CTOI(*p++) * mag + xorg;
			oypos = CTOI(*p++) * mag + yorg;
			if (nums > 0)
			{
				sprintf(spoints, "%d", i);
				XDrawString(d, w, gc, oxpos + 2, oypos,
					spoints, strlen(spoints));
			}
		}
		else
		{
			xpos = CTOI(*p++) * mag + xorg;
			ypos = CTOI(*p++) * mag + yorg;
			XDrawLine(d, w, gc, oxpos, oypos, xpos, ypos);
			if (nums == 2 || nums == 1
				&& (*p == ' ' || i == npoints - 1))
			{
				sprintf(spoints, "%d", i);
				XDrawString(d, w, gc, xpos + 2, ypos,
					spoints, strlen(spoints));
			}
			oxpos = xpos;
			oypos = ypos;
		}
	}
	for (;;)
	{
		XNextEvent(d, &event);
		switch (event.type)
		{
		case Expose:
			while (XCheckTypedEvent(d, Expose, &event))
				;
			break;
		case ButtonPress:
			return;
			break;
		default:
			(void)fprintf(stderr, "Unknown event type %d\n", event.type);
			break;
		}
	}
}
#endif	NO_X_WINDOW

static genchar(buf)
	char		*buf;
/*
**	Generate METAFONT code for char
*/
{
	register int	i, npoints, oxpos, oypos, xpos, ypos;
	register char	*p;
	int		x0, y0, start, width, ymax = 0, ymin = 256;
	char		spoints[4];

	spoints[3] = '\0';
	(void)strncpy(spoints, &buf[5], 3);
	npoints = atoi(spoints) - 2;
	p = &buf[8];

	/* first two numbers are xmin and xmax */
	x0 = CTOI(*p++);
	width = CTOI(*p++) - x0;
	x0 += atoi(perchar.hoff);
	y0 = NORMALVOFF + atoi(perchar.voff);
	/* find height and depth */
	for (i = 0; i < npoints; ++i, p += 2)
	{
		if (*p != ' ')
		{
			ypos = y0 - CTOI(p[1]);
			if (ypos > ymax)
				ymax = ypos;
			if (ypos < ymin)
				ymin = ypos;
		}
	}
	if (ymin > 0)
		ymin = 0;

	/* output header */
	(void)printf("x#:=%su#; y#:=%su#;\n", perchar.hratio, perchar.vratio);
	if ('!' <= perchar.asciiindex && perchar.asciiindex <= '~' && perchar.asciiindex != '"')
		(void)printf("beginchar(\"%c\",%dx#,%dy#,%dy#); \"The letter %c\";\n",
			perchar.asciiindex, width, ymax, -ymin,
			perchar.asciiindex);
	else
		(void)printf("beginchar(char %d,%dx#,%dy#,%dy#); \"The letter '\\%03o'\";\n",
			perchar.asciiindex, width, ymax, -ymin,
			perchar.asciiindex);
	(void)printf("adjust_fit(0,0); pickup plotter_pen;\n");
	(void)printf("x:=%su; y:=%su;\n", perchar.hratio, perchar.vratio);

	p = &buf[10];
	/* get first point */
	start = 0;
	oxpos = CTOI(*p++) - x0;
	oypos = y0 - CTOI(*p++);
	(void)printf("z%d=(%dx,%dy);\n", start, oxpos, oypos);
	for (i = 1; i <= npoints; ++i)
	{
		/* lift pen */
		if (*p == ' ')
		{
			outlist(start, i-1);
			p += 2;
			++i;
			oxpos = CTOI(*p++) - x0;
			oypos = y0 - CTOI(*p++);
			start = i;
			(void)printf("z%d=(%dx,%dy);\n", i, oxpos, oypos);
		}
		else
		{
			xpos = CTOI(*p++) - x0;
			ypos = y0 - CTOI(*p++);
			(void)printf("z%d=(%dx,%dy);\n", i, xpos, ypos);
			oxpos = xpos;
			oypos = ypos;
		}
	}
	outlist(start, i-1);
	(void)printf("endchar;\n");
}

static outlist(start, end)
	int		start, end;
/*
**	Output a list of points to join with curve
*/
{
	register int	i;

	/* null case? */
	if (start == end)
		return;
	(void)printf("draw ");
	for (i = start; i < end; ++i)
		(void)printf("z%d--", i);
	(void)printf("z%d;\n", end);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.