From stephenf@elecvax.eecs.unsw.oz (Stephen Frede) Wed May 21 04:00:12 1986 Path: seismo!munnari!basser!elecvax!stephenf From: stephenf@elecvax.eecs.unsw.oz (Stephen Frede) Newsgroups: net.sources Subject: Part 1 of 4 - PostScript programs (for ditroff etc.) Message-ID: <2404@elecvax.eecs.unsw.oz> Date: 21 May 86 08:00:12 GMT Followup-To: net.sources.d Organization: EE and CS, Uni of NSW, Sydney, Australia Lines: 1221 # This is a set of programs which produce PostScript. Included are # a back end for ditroff, a program which accepts plain text, and a # program which accepts images. # Also included are ditroff font width files and some miscellaneous # PostScript scripts. # For more details see the file READ_ME in the first part. # There are 4 parts. # # Stephen Frede University of New South Wales, Sydney, Australia # # ACSnet: stephenf@elecvax.oz ARPA: stephenf%elecvax.oz@seismo # CSnet: stephenf@elecvax.oz@csnet-relay.csnet # UUCP: {seimso,ubc-vision,ukc,mcvax,prlb2}!munnari!elecvax.oz!stephenf # ------------------------------------------------------------------------ # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # READ_ME Makefile man/ipscript.1 man/lpscript.1 src/Makefile src/troff.sh src/tpscript/Makefile src/tpscript/dev.h src/tpscript/gendefs.sed src/tpscript/hash.h src/tpscript/pscript.h src/tpscript/sfont2defs.H src/tpscript/sfont2defs.h src/tpscript/stringdefs.H src/tpscript/stringdefs.h src/tpscript/tpscript.h echo Creating directories man src src/opscript src/tpscript src/pscript devalw mkdir man mkdir src mkdir src/opscript mkdir src/tpscript mkdir src/pscript mkdir devalw echo x - READ_ME cat > "READ_ME" << '//E*O*F READ_ME//' Copyright: 1985, Stephen Frede, UNSW Australia Use it and copy it as much as you want, but don't pretend you wrote it, or sell it for profit. Authorship: Originally by Stephen Frede. Various extensive changes by Cameron Davidson and Michael Rourke. Contents: 0) File 'READ_ME', directories 'src', 'src/tpscript', 'src/opscript', 'src/pscript', 'man', 'devalw' 1) Source for a back end to ditroff which converts ditroff output to PostScript (src/tpscript). 2) Font code and width tables suitable for use with ditroff (devalw). 3) A program (lpscript) which converts plain text into postscript. various options allow selection of font, size and rotation, etc. 4) A program (ipscript) which converts bitmap images of various sorts into postscript. 5) Manual entries for lpscript and ipscript. 6) The directory src/pscript contains some random postscript programs that may or may not be useful. NOTES: The sources should be pretty much bug free. They have been run on a few different systems, but I have no doubt that upon releasing it to the world, some will come to light. Please mail suggestions and fixes directly to me at the address given above. The troff names for many of the characters were taken from a paper about such things from: "Adventures with Typesetter Independent Troff", by Mark Kahrs and Lee Moore, Dept. Computer Science, University of Rochester, Rochester, NY 14627. TR159; June, 1985. Work is in progress to allow down-line loading of fonts other than those available by default in the LaserWriter (or whatever), such as the Berkeley fonts. They have never been run on anything other than a LaserWriter, but I don't know of any inherent machine dependencies (other than those indicated by "#if ALW"). There are some further changes made by Cameron Davidson to fine tune some problems with rounding to pixel boundaries on the LaserWriter that are not included in this release. There are two basica possible approaches to generating postscript from some other format. The first is to generate a postscript program which then reads input and does the conversion itself. The alternative is to do as much of the translation as possible first, generating relatively simple postscript commands. This is the way these programs work. I have not seen Transcript, by Adobe Systems, but I suspect they do it the first way. Add an entry to the "magic" file that the file(1) command uses to look for the characters "%!" at the start of a file. This indicates that a file is "PostScript". Installation: First you must have ditroff, a device independant troff from ATT, requiring a licence. This most usually comes with Documenter's WorkBench (DWB). This should include the program "makedev", used to "compile" the ascii font tables into binary, so that troff and tpscript can read them. Put all of this stuff into a directory somewhere. Edit the Makefile in the top directory and set SYS= one of the systems indicated there (AUSAM, V7, SYS5, BSD). Then set VERBOSE=1 if you want some needless extra frills. This is mainly just identifying jobs by username, etc. Set MAKEDEV to be the pathname of the makedev program (in the troff source directory ?). Then compile it all by saying "make" in the top directory. This should generate tpscript, ipscript and lpscript. Install them manually in whatever way is appropriate for your system. Possibly change the Makefiles to do this. Also note that the Makefiles will not do anything smart about .o files or anything like that. We have installed the real troff in /bin/ditroff and made troff a shell script that invokes the appropriate back end. The shell script is included here as src/troff.sh, use it if you want. Install the manual entries for ipscript and lpscript (from the man directory). Possible problems: First read the problems section in "Inside LaserWriter". Note the various patches from Adobe that have come over USENET. On some versions of Unix, if the LaserWriter is connected to a tty port, and a daemon of some sort continually sends stuff to the LaserWriter, but never reads anything, and the LaserWriter sends messages back (which aren't read by anyone), then when the total number of unread characters reaches a certain amount (TTYHOG, 256 or 512 usually), both the input AND output queues are flushed, so some characters to the LaserWriter get dropped, probably causing a syntax error and the rest of the job to be flushed. A good thing to do (even if you don't have this problem) is to collect all the output from that line and save it in a file. This makes looking at error and other messages from the LaserWriter quite easy (tail /tmp/laserout). Note a bug in many versions of eqn(1) which causes a right large square bracket to be made of '|' characters instead of "\(bv" chars. If you have the source, this is easy to fix. I don't know what some of the Berkeley ditroff output means. If someone would like to fill me in, I'll add it to tpscript. //E*O*F READ_ME// echo x - Makefile cat > "Makefile" << '//E*O*F Makefile//' # SYS should be one of AUSAM, BSD, SYSV, V7 # This is only really important if VERBOSE (below) is 1. SYS=SYSV # VERBOSE should be 1 to generate postscript code to echo stuff # back down the communication line. Otherwise 0. VERBOSE=0 MAKEDEV=../devalw # pathname relative to devalw CD=builtin cd all: $(CD) src; $(MAKE) $(MFLAGS) SYS=$(SYS) VERBOSE=$(VERBOSE) $(CD) devalw; $(MAKE) MAKEDEV=$(MAKEDEV) //E*O*F Makefile// echo x - man/ipscript.1 cat > "man/ipscript.1" << '//E*O*F man/ipscript.1//' .TH IPSCRIPT 1 .SH NAME ipscript \- convert bit image into postscript .SH SYNOPSIS .B ipscript [option] ... [file] ... .SH DESCRIPTION .I Ipscript reads bit images from standard input (or files if specified) and produces postscript output, suitable for sending to any postscript device (such as an Apple Laserwriter) or for using with any program that expects postscript input (such as a postscript interpreter used to drive some other raster device). In the output, grey levels are represented by a halftoning technique, whereby a grid of halftone cells is produced from the input data. The default frequency of halftone cells is 60 per inch, and an angle of 45 degrees. (Alterable using the .B \-f and .B \-p options.) The following options are understood: .TP .B \-wWidth The image produced will be the given width (in cm). This may be a real number. The default is 18 cm. .TP .B \-hHeight The image will be produced with the given height (in cm). This may be a real number. The default is 12cm. .TP .B \-aAspect The image will be produced with the given aspect ratio. The default aspect ratio is 1.5 (width/height). If both width and height are specified on the command line, the aspect ratio will be determined from these, rather than this argument. .TP .B \-bBits This argument controls the output resolution (ie the number of grey levels used). It may be any of 1, 2, 4, or 8 for 2, 4, 16 or 256 output grey levels respectively. The default is 8 bits. .TP .B \-gGrey This (signed integer) value can be used to offset the input grey level by a fixed amount. It can be used to brighten or darken images. .TP .B \-yScanlines This value determines the number of pixels along the Y axis of the input image. This is the number of scanlines of the input. The default is 256. .TP .B \-xScanlength This value is the number of pixels along the X axis of the input image. This is the length of an input scanline. The default is 256. .TP .B \-fFrequency This value determines the output frequency in halftone cells/inch. The default is device dependant, but is 60 for the Apple LaserWriter. .TP .B \-pAngle Specifies the angle (in degrees) at which the output halftone cell grid is rotated. The default is device dependant, but is 45 for the Apple LaserWriter. .TP .B \-iFormat This argument specifies the input format and resolution. It consists of a character ('b' or 'x') followed by a value. The character specifies the form of the input: whether input data is given in raw bytes or in hex notation. The following value gives the input greyscale resolution - the number of bits representing the image which may appear in the input. If hex input format is being used and the greyscale resolution is less than or equal to 4 bits, single hex bytes are read, otherwise pairs of hex bytes are read to achieve a resolution of up to 8 bits. The default is 'b8' - bytes with a possible value of from 0 to 255. Input is scaled using this information and the number of output grey levels (if necessary). .TP .B \-sSkip Directs \fIipscript\fP to skip the given no. of bytes at the start of the input file. This is useful for files which have headers at the beginning. For example, Macquarie Uni satellite photos have a 128 byte header. .TP .B \-r[angle] This argument specifies an image rotation in degrees. If '-r' is given with no value, 90 is assumed, which results in landscape mode being used (long axis of paper horizontal). The default is 0, which is portrait mode (long axis of paper vertical). .TP .B \-n Print the negative of the image. That is, reverse black and white. .TP .B \-S Use manual feed instead of feeding from the paper tray. .TP .B \-L Print using legal page type - 17.8 by 31.8 cm (7 by 12.5 inches) imageable region, centred on a 21.6 by 35.6 cm (8.5 by 14 inch) page. The default (letter) paper type uses a 20.3 by 26.7 cm (8 by 10.5 inch) imageable region, centred on a 21.6 by 27.9 cm (8.5 by 11 inch) page. .SH SEE ALSO ditroff(1) .SH AUTHOR Stephen Frede, UNSW, Australia //E*O*F man/ipscript.1// echo x - man/lpscript.1 cat > "man/lpscript.1" << '//E*O*F man/lpscript.1//' .TH LPSCRIPT 1 .SH NAME lpscript \- convert text to postscript .SH SYNOPSIS .B lpscript [-o[offset]] [-r[rotation]] [-s[fontsize]] [-f[font]] [-p[pitch]] [-t[tabsize]] [-h[horizontal_spacing]] [-S] [-L] [file ...] .SH DESCRIPTION .I Lpscript reads text from standard input (or files if specified) and produces postscript output, suitable for sending to any postscript device (such as an Apple Laserwriter) or for using with any program that expects postscript input (such as a postscript interpreter used to drive some other raster device). Text is normally aligned at the top and left with the imageable region of the page (probably slightly smaller than the physical page size), and a new page is taken whenever text would fall below this imageable region. The following options are understood, with all values able to be given as integer or real: .TP .B \-o[distance] Offset the text from the left edge of the imageable region, by the given distance (in centimeters). If \fB-o\fP is specified without a distance, 1 cm is assumed. .TP .B \-r[angle] Rotate the page by the given angle, specified in degrees. If no angle is specified, 90 degrees is assumed. Normally, the page will be printed in portrait mode, ie with the long axis vertical. This option allows printing in landscape mode (with the long axis horizontal). Note that specifying an angle other than 0 or 90 will almost certainly cause part of the text to fall outside the imageable region, which serves you right for trying to be silly. .TP .B \-s[size] Set the font size to the value given (in points) (72 points = 1 inch). If a size is omitted, 12 is assumed. The default point size without using this option is 10. Specifying point sizes greater than 200 is probably silly and certainly wastes toner. .TP .B \-t[tabsize] Set the tab size to the value given (in characters). If a value is omitted, 4 is assumed (the default is 8). This option allows printing of program listings etc., to fit across the page. .TP .B \-p[pitch] Set the line spacing of printed text to this value. Giving a value here will cause the line spacing to be set to that value, in points (72 points = 1 inch). If this argument is given without a value, double spacing is selected. The default spacing is 0. .TP .B \-f[fontname] Set the font used to the name given. The default font is `Courier'. If this argument is given without a fontname, `Times-Roman' is used. The list of available fonts (for the Apple Laser-Writer) is: `Times-Roman' ; `Times-Italic' ; `Times-Bold'; `Times-BoldItalic'; `Courier'; `Courier-Oblique' ; `Courier-Bold'; `Courier-BoldOblique'; `Helvetica'; `Helvetica-Bold' ; `Helvetica-Oblique'; `Helvetica-BoldOblique'. Note that only the Courier family is a fixed-width font; all the others are variable width, and so program listings or columns of data will not line up. .TP .B \-h[space] Increase the horizontal spacing of characters by the given fraction of the current font size. For example, using `-h0.25' with a font size of 12 points in effect, would cause an increase of horizontal spacing by 3 points. By default, the characters are placed next to each other, using the natural width of the characters. Negative values (eg. -h-0.1) cause horizontal spacing to be decreased. .TP .B \-a[aspect-ratio] Set the aspect ratio (height:width) of each character to the given value (default 1). .TP .B \-S Use manual feed instead of feeding from the paper tray. .TP .B \-L Print using legal page type - 17.8 by 31.8 cm (7 by 12.5 inches) imageable region, centred on a 21.6 by 35.6 cm (8.5 by 14 inch) page. The default (letter) paper type uses a 20.3 by 26.7 cm (8 by 10.5 inch) imageable region, centred on a 21.6 by 27.9 cm (8.5 by 11 inch) page. .SH SEE ALSO ditroff(1) .SH AUTHOR Stephen Frede, UNSW, Australia //E*O*F man/lpscript.1// echo x - src/Makefile cat > "src/Makefile" << '//E*O*F src/Makefile//' CD=builtin cd all: tpscript.d others MFLAGS=SYS=$(SYS) VERBOSE=$(VERBOSE) tpscript.d: $(CD) tpscript; $(MAKE) $(MFLAGS) others: $(CD) opscript; $(MAKE) $(MFLAGS) //E*O*F src/Makefile// echo x - src/troff.sh cat > "src/troff.sh" << '//E*O*F src/troff.sh//' # troff shell script - invoke ditroff with appropriate args # - Stephen Frede # The default device dev=-Talw # default postprocessor post=tpscript # ditroff arguments ditargs= # postprocessor arguments postargs= for i do case $i in -Talw) dev=-Talw post=tpscript ;; -Toldalw) dev=-Toldalw post=oldtpscript ;; -Ttek) dev=-Talw # use alw font tables post=tc ;; -Tuqalw) dev=-Talw post=tpscript echo "-Tuqalw has been re-named -Talw (new default) (warning)" 1>&2 ;; -Thpgl) dev=-Talw # use alw font tables for now post=hpgl echo "hpgl back end not finished yet" 1>&2 exit 1 ;; -T*) echo invalid device $i; exit 1 ;; -c*) # -cxxx doesn't work; translate to -mxxx ditargs="$ditargs "-m`expr "$i" : "-.\(.*\)"` ;; -a) # ascii representation - no postprocessor ditargs="$ditargs -a" post="" ;; -R*) # rotate if [ "$dev" != "-Talw" ] then echo "-R option only applies to device 'alw'" 1>&2 exit 1 fi postargs="$postargs "-r`expr "$i" : "-.\(.*\)"` ;; -[sS]) # single page at a time - manual feed on ALW if [ "$dev" = "-Talw" ] then postargs="$postargs -S" else ditargs="$ditargs $i" fi ;; *) ditargs="$ditargs "$i ;; esac done if [ "$post" = "" ] then /bin/ditroff $dev $ditargs else /bin/ditroff $dev $ditargs | /usr/lib/troff/$post $postargs fi //E*O*F src/troff.sh// echo x - src/tpscript/Makefile cat > "src/tpscript/Makefile" << '//E*O*F src/tpscript/Makefile//' # INSTALL=cp INSTALL=: I=.. ROOT= INSDIR=/usr/bin # -DUQMINMET for hashed character name lookup SYS=SYSV VERBOSE=1 # 1 to turn on stuff; 0 to turn off LOCALSYS= # for various local mods CFLAGS= -O LDFLAGS= -n DFLAGS= -DUQMINMET -D$(SYS) -DALW -DVERBOSE=$(VERBOSE) -D$(LOCALSYS) CFILES=tpscript.c pcom.c stringdefs.c spline.c sfont2.c hash.c OFILES=tpscript.o pcom.o stringdefs.o spline.o sfont2.o hash.o .c.o: $(CC) $(CFLAGS) $(DFLAGS) -c $< all tpscript: $(OFILES) $(CC) $(LDFLAGS) -o tpscript $(OFILES) install: tpscript $(INSTALL) tpscript $(ROOT)$(INSDIR)/dalw chown bin $(ROOT)$(INSDIR)/dalw chgrp bin $(ROOT)$(INSDIR)/dalw chmod 711 $(ROOT)$(INSDIR)/dalw lint: tpscript.lint tpscript.lint: $(CFILES) lint -D$(SYS) $(CFILES) > tpscript.lint clean: rm -f *.o tpscript.lint clobber: clean rm tpscript stringdefs.h sfont2defs.H stringdefs.h: stringdefs.H sed -f gendefs.sed stringdefs.H >stringdefs.h sfont2defs.h: sfont2defs.H sed -f gendefs.sed sfont2defs.H >sfont2defs.h hash.o: hash.h tpscript.h pcom.o: pscript.h sfont2.o: sfont2defs.h tpscript.h spline.o: tpscript.h stringdefs.o: hash.h stringdefs.h tpscript.o: tpscript.h dev.h pscript.h //E*O*F src/tpscript/Makefile// echo x - src/tpscript/dev.h cat > "src/tpscript/dev.h" << '//E*O*F src/tpscript/dev.h//' /* @(#)dev.h 1.1 */ /* dev.h: characteristics of a typesetter */ struct dev { short filesize; /* number of bytes in file, */ /* excluding dev part */ short res; /* basic resolution in goobies/inch */ short hor; /* goobies horizontally */ short vert; short unitwidth; /* size at which widths are given, in effect */ short nfonts; /* number of fonts physically available */ short nsizes; /* number of sizes it has */ short sizescale; /* scaling for fractional point sizes */ short paperwidth; /* max line length in units */ short paperlength; /* max paper length in units */ short nchtab; /* number of funny names in chtab */ short lchname; /* length of chname table */ short spare1; /* in case of expansion */ short spare2; }; struct font { /* characteristics of a font */ char nwfont; /* number of width entries for this font */ char specfont; /* 1 == special font */ char ligfont; /* 1 == ligatures exist on this font */ char spare1; /* unused for now */ char namefont[10]; /* name of this font (e.g., "R" */ char intname[10]; /* internal name (=number) on device, in ascii */ }; /* ligatures, ORed into ligfont */ #define LFF 01 #define LFI 02 #define LFL 04 #define LFFI 010 #define LFFL 020 //E*O*F src/tpscript/dev.h// echo x - src/tpscript/gendefs.sed cat > "src/tpscript/gendefs.sed" << '//E*O*F src/tpscript/gendefs.sed//' /^#/ d /^$/ d /^[ ]/ d /^[^ ]/ { s/{// s/#.*// t loop :loop N s/\n}$/ / t done s/#.*// t loop b loop :done s/[ ][ ]*/ /g s/\n/ /g s/ / "/ s/^/#define DEF_/ s/ *$/"/ } //E*O*F src/tpscript/gendefs.sed// echo x - src/tpscript/hash.h cat > "src/tpscript/hash.h" << '//E*O*F src/tpscript/hash.h//' struct hash_element { struct hash_element *hash_next; /* pointer in linked list */ struct special_name *hash_special; /* if needs special treatment */ short hash_index; /* index into chartab */ }; /* * special names need a postscript subroutine to print them as * troff expects - the first request to print \(xx will generate * the definition of a subroutine named Cxx and the character * will be printed by invoking Cxx. */ struct special_name { char *troff_name, /* the name by which troff knows the char */ *definition, /* the definition string in postscript */ sn_flags; /* flag for various values defined below */ }; #define SN_DEFINED 01 #define SN_FRACTION 02 /* use special set-up common to all fractions */ #define SN_BRACKET 04 /* use special set-up common to brackets */ #define SN_BRK_ROUNDING 010 /* correct for rounding errors in width tables */ /* * if one of these is defined then there is some common * procedure to define * only one can be defined for any one name */ #define SN_ANY_MULTIPLE (SN_FRACTION | SN_BRACKET | SN_BRK_ROUNDING ) typedef struct hash_element HASH_ELEMENT; typedef struct special_name SPECIAL_NAME; extern SPECIAL_NAME specnames[], multdefs[]; #define HASH_SIZE 37 #define NOHASH (HASH_ELEMENT *)0 #define NOSPECIAL (SPECIAL_NAME *)0 //E*O*F src/tpscript/hash.h// echo x - src/tpscript/pscript.h cat > "src/tpscript/pscript.h" << '//E*O*F src/tpscript/pscript.h//' /* * pscript.h * Some common definitions for programs that produce postscript */ #ifndef PSCRIPT_DEFINED #define PSCRIPT_DEFINED 1 #ifndef VERBOSE #if lint #define VERBOSE 1 /* if linting, check all the code */ #else lint #define VERBOSE 0 #endif lint #endif VERBOSE #if UNSW #undef AUSAM #define AUSAM 1 #endif UNSW #ifdef AUSAM #undef AUSAM #define AUSAM 1 #else #define AUSAM 0 #endif AUSAM #ifdef BSD #undef BSD #define BSD 1 #define index strchr #define rindex strrchr #include /* declarations for string functions */ #else #define BSD 0 #include /* declarations for string functions */ #endif BSD #ifdef SYSV #undef SYSV #define SYSV 1 #else #define SYSV 0 #endif SYSV #ifdef V7 #undef V7 #define V7 1 #else #define V7 0 #endif V7 #if AUSAM + BSD + SYSV + V7 != 1 #include "Must define 1 only of AUSAM, BSD, SYSV, V7" #endif #include /* LaserWriter page types */ #define PT_DEFAULT 0 #define PT_LETTER 1 #define PT_LEGAL 2 #define PT_NOTE 3 #ifdef ALW #define PT_A4 4 /* currently only on Apple LaserWriter */ #endif ALW /* Postscript defaults */ #define PD_PAGETYPE PT_LETTER /* page size is "letter" */ #define PD_ROTATION 0 /* page is portrait mode */ #define PD_PFREQUENCY 60 /* pixel frequency (pixels/inch) */ #define PD_PROTATION 45 /* pixel grid rotation (degrees) */ #define ALW_RES 300 /* LaserWriter resolution is 300 dots/inch */ #define PU_INCH 72 /* postscript units / inch */ #define PU_CM 28.3465 /* postscript units / cm */ #define TRUE (bool)1 #define FALSE (bool)0 typedef int bool; extern FILE * postr; /* output stream */ void perror(), exit(); #endif PSCRIPT_DEFINED //E*O*F src/tpscript/pscript.h// echo ln src/tpscript/pscript.h src/opscript/pscript.h ln src/tpscript/pscript.h src/opscript/pscript.h echo x - src/tpscript/sfont2defs.H cat > "src/tpscript/sfont2defs.H" << '//E*O*F src/tpscript/sfont2defs.H//' # sfont2defs.H # source file for definitions of special characters in the second # locally-defined special font # this file is processed by sed to produce sfont2defs.h # syntax is: # troff-name { definition including optional comments # terminated by "}" on a line of its own # white space is minimised on output # anything following `#' is ignored # a line commencing with `#' is deleted # as are blank lines # note `\` should be escaped as "\\" # The bracket end pieces just load the stack with values which are then # used by the common procedure C.brk.end which does a # moveto rlineto rcurveto (then back to the start and across by 60) # rlineto rcurveto fill # This is only done to save the output file size and to make it # more confusing to interpret what is going on. # Remember the stack is loaded last in first out lt { 0 150 50 210 140 250 # inside rcurve to just below tip 0 730 0 150 50 250 200 250 # outside rcurve to tip 0 750 # rline up 220 -250 # starting point C.brk.end } lb { 0 -150 50 -210 140 -250 # inside rcurve to just below tip 0 -730 0 -150 50 -250 200 -250 # outside rcurve to tip 0 -750 # rline up 220 750 # starting point C.brk.end } lk { 1 setlinewidth 220 -250 moveto 0 400 rlineto 0 50 -50 100 -100 100 rcurveto 50 0 100 50 100 100 rcurveto 0 400 rlineto 60 0 rlineto 0 -400 rlineto 0 -50 -50 -100 -100 -100 rcurveto 50 0 100 -50 100 -100 rcurveto 0 -400 rlineto closepath fill } rt { 0 150 -50 250 -200 250 # outside rcurve to tip 0 750 # rline up 0 150 -50 210 -140 250 # inside rcurve to just below tip 0 730 220 -250 # starting point C.brk.end } rb { 0 -150 -50 -250 -200 -250 # outside rcurve to tip 0 -750 # rline up 0 -150 -50 -210 -140 -250 # inside rcurve to just below tip 0 -730 220 750 # starting point C.brk.end } rk { 1 setlinewidth 220 -250 moveto 0 400 rlineto 0 50 50 100 100 100 rcurveto -50 0 -100 50 -100 100 rcurveto 0 400 rlineto 60 0 rlineto 0 -400 rlineto 0 -50 50 -100 100 -100 rcurveto -50 0 -100 -50 -100 -100 rcurveto 0 -400 rlineto fill } # the floor and ceiling bracket parts are made up with two # procedures defined within the context of the font: # C.bv which draws the bold vertical # C.barc which adds the horizontal piece to the ceiling; # the X coord on the stack should be set to the # left edge of where the bar is to be put # C.barf likewise for floor lc { C.bv # draw the bv part 280 # move to bottom right edge of vert bar C.barc # and draw in horizontal bar } lf { C.bv 280 C.barf } rc { C.bv 40 C.barc } rf { C.bv 40 C.barf } br { 40 C.setl 0 -250 moveto 0 1000 rlineto stroke } rn { 40 C.setl 0 895 moveto 500 0 rlineto stroke } ci { 40 C.setl 500 250 # centre 400 # radius 0 360 arc # draw circle stroke } sp_6 { # 1/6 em narrow space # do nothing, the width is all that is needed } sp_12 { # 1/12 em narrow space # null op } r1 { # reversible chemical reaction 40 C.setl 0 setlinejoin 700 180 moveto -650 currentlinewidth add 0 rlineto 200 -200 rlineto 50 360 moveto 650 currentlinewidth sub 0 rlineto -200 200 rlineto stroke } r2 { # reversible reaction with full arrowheads 40 C.setl 2 setlinejoin 217 18 moveto # left arrowhead -150 150 rlineto 150 150 rlineto -150 -150 rlineto 633 0 rlineto 50 360 moveto 633 0 rlineto -150 150 rlineto 150 -150 rlineto -150 -150 rlineto stroke } //E*O*F src/tpscript/sfont2defs.H// echo x - src/tpscript/sfont2defs.h cat > "src/tpscript/sfont2defs.h" << '//E*O*F src/tpscript/sfont2defs.h//' #define DEF_lt " 0 150 50 210 140 250 0 730 0 150 50 250 200 250 0 750 220 -250 C.brk.end" #define DEF_lb " 0 -150 50 -210 140 -250 0 -730 0 -150 50 -250 200 -250 0 -750 220 750 C.brk.end" #define DEF_lk " 1 setlinewidth 220 -250 moveto 0 400 rlineto 0 50 -50 100 -100 100 rcurveto 50 0 100 50 100 100 rcurveto 0 400 rlineto 60 0 rlineto 0 -400 rlineto 0 -50 -50 -100 -100 -100 rcurveto 50 0 100 -50 100 -100 rcurveto 0 -400 rlineto closepath fill" #define DEF_rt " 0 150 -50 250 -200 250 0 750 0 150 -50 210 -140 250 0 730 220 -250 C.brk.end" #define DEF_rb " 0 -150 -50 -250 -200 -250 0 -750 0 -150 -50 -210 -140 -250 0 -730 220 750 C.brk.end" #define DEF_rk " 1 setlinewidth 220 -250 moveto 0 400 rlineto 0 50 50 100 100 100 rcurveto -50 0 -100 50 -100 100 rcurveto 0 400 rlineto 60 0 rlineto 0 -400 rlineto 0 -50 50 -100 100 -100 rcurveto -50 0 -100 -50 -100 -100 rcurveto 0 -400 rlineto fill" #define DEF_lc " C.bv 280 C.barc" #define DEF_lf " C.bv 280 C.barf" #define DEF_rc " C.bv 40 C.barc" #define DEF_rf " C.bv 40 C.barf" #define DEF_br " 40 C.setl 0 -250 moveto 0 1000 rlineto stroke" #define DEF_rn " 40 C.setl 0 895 moveto 500 0 rlineto stroke" #define DEF_ci " 40 C.setl 500 250 400 0 360 arc stroke" #define DEF_sp_6 "" #define DEF_sp_12 "" #define DEF_r1 " 40 C.setl 0 setlinejoin 700 180 moveto -650 currentlinewidth add 0 rlineto 200 -200 rlineto 50 360 moveto 650 currentlinewidth sub 0 rlineto -200 200 rlineto stroke" #define DEF_r2 " 40 C.setl 2 setlinejoin 217 18 moveto -150 150 rlineto 150 150 rlineto -150 -150 rlineto 633 0 rlineto 50 360 moveto 633 0 rlineto -150 150 rlineto 150 -150 rlineto -150 -150 rlineto stroke" //E*O*F src/tpscript/sfont2defs.h// echo x - src/tpscript/stringdefs.H cat > "src/tpscript/stringdefs.H" << '//E*O*F src/tpscript/stringdefs.H//' # source file for definitions for special characters in postscript # this file is processed by sed to produce stringdefs.h # syntax is: # troff-name { definition including optional comments # terminated by "}" on a line of its own # white space is minimised on output # anything following `#' is ignored # a line commencing with `#' is deleted # as are blank lines # note `\` should be escaped as "\\" 12 { (1) (2) Cfract } 14 { (1) (4) Cfract } 34 { (3) (4) Cfract } 13 { (1) (3) Cfract } 18 { (1) (8) Cfract } 23 { (2) (3) Cfract } 38 { (3) (8) Cfract } 58 { (5) (8) Cfract } 78 { (7) (8) Cfract } ru { 0 ysiz pt 5 div 2 copy rmoveto # up dist from bottom to baseline (_) show neg rmoveto # back down } sr { # square root needs to be shoved to the right a touch currentfont # save for later restoring /dx xsiz pt 0.05 mul def dx 0 rmoveto # jump right by a bit f.S [ xsiz pt 0 0 ysiz pt 0 0 ]makefont setfont (\\326)s dx neg 0 rmoveto # back again setfont # restore prev font } sq { # draw a square box currentlinewidth currentpoint currentpoint ysiz pt 20.8 div dup dtransform round idtransform setlinewidth pop newpath moveto /dy ysiz pt 0.8 mul def # side is 0.8em /dx xsiz pt 0.8 mul def # side is 0.8em dx 8 div dy .1875 mul neg rmoveto # move to starting point 0 dy rlineto dx 0 rlineto 0 dy neg rlineto closepath # the following search will put a different number of elements # on the stack depending whether true or false; thus we mark # here to clean up later mark currentfont /FontName get # get the font name 40 string cvs # turn into a string (Bold) search # is it bold type? {fill} # if so then block in {stroke} # otherwise outline ifelse cleartomark # clean up stack moveto # back to start xsiz pt 0 rmoveto # to the end of the char setlinewidth } ff { (f) show xsiz pt 20 div neg 0 rmoveto (f) s } Fi { (f) show xsiz pt 20 div neg 0 rmoveto (\\256) s } Fl { (f) show xsiz pt 20 div neg 0 rmoveto (\\257) s } # fraction construction common procedure # this won't work properly yet for fonts slanted with \S fract { /fbot exch def # arg 1 is bottom character /ftop exch def # arg 2 is top character currentfont currentpoint # for later restoration /f0 ysiz pt 2 div def # little chars half size (0) stringwidth pop 2 div 0 rmoveto # charwidth at half size (\\244)show # draw the slanting line currentpoint 4 2 roll moveto # save current and back to beginning 0 f0 0.75 mul rmoveto # up a bit fonttype [ xsiz pt 2 div 0 0 f0 0 0 ]makefont setfont # set a smaller font size ftop show moveto # back to the end of the / fbot show setfont # restore font } //E*O*F src/tpscript/stringdefs.H// echo x - src/tpscript/stringdefs.h cat > "src/tpscript/stringdefs.h" << '//E*O*F src/tpscript/stringdefs.h//' #define DEF_12 " (1) (2) Cfract" #define DEF_14 " (1) (4) Cfract" #define DEF_34 " (3) (4) Cfract" #define DEF_13 " (1) (3) Cfract" #define DEF_18 " (1) (8) Cfract" #define DEF_23 " (2) (3) Cfract" #define DEF_38 " (3) (8) Cfract" #define DEF_58 " (5) (8) Cfract" #define DEF_78 " (7) (8) Cfract" #define DEF_ru " 0 ysiz pt 5 div 2 copy rmoveto (_) show neg rmoveto" #define DEF_sr " currentfont /dx xsiz pt 0.05 mul def dx 0 rmoveto f.S [ xsiz pt 0 0 ysiz pt 0 0 ]makefont setfont (\\326)s dx neg 0 rmoveto setfont" #define DEF_sq " currentlinewidth currentpoint currentpoint ysiz pt 20.8 div dup dtransform round idtransform setlinewidth pop newpath moveto /dy ysiz pt 0.8 mul def /dx xsiz pt 0.8 mul def dx 8 div dy .1875 mul neg rmoveto 0 dy rlineto dx 0 rlineto 0 dy neg rlineto closepath mark currentfont /FontName get 40 string cvs (Bold) search {fill} {stroke} ifelse cleartomark moveto xsiz pt 0 rmoveto setlinewidth" #define DEF_ff " (f) show xsiz pt 20 div neg 0 rmoveto (f) s" #define DEF_Fi " (f) show xsiz pt 20 div neg 0 rmoveto (\\256) s" #define DEF_Fl " (f) show xsiz pt 20 div neg 0 rmoveto (\\257) s" #define DEF_fract " /fbot exch def /ftop exch def currentfont currentpoint /f0 ysiz pt 2 div def (0) stringwidth pop 2 div 0 rmoveto (\\244)show currentpoint 4 2 roll moveto 0 f0 0.75 mul rmoveto fonttype [ xsiz pt 2 div 0 0 f0 0 0 ]makefont setfont ftop show moveto fbot show setfont" //E*O*F src/tpscript/stringdefs.h// echo x - src/tpscript/tpscript.h cat > "src/tpscript/tpscript.h" << '//E*O*F src/tpscript/tpscript.h//' /* * tpscript.h * header definitions for tpscript.c: * Troff post-processor for postscript devices */ #include #include "dev.h" #include "pscript.h" #define ERR_WARN 1 /* an input error - continue processing */ #define ERR_FATAL 2 /* an input error - abort processing */ #define ERR_SNARK 3 /* a program error - abort processing */ #define UNDEFINED -1 #define BMASK 0xFF /* low order byte */ #define NASCII 128 /* no. ascii characters */ #define NUNPRINT 32 /* no. unprintable characters */ #define NASCPRINT (NASCII-NUNPRINT) /* no. printable ascii chars */ #define MAXCHARS 255 /* max no. character codes */ #define DEF_FONT 1 /* default initial font */ #define DEF_SIZE 10 /* default initial point size */ #define DEF_DEV "alw" /* default device - apple laser-writer */ extern int errno; extern char *sys_errlist[]; extern FILE *Debug ; extern char *ifile; /* current input file name */ extern int lineno, /* line no. in current input file */ npages; /* no. pages printed so far */ extern char device[100], errbuf[100]; /* tmp buffer for error messages */ extern int hpos, /* current horizontal position */ vpos; /* current vertical position (rel. TOP pg.) */ extern int res, /* resolution in THINGS/inch */ hor_res, /* min horizontal movement (in THINGS) */ vert_res, /* min vertical movement (in THINGS) */ respunits; float rotation; /* page orientation (degrees) */ extern int currtfont, /* current font number selected by troff */ papertype; /* paper type (different imageable regions) */ /* font parameters */ struct fontparam { int fp_size; /* character point size */ float fp_height, /* character height (points) */ fp_slant; /* character slant (degrees) */ struct fontdesc * fp_font; /* font style */ }; extern struct fontparam tfp, /* current troff font parameters */ pfp; /* current postscript font parameters */ #define NOFONTDESC ((struct fontdesc *)NULL ) /* table of font descriptions */ struct fontdesc { char *f_intname; /* postscript name */ char *f_extname; /* troff name */ int f_nent; /* no. entries for this font */ char *f_widthtab; /* character width tables */ char *f_codetab; /* code table for this font */ char *f_fitab; /* font index for this font */ bool f_mounted; /* whether font is mounted or not */ }; extern struct fontdesc *fontd, *spcfnt1, /* special font */ *spcfnt2; /* special font 2 */ /* font mount table - array of pointers to font descriptions */ extern struct fontdesc **fontmount; /* mapping between troff font names and builtin font names * This should go in the internal name part of the font description * itself, but there is only 10 bytes allocated (see dev.h). */ struct fontmap { char *fm_extname; /* Troff font name */ char *fm_intname; /* Postscript font name */ }; extern struct fontmap fontmap[]; #define NFONT (sizeof(fontmap)/sizeof(fontmap[0])) extern struct dev dev; extern short *chartab; /* char's index in charname array */ extern char *charname; /* special character names */ extern int ncharname; /* no. special character names */ extern int nfonts; /* no. of fonts mounted */ extern int nfontmount; /* no. of font mount positions */ #define GETWIDTH(fdp, index) \ ((tfp.fp_size * ((fdp)->f_widthtab[ (index) ] & BMASK) + (respunits>>1)) / respunits) /* * this is the width that the printer will have moved following * the last printed character, if troff then says to move a * different amount we will shift the difference */ extern int width_pending; extern bool word_started; /* we are in middle of word string */ #define CLOSEWORD() {if ( word_started == TRUE ) { \ fputs( ")s", postr ); \ word_started = FALSE; \ } \ } extern int strcmp(); extern char *emalloc(); extern struct fontdesc *findfont(); extern struct fontmap *getfmap(); //E*O*F src/tpscript/tpscript.h// echo Possible errors detected by \'wc\' [hopefully none]: temp=/tmp/shar$$ trap "rm -f $temp; exit" 0 1 2 3 15 cat > $temp <<\!!! 114 826 5046 READ_ME 13 62 404 Makefile 114 720 3990 ipscript.1 96 632 3778 lpscript.1 9 17 166 Makefile 66 200 1326 troff.sh 50 132 1172 Makefile 39 219 1242 dev.h 21 40 213 gendefs.sed 42 202 1323 hash.h 90 268 1661 pscript.h 165 685 3557 sfont2defs.H 17 327 1751 sfont2defs.h 124 540 2717 stringdefs.H 16 264 1494 stringdefs.h 124 609 3837 tpscript.h 1100 5743 33677 total !!! wc READ_ME Makefile man/ipscript.1 man/lpscript.1 src/Makefile src/troff.sh src/tpscript/Makefile src/tpscript/dev.h src/tpscript/gendefs.sed src/tpscript/hash.h src/tpscript/pscript.h src/tpscript/sfont2defs.H src/tpscript/sfont2defs.h src/tpscript/stringdefs.H src/tpscript/stringdefs.h src/tpscript/tpscript.h | sed 's=[^ ]*/==' | diff -b $temp - exit 0