🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.postscript
1 messages
1 total messages Started by Jon Greenblatt Fri, 12 Feb 1988 17:59
IBM PC Graphics to PS
#6875
Author: Jon Greenblatt
Date: Fri, 12 Feb 1988 17:59
517 lines
11786 bytes
	Here is the epson to postscript program I promised earlier. It works
very well now but it's still a baby. I am distributing it in hopes to get
other postscript hackers interested in giving input. This program is
implemented using a finite state machine in readable format. I am not much
of a believer in comments but I strongly believe in readable code. If you
read the source carefully, you should know what's going on.


# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by rover!jonnyg on Fri Feb 12 12:33:06 EST 1988
# Contents:  epson.c set.h set.c crlf.c makefile
 
echo x - epson.c
sed 's/^@//' > "epson.c" <<'@//E*O*F epson.c//'
/*
 *  Version 0.5 {Supports about half of the more reasonable escapes}
 *
 *  IBM Graphics printer to postscript translator.
 *
 *	Copyright (c) 1988, Jonathan Greenblatt,
 *		<jonnyg@rover.umd.edu> (128.8.2.73)
 *		<jonnyg@umd5.umd.edu> (128.8.10.5)
 *		<pcproj@gymble.umd.edu> (128.8.128.16)
 *      This program may be redistributed in source form,
 *      provided no fee is charged and this copyright notice is preserved.
 *
 *  DESCRIPTION:
 *	This program uses standard input and output to convert epson printer
 *	codes to Postcript. This program is an execlent ASCII listing printer.
 *	The crlf program is include to add PC crlf to end of lines for
 *	printing UNIX listings. This program was written on an IBM RT running
 *	4.3. The RT does not do crlf conversions by default so some changes
 *	may have to be made on other systems. This is a working subset of
 *	what I plan to complete. I am distributing this in hopes someone else
 *	will take interest in this code.
 *
 *  SUPPORTS:
 *	1: ASCII text.
 *	2: Underlining.
 *	3: Overstrike.
 *	4: Double width.
 *	5: Highlighting <Esc>G
 *	6: Super/Subscript
 *	7: 80x66 character on a page.
 *
 *  NEEDED:
 *	1: Compressed mode.
 *	2: Variable line spacing.
 *	3: Option for hadling CRLF
 *	4: Non ASCII characters.
 *	5: Graphics escapes.
 *	6: I make an assumption that the font has a 6/10 ration, there are
 *	   better ways of doing this.
 *
 *  BUGS:
 *	1: Seems to timeout the apple laserwriter when I send large prinouts
 *	   through the tty line using no specail line controll.
 *
 *  PORTABILITY:
 *	I have not tried this anywhere else but it should be easily portable
 *	to the IBM PC with turbo or Microsoft C.
 *
 *  FILES:
 *	crlf.c:	Convert UNIX file to pc Carriage return linefeed format.
 *	epson.c: Main program.
 *	set.c: ASCII set functions, like pascal, will be used more as I write
 *		more.
 *	set.h: Include file for set handling code.
 *	makefile: Unix makefile.
 *
 */

#include	<stdio.h>
#include	"set.h" /* Set functions for characters */

#define	MAXX	480
#define	MAXY	396
#define	XSTART	0
#define	YSTART	point_sizey
#define	YSTOP	MAXY
#define	XSTOP	MAXX

#define	BNDX	(cx >= (XSTOP - point_sizex - 1))
#define	BNDY	(cy >= (YSTOP - 1))

#define	NUM_TABS	28
int tabs[NUM_TABS+1] = {8,16,32,40,48,56,64,72,80,88,96,104,112,124,
		-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};

char *printables =
" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`,./\\[]=-!@#$%^&*()_+|{}:\"<>?~;'";
char *needesc = "()\\";

typedef enum {normal,bold,doublenorm,doublebold} _font_type;

char *font_descr[] = {"Courier","Courier-Bold","Courier","Courier-Bold"};
char *font_name[] = {"normalfont","boldfont","doublefont","doublebold"};
int font_size[][2] = {{10,10},{10,10},{5,10},{5,10}};

char_set printable_set;
char_set needesc_set;

_font_type font_type;

int cx, cy;
int point_sizex, point_sizey;

int underline = 0;
int subscript =  0;
int doublewidth = 0;
int highlight = 0;

char *start_doc[] = {
	"/saveobj1 save def",
	"/mt {moveto} def",
	"/s {show} def",
	"clippath pathbbox",
	"/ymax exch def /xmax exch def /ymin exch def /xmin exch def",
	"xmin ymax translate",
	"xmax xmin sub 480 div",
	"ymin ymax sub 396 div",
	"scale",
	"newpath",
	".5 setlinewidth",
	NULL};

char *start_page[] = {
	"/saveobj2 save def",
	NULL};

char *end_page[] = {
	"showpage",
	"saveobj2 restore",
	NULL};

char *end_doc[] = {
	"saveobj1 restore",
	"\004",
	NULL};

define_font(name,font,sizex,sizey)
char *name, *font;
	{
	printf("/%s {/%s findfont [%d 10 6 div mul 0 0 -%d 0 0] makefont setfont} def\n",name,font,sizex,sizey);
	}

new_page() {
	cx = XSTART;
	cy = YSTART;
	plist(start_page);
	set_font();
	}

set_font()
	{
	font_type = 
		(doublewidth) ?
			(highlight) ?	doublebold : doublenorm
		:	(highlight) ?	bold: normal;
	point_sizex = get_pointx(font_size[(int)font_type][0]);
	point_sizey = get_pointy(font_size[(int)font_type][1]);
	printf("%s\n",font_name[(int)font_type]);
	}

eject_page() {
	plist(end_page);
	new_page();
	}

init_sets() {
	clear_set(printable_set);
	clear_set(needesc_set);
	str_add_set(printable_set,printables);
	str_add_set(needesc_set,needesc);
	}

get_pointx(char_per_inch)
	{
	return(60/char_per_inch);
	}

get_pointy(char_per_inch)
	{
	return(60/char_per_inch);
	}

init_printer() {
	point_sizex = get_pointx(font_size[(int)normal][0]);
	point_sizey = get_pointy(font_size[(int)normal][1]);
	plist(start_doc);
	define_font(font_name[(int)normal],font_descr[(int)normal],point_sizex,point_sizey);
	define_font(font_name[(int)bold],font_descr[(int)bold],point_sizex,point_sizey);
	point_sizex = get_pointx(font_size[(int)doublenorm][0]);
	point_sizey = get_pointy(font_size[(int)doublenorm][1]);
	define_font(font_name[(int)doublenorm],font_descr[(int)doublenorm],point_sizex,point_sizey);
	define_font(font_name[(int)doublebold],font_descr[(int)doublebold],point_sizex,point_sizey);
	font_type = normal;
	new_page();
	}

plist(l)
char **l;
	{
	while (*l != NULL)
		printf("%s\n",*l++);
	}

#define	LINE_SIZE	256
char pline[256];
int ptr = 0;

char outline[258];

putline()
	{
	char *s = pline;
	int p;
	int lx;

	if (BNDY) eject_page();
	while (*s == ' ' && ptr > 0)
		{
		s++;
		ptr--;
		if (BNDX) {cx = XSTART; newline();}
		cx += point_sizex;
		}
	while (ptr>0) {
		p = 0;
		if (BNDY) eject_page();
		if (BNDX) {cx = XSTART; newline();}
		lx = cx;
		while ((lx+point_sizex-1) < XSTOP && ptr > 0) {
			if (in_set(needesc_set,*s)) outline[p++] = '\\';
			outline[p++] = *s++;
			ptr--;
			lx += point_sizex;
			}
		outline[p] = 0;
		if (p > 0) {
		   int i = strlen(outline);
		   /* Forward slash won't work at the end of a string */
		   if (outline[i-1] == '/') {
				outline[i] = ' ';
				outline[i+1] = '\0';
				}
		   if (subscript)
			if (subscript == 1) /* Subscript */
			   printf("%d %d mt gsave 1 .5 scale (%s) s grestore\n",cx,cy,outline);
			else /* Superscript */
			   printf("%d %d mt gsave 1 .5 scale (%s) s grestore\n",cx,cy-(point_sizey>>1),outline);
		   else /* Normal printing */
			printf("%d %d mt (%s) s\n",cx,cy,outline);
		   if (underline)
			printf("%d %d mt %d %d lineto stroke\n",cx,cy+1,lx-1,cy+1);
		   }
		cx = lx;
		}
		
	}

newline() {
	cy += point_sizey;
	if (BNDY) eject_page();
	}

typedef enum {S_BASE,S_ESC,S_UNDERLINE,S_SUBSCRIPT,S_DOUBLE} states;

states state = S_BASE;

dochar(c)
	{
	if (ptr >= LINE_SIZE) putline();
	switch (state) {
	   case S_UNDERLINE:
		state = S_BASE;
		if (c == '\0')	underline = 0;
		else if (c == '\1') underline = 1;
		break;
	   case S_DOUBLE:
		state = S_BASE;
		if (c == '\0')	doublewidth = 0;
		else if (c == '\1') doublewidth = 1;
		set_font();
		break;
	   case S_SUBSCRIPT:
		state = S_BASE;
		if (c == '\0') subscript = 2;
		else if (c == '\1') subscript = 1;
		break;
	   case S_ESC:
		state = S_BASE;
		switch (c)
			{
			case 'G':
				highlight = 1;
				set_font();
				break;
			case 'H':
				highlight = 0;
				set_font();
				break;
			case '-':
				state = S_UNDERLINE;
				break;
			case 'T':
				subscript = 0;
				break;
			case 'S':
				state = S_SUBSCRIPT;
				break;
			case 'W':
				state = S_DOUBLE;
				break;
			}
		break;
	   case S_BASE:
		switch(c) {
		   case '\011': {
			int i,l;

			l = cx / point_sizex + ptr;
			for (i = 0; i < NUM_TABS && tabs[i] <= l; i++);
			if (tabs[i] == -1) break;
			i = tabs[i] - l;
			while (i-- > 0) dochar(' ');
			}
			break;
		   case '\033':
			putline();
			state = S_ESC;
			break;
		   case '\014':
			putline();
			eject_page();
			break;
		   case '\n':
			putline();
			newline();
			break;
		   case '\r':
			putline();
			cx = XSTART;
			break;
		   case 26:	/* CTRL-Z */
			break;
		   default:
			if (in_set(printable_set,c)) pline[ptr++] = c;
			else pline[ptr++] = ' ';
			break;
		   }
		   break;
		}
	}

char istr[128];

main() {
	int n;
	char *p;

	init_sets();
	init_printer();
	while ((n = read(0,p = istr,128)) > 0)
		while (n--) dochar(*p++);
	if (cx > XSTART || cy > YSTART)
		plist(end_page);
	else	printf("saveobj2 restore\n");
	plist(end_doc);
	}
@//E*O*F epson.c//
chmod u=rw,g=r,o=r epson.c
 
echo x - set.h
sed 's/^@//' > "set.h" <<'@//E*O*F set.h//'
#define INTS_IN_SET	16

typedef unsigned int char_set[INTS_IN_SET];
@//E*O*F set.h//
chmod u=rw,g=r,o=r set.h
 
echo x - set.c
sed 's/^@//' > "set.c" <<'@//E*O*F set.c//'
#include "set.h"

clear_set(set)
char_set set;
	{
	int i;
	for (i = 0; i < INTS_IN_SET; i++) set[i] = 0;
	}

fill_set(set)
char_set set;
	{
	int i;
	for (i = 0; i < INTS_IN_SET; i++) set[i] = 0xffff;
	}

not_set(set)
char_set set;
	{
	int i;
	for (i = 0; i < INTS_IN_SET; i++) set[i] ^= 0xffff;
	}

and_set(set,set1)
char_set set, set1;
	{
	int i;
	for (i = 0; i < INTS_IN_SET; i++) set[i] &= set1[i];
	}

or_set(set,set1)
char_set set,set1;
	{
	int i;
	for (i = 0; i < INTS_IN_SET; i++) set[i] |= set1[i];
	}

add_set(set,c)
char_set set;
unsigned int c;
	{
	c &= 0xff;
	set[c >> 4] |= 1 << (c & 15);
	}

del_set(set,c)
char_set set;
unsigned int c;
	{
	c &= 0xff;
	set[c >> 4] &= ~(1 << (c & 15));
	}

in_set(set,c)
char_set set;
unsigned int c;
	{
	c &= 0xff;
	return ((set[c >> 4] & (1 << (c & 15))) != 0);
	}

str_add_set(set,s)
char_set set;
char *s;
	{
	unsigned int c;
	while (*s) {
		c = *s++;
		c &= 0xff;
		set[c >> 4] |= 1 << (c & 15);
		}
	}

str_del_set(set,s)
char_set set;
char *s;
	{
	unsigned int c;
	while (*s) {
		c = *s++;
		c &= 0xff;
		set[c >> 4] &= ~(1 << (c & 15));
		}
	}
@//E*O*F set.c//
chmod u=rw,g=r,o=r set.c
 
echo x - crlf.c
sed 's/^@//' > "crlf.c" <<'@//E*O*F crlf.c//'
main() {
	char ibuff[512], *ip;
	char obuff[1024];
	int ic, oc;

	while ((ic = read(0,ip = ibuff,512)) > 0) {
		oc = 0;
		while (ic--)
			if (*ip == '\n')
				{
				ip++;
				obuff[oc++] = '\r';
				obuff[oc++] = '\n';
				}
			else	obuff[oc++] = *ip++;
		write(1,obuff,oc);
		}
	}
@//E*O*F crlf.c//
chmod u=rw,g=r,o=r crlf.c
 
echo x - makefile
sed 's/^@//' > "makefile" <<'@//E*O*F makefile//'
CC=cc

all: epson crlf

epson: epson.o set.o
	$(CC) epson.o set.o -o epson

epson.o: epson.c set.h
	$(CC) -O -c epson.c

set.o: set.c set.h
	$(CC) -O -c set.c

crlf: crlf.c
	$(CC) -O crlf.c -o crlf
@//E*O*F makefile//
chmod u=rw,g=r,o=r makefile
 
exit 0
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads