17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23f928ce67Sceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*48bbca81SDaniel Hoffman  * Copyright (c) 2016 by Delphix. All rights reserved.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
297c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  * dpost - troff post-processor for PostScript printers.
347c478bd9Sstevel@tonic-gate  *
357c478bd9Sstevel@tonic-gate  * A program that translates output generated by the device independent troff
367c478bd9Sstevel@tonic-gate  * into PostScript. Much was borrowed from dimpress and dps (formally dlzw),
377c478bd9Sstevel@tonic-gate  * and even though the code has been changed, credit has to be given to Richard
387c478bd9Sstevel@tonic-gate  * Flood for his early work on the PostScript driver.
397c478bd9Sstevel@tonic-gate  *
407c478bd9Sstevel@tonic-gate  * Among the most interesting new features are color support (see devcntrl() and
417c478bd9Sstevel@tonic-gate  * file color.c) and code to handle complex paths pieced together using any of the
427c478bd9Sstevel@tonic-gate  * standard drawing commands (see devcntrl() and file draw.c). Reverse video mode
437c478bd9Sstevel@tonic-gate  * has also been included as a special case of the color support. Two encoding
447c478bd9Sstevel@tonic-gate  * schemes based on widthshow are also new additions. The safe one is obtained when
457c478bd9Sstevel@tonic-gate  * you set encoding to 2 (eg. using the -e2 option). The slightly faster method
467c478bd9Sstevel@tonic-gate  * is obtained by setting encoding to 3 (eg. using the -e3 option), although it's
477c478bd9Sstevel@tonic-gate  * not recommended. Rounding errors in character widths can accumulate and become
487c478bd9Sstevel@tonic-gate  * quite noticeable by the time you get to the right margin. More often than not
497c478bd9Sstevel@tonic-gate  * you end up getting a ragged right margin.
507c478bd9Sstevel@tonic-gate  *
517c478bd9Sstevel@tonic-gate  * The program handles files formatted for any device, although the best and
527c478bd9Sstevel@tonic-gate  * most efficient output is generated when the font and description files match
537c478bd9Sstevel@tonic-gate  * PostScript's resident fonts. Device emulation is relatively expensive, and
547c478bd9Sstevel@tonic-gate  * can produce output files that are more than twice the size of the input files.
557c478bd9Sstevel@tonic-gate  * In most cases output files will be smaller than input files, perhaps by up to
567c478bd9Sstevel@tonic-gate  * 40 percent, although the results you get depend on what you're doing and the
577c478bd9Sstevel@tonic-gate  * text encoding you're using. You'll get the worst results if you're emulating
587c478bd9Sstevel@tonic-gate  * another device, using special bitmap characters, like the logo, or doing lots
597c478bd9Sstevel@tonic-gate  * of vertical motion or drawing.
607c478bd9Sstevel@tonic-gate  *
617c478bd9Sstevel@tonic-gate  * PostScript fonts don't support all of troff's characters, so some have to
627c478bd9Sstevel@tonic-gate  * be built by special PostScript procedures. Those routines can be found in
637c478bd9Sstevel@tonic-gate  * *fontdir/devpost/charlib, and are only used when we try to print a character
647c478bd9Sstevel@tonic-gate  * that has been assigned a code less than 32. Definitions are only made the
657c478bd9Sstevel@tonic-gate  * first time each character is used. Subsequent requests to print the character
667c478bd9Sstevel@tonic-gate  * only generate a call to the PostScript procedure that's been copied to the
677c478bd9Sstevel@tonic-gate  * output file. For example you'll find a file called sq in directory
687c478bd9Sstevel@tonic-gate  * *fontdir/devpost/charlib. It defines a PostScript procedure called build_sq
697c478bd9Sstevel@tonic-gate  * that's called whenever we need to print a square. Special characters that
707c478bd9Sstevel@tonic-gate  * have been assigned a code of 2 are expected to come in two pieces. The
717c478bd9Sstevel@tonic-gate  * definition part and bitmap part (or whatever). The definition is only made
727c478bd9Sstevel@tonic-gate  * once, but the contents of the character's .map file are copied to the output
737c478bd9Sstevel@tonic-gate  * file each time, immediately after charlib() generates the call to the
747c478bd9Sstevel@tonic-gate  * PostScript procedure (build_?? ) that builds the character. That's typically
757c478bd9Sstevel@tonic-gate  * how logos built from bitmaps would be handled.
767c478bd9Sstevel@tonic-gate  *
777c478bd9Sstevel@tonic-gate  * Several different methods can be used to encode lines of text. What's done
787c478bd9Sstevel@tonic-gate  * depends on the value assigned to encoding. Print time should decrease as
797c478bd9Sstevel@tonic-gate  * encoding increases (up to MAXENCODING). Setting encoding to 0, which should
807c478bd9Sstevel@tonic-gate  * probably be the default, produces output essentially identical to the original
817c478bd9Sstevel@tonic-gate  * version of dpost. It's the slowest but most stable method of encoding lines of
827c478bd9Sstevel@tonic-gate  * text, and won't be bothered by rounding errors in the font width tables that
837c478bd9Sstevel@tonic-gate  * could become noticeable by the time you get to the end of a line. Other schemes
847c478bd9Sstevel@tonic-gate  * seem to work, but aren't well tested and are not guaranteed for all possible
857c478bd9Sstevel@tonic-gate  * jobs. encoding can be changed on the command line using the -e option. Part of
867c478bd9Sstevel@tonic-gate  * the support for different encoding schemes was to move control of all text
877c478bd9Sstevel@tonic-gate  * related output to separate routines. It makes dpost work harder, but changing
887c478bd9Sstevel@tonic-gate  * things is easy. For example adding stuff to support widthshow took less than
897c478bd9Sstevel@tonic-gate  * an hour.
907c478bd9Sstevel@tonic-gate  *
917c478bd9Sstevel@tonic-gate  * According to Adobe's structuring conventions, the output produced by dpost is
927c478bd9Sstevel@tonic-gate  * still nonconforming. Global definitions that are occasionally made in individual
937c478bd9Sstevel@tonic-gate  * pages are the primary problem. Among other things they handle downloading host
947c478bd9Sstevel@tonic-gate  * resident fonts and defining special characters not generally available on
957c478bd9Sstevel@tonic-gate  * PostScript printers. The approach used here works on a demand basis and violates
967c478bd9Sstevel@tonic-gate  * page independence. A definition is made once in the first page that needs it
977c478bd9Sstevel@tonic-gate  * and is bracketed by PostScript code that ensures the definition is exported to
987c478bd9Sstevel@tonic-gate  * the global environment where it will be available for use by all the pages that
997c478bd9Sstevel@tonic-gate  * follow.  Simple changes, like downloading definitions the first time they're
1007c478bd9Sstevel@tonic-gate  * used in each page, restores page independence but wouldn't be an efficient
1017c478bd9Sstevel@tonic-gate  * solution. Other approaches are also available, but every one I've considered
1027c478bd9Sstevel@tonic-gate  * sacrifices much in efficiency - just to maintain page independence. I'll leave
1037c478bd9Sstevel@tonic-gate  * things be for now. Global definitions made in individual pages are bracketed
1047c478bd9Sstevel@tonic-gate  * by %%BeginGlobal and %%EndGlobal comments and can easily be pulled out of
1057c478bd9Sstevel@tonic-gate  * individual pages and put in the prologue by utility programs like postreverse.
1067c478bd9Sstevel@tonic-gate  *
1077c478bd9Sstevel@tonic-gate  * I've also added code that handles the DOCUMENTFONTS comment, although it's
1087c478bd9Sstevel@tonic-gate  * only produced for those fonts in directory /usr/lib/font/devpost that have an
1097c478bd9Sstevel@tonic-gate  * associated .name file. The first string in a .name file should be the (long)
1107c478bd9Sstevel@tonic-gate  * PostScript name (eg. Times-Roman in R.name). For now everything else in the
1117c478bd9Sstevel@tonic-gate  * .name file is ignored, although that may also change. You'll find .name files
1127c478bd9Sstevel@tonic-gate  * for all the supported fonts in the devpost source directory, although they may
1137c478bd9Sstevel@tonic-gate  * not be installed in /usr/lib/font/devpost.
1147c478bd9Sstevel@tonic-gate  *
1157c478bd9Sstevel@tonic-gate  * The PostScript prologue is copied from *prologue before any of the input files
1167c478bd9Sstevel@tonic-gate  * are translated. The program expects the following procedures are avaliable:
1177c478bd9Sstevel@tonic-gate  *
1187c478bd9Sstevel@tonic-gate  *	setup
1197c478bd9Sstevel@tonic-gate  *
1207c478bd9Sstevel@tonic-gate  *	  mark ... setup -
1217c478bd9Sstevel@tonic-gate  *
1227c478bd9Sstevel@tonic-gate  *	    Handles special initialization stuff that depends on how the program
1237c478bd9Sstevel@tonic-gate  *	    was called. Expects to find a mark followed by key/value pairs on the
1247c478bd9Sstevel@tonic-gate  *	    stack. The def operator is applied to each pair up to the mark, then
1257c478bd9Sstevel@tonic-gate  *	    the default state is set up. An 'x res' command must preceed the
1267c478bd9Sstevel@tonic-gate  *	    'x init' command!
1277c478bd9Sstevel@tonic-gate  *
1287c478bd9Sstevel@tonic-gate  *	pagesetup
1297c478bd9Sstevel@tonic-gate  *
1307c478bd9Sstevel@tonic-gate  *	  page pagesetup -
1317c478bd9Sstevel@tonic-gate  *
1327c478bd9Sstevel@tonic-gate  *	    Called at the start of each page, immediately after the page level
1337c478bd9Sstevel@tonic-gate  *	    save, to do special initialization on a per page basis. Right now the
1347c478bd9Sstevel@tonic-gate  *	    only argument is the current page number, and actually nothing of any
1357c478bd9Sstevel@tonic-gate  *	    importance is currently done.
1367c478bd9Sstevel@tonic-gate  *
1377c478bd9Sstevel@tonic-gate  *	setdecoding
1387c478bd9Sstevel@tonic-gate  *
1397c478bd9Sstevel@tonic-gate  *	  num setdecoding -
1407c478bd9Sstevel@tonic-gate  *
1417c478bd9Sstevel@tonic-gate  *	    Selects the text decoding procedure (ie. what's assigned to PostScript
1427c478bd9Sstevel@tonic-gate  *	    procedure t) from the decodingdefs array defined in the prologue. num
1437c478bd9Sstevel@tonic-gate  *	    should be the value assigned to variable encoding (in dpost) and will
1447c478bd9Sstevel@tonic-gate  *	    remain constant throughout a job, unless special features, like reverse
1457c478bd9Sstevel@tonic-gate  *	    video printing, are requested. The text encoding scheme can be set on
1467c478bd9Sstevel@tonic-gate  *	    the command line using the -e option. Print time and the size of the
1477c478bd9Sstevel@tonic-gate  *	    output file will usually decrease as the value assigned to encoding
1487c478bd9Sstevel@tonic-gate  *	    increases.
1497c478bd9Sstevel@tonic-gate  *
1507c478bd9Sstevel@tonic-gate  *	f
1517c478bd9Sstevel@tonic-gate  *
1527c478bd9Sstevel@tonic-gate  *	  size font f -
1537c478bd9Sstevel@tonic-gate  *
1547c478bd9Sstevel@tonic-gate  *	    Selects the size and font to be used for character imaging. Font names
1557c478bd9Sstevel@tonic-gate  *	    are defined, in *prologue, so they agree with the one or two character
1567c478bd9Sstevel@tonic-gate  *	    names used by troff.
1577c478bd9Sstevel@tonic-gate  *
1587c478bd9Sstevel@tonic-gate  *	m
1597c478bd9Sstevel@tonic-gate  *
1607c478bd9Sstevel@tonic-gate  *	  x y m -
1617c478bd9Sstevel@tonic-gate  *
1627c478bd9Sstevel@tonic-gate  *	    Moves to point (x, y). Normally only used when the vertical position
1637c478bd9Sstevel@tonic-gate  *	    changes. Horizontal positioning between words (or letters) is handled
1647c478bd9Sstevel@tonic-gate  *	    in procedure t (below).
1657c478bd9Sstevel@tonic-gate  *
1667c478bd9Sstevel@tonic-gate  *	t
1677c478bd9Sstevel@tonic-gate  *
1687c478bd9Sstevel@tonic-gate  *	  mark text t mark
1697c478bd9Sstevel@tonic-gate  *
1707c478bd9Sstevel@tonic-gate  *	    Processes everything on the stack, up to the mark, as a single line
1717c478bd9Sstevel@tonic-gate  *	    of text to be printed at a fixed vertical position. What's put out as
1727c478bd9Sstevel@tonic-gate  *	    text depends on the encoding scheme. Setting encoding to 0 produces
1737c478bd9Sstevel@tonic-gate  *	    output essentially identical to the original version of dpost. In that
1747c478bd9Sstevel@tonic-gate  *	    case everything on the stack, up to a mark, is interpreted (from top
1757c478bd9Sstevel@tonic-gate  *	    down) as an absolute horizontal position and a string to be printed at
1767c478bd9Sstevel@tonic-gate  *	    that point. For example the stack might look like,
1777c478bd9Sstevel@tonic-gate  *
1787c478bd9Sstevel@tonic-gate  *		mark(this)1000(is)1100(an)1200(example)1300 t
1797c478bd9Sstevel@tonic-gate  *
1807c478bd9Sstevel@tonic-gate  *	    Procedure t would go through the stack, up to the mark, adjusting the
1817c478bd9Sstevel@tonic-gate  *	    horizontal position before printing each string. In other encoding
1827c478bd9Sstevel@tonic-gate  *	    schemes, like the one based on widthshow, strings containing several
1837c478bd9Sstevel@tonic-gate  *	    space separated words would appear on the stack, and each one would be
1847c478bd9Sstevel@tonic-gate  *	    preceeded by a number that's expected to be added to the width of a
1857c478bd9Sstevel@tonic-gate  *	    space. For example we might have,
1867c478bd9Sstevel@tonic-gate  *
1877c478bd9Sstevel@tonic-gate  *		mark(an example)30(this is)40 2 1000 2000 t
1887c478bd9Sstevel@tonic-gate  *
1897c478bd9Sstevel@tonic-gate  *	    where (1000, 2000) is where the first string starts and 2 is the repeat
1907c478bd9Sstevel@tonic-gate  *	    count (ie. number of string and space pairs on the stack).
1917c478bd9Sstevel@tonic-gate  *
1927c478bd9Sstevel@tonic-gate  *	w
1937c478bd9Sstevel@tonic-gate  *
1947c478bd9Sstevel@tonic-gate  *	  string x y w -
1957c478bd9Sstevel@tonic-gate  *
1967c478bd9Sstevel@tonic-gate  *	    Prints a single word starting at position (x, y). Only used in the more
1977c478bd9Sstevel@tonic-gate  *	    complicated encoding schemes (eg. the ones based on widthshow).
1987c478bd9Sstevel@tonic-gate  *
1997c478bd9Sstevel@tonic-gate  *	done
2007c478bd9Sstevel@tonic-gate  *
2017c478bd9Sstevel@tonic-gate  *	    Makes sure the last page is printed. Only needed when we're printing
2027c478bd9Sstevel@tonic-gate  *	    more than one page on each sheet of paper.
2037c478bd9Sstevel@tonic-gate  *
2047c478bd9Sstevel@tonic-gate  * The PostScript procedures that support troff's drawing commands have been moved
2057c478bd9Sstevel@tonic-gate  * out of *prologue and put in a separate file (ie. DRAW as defined in path.h).
2067c478bd9Sstevel@tonic-gate  * The procedures are used by the routines in file draw.c, and are copied to the
2077c478bd9Sstevel@tonic-gate  * output file at most once and only when needed. Yet another convenient violation
2087c478bd9Sstevel@tonic-gate  * of page independence. If you don't approve append *drawfile to *prologue and
2097c478bd9Sstevel@tonic-gate  * make sure *drawfile can't be read when DPOST runs.
2107c478bd9Sstevel@tonic-gate  *
211*48bbca81SDaniel Hoffman  * Many default values, like the magnification and orientation, are defined in
2127c478bd9Sstevel@tonic-gate  * the prologue, which is where they belong. If they're changed (by options), an
2137c478bd9Sstevel@tonic-gate  * appropriate definition is made after the prologue is added to the output file.
2147c478bd9Sstevel@tonic-gate  * The -P option passes arbitrary PostScript through to the output file. Among
2157c478bd9Sstevel@tonic-gate  * other things it can be used to set (or change) values that can't be accessed by
2167c478bd9Sstevel@tonic-gate  * other options.
2177c478bd9Sstevel@tonic-gate  *
2187c478bd9Sstevel@tonic-gate  *
2197c478bd9Sstevel@tonic-gate  * output language from troff:
2207c478bd9Sstevel@tonic-gate  * all numbers are character strings
221*48bbca81SDaniel Hoffman  *
2227c478bd9Sstevel@tonic-gate  * sn	size in points
2237c478bd9Sstevel@tonic-gate  * fn	font as number from 1-n
2247c478bd9Sstevel@tonic-gate  * cx	ascii character x
2257c478bd9Sstevel@tonic-gate  * Cxyz	funny char xyz. terminated by white space
2267c478bd9Sstevel@tonic-gate  * Hn	go to absolute horizontal position n
2277c478bd9Sstevel@tonic-gate  * Vn	go to absolute vertical position n (down is positive)
2287c478bd9Sstevel@tonic-gate  * hn	go n units horizontally (relative)
2297c478bd9Sstevel@tonic-gate  * vn	ditto vertically
2307c478bd9Sstevel@tonic-gate  * nnc	move right nn, then print c (exactly 2 digits!)
2317c478bd9Sstevel@tonic-gate  * 		(this wart is an optimization that shrinks output file size
2327c478bd9Sstevel@tonic-gate  * 		 about 35% and run-time about 15% while preserving ascii-ness)
2337c478bd9Sstevel@tonic-gate  * Dt ...\n	draw operation 't':
2347c478bd9Sstevel@tonic-gate  * 	Dl x y		line from here by x,y
2357c478bd9Sstevel@tonic-gate  * 	Dc d		circle of diameter d with left side here
2367c478bd9Sstevel@tonic-gate  * 	De x y		ellipse of axes x,y with left side here
2377c478bd9Sstevel@tonic-gate  *	Da x1 y1 x2 y2	arc counter-clockwise from current point (x, y) to
2387c478bd9Sstevel@tonic-gate  *			(x + x1 + x2, y + y1 + y2)
2397c478bd9Sstevel@tonic-gate  * 	D~ x y x y ...	wiggly line by x,y then x,y ...
2407c478bd9Sstevel@tonic-gate  * nb a	end of line (information only -- no action needed)
2417c478bd9Sstevel@tonic-gate  * 	b = space before line, a = after
2427c478bd9Sstevel@tonic-gate  * p	new page begins -- set v to 0
2437c478bd9Sstevel@tonic-gate  * #...\n	comment
2447c478bd9Sstevel@tonic-gate  * x ...\n	device control functions:
2457c478bd9Sstevel@tonic-gate  * 	x i	init
2467c478bd9Sstevel@tonic-gate  * 	x T s	name of device is s
2477c478bd9Sstevel@tonic-gate  * 	x r n h v	resolution is n/inch
2487c478bd9Sstevel@tonic-gate  * 		h = min horizontal motion, v = min vert
2497c478bd9Sstevel@tonic-gate  * 	x p	pause (can restart)
2507c478bd9Sstevel@tonic-gate  * 	x s	stop -- done forever
2517c478bd9Sstevel@tonic-gate  * 	x t	generate trailer
2527c478bd9Sstevel@tonic-gate  * 	x f n s	font position n contains font s
2537c478bd9Sstevel@tonic-gate  * 	x H n	set character height to n
2547c478bd9Sstevel@tonic-gate  * 	x S n	set slant to N
255*48bbca81SDaniel Hoffman  *
2567c478bd9Sstevel@tonic-gate  * 	Subcommands like "i" are often spelled out like "init".
2577c478bd9Sstevel@tonic-gate  *
2587c478bd9Sstevel@tonic-gate  */
2597c478bd9Sstevel@tonic-gate 
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate #include	<stdio.h>
2627c478bd9Sstevel@tonic-gate #include	<fcntl.h>
2637c478bd9Sstevel@tonic-gate #include	<signal.h>
2647c478bd9Sstevel@tonic-gate #include	<math.h>
2657c478bd9Sstevel@tonic-gate #include	<ctype.h>
2667c478bd9Sstevel@tonic-gate #include	<time.h>
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate #include	"comments.h"		/* PostScript file structuring comments */
2697c478bd9Sstevel@tonic-gate #include	"gen.h"			/* general purpose definitions */
2707c478bd9Sstevel@tonic-gate #include	"path.h"		/* for the prologue and a few other files */
2717c478bd9Sstevel@tonic-gate #include	"ext.h"			/* external variable definitions */
2727c478bd9Sstevel@tonic-gate #include	"dev.h"			/* typesetter and font descriptions */
2737c478bd9Sstevel@tonic-gate #include	"dpost.h"		/* a few definitions just used here */
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate char		*prologue = DPOST;	/* the basic PostScript prologue */
2777c478bd9Sstevel@tonic-gate char		*colorfile = COLOR;	/* things needed for color support */
2787c478bd9Sstevel@tonic-gate char		*drawfile = DRAW;	/* and drawing */
2797c478bd9Sstevel@tonic-gate char		*formfile = FORMFILE;	/* stuff for multiple pages per sheet */
2807c478bd9Sstevel@tonic-gate char		*baselinefile = BASELINE;
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate char		*fontdir = FONTDIR;	/* binary device directories found here */
2837c478bd9Sstevel@tonic-gate char		*hostfontdir = NULL;	/* host resident font directory */
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate int		formsperpage = 1;	/* page images on each piece of paper */
2867c478bd9Sstevel@tonic-gate int		copies = 1;		/* and this many copies of each sheet */
2877c478bd9Sstevel@tonic-gate int		picflag = ON;		/* enable/disable picture inclusion */
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate /*
2917c478bd9Sstevel@tonic-gate  *
2927c478bd9Sstevel@tonic-gate  * encoding selects the encoding scheme used to output lines of text. Change it
2937c478bd9Sstevel@tonic-gate  * to something other than 0 at your own risk. The other methods seem to work but
2947c478bd9Sstevel@tonic-gate  * aren't well tested and are not guaranteed. Some special features, like reverse
2957c478bd9Sstevel@tonic-gate  * video, may temporarily change the encoding scheme and reset it to realencoding
2967c478bd9Sstevel@tonic-gate  * when done.
2977c478bd9Sstevel@tonic-gate  *
2987c478bd9Sstevel@tonic-gate  */
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate int		encoding = DFLTENCODING;
3027c478bd9Sstevel@tonic-gate int		realencoding = DFLTENCODING;
3037c478bd9Sstevel@tonic-gate int		maxencoding = MAXENCODING;
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate /*
3077c478bd9Sstevel@tonic-gate  *
3087c478bd9Sstevel@tonic-gate  * seenfonts[] keeps track of the fonts we've used, based on internal numbers. It
3097c478bd9Sstevel@tonic-gate  * helps manage host resident fonts and the DOCUMENTFONTS comment, but only works
3107c478bd9Sstevel@tonic-gate  * if all fonts have internal numbers less than MAXINTERNAL. *docfonts counts the
3117c478bd9Sstevel@tonic-gate  * number of font names we've recorded in *temp_file. If it's positive routine
3127c478bd9Sstevel@tonic-gate  * done() adds *temp_file to the output file before quitting.
3137c478bd9Sstevel@tonic-gate  *
3147c478bd9Sstevel@tonic-gate  */
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate char		seenfonts[MAXINTERNAL+1];
3187c478bd9Sstevel@tonic-gate int		docfonts = 0;
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate /*
3227c478bd9Sstevel@tonic-gate  *
3237c478bd9Sstevel@tonic-gate  * devname[] is the device troff used when the job was formatted, while *realdev
3247c478bd9Sstevel@tonic-gate  * is combined with *fontdir and used to locate the font and device tables that
3257c478bd9Sstevel@tonic-gate  * that control the translation of the input files into PostScript. *realdev can
3267c478bd9Sstevel@tonic-gate  * be changed using the -T option, but if you do you may end up getting garbage.
3277c478bd9Sstevel@tonic-gate  * The character code field must agree with PostScript's font encoding and font
3287c478bd9Sstevel@tonic-gate  * names must be properly mapped into PostScript font names in the prologue.
3297c478bd9Sstevel@tonic-gate  *
3307c478bd9Sstevel@tonic-gate  */
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate char		devname[20] = "";	/* job is formatted for this printer */
3347c478bd9Sstevel@tonic-gate char		*realdev = DEVNAME;	/* a good description of target printer */
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate /*
3387c478bd9Sstevel@tonic-gate  *
3397c478bd9Sstevel@tonic-gate  * Standard things that come from binary font and description files for *realdev.
3407c478bd9Sstevel@tonic-gate  * Most are initialized in fontinit() or loadfont().
3417c478bd9Sstevel@tonic-gate  *
3427c478bd9Sstevel@tonic-gate  */
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate struct dev	dev;			/* DESC.out starts this way */
3467c478bd9Sstevel@tonic-gate struct Font	*fontbase[NFONT+1];	/* FONT.out files begin this way */
3477c478bd9Sstevel@tonic-gate short		*pstab;			/* list of available sizes */
3487c478bd9Sstevel@tonic-gate int		nsizes = 1;		/* and the number of sizes in that list */
3497c478bd9Sstevel@tonic-gate int		smnt;			/* index of first special font */
3507c478bd9Sstevel@tonic-gate int		nchtab;			/* number of special character names */
3517c478bd9Sstevel@tonic-gate int		fsize;			/* max size of a font files in bytes */
3527c478bd9Sstevel@tonic-gate int		unitwidth;		/* set to dev.unitwidth */
3537c478bd9Sstevel@tonic-gate char		*chname;		/* special character strings */
3547c478bd9Sstevel@tonic-gate short		*chtab;			/* used to locate character names */
3557c478bd9Sstevel@tonic-gate char		*fitab[NFONT+1];	/* locates char info on each font */
3567c478bd9Sstevel@tonic-gate char		*widthtab[NFONT+1];	/* character width data for each font */
3577c478bd9Sstevel@tonic-gate char		*codetab[NFONT+1];	/* and codes to get characters printed */
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate /*
3617c478bd9Sstevel@tonic-gate  *
3627c478bd9Sstevel@tonic-gate  * Special characters missing from standard PostScript fonts are defined by files
3637c478bd9Sstevel@tonic-gate  * in directory *fontdir/devpost/charlib. Files have the same names as the troff
3647c478bd9Sstevel@tonic-gate  * special character names (for now at least) and each one defines a PostScript
3657c478bd9Sstevel@tonic-gate  * procedure that begins with the prefix build_ and ends with the character's
3667c478bd9Sstevel@tonic-gate  * name.
3677c478bd9Sstevel@tonic-gate  *
3687c478bd9Sstevel@tonic-gate  * For example, the routine used to build character \(12, would be build_12.
3697c478bd9Sstevel@tonic-gate  * downloaded[] points to an array, allocated in fontinit(), that keeps track of
3707c478bd9Sstevel@tonic-gate  * the characters that have already been defined - so we only do it once.
3717c478bd9Sstevel@tonic-gate  *
3727c478bd9Sstevel@tonic-gate  */
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate char		*downloaded;		/* nonzero means it's been downloaded */
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate /*
3797c478bd9Sstevel@tonic-gate  *
3807c478bd9Sstevel@tonic-gate  * Variables that keep track of troff's requests. All are set from values in the
3817c478bd9Sstevel@tonic-gate  * input files. nfonts is adjusted in t_fp() as new fonts are mounted.
3827c478bd9Sstevel@tonic-gate  *
3837c478bd9Sstevel@tonic-gate  */
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate int		nfonts = 0;		/* number of font positions */
3877c478bd9Sstevel@tonic-gate int		size = 1;		/* current size - internal value */
3887c478bd9Sstevel@tonic-gate int		font = 0;		/* font position we're using now */
3897c478bd9Sstevel@tonic-gate int		hpos = 0;		/* where troff wants to be - horizontally */
3907c478bd9Sstevel@tonic-gate int		vpos = 0;		/* same but vertically */
3917c478bd9Sstevel@tonic-gate float		lastw = 0;		/* width of the last input character */
3927c478bd9Sstevel@tonic-gate int		lastc = 0;		/* and its name (or index) */
3937c478bd9Sstevel@tonic-gate 
3947c478bd9Sstevel@tonic-gate int		fontheight = 0;		/* points from x H ... */
3957c478bd9Sstevel@tonic-gate int		fontslant = 0;		/* angle from x S ... */
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate int		res;			/* resolution assumed in input file */
3987c478bd9Sstevel@tonic-gate float		widthfac = 1.0;		/* for emulation = res/dev.res */
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate /*
4027c478bd9Sstevel@tonic-gate  *
4037c478bd9Sstevel@tonic-gate  * Remember some of the same things, but this time for the printer. lastend is only
4047c478bd9Sstevel@tonic-gate  * used when we're doing reverse video, and is where the last character on the
4057c478bd9Sstevel@tonic-gate  * current line was printed.
4067c478bd9Sstevel@tonic-gate  *
4077c478bd9Sstevel@tonic-gate  */
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate int		lastsize = -1;		/* last internal size we used */
4117c478bd9Sstevel@tonic-gate int		lastfont = -1;		/* last font we told printer about */
4127c478bd9Sstevel@tonic-gate float		lastx = -1;		/* printer's current position */
4137c478bd9Sstevel@tonic-gate int		lasty = -1;
4147c478bd9Sstevel@tonic-gate int		lastend;		/* where last character on this line was */
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate /*
4187c478bd9Sstevel@tonic-gate  *
4197c478bd9Sstevel@tonic-gate  * fontname[] keeps track of the mounted fonts. Filled in (by t_fp()) from data
4207c478bd9Sstevel@tonic-gate  * in the binary font files.
4217c478bd9Sstevel@tonic-gate  *
4227c478bd9Sstevel@tonic-gate  */
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 
4257c478bd9Sstevel@tonic-gate struct  {
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate 	char	*name;			/* name of the font loaded here */
4287c478bd9Sstevel@tonic-gate 	int	number;			/* its internal number */
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate } fontname[NFONT+1] = {NULL, 0};
4317c478bd9Sstevel@tonic-gate 
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate /*
4347c478bd9Sstevel@tonic-gate  *
4357c478bd9Sstevel@tonic-gate  * All the special fonts will be mounted after the last legitimate font position.
4367c478bd9Sstevel@tonic-gate  * It helps when we're translating files prepared for devices, like the 202, that
4377c478bd9Sstevel@tonic-gate  * have a different set of special fonts. The set of special fonts needed when
4387c478bd9Sstevel@tonic-gate  * *realdev's tables are used may not get mounted when we're emulating another
4397c478bd9Sstevel@tonic-gate  * device. gotspecial keeps track of whether we've done it yet. seenpage is set
4407c478bd9Sstevel@tonic-gate  * to TRUE after we've seen the first page command in the input file. It controls
4417c478bd9Sstevel@tonic-gate  * what's done in t_font() and is needed because nfonts is no longer set when the
4427c478bd9Sstevel@tonic-gate  * DESC.out file is read, but rather is updated from "x font" commands in the
4437c478bd9Sstevel@tonic-gate  * input files.
4447c478bd9Sstevel@tonic-gate  *
4457c478bd9Sstevel@tonic-gate  */
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate int		gotspecial = FALSE;
4497c478bd9Sstevel@tonic-gate int		seenpage = FALSE;
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate /*
4537c478bd9Sstevel@tonic-gate  *
4547c478bd9Sstevel@tonic-gate  * The amount of horizontal positioning error we accept controls both the size
4557c478bd9Sstevel@tonic-gate  * of the output file and the appearance of the printed text. It's probably most
4567c478bd9Sstevel@tonic-gate  * important when we're emulating other devices, like the APS-5. The error can be
4577c478bd9Sstevel@tonic-gate  * set using the -S option. It's converted from points to machine units in t_init()
4587c478bd9Sstevel@tonic-gate  * after the resolution is known. rvslop is also set in t_init() and only used to
4597c478bd9Sstevel@tonic-gate  * adjust the width of the box that's drawn around text when we're printing in
4607c478bd9Sstevel@tonic-gate  * reverse video mode.
4617c478bd9Sstevel@tonic-gate  *
4627c478bd9Sstevel@tonic-gate  */
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate float		pointslop = SLOP;	/* horizontal error in points */
4667c478bd9Sstevel@tonic-gate int		slop;			/* and machine units */
4677c478bd9Sstevel@tonic-gate int		rvslop;			/* to extend box in reverse video mode */
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate /*
4717c478bd9Sstevel@tonic-gate  *
4727c478bd9Sstevel@tonic-gate  * Characters are accumulated and saved in PostScript strings that are eventually
4737c478bd9Sstevel@tonic-gate  * processed by making a single call to procedure t. textcount counts the number
4747c478bd9Sstevel@tonic-gate  * of individual strings collected but not yet processed, and is primarily used to
4757c478bd9Sstevel@tonic-gate  * make sure PostScript's stack doesn't get too big. When textcount is positive
4767c478bd9Sstevel@tonic-gate  * we've started accumulating strings and need to generate a call to PostScript
4777c478bd9Sstevel@tonic-gate  * procedure t to process the text before anything else (like a font change) is
4787c478bd9Sstevel@tonic-gate  * done.
4797c478bd9Sstevel@tonic-gate  *
4807c478bd9Sstevel@tonic-gate  */
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate int		textcount = 0;		/* strings accumulated so far */
4847c478bd9Sstevel@tonic-gate int		stringstart = 0;	/* where the next one starts */
4857c478bd9Sstevel@tonic-gate int		spacecount = 0;		/* spaces seen so far on current line */
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate /*
4897c478bd9Sstevel@tonic-gate  *
4907c478bd9Sstevel@tonic-gate  * Things that can be used by text line encoding schemes that need to read and
4917c478bd9Sstevel@tonic-gate  * remember an entire line before doing any output. The strings that make up the
4927c478bd9Sstevel@tonic-gate  * line can be saved in array strings[] and accessed by fields in line[]. *strptr
4937c478bd9Sstevel@tonic-gate  * points to the next free slot in strings[].
4947c478bd9Sstevel@tonic-gate  *
4957c478bd9Sstevel@tonic-gate  */
4967c478bd9Sstevel@tonic-gate 
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate char		strings[STRINGSPACE];
4997c478bd9Sstevel@tonic-gate char		*strptr;
5007c478bd9Sstevel@tonic-gate Line		line[MAXSTACK+3];
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate /*
5047c478bd9Sstevel@tonic-gate  *
5057c478bd9Sstevel@tonic-gate  * When we're emulating another device we may want to map font name requests that
5067c478bd9Sstevel@tonic-gate  * come in as "x font pos name" commands into some other font name before anything
5077c478bd9Sstevel@tonic-gate  * else is done (ie. calling loadfont()). Font names can collide or we may just
5087c478bd9Sstevel@tonic-gate  * want to a mapping that depends on the device troff used to format the input
5097c478bd9Sstevel@tonic-gate  * files. devfontmap points to a structure that's filled in by getdevmap() if the
5107c478bd9Sstevel@tonic-gate  * mapping file /usr/lib/font/dev*realdev/fontmaps/devname exists. mapdevfont()
5117c478bd9Sstevel@tonic-gate  * then uses that table to translate font name requests into something else before
5127c478bd9Sstevel@tonic-gate  * loadfont() gets called.
5137c478bd9Sstevel@tonic-gate  *
5147c478bd9Sstevel@tonic-gate  * fontmap[] provides a simple minded translation that maps an unrecognized font
5157c478bd9Sstevel@tonic-gate  * name (in loadfont()) into another font name that we know will be available. It
5167c478bd9Sstevel@tonic-gate  * doesn't provide the fine control available with *devfontmap, but should be good
5177c478bd9Sstevel@tonic-gate  * enough for most jobs. Both structures are only needed when emulating another
5187c478bd9Sstevel@tonic-gate  * device using *realdev's font tables.
5197c478bd9Sstevel@tonic-gate  *
5207c478bd9Sstevel@tonic-gate  */
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate Devfontmap	*devfontmap = NULL;	/* device level */
5247c478bd9Sstevel@tonic-gate Fontmap		fontmap[] = FONTMAP;	/* and general mapping tables - emulation */
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate /*
5287c478bd9Sstevel@tonic-gate  *
5297c478bd9Sstevel@tonic-gate  * A few variables that are really only used if we're doing accounting. Designed
5307c478bd9Sstevel@tonic-gate  * for our use at Murray Hill and probably won't suit your needs. Changes should
5317c478bd9Sstevel@tonic-gate  * be easy and can be made in routine account().
5327c478bd9Sstevel@tonic-gate  *
5337c478bd9Sstevel@tonic-gate  */
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate int		printed = 0;		/* charge for this many pages */
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate /*
5407c478bd9Sstevel@tonic-gate  *
5417c478bd9Sstevel@tonic-gate  * Output and accounting file definitions. The PostScript output always goes to
5427c478bd9Sstevel@tonic-gate  * stdout or /dev/null, while the accounting file can be selected using the -A
5437c478bd9Sstevel@tonic-gate  * option.
5447c478bd9Sstevel@tonic-gate  *
5457c478bd9Sstevel@tonic-gate  */
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate FILE		*tf = NULL;		/* PostScript output goes here */
5497c478bd9Sstevel@tonic-gate FILE		*fp_acct = NULL;	/* accounting stuff written here */
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate 
5527c478bd9Sstevel@tonic-gate /*
5537c478bd9Sstevel@tonic-gate  *
5547c478bd9Sstevel@tonic-gate  * Need the list of valid options in header() and options(), so I've moved the
5557c478bd9Sstevel@tonic-gate  * definition here.
5567c478bd9Sstevel@tonic-gate  *
5577c478bd9Sstevel@tonic-gate  */
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate char		*optnames = "a:c:e:m:n:o:p:tw:x:y:A:C:J:F:H:L:OP:R:S:T:DI";
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate /*
5647c478bd9Sstevel@tonic-gate  *
5657c478bd9Sstevel@tonic-gate  * Very temporary space that can be used to do things like building up pathnames
5667c478bd9Sstevel@tonic-gate  * immediately before opening a file. Contents may not be preserved across calls
5677c478bd9Sstevel@tonic-gate  * to subroutines defined in this file, so it probably should only be used in low
5687c478bd9Sstevel@tonic-gate  * level subroutines like loadfont() or fontinit() and nowhere else.
5697c478bd9Sstevel@tonic-gate  *
5707c478bd9Sstevel@tonic-gate  */
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 
5737c478bd9Sstevel@tonic-gate char		temp[150];
5747c478bd9Sstevel@tonic-gate 
575f928ce67Sceastha static void account(void);
576f928ce67Sceastha static void addchar(int);
577f928ce67Sceastha static void addoctal(int);
578f928ce67Sceastha static void arguments(void);
579f928ce67Sceastha static void charlib(int);
580f928ce67Sceastha static void conv(FILE *);
581f928ce67Sceastha static void devcntrl(FILE *);
582f928ce67Sceastha static void documentfonts(void);
583f928ce67Sceastha static void done(void);
584f928ce67Sceastha static void endline(void);
585f928ce67Sceastha static void endstring(void);
586f928ce67Sceastha void endtext(void);
587f928ce67Sceastha static void fontinit(void);
588f928ce67Sceastha static void fontprint(int);
589f928ce67Sceastha static void getdevmap(void);
590f928ce67Sceastha static void header(void);
591f928ce67Sceastha void hgoto(int);
592f928ce67Sceastha static void hmot(int);
593f928ce67Sceastha static void init_signals(void);
594f928ce67Sceastha static void loaddefault(void);
595f928ce67Sceastha static void loadfont(int, char *, char *);
596f928ce67Sceastha static void loadspecial(void);
597f928ce67Sceastha static void options(void);
598f928ce67Sceastha static void oput(int);
599f928ce67Sceastha static void put1(int);
600f928ce67Sceastha static void put1s(char *);
601f928ce67Sceastha static void redirect(int);
602f928ce67Sceastha void reset(void);
603f928ce67Sceastha void resetpos(void);
604f928ce67Sceastha static void setfont(int);
605f928ce67Sceastha static void setpaths(char *);
606f928ce67Sceastha static void setsize(int);
607f928ce67Sceastha static void setup(void);
608f928ce67Sceastha static void starttext(void);
609f928ce67Sceastha static void t_charht(int);
610f928ce67Sceastha static void t_fp(int, char *, char *);
611f928ce67Sceastha static void t_init(void);
612f928ce67Sceastha static void t_newline(void);
613f928ce67Sceastha static void t_page(int);
614f928ce67Sceastha static void t_reset(int);
615f928ce67Sceastha void t_sf(void);
616f928ce67Sceastha static void t_slant(int);
617f928ce67Sceastha static void t_trailer(void);
618f928ce67Sceastha void vgoto(int);
619f928ce67Sceastha static void vmot(int);
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 
622f928ce67Sceastha /*****************************************************************************/
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate 
625f928ce67Sceastha int
main(int agc,char * agv[])626f928ce67Sceastha main(int agc, char *agv[])
6277c478bd9Sstevel@tonic-gate {
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate /*
6307c478bd9Sstevel@tonic-gate  *
6317c478bd9Sstevel@tonic-gate  * A program that translates troff output into PostScript. All the input files
6327c478bd9Sstevel@tonic-gate  * must have been formatted for the same device, which doesn't necessarily have to
6337c478bd9Sstevel@tonic-gate  * be *realdev. If there's more than one input file, each begins on a new page.
6347c478bd9Sstevel@tonic-gate  *
6357c478bd9Sstevel@tonic-gate  */
6367c478bd9Sstevel@tonic-gate 
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate     argc = agc;				/* global so everyone can use them */
6397c478bd9Sstevel@tonic-gate     argv = agv;
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate     prog_name = argv[0];		/* just for error messages */
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate     init_signals();			/* sets up interrupt handling */
6447c478bd9Sstevel@tonic-gate     header();				/* PostScript file structuring comments */
6457c478bd9Sstevel@tonic-gate     options();				/* command line options */
6467c478bd9Sstevel@tonic-gate     arguments();			/* translate all the input files */
6477c478bd9Sstevel@tonic-gate     done();				/* add trailing comments etc. */
6487c478bd9Sstevel@tonic-gate     account();				/* job accounting data */
6497c478bd9Sstevel@tonic-gate 
650f928ce67Sceastha     return (x_stat);			/* everything probably went OK */
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate }   /* End of main */
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate /*****************************************************************************/
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate 
658f928ce67Sceastha static void
init_signals(void)659f928ce67Sceastha init_signals(void)
6607c478bd9Sstevel@tonic-gate {
6617c478bd9Sstevel@tonic-gate     void	interrupt();		/* signal handler */
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate /*
6647c478bd9Sstevel@tonic-gate  *
6657c478bd9Sstevel@tonic-gate  * Make sure we handle interrupts.
6667c478bd9Sstevel@tonic-gate  *
6677c478bd9Sstevel@tonic-gate  */
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate     if ( signal(SIGINT, interrupt) == SIG_IGN )  {
6717c478bd9Sstevel@tonic-gate 	signal(SIGINT, SIG_IGN);
6727c478bd9Sstevel@tonic-gate 	signal(SIGQUIT, SIG_IGN);
6737c478bd9Sstevel@tonic-gate 	signal(SIGHUP, SIG_IGN);
6747c478bd9Sstevel@tonic-gate     } else {
6757c478bd9Sstevel@tonic-gate 	signal(SIGHUP, interrupt);
6767c478bd9Sstevel@tonic-gate 	signal(SIGQUIT, interrupt);
6777c478bd9Sstevel@tonic-gate     }   /* End else */
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate     signal(SIGTERM, interrupt);
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate }   /* End of init_signals */
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate /*****************************************************************************/
6857c478bd9Sstevel@tonic-gate 
686f928ce67Sceastha static void
header(void)687f928ce67Sceastha header(void)
6887c478bd9Sstevel@tonic-gate {
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate     int		ch;			/* return value from getopt() */
6927c478bd9Sstevel@tonic-gate     int		old_optind = optind;	/* for restoring optind - should be 1 */
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate /*
6967c478bd9Sstevel@tonic-gate  *
6977c478bd9Sstevel@tonic-gate  * Scans the option list looking for things, like the prologue file, that we need
6987c478bd9Sstevel@tonic-gate  * right away but could be changed from the default. Doing things this way is an
6997c478bd9Sstevel@tonic-gate  * attempt to conform to Adobe's latest file structuring conventions. In particular
7007c478bd9Sstevel@tonic-gate  * they now say there should be nothing executed in the prologue, and they have
7017c478bd9Sstevel@tonic-gate  * added two new comments that delimit global initialization calls. Once we know
7027c478bd9Sstevel@tonic-gate  * where things really are we write out the job header, follow it by the prologue,
7037c478bd9Sstevel@tonic-gate  * and then add the ENDPROLOG and BEGINSETUP comments.
7047c478bd9Sstevel@tonic-gate  *
7057c478bd9Sstevel@tonic-gate  */
7067c478bd9Sstevel@tonic-gate 
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate     while ( (ch = getopt(argc, argv, optnames)) != EOF )
7097c478bd9Sstevel@tonic-gate 	if ( ch == 'L' )
7107c478bd9Sstevel@tonic-gate 	    setpaths(optarg);
7117c478bd9Sstevel@tonic-gate 	else if ( ch == '?' )
7127c478bd9Sstevel@tonic-gate 	    error(FATAL, "");
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate     optind = old_optind;		/* get ready for option scanning */
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s", NONCONFORMING);
7177c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s %s\n", VERSION, PROGRAMVERSION);
7187c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s %s\n", DOCUMENTFONTS, ATEND);
7197c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s %s\n", PAGES, ATEND);
7207c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s", ENDCOMMENTS);
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate     if ( cat(prologue) == FALSE )
7237c478bd9Sstevel@tonic-gate 	error(FATAL, "can't read %s", prologue);
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s", ENDPROLOG);
7267c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s", BEGINSETUP);
7277c478bd9Sstevel@tonic-gate     fprintf(stdout, "mark\n");
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate }   /* End of header */
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate /*****************************************************************************/
7337c478bd9Sstevel@tonic-gate 
7347c478bd9Sstevel@tonic-gate 
735f928ce67Sceastha static void
options(void)736f928ce67Sceastha options(void)
7377c478bd9Sstevel@tonic-gate {
7387c478bd9Sstevel@tonic-gate     int		ch;			/* name returned by getopt() */
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate     extern char	*optarg;		/* option argument set by getopt() */
7417c478bd9Sstevel@tonic-gate     extern int	optind;
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate /*
7447c478bd9Sstevel@tonic-gate  *
7457c478bd9Sstevel@tonic-gate  * Reads and processes the command line options. There are, without a doubt, too
7467c478bd9Sstevel@tonic-gate  * many options!
7477c478bd9Sstevel@tonic-gate  *
7487c478bd9Sstevel@tonic-gate  */
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate 
7517c478bd9Sstevel@tonic-gate     while ( (ch = getopt(argc, argv, optnames)) != EOF )  {
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate 	switch ( ch )  {
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate 	    case 'a':			/* aspect ratio */
7567c478bd9Sstevel@tonic-gate 		    fprintf(stdout, "/aspectratio %s def\n", optarg);
7577c478bd9Sstevel@tonic-gate 		    break;
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 	    case 'c':			/* number of copies */
7607c478bd9Sstevel@tonic-gate 		    copies = atoi(optarg);
7617c478bd9Sstevel@tonic-gate 		    fprintf(stdout, "/#copies %s store\n", optarg);
7627c478bd9Sstevel@tonic-gate 		    break;
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate 	    case 'e':			/* change the encoding scheme */
7657c478bd9Sstevel@tonic-gate 		    if ( (encoding = atoi(optarg)) < 0 || encoding > MAXENCODING )
7667c478bd9Sstevel@tonic-gate 			encoding = DFLTENCODING;
7677c478bd9Sstevel@tonic-gate 		    realencoding = encoding;
7687c478bd9Sstevel@tonic-gate 		    break;
7697c478bd9Sstevel@tonic-gate 
7707c478bd9Sstevel@tonic-gate 	    case 'm':			/* magnification */
7717c478bd9Sstevel@tonic-gate 		    fprintf(stdout, "/magnification %s def\n", optarg);
7727c478bd9Sstevel@tonic-gate 		    break;
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate 	    case 'n':			/* forms per page */
7757c478bd9Sstevel@tonic-gate 		    formsperpage = atoi(optarg);
7767c478bd9Sstevel@tonic-gate 		    fprintf(stdout, "%s %s\n", FORMSPERPAGE, optarg);
7777c478bd9Sstevel@tonic-gate 		    fprintf(stdout, "/formsperpage %s def\n", optarg);
7787c478bd9Sstevel@tonic-gate 		    break;
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate 	    case 'o':			/* output page list */
7817c478bd9Sstevel@tonic-gate 		    out_list(optarg);
7827c478bd9Sstevel@tonic-gate 		    break;
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate 	    case 'p':			/* landscape or portrait mode */
7857c478bd9Sstevel@tonic-gate 		    if ( *optarg == 'l' )
7867c478bd9Sstevel@tonic-gate 			fprintf(stdout, "/landscape true def\n");
7877c478bd9Sstevel@tonic-gate 		    else fprintf(stdout, "/landscape false def\n");
7887c478bd9Sstevel@tonic-gate 		    break;
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate 	    case 't':			/* just for compatibility */
7917c478bd9Sstevel@tonic-gate 		    break;
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 	    case 'w':			/* line width for drawing */
7947c478bd9Sstevel@tonic-gate 		    fprintf(stdout, "/linewidth %s def\n", optarg);
7957c478bd9Sstevel@tonic-gate 		    break;
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 	    case 'x':			/* shift horizontally */
7987c478bd9Sstevel@tonic-gate 		    fprintf(stdout, "/xoffset %s def\n", optarg);
7997c478bd9Sstevel@tonic-gate 		    break;
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate 	    case 'y':			/* and vertically on the page */
8027c478bd9Sstevel@tonic-gate 		    fprintf(stdout, "/yoffset %s def\n", optarg);
8037c478bd9Sstevel@tonic-gate 		    break;
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate 	    case 'A':			/* force job accounting */
8067c478bd9Sstevel@tonic-gate 	    case 'J':
8077c478bd9Sstevel@tonic-gate 		    if ( (fp_acct = fopen(optarg, "a")) == NULL )
8087c478bd9Sstevel@tonic-gate 			error(FATAL, "can't open accounting file %s", optarg);
8097c478bd9Sstevel@tonic-gate 		    break;
8107c478bd9Sstevel@tonic-gate 
8117c478bd9Sstevel@tonic-gate 	    case 'C':			/* copy file to straight to output */
8127c478bd9Sstevel@tonic-gate 		    if ( cat(optarg) == FALSE )
8137c478bd9Sstevel@tonic-gate 			error(FATAL, "can't read %s", optarg);
8147c478bd9Sstevel@tonic-gate 		    break;
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 	    case 'F':			/* font table directory */
8177c478bd9Sstevel@tonic-gate 		    fontdir = optarg;
8187c478bd9Sstevel@tonic-gate 		    break;
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 	    case 'H':			/* host resident font directory */
8217c478bd9Sstevel@tonic-gate 		    hostfontdir = optarg;
8227c478bd9Sstevel@tonic-gate 		    break;
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate 	    case 'L':			/* PostScript prologue file */
8257c478bd9Sstevel@tonic-gate 		    setpaths(optarg);	/* already been done in header() */
8267c478bd9Sstevel@tonic-gate 		    break;
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate 	    case 'O':			/* turn picture inclusion off */
8297c478bd9Sstevel@tonic-gate 		    picflag = OFF;
8307c478bd9Sstevel@tonic-gate 		    break;
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 	    case 'P':			/* PostScript pass through */
8337c478bd9Sstevel@tonic-gate 		    fprintf(stdout, "%s\n", optarg);
8347c478bd9Sstevel@tonic-gate 		    break;
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate 	    case 'R':			/* special global or page level request */
8377c478bd9Sstevel@tonic-gate 		    saverequest(optarg);
8387c478bd9Sstevel@tonic-gate 		    break;
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate 	    case 'S':			/* horizontal position error */
8417c478bd9Sstevel@tonic-gate 		    if ( (pointslop = atof(optarg)) < 0 )
8427c478bd9Sstevel@tonic-gate 			pointslop = 0;
8437c478bd9Sstevel@tonic-gate 		    break;
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate 	    case 'T':			/* target printer */
8467c478bd9Sstevel@tonic-gate 		    realdev = optarg;
8477c478bd9Sstevel@tonic-gate 		    break;
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 	    case 'D':			/* debug flag */
8507c478bd9Sstevel@tonic-gate 		    debug = ON;
8517c478bd9Sstevel@tonic-gate 		    tf = stdout;
8527c478bd9Sstevel@tonic-gate 		    break;
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 	    case 'I':			/* ignore FATAL errors */
8557c478bd9Sstevel@tonic-gate 		    ignore = ON;
8567c478bd9Sstevel@tonic-gate 		    break;
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 	    case '?':			/* don't know the option */
8597c478bd9Sstevel@tonic-gate 		    error(FATAL, "");
8607c478bd9Sstevel@tonic-gate 		    break;
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate 	    default:
8637c478bd9Sstevel@tonic-gate 		    error(FATAL, "missing case for option %c", ch);
8647c478bd9Sstevel@tonic-gate 		    break;
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate 	}   /* End switch */
8677c478bd9Sstevel@tonic-gate     }	/* End while */
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate     argc -= optind;			/* get ready for non-options args */
8707c478bd9Sstevel@tonic-gate     argv += optind;
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate }   /* End of options */
8737c478bd9Sstevel@tonic-gate 
8747c478bd9Sstevel@tonic-gate 
8757c478bd9Sstevel@tonic-gate /*****************************************************************************/
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 
878f928ce67Sceastha static void
setpaths(char * name)879f928ce67Sceastha setpaths(char *name)
880f928ce67Sceastha     /* string that followed the -L option */
8817c478bd9Sstevel@tonic-gate {
8827c478bd9Sstevel@tonic-gate     char	*path;			/* start of the pathname */
8837c478bd9Sstevel@tonic-gate 
8847c478bd9Sstevel@tonic-gate /*
8857c478bd9Sstevel@tonic-gate  *
8867c478bd9Sstevel@tonic-gate  * Extends the -L option to permit run time modification of pathnames that were
8877c478bd9Sstevel@tonic-gate  * fixed or didn't exist in previous versions of dpost. For example, the PostScript
8887c478bd9Sstevel@tonic-gate  * drawing procedures have been moved out of *prologue and put in *drawfile. The
8897c478bd9Sstevel@tonic-gate  * new syntax can be either -Lfile or -Lname:file. If the "name:" prefix is omitted
8907c478bd9Sstevel@tonic-gate  * file will be used as the prologue, otherwise name should be one of "prologue",
8917c478bd9Sstevel@tonic-gate  * "font", "draw", "color", or "form" and is used to select the pointer that gets
8927c478bd9Sstevel@tonic-gate  * set to string "file".
8937c478bd9Sstevel@tonic-gate  *
8947c478bd9Sstevel@tonic-gate  */
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate     for ( path = name; *path; path++ )
8987c478bd9Sstevel@tonic-gate 	if ( *path == ':' || *path == ' ' )  {
8997c478bd9Sstevel@tonic-gate 	    while ( *path == ':' || *path == ' ' ) path++;
9007c478bd9Sstevel@tonic-gate 	    break;
9017c478bd9Sstevel@tonic-gate 	}   /* End if */
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate     if ( *path == '\0' )		/* didn't find a "name:" prefix */
9047c478bd9Sstevel@tonic-gate 	path = name;
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate     if ( path == name || strncmp(name, "prologue", strlen("prologue")) == 0 )
9077c478bd9Sstevel@tonic-gate 	prologue = path;
9087c478bd9Sstevel@tonic-gate     else if ( strncmp(name, "draw", strlen("draw")) == 0 )
9097c478bd9Sstevel@tonic-gate 	drawfile = path;
9107c478bd9Sstevel@tonic-gate     else if ( strncmp(name, "color", strlen("color")) == 0 )
9117c478bd9Sstevel@tonic-gate 	colorfile = path;
9127c478bd9Sstevel@tonic-gate     else if ( strncmp(name, "form", strlen("form")) == 0 )
9137c478bd9Sstevel@tonic-gate 	formfile = path;
9147c478bd9Sstevel@tonic-gate     else if ( strncmp(name, "baseline", strlen("baseline")) == 0 )
9157c478bd9Sstevel@tonic-gate 	baselinefile = path;
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate }   /* End of setpaths */
9187c478bd9Sstevel@tonic-gate 
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate /*****************************************************************************/
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 
923f928ce67Sceastha static void
setup(void)924f928ce67Sceastha setup(void)
9257c478bd9Sstevel@tonic-gate {
9267c478bd9Sstevel@tonic-gate 
9277c478bd9Sstevel@tonic-gate /*
9287c478bd9Sstevel@tonic-gate  * Handles things that must be done after the options are read but before the
9297c478bd9Sstevel@tonic-gate  * input files are processed. Called from t_init() after an "x init" command is
9307c478bd9Sstevel@tonic-gate  * read, because we need the resolution before we can generate the call to the
9317c478bd9Sstevel@tonic-gate  * setup procedure defined in *prologue. Only allowing one call to setup assumes
9327c478bd9Sstevel@tonic-gate  * all the input files have been prepared for the same device.
9337c478bd9Sstevel@tonic-gate  *
9347c478bd9Sstevel@tonic-gate  */
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate     writerequest(0, stdout);		/* global requests eg. manual feed */
9387c478bd9Sstevel@tonic-gate     fprintf(stdout, "/resolution %d def\n", res);
9397c478bd9Sstevel@tonic-gate     fprintf(stdout, "setup\n");
9407c478bd9Sstevel@tonic-gate     fprintf(stdout, "%d setdecoding\n", encoding);
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate     if ( formsperpage > 1 )  {		/* followed by stuff for multiple pages */
9437c478bd9Sstevel@tonic-gate 	if ( cat(formfile) == FALSE )
9447c478bd9Sstevel@tonic-gate 	    error(FATAL, "can't read %s", formfile);
9457c478bd9Sstevel@tonic-gate 	fprintf(stdout, "%d setupforms\n", formsperpage);
9467c478bd9Sstevel@tonic-gate     }	/* End if */
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s", ENDSETUP);
9497c478bd9Sstevel@tonic-gate 
9507c478bd9Sstevel@tonic-gate }   /* End of setup */
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate /*****************************************************************************/
9547c478bd9Sstevel@tonic-gate 
9557c478bd9Sstevel@tonic-gate 
956f928ce67Sceastha static void
arguments(void)957f928ce67Sceastha arguments(void)
9587c478bd9Sstevel@tonic-gate {
9597c478bd9Sstevel@tonic-gate     FILE	*fp;			/* next input file */
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate /*
9627c478bd9Sstevel@tonic-gate  *
9637c478bd9Sstevel@tonic-gate  * Makes sure all the non-option command line arguments are processed. If we get
9647c478bd9Sstevel@tonic-gate  * here and there aren't any arguments left, or if '-' is one of the input files
9657c478bd9Sstevel@tonic-gate  * we'll translate stdin.
9667c478bd9Sstevel@tonic-gate  *
9677c478bd9Sstevel@tonic-gate  */
9687c478bd9Sstevel@tonic-gate 
9697c478bd9Sstevel@tonic-gate 
9707c478bd9Sstevel@tonic-gate     if ( argc < 1 )
9717c478bd9Sstevel@tonic-gate 	conv(stdin);
9727c478bd9Sstevel@tonic-gate     else
9737c478bd9Sstevel@tonic-gate 	while ( argc > 0 ) {
9747c478bd9Sstevel@tonic-gate 	    if ( strcmp(*argv, "-") == 0 )
9757c478bd9Sstevel@tonic-gate 		fp = stdin;
9767c478bd9Sstevel@tonic-gate 	    else if ( (fp = fopen(*argv, "r")) == NULL )
9777c478bd9Sstevel@tonic-gate 		error(FATAL, "can't open %s", *argv);
9787c478bd9Sstevel@tonic-gate 	    conv(fp);
9797c478bd9Sstevel@tonic-gate 	    if ( fp != stdin )
9807c478bd9Sstevel@tonic-gate 		fclose(fp);
9817c478bd9Sstevel@tonic-gate 	    argc--;
9827c478bd9Sstevel@tonic-gate 	    argv++;
9837c478bd9Sstevel@tonic-gate 	}   /* End while */
9847c478bd9Sstevel@tonic-gate 
9857c478bd9Sstevel@tonic-gate }   /* End of arguments */
9867c478bd9Sstevel@tonic-gate 
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate /*****************************************************************************/
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate 
991f928ce67Sceastha static void
done(void)992f928ce67Sceastha done(void)
9937c478bd9Sstevel@tonic-gate {
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate /*
9967c478bd9Sstevel@tonic-gate  *
9977c478bd9Sstevel@tonic-gate  * Finished with all the input files, so mark the end of the pages with a TRAILER
9987c478bd9Sstevel@tonic-gate  * comment, make sure the last page prints, and add things like the DOCUMENTFONTS
9997c478bd9Sstevel@tonic-gate  * and PAGES comments that can only be determined after all the input files have
10007c478bd9Sstevel@tonic-gate  * been read.
10017c478bd9Sstevel@tonic-gate  *
10027c478bd9Sstevel@tonic-gate  */
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate 
10057c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s", TRAILER);
10067c478bd9Sstevel@tonic-gate     fprintf(stdout, "done\n");
10077c478bd9Sstevel@tonic-gate 
10087c478bd9Sstevel@tonic-gate     if ( temp_file != NULL )  {
10097c478bd9Sstevel@tonic-gate 	if ( docfonts > 0 )  {
10107c478bd9Sstevel@tonic-gate 	    cat(temp_file);
10117c478bd9Sstevel@tonic-gate 	    putc('\n', stdout);
10127c478bd9Sstevel@tonic-gate 	}   /* End if */
10137c478bd9Sstevel@tonic-gate 	unlink(temp_file);
10147c478bd9Sstevel@tonic-gate     }	/* End if */
10157c478bd9Sstevel@tonic-gate 
10167c478bd9Sstevel@tonic-gate     fprintf(stdout, "%s %d\n", PAGES, printed);
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate }   /* End of done */
10197c478bd9Sstevel@tonic-gate 
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate /*****************************************************************************/
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate 
1024f928ce67Sceastha static void
account(void)1025f928ce67Sceastha account(void)
10267c478bd9Sstevel@tonic-gate {
10277c478bd9Sstevel@tonic-gate 
10287c478bd9Sstevel@tonic-gate /*
10297c478bd9Sstevel@tonic-gate  *
10307c478bd9Sstevel@tonic-gate  * Writes an accounting record to *fp_acct provided it's not NULL. Accounting is
10317c478bd9Sstevel@tonic-gate  * requested using the -A or -J options.
10327c478bd9Sstevel@tonic-gate  *
10337c478bd9Sstevel@tonic-gate  */
10347c478bd9Sstevel@tonic-gate 
10357c478bd9Sstevel@tonic-gate     if ( fp_acct != NULL )
10367c478bd9Sstevel@tonic-gate 	fprintf(fp_acct, " print %d\n copies %d\n", printed, copies);
10377c478bd9Sstevel@tonic-gate 
10387c478bd9Sstevel@tonic-gate }   /* End of account */
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 
10417c478bd9Sstevel@tonic-gate /*****************************************************************************/
10427c478bd9Sstevel@tonic-gate 
10437c478bd9Sstevel@tonic-gate 
1044f928ce67Sceastha static void
conv(FILE * fp)1045f928ce67Sceastha conv(FILE *fp)
1046f928ce67Sceastha     /* next input file */
10477c478bd9Sstevel@tonic-gate {
1048f928ce67Sceastha     int			c;		/* usually first char in next command */
10497c478bd9Sstevel@tonic-gate     int			m, n, n1, m1;	/* when we need to read integers */
10507c478bd9Sstevel@tonic-gate     char		str[50];	/* for special chars and font numbers */
10517c478bd9Sstevel@tonic-gate 
10527c478bd9Sstevel@tonic-gate 
10537c478bd9Sstevel@tonic-gate /*
10547c478bd9Sstevel@tonic-gate  *
10557c478bd9Sstevel@tonic-gate  * Controls the translation of troff's device independent output language into
10567c478bd9Sstevel@tonic-gate  * PostScript. The call to t_page() that prints the last page is made when we
10577c478bd9Sstevel@tonic-gate  * exit the loop, but probably belongs in t_trailer().
10587c478bd9Sstevel@tonic-gate  *
10597c478bd9Sstevel@tonic-gate  */
10607c478bd9Sstevel@tonic-gate 
10617c478bd9Sstevel@tonic-gate 
10627c478bd9Sstevel@tonic-gate     redirect(-1);			/* only do output after a page command */
10637c478bd9Sstevel@tonic-gate     lineno = 1;				/* line in current file */
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate     while ((c = getc(fp)) != EOF)  {
10667c478bd9Sstevel@tonic-gate 
10677c478bd9Sstevel@tonic-gate 	switch (c)  {
10687c478bd9Sstevel@tonic-gate 
10697c478bd9Sstevel@tonic-gate 	    case '\n':			/* just count this line */
10707c478bd9Sstevel@tonic-gate 		    lineno++;
10717c478bd9Sstevel@tonic-gate 		    break;
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 	    case ' ':			/* when input is text */
10747c478bd9Sstevel@tonic-gate 	    case 0:			/* occasional noise creeps in */
10757c478bd9Sstevel@tonic-gate 		    break;
10767c478bd9Sstevel@tonic-gate 
10777c478bd9Sstevel@tonic-gate 	    case '0': case '1': case '2': case '3': case '4':
10787c478bd9Sstevel@tonic-gate 	    case '5': case '6': case '7': case '8': case '9':
10797c478bd9Sstevel@tonic-gate 		    /* two motion digits plus a character */
10807c478bd9Sstevel@tonic-gate 		    hmot((c-'0')*10 + getc(fp)-'0');
10817c478bd9Sstevel@tonic-gate 		    put1(getc(fp));
10827c478bd9Sstevel@tonic-gate 		    break;
10837c478bd9Sstevel@tonic-gate 
10847c478bd9Sstevel@tonic-gate 	    case 'c':			/* single ascii character */
10857c478bd9Sstevel@tonic-gate 		    put1(getc(fp));
10867c478bd9Sstevel@tonic-gate 		    break;
10877c478bd9Sstevel@tonic-gate 
10887c478bd9Sstevel@tonic-gate 	    case 'C':			/* special character */
10897c478bd9Sstevel@tonic-gate 		    fscanf(fp, "%s", str);
10907c478bd9Sstevel@tonic-gate 		    put1s(str);
10917c478bd9Sstevel@tonic-gate 		    break;
10927c478bd9Sstevel@tonic-gate 
10937c478bd9Sstevel@tonic-gate 	    case 'N':			/* character at position n */
10947c478bd9Sstevel@tonic-gate 		    fscanf(fp, "%d", &m);
10957c478bd9Sstevel@tonic-gate 		    endtext();
10967c478bd9Sstevel@tonic-gate 		    oput(m);
10977c478bd9Sstevel@tonic-gate 		    break;
10987c478bd9Sstevel@tonic-gate 
10997c478bd9Sstevel@tonic-gate 	    case 'D':			/* drawing functions */
11007c478bd9Sstevel@tonic-gate 		    endtext();
11017c478bd9Sstevel@tonic-gate 		    getdraw();
11027c478bd9Sstevel@tonic-gate 		    if ( size != lastsize )
11037c478bd9Sstevel@tonic-gate 			t_sf();
11047c478bd9Sstevel@tonic-gate 		    switch ((c=getc(fp))) {
11057c478bd9Sstevel@tonic-gate 			case 'p':	/* draw a path */
11067c478bd9Sstevel@tonic-gate 			    while (fscanf(fp, "%d %d", &n, &m) == 2)
11077c478bd9Sstevel@tonic-gate 				drawline(n, m);
11087c478bd9Sstevel@tonic-gate 			    lineno++;
11097c478bd9Sstevel@tonic-gate 			    break;
11107c478bd9Sstevel@tonic-gate 
11117c478bd9Sstevel@tonic-gate 			case 'l':	/* draw a line */
11127c478bd9Sstevel@tonic-gate 			    fscanf(fp, "%d %d %c", &n, &m, &n1);
11137c478bd9Sstevel@tonic-gate 			    drawline(n, m);
11147c478bd9Sstevel@tonic-gate 			    break;
11157c478bd9Sstevel@tonic-gate 
11167c478bd9Sstevel@tonic-gate 			case 'c':	/* circle */
11177c478bd9Sstevel@tonic-gate 			    fscanf(fp, "%d", &n);
11187c478bd9Sstevel@tonic-gate 			    drawcirc(n);
11197c478bd9Sstevel@tonic-gate 			    break;
11207c478bd9Sstevel@tonic-gate 
11217c478bd9Sstevel@tonic-gate 			case 'e':	/* ellipse */
11227c478bd9Sstevel@tonic-gate 			    fscanf(fp, "%d %d", &m, &n);
11237c478bd9Sstevel@tonic-gate 			    drawellip(m, n);
11247c478bd9Sstevel@tonic-gate 			    break;
11257c478bd9Sstevel@tonic-gate 
11267c478bd9Sstevel@tonic-gate 			case 'a':	/* counter-clockwise arc */
11277c478bd9Sstevel@tonic-gate 			case 'A':	/* clockwise arc */
11287c478bd9Sstevel@tonic-gate 			    fscanf(fp, "%d %d %d %d", &n, &m, &n1, &m1);
11297c478bd9Sstevel@tonic-gate 			    drawarc(n, m, n1, m1, c);
11307c478bd9Sstevel@tonic-gate 			    break;
11317c478bd9Sstevel@tonic-gate 
11327c478bd9Sstevel@tonic-gate 			case 'q':	/* spline without end points */
11337c478bd9Sstevel@tonic-gate 			    drawspline(fp, 1);
11347c478bd9Sstevel@tonic-gate 			    lineno++;
11357c478bd9Sstevel@tonic-gate 			    break;
11367c478bd9Sstevel@tonic-gate 
11377c478bd9Sstevel@tonic-gate 			case '~':	/* wiggly line */
11387c478bd9Sstevel@tonic-gate 			    drawspline(fp, 2);
11397c478bd9Sstevel@tonic-gate 			    lineno++;
11407c478bd9Sstevel@tonic-gate 			    break;
11417c478bd9Sstevel@tonic-gate 
11427c478bd9Sstevel@tonic-gate 			default:
11437c478bd9Sstevel@tonic-gate 			    error(FATAL, "unknown drawing function %c", c);
11447c478bd9Sstevel@tonic-gate 			    break;
11457c478bd9Sstevel@tonic-gate 		    }	/* End switch */
11467c478bd9Sstevel@tonic-gate 		    break;
11477c478bd9Sstevel@tonic-gate 
11487c478bd9Sstevel@tonic-gate 	    case 's':			/* use this point size */
11497c478bd9Sstevel@tonic-gate 		    fscanf(fp, "%d", &n);	/* ignore fractional sizes */
11507c478bd9Sstevel@tonic-gate 		    setsize(t_size(n));
11517c478bd9Sstevel@tonic-gate 		    break;
11527c478bd9Sstevel@tonic-gate 
11537c478bd9Sstevel@tonic-gate 	    case 'f':			/* use font mounted here */
11547c478bd9Sstevel@tonic-gate 		    fscanf(fp, "%s", str);
11557c478bd9Sstevel@tonic-gate 		    setfont(t_font(str));
11567c478bd9Sstevel@tonic-gate 		    break;
11577c478bd9Sstevel@tonic-gate 
11587c478bd9Sstevel@tonic-gate 	    case 'H':			/* absolute horizontal motion */
11597c478bd9Sstevel@tonic-gate 		    fscanf(fp, "%d", &n);
11607c478bd9Sstevel@tonic-gate 		    hgoto(n);
11617c478bd9Sstevel@tonic-gate 		    break;
11627c478bd9Sstevel@tonic-gate 
11637c478bd9Sstevel@tonic-gate 	    case 'h':			/* relative horizontal motion */
11647c478bd9Sstevel@tonic-gate 		    fscanf(fp, "%d", &n);
11657c478bd9Sstevel@tonic-gate 		    hmot(n);
11667c478bd9Sstevel@tonic-gate 		    break;
11677c478bd9Sstevel@tonic-gate 
11687c478bd9Sstevel@tonic-gate 	    case 'w':			/* word space */
11697c478bd9Sstevel@tonic-gate 		    break;
11707c478bd9Sstevel@tonic-gate 
11717c478bd9Sstevel@tonic-gate 	    case 'V':			/* absolute vertical position */
11727c478bd9Sstevel@tonic-gate 		    fscanf(fp, "%d", &n);
11737c478bd9Sstevel@tonic-gate 		    vgoto(n);
11747c478bd9Sstevel@tonic-gate 		    break;
11757c478bd9Sstevel@tonic-gate 
11767c478bd9Sstevel@tonic-gate 	    case 'v':			/* relative vertical motion */
11777c478bd9Sstevel@tonic-gate 		    fscanf(fp, "%d", &n);
11787c478bd9Sstevel@tonic-gate 		    vmot(n);
11797c478bd9Sstevel@tonic-gate 		    break;
11807c478bd9Sstevel@tonic-gate 
11817c478bd9Sstevel@tonic-gate 	    case 'p':			/* new page */
11827c478bd9Sstevel@tonic-gate 		    fscanf(fp, "%d", &n);
11837c478bd9Sstevel@tonic-gate 		    t_page(n);
11847c478bd9Sstevel@tonic-gate 		    break;
11857c478bd9Sstevel@tonic-gate 
11867c478bd9Sstevel@tonic-gate 	    case 'n':			/* end of line */
11877c478bd9Sstevel@tonic-gate 		    while ( (c = getc(fp)) != '\n'  &&  c != EOF ) ;
11887c478bd9Sstevel@tonic-gate 		    t_newline();
11897c478bd9Sstevel@tonic-gate 		    lineno++;
11907c478bd9Sstevel@tonic-gate 		    break;
11917c478bd9Sstevel@tonic-gate 
11927c478bd9Sstevel@tonic-gate 	    case '#':			/* comment */
11937c478bd9Sstevel@tonic-gate 		    while ( (c = getc(fp)) != '\n'  &&  c != EOF ) ;
11947c478bd9Sstevel@tonic-gate 		    lineno++;
11957c478bd9Sstevel@tonic-gate 		    break;
11967c478bd9Sstevel@tonic-gate 
11977c478bd9Sstevel@tonic-gate 	    case 'x':			/* device control function */
11987c478bd9Sstevel@tonic-gate 		    devcntrl(fp);
11997c478bd9Sstevel@tonic-gate 		    lineno++;
12007c478bd9Sstevel@tonic-gate 		    break;
12017c478bd9Sstevel@tonic-gate 
12027c478bd9Sstevel@tonic-gate 	    default:
12037c478bd9Sstevel@tonic-gate 		    error(FATAL, "unknown input character %o %c", c, c);
12047c478bd9Sstevel@tonic-gate 		    done();
12057c478bd9Sstevel@tonic-gate 
12067c478bd9Sstevel@tonic-gate 	}   /* End switch */
12077c478bd9Sstevel@tonic-gate 
12087c478bd9Sstevel@tonic-gate     }	/* End while */
12097c478bd9Sstevel@tonic-gate 
12107c478bd9Sstevel@tonic-gate     t_page(-1);				/* print the last page */
12117c478bd9Sstevel@tonic-gate     endtext();
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate }   /* End of conv */
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 
12167c478bd9Sstevel@tonic-gate /*****************************************************************************/
12177c478bd9Sstevel@tonic-gate 
12187c478bd9Sstevel@tonic-gate 
1219f928ce67Sceastha static void
devcntrl(FILE * fp)1220f928ce67Sceastha devcntrl(FILE *fp)
1221f928ce67Sceastha     /* current input file */
12227c478bd9Sstevel@tonic-gate {
12237c478bd9Sstevel@tonic-gate 
12247c478bd9Sstevel@tonic-gate 
12257c478bd9Sstevel@tonic-gate     char	str[50], buf[256], str1[50];
12267c478bd9Sstevel@tonic-gate     int		c, n;
12277c478bd9Sstevel@tonic-gate 
12287c478bd9Sstevel@tonic-gate 
12297c478bd9Sstevel@tonic-gate /*
12307c478bd9Sstevel@tonic-gate  *
12317c478bd9Sstevel@tonic-gate  * Called from conv() to process the rest of a device control function. There's
12327c478bd9Sstevel@tonic-gate  * a whole family of them and they all start with the string "x ", which we've
12337c478bd9Sstevel@tonic-gate  * already read. The "x X ..." commands are an extensible (and device dependent)
12347c478bd9Sstevel@tonic-gate  * family that we use here for things like picture inclusion. Unrecognized device
12357c478bd9Sstevel@tonic-gate  * control commands are ignored.
12367c478bd9Sstevel@tonic-gate  *
12377c478bd9Sstevel@tonic-gate  */
12387c478bd9Sstevel@tonic-gate 
12397c478bd9Sstevel@tonic-gate 
12407c478bd9Sstevel@tonic-gate     fscanf(fp, "%s", str);		/* get the control function name */
12417c478bd9Sstevel@tonic-gate 
12427c478bd9Sstevel@tonic-gate     switch ( str[0] )  {		/* only the first character counts */
12437c478bd9Sstevel@tonic-gate 
12447c478bd9Sstevel@tonic-gate 	case 'i':			/* initialize */
12457c478bd9Sstevel@tonic-gate 		t_init();
12467c478bd9Sstevel@tonic-gate 		break;
12477c478bd9Sstevel@tonic-gate 
12487c478bd9Sstevel@tonic-gate 	case 'T':			/* device name */
12497c478bd9Sstevel@tonic-gate 		fscanf(fp, "%s", devname);
12507c478bd9Sstevel@tonic-gate 		getdevmap();
12517c478bd9Sstevel@tonic-gate 		strcpy(devname, realdev);
12527c478bd9Sstevel@tonic-gate 		break;
12537c478bd9Sstevel@tonic-gate 
12547c478bd9Sstevel@tonic-gate 	case 't':			/* trailer */
12557c478bd9Sstevel@tonic-gate 		t_trailer();
12567c478bd9Sstevel@tonic-gate 		break;
12577c478bd9Sstevel@tonic-gate 
12587c478bd9Sstevel@tonic-gate 	case 'p':			/* pause -- can restart */
12597c478bd9Sstevel@tonic-gate 		t_reset('p');
12607c478bd9Sstevel@tonic-gate 		break;
12617c478bd9Sstevel@tonic-gate 
12627c478bd9Sstevel@tonic-gate 	case 's':			/* stop */
12637c478bd9Sstevel@tonic-gate 		t_reset('s');
12647c478bd9Sstevel@tonic-gate 		break;
12657c478bd9Sstevel@tonic-gate 
12667c478bd9Sstevel@tonic-gate 	case 'r':			/* resolution assumed when prepared */
12677c478bd9Sstevel@tonic-gate 		fscanf(fp, "%d", &res);
12687c478bd9Sstevel@tonic-gate 		break;
12697c478bd9Sstevel@tonic-gate 
12707c478bd9Sstevel@tonic-gate 	case 'f':			/* load font in a position */
12717c478bd9Sstevel@tonic-gate 		fscanf(fp, "%d %s", &n, str);
12727c478bd9Sstevel@tonic-gate 		fgets(buf, sizeof buf, fp);	/* in case there's a filename */
12737c478bd9Sstevel@tonic-gate 		ungetc('\n', fp);	/* fgets() goes too far */
12747c478bd9Sstevel@tonic-gate 		str1[0] = '\0';		/* in case there's nothing to come in */
12757c478bd9Sstevel@tonic-gate 		sscanf(buf, "%s", str1);
12767c478bd9Sstevel@tonic-gate 		loadfont(n, mapdevfont(str), str1);
12777c478bd9Sstevel@tonic-gate 		break;
12787c478bd9Sstevel@tonic-gate 
12797c478bd9Sstevel@tonic-gate 	/* these don't belong here... */
12807c478bd9Sstevel@tonic-gate 	case 'H':			/* char height */
12817c478bd9Sstevel@tonic-gate 		fscanf(fp, "%d", &n);
12827c478bd9Sstevel@tonic-gate 		t_charht(n);
12837c478bd9Sstevel@tonic-gate 		break;
12847c478bd9Sstevel@tonic-gate 
12857c478bd9Sstevel@tonic-gate 	case 'S':			/* slant */
12867c478bd9Sstevel@tonic-gate 		fscanf(fp, "%d", &n);
12877c478bd9Sstevel@tonic-gate 		t_slant(n);
12887c478bd9Sstevel@tonic-gate 		break;
12897c478bd9Sstevel@tonic-gate 
12907c478bd9Sstevel@tonic-gate 	case 'X':			/* copy through - from troff */
12917c478bd9Sstevel@tonic-gate 		fscanf(fp, " %[^: \n]:", str);
12927c478bd9Sstevel@tonic-gate 		fgets(buf, sizeof(buf), fp);
12937c478bd9Sstevel@tonic-gate 		ungetc('\n', fp);
12947c478bd9Sstevel@tonic-gate 		if ( strcmp(str, "PI") == 0 || strcmp(str, "PictureInclusion") == 0 )
12957c478bd9Sstevel@tonic-gate 		    picture(buf);
12967c478bd9Sstevel@tonic-gate 		else if ( strcmp(str, "InlinePicture") == 0 )
12977c478bd9Sstevel@tonic-gate 		    inlinepic(fp, buf);
12987c478bd9Sstevel@tonic-gate 		else if ( strcmp(str, "BeginPath") == 0 )
12997c478bd9Sstevel@tonic-gate 		    beginpath(buf, FALSE);
13007c478bd9Sstevel@tonic-gate 		else if ( strcmp(str, "DrawPath") == 0 )
13017c478bd9Sstevel@tonic-gate 		    drawpath(buf, FALSE);
13027c478bd9Sstevel@tonic-gate 		else if ( strcmp(str, "BeginObject") == 0 )
13037c478bd9Sstevel@tonic-gate 		    beginpath(buf, TRUE);
13047c478bd9Sstevel@tonic-gate 		else if ( strcmp(str, "EndObject") == 0 )
13057c478bd9Sstevel@tonic-gate 		    drawpath(buf, TRUE);
13067c478bd9Sstevel@tonic-gate 		else if ( strcmp(str, "NewBaseline") == 0 )
13077c478bd9Sstevel@tonic-gate 		    newbaseline(buf);
13087c478bd9Sstevel@tonic-gate 		else if ( strcmp(str, "DrawText") == 0 )
13097c478bd9Sstevel@tonic-gate 		    drawtext(buf);
13107c478bd9Sstevel@tonic-gate 		else if ( strcmp(str, "SetText") == 0 )
13117c478bd9Sstevel@tonic-gate 		    settext(buf);
13127c478bd9Sstevel@tonic-gate 		else if ( strcmp(str, "SetColor") == 0 )  {
13137c478bd9Sstevel@tonic-gate 		    newcolor(buf);
13147c478bd9Sstevel@tonic-gate 		    setcolor();
13157c478bd9Sstevel@tonic-gate 		} else if ( strcmp(str, "PS") == 0 || strcmp(str, "PostScript") == 0 )  {
13167c478bd9Sstevel@tonic-gate 		    endtext();
13177c478bd9Sstevel@tonic-gate 		    /* xymove(hpos, vpos); ul90-22006 */
13187c478bd9Sstevel@tonic-gate 		    fprintf(tf, "%s", buf);
13197c478bd9Sstevel@tonic-gate 		}   /* End else */
13207c478bd9Sstevel@tonic-gate 		break;
13217c478bd9Sstevel@tonic-gate     }	/* End switch */
13227c478bd9Sstevel@tonic-gate 
13237c478bd9Sstevel@tonic-gate     while ( (c = getc(fp)) != '\n'  &&  c != EOF ) ;
13247c478bd9Sstevel@tonic-gate 
13257c478bd9Sstevel@tonic-gate }   /* End of devcntrl */
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate 
13287c478bd9Sstevel@tonic-gate /*****************************************************************************/
13297c478bd9Sstevel@tonic-gate 
13307c478bd9Sstevel@tonic-gate 
1331f928ce67Sceastha static void
fontinit(void)1332f928ce67Sceastha fontinit(void)
13337c478bd9Sstevel@tonic-gate {
13347c478bd9Sstevel@tonic-gate     int		fin;			/* for reading the DESC.out file */
13357c478bd9Sstevel@tonic-gate     char	*filebase;		/* the whole thing goes here */
13367c478bd9Sstevel@tonic-gate     int		i;			/* loop index */
13377c478bd9Sstevel@tonic-gate 
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate /*
13407c478bd9Sstevel@tonic-gate  *
13417c478bd9Sstevel@tonic-gate  * Reads *realdev's DESC.out file and uses what's there to initialize things like
13427c478bd9Sstevel@tonic-gate  * the list of available point sizes. Old versions of the program used *devname's
13437c478bd9Sstevel@tonic-gate  * DESC.out file to initialize nfonts, but that meant we needed to have *devname's
13447c478bd9Sstevel@tonic-gate  * binary font files available for emulation. That restriction has been removed
13457c478bd9Sstevel@tonic-gate  * and we now set nfonts using the "x font" commands in the input file, so by the
13467c478bd9Sstevel@tonic-gate  * time we get here all we really need is *realdev. In fact devcntrl() reads the
13477c478bd9Sstevel@tonic-gate  * device name from the "x T ..." command, but almost immediately replaces it with
13487c478bd9Sstevel@tonic-gate  * string *realdev so we end up using *realdev's DESC.out file. Later on (in
13497c478bd9Sstevel@tonic-gate  * t_font()) we mount all of *realdev's special fonts after the last legitimate
13507c478bd9Sstevel@tonic-gate  * font position, just to be sure device emulation works reasonably well - there's
13517c478bd9Sstevel@tonic-gate  * no guarantee *devname's special fonts match what's needed when *realdev's tables
13527c478bd9Sstevel@tonic-gate  * are used.
1353*48bbca81SDaniel Hoffman  *
13547c478bd9Sstevel@tonic-gate  */
13557c478bd9Sstevel@tonic-gate 
13567c478bd9Sstevel@tonic-gate 
13577c478bd9Sstevel@tonic-gate     sprintf(temp, "%s/dev%s/DESC.out", fontdir, devname);
13587c478bd9Sstevel@tonic-gate     if ( (fin = open(temp, 0)) < 0 )
13597c478bd9Sstevel@tonic-gate 	error(FATAL, "can't open tables for %s", temp);
13607c478bd9Sstevel@tonic-gate 
13617c478bd9Sstevel@tonic-gate     read(fin, &dev, sizeof(struct dev));
13627c478bd9Sstevel@tonic-gate 
13637c478bd9Sstevel@tonic-gate     nfonts = 0;				/* was dev.nfonts - now set in t_fp() */
13647c478bd9Sstevel@tonic-gate     nsizes = dev.nsizes;
13657c478bd9Sstevel@tonic-gate     nchtab = dev.nchtab;
13667c478bd9Sstevel@tonic-gate     unitwidth = dev.unitwidth;
13677c478bd9Sstevel@tonic-gate 
13687c478bd9Sstevel@tonic-gate     if ( (filebase = malloc(dev.filesize)) == NULL )
13697c478bd9Sstevel@tonic-gate 	error(FATAL, "no memory for description file");
13707c478bd9Sstevel@tonic-gate 
13717c478bd9Sstevel@tonic-gate     read(fin, filebase, dev.filesize);	/* all at once */
13727c478bd9Sstevel@tonic-gate     close(fin);
13737c478bd9Sstevel@tonic-gate 
13747c478bd9Sstevel@tonic-gate     pstab = (short *) filebase;
13757c478bd9Sstevel@tonic-gate     chtab = pstab + nsizes + 1;
13767c478bd9Sstevel@tonic-gate     chname = (char *) (chtab + nchtab);
13777c478bd9Sstevel@tonic-gate     fsize = 3 * 255 + nchtab + 128 - 32 + sizeof(struct Font);
13787c478bd9Sstevel@tonic-gate 
13797c478bd9Sstevel@tonic-gate     for ( i = 1; i <= NFONT; i++ )  {	/* so loadfont() knows nothing's there */
13807c478bd9Sstevel@tonic-gate 	fontbase[i] = NULL;
13817c478bd9Sstevel@tonic-gate 	widthtab[i] = codetab[i] = fitab[i] = NULL;
13827c478bd9Sstevel@tonic-gate     }	/* End for */
13837c478bd9Sstevel@tonic-gate 
13847c478bd9Sstevel@tonic-gate     if ( (downloaded = (char *) calloc(nchtab + 128, sizeof(char))) == NULL )
13857c478bd9Sstevel@tonic-gate 	error(FATAL, "no memory");
13867c478bd9Sstevel@tonic-gate 
13877c478bd9Sstevel@tonic-gate }   /* End of fontinit */
13887c478bd9Sstevel@tonic-gate 
13897c478bd9Sstevel@tonic-gate 
13907c478bd9Sstevel@tonic-gate /*****************************************************************************/
13917c478bd9Sstevel@tonic-gate 
13927c478bd9Sstevel@tonic-gate 
1393f928ce67Sceastha static void
loadfont(int n,char * s,char * s1)1394f928ce67Sceastha loadfont(int n, char *s, char *s1)
1395f928ce67Sceastha     /* n - load this font position */
1396f928ce67Sceastha     /* s - with the .out file for this font */
1397f928ce67Sceastha     /* s1 - taken from here - possibly */
13987c478bd9Sstevel@tonic-gate {
13997c478bd9Sstevel@tonic-gate     int		fin;			/* for reading *s.out file */
14007c478bd9Sstevel@tonic-gate     int		nw;			/* number of width table entries */
14017c478bd9Sstevel@tonic-gate 
14027c478bd9Sstevel@tonic-gate 
14037c478bd9Sstevel@tonic-gate /*
14047c478bd9Sstevel@tonic-gate  *
14057c478bd9Sstevel@tonic-gate  * Loads font position n with the binary font file for *s.out provided it's not
14067c478bd9Sstevel@tonic-gate  * already there. If *s1 is NULL or points to the empty string we read files from
14077c478bd9Sstevel@tonic-gate  * directory *fontdir/dev*devname, otherwise directory *s1 is used. If the first
14087c478bd9Sstevel@tonic-gate  * open fails we try to map font *s into one we expect will be available, and then
14097c478bd9Sstevel@tonic-gate  * we try again.
14107c478bd9Sstevel@tonic-gate  *
14117c478bd9Sstevel@tonic-gate  */
14127c478bd9Sstevel@tonic-gate 
14137c478bd9Sstevel@tonic-gate 
14147c478bd9Sstevel@tonic-gate     if ( n < 0  ||  n > NFONT )		/* make sure it's a legal position */
14157c478bd9Sstevel@tonic-gate 	error(FATAL, "illegal fp command %d %s", n, s);
14167c478bd9Sstevel@tonic-gate 
14177c478bd9Sstevel@tonic-gate     if ( fontbase[n] != NULL && strcmp(s, fontbase[n]->namefont) == 0 )
14187c478bd9Sstevel@tonic-gate 	return;
14197c478bd9Sstevel@tonic-gate 
14207c478bd9Sstevel@tonic-gate     if ( s1 == NULL || s1[0] == '\0' )
14217c478bd9Sstevel@tonic-gate 	sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, s);
14227c478bd9Sstevel@tonic-gate     else sprintf(temp, "%s/%s.out", s1, s);
14237c478bd9Sstevel@tonic-gate 
14247c478bd9Sstevel@tonic-gate     if ( (fin = open(temp, 0)) < 0 )  {
14257c478bd9Sstevel@tonic-gate 	sprintf(temp, "%s/dev%s/%s.out", fontdir, devname, mapfont(s));
14267c478bd9Sstevel@tonic-gate 	if ( (fin = open(temp, 0)) < 0 )
14277c478bd9Sstevel@tonic-gate 	    error(FATAL, "can't open font table %s", temp);
14287c478bd9Sstevel@tonic-gate     }	/* End if */
14297c478bd9Sstevel@tonic-gate 
14307c478bd9Sstevel@tonic-gate     if ( fontbase[n] != NULL )		/* something's already there */
14317c478bd9Sstevel@tonic-gate 	free(fontbase[n]);		/* so release the memory first */
14327c478bd9Sstevel@tonic-gate 
14337c478bd9Sstevel@tonic-gate     fontbase[n] = (struct Font *) malloc(fsize);
14347c478bd9Sstevel@tonic-gate     if ( fontbase[n] == NULL )
14357c478bd9Sstevel@tonic-gate 	error(FATAL, "Out of space in loadfont %s", s);
14367c478bd9Sstevel@tonic-gate 
14377c478bd9Sstevel@tonic-gate     read(fin, fontbase[n], fsize);
14387c478bd9Sstevel@tonic-gate     close(fin);
14397c478bd9Sstevel@tonic-gate 
14407c478bd9Sstevel@tonic-gate     if ( smnt == 0 && fontbase[n]->specfont == 1 )
14417c478bd9Sstevel@tonic-gate 	smnt = n;
14427c478bd9Sstevel@tonic-gate 
14437c478bd9Sstevel@tonic-gate     nw = fontbase[n]->nwfont & BMASK;
14447c478bd9Sstevel@tonic-gate     widthtab[n] = (char *) fontbase[n] + sizeof(struct Font);
14457c478bd9Sstevel@tonic-gate     codetab[n] = (char *) widthtab[n] + 2 * nw;
14467c478bd9Sstevel@tonic-gate     fitab[n] = (char *) widthtab[n] + 3 * nw;
14477c478bd9Sstevel@tonic-gate 
14487c478bd9Sstevel@tonic-gate     t_fp(n, fontbase[n]->namefont, fontbase[n]->intname);
14497c478bd9Sstevel@tonic-gate 
14507c478bd9Sstevel@tonic-gate     if ( debug == ON )
14517c478bd9Sstevel@tonic-gate 	fontprint(n);
14527c478bd9Sstevel@tonic-gate 
14537c478bd9Sstevel@tonic-gate }   /* End of loadfont */
14547c478bd9Sstevel@tonic-gate 
14557c478bd9Sstevel@tonic-gate 
14567c478bd9Sstevel@tonic-gate /*****************************************************************************/
14577c478bd9Sstevel@tonic-gate 
14587c478bd9Sstevel@tonic-gate 
1459f928ce67Sceastha static void
loadspecial(void)1460f928ce67Sceastha loadspecial(void)
14617c478bd9Sstevel@tonic-gate {
14627c478bd9Sstevel@tonic-gate     char	*p;			/* for next binary font file */
14637c478bd9Sstevel@tonic-gate     int		nw;			/* width entries in next font */
14647c478bd9Sstevel@tonic-gate     int		i;			/* loop index */
14657c478bd9Sstevel@tonic-gate 
14667c478bd9Sstevel@tonic-gate 
14677c478bd9Sstevel@tonic-gate /*
14687c478bd9Sstevel@tonic-gate  *
14697c478bd9Sstevel@tonic-gate  * Loads all the special fonts after the last legal font position. Mostly used
14707c478bd9Sstevel@tonic-gate  * for device emulation, but we'll do it no matter what. Needed because there's
14717c478bd9Sstevel@tonic-gate  * no consistency in special fonts across different devices, and relying on having
14727c478bd9Sstevel@tonic-gate  * them mounted in the input file doesn't guarantee the whole collection will be
14737c478bd9Sstevel@tonic-gate  * there. The special fonts are determined and mounted using the copy of the
14747c478bd9Sstevel@tonic-gate  * DESC.out file that's been read into memory. Initially had this stuff at the
14757c478bd9Sstevel@tonic-gate  * end of fontinit(), but we now don't know nfonts until much later.
14767c478bd9Sstevel@tonic-gate  *
14777c478bd9Sstevel@tonic-gate  */
14787c478bd9Sstevel@tonic-gate 
14797c478bd9Sstevel@tonic-gate 
14807c478bd9Sstevel@tonic-gate     if ( gotspecial == FALSE )
14817c478bd9Sstevel@tonic-gate 	for ( i = 1, p = chname + dev.lchname; i <= dev.nfonts; i++ )  {
14827c478bd9Sstevel@tonic-gate 	    nw = *p & BMASK;
14837c478bd9Sstevel@tonic-gate 	    if ( ((struct Font *) p)->specfont == 1 )
14847c478bd9Sstevel@tonic-gate 		loadfont(++nfonts, ((struct Font *)p)->namefont, NULL);
14857c478bd9Sstevel@tonic-gate 	    p += 3 * nw + dev.nchtab + 128 - 32 + sizeof(struct Font);
14867c478bd9Sstevel@tonic-gate 	}   /* End for */
14877c478bd9Sstevel@tonic-gate 
14887c478bd9Sstevel@tonic-gate     gotspecial = TRUE;
14897c478bd9Sstevel@tonic-gate 
14907c478bd9Sstevel@tonic-gate }   /* End of loadspecial */
14917c478bd9Sstevel@tonic-gate 
14927c478bd9Sstevel@tonic-gate 
14937c478bd9Sstevel@tonic-gate /*****************************************************************************/
14947c478bd9Sstevel@tonic-gate char *defaultFonts[] =
14957c478bd9Sstevel@tonic-gate 	{ "R", "I", "B", "BI", "CW", "H", "HB", "HX", "S1", "S", NULL };
14967c478bd9Sstevel@tonic-gate 
1497f928ce67Sceastha static void
loaddefault(void)1498f928ce67Sceastha loaddefault(void)
14997c478bd9Sstevel@tonic-gate {
15007c478bd9Sstevel@tonic-gate   int i;
15017c478bd9Sstevel@tonic-gate 
15027c478bd9Sstevel@tonic-gate   for (i = 0; defaultFonts[i] != NULL ; i++)
15037c478bd9Sstevel@tonic-gate     loadfont(++nfonts, defaultFonts[i], NULL);
15047c478bd9Sstevel@tonic-gate }
15057c478bd9Sstevel@tonic-gate 
15067c478bd9Sstevel@tonic-gate 
1507f928ce67Sceastha static void
fontprint(int i)1508f928ce67Sceastha fontprint(int i)
1509f928ce67Sceastha     /* font's index in fontbase[] */
15107c478bd9Sstevel@tonic-gate {
15117c478bd9Sstevel@tonic-gate     int		j, n;
15127c478bd9Sstevel@tonic-gate     char	*p;
15137c478bd9Sstevel@tonic-gate 
15147c478bd9Sstevel@tonic-gate 
15157c478bd9Sstevel@tonic-gate /*
15167c478bd9Sstevel@tonic-gate  *
15177c478bd9Sstevel@tonic-gate  * Debugging routine that dumps data about the font mounted in position i.
15187c478bd9Sstevel@tonic-gate  *
15197c478bd9Sstevel@tonic-gate  */
15207c478bd9Sstevel@tonic-gate 
15217c478bd9Sstevel@tonic-gate 
15227c478bd9Sstevel@tonic-gate     fprintf(tf, "font %d:\n", i);
15237c478bd9Sstevel@tonic-gate 
15247c478bd9Sstevel@tonic-gate     p = (char *) fontbase[i];
15257c478bd9Sstevel@tonic-gate     n = fontbase[i]->nwfont & BMASK;
15267c478bd9Sstevel@tonic-gate 
15277c478bd9Sstevel@tonic-gate     fprintf(tf, "base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",
15287c478bd9Sstevel@tonic-gate 	    p, n, fontbase[i]->specfont, fontbase[i]->namefont, widthtab[i], fitab[i]);
15297c478bd9Sstevel@tonic-gate 
15307c478bd9Sstevel@tonic-gate     fprintf(tf, "widths:\n");
15317c478bd9Sstevel@tonic-gate     for ( j = 0; j <= n; j++ )  {
15327c478bd9Sstevel@tonic-gate 	fprintf(tf, " %2d", widthtab[i][j] & BMASK);
15337c478bd9Sstevel@tonic-gate 	if ( j % 20 == 19 ) putc('\n', tf);
15347c478bd9Sstevel@tonic-gate     }	/* End for */
15357c478bd9Sstevel@tonic-gate 
15367c478bd9Sstevel@tonic-gate     fprintf(tf, "\ncodetab:\n");
15377c478bd9Sstevel@tonic-gate     for ( j = 0; j <= n; j++ )  {
15387c478bd9Sstevel@tonic-gate 	fprintf(tf, " %2d", codetab[i][j] & BMASK);
15397c478bd9Sstevel@tonic-gate 	if ( j % 20 == 19 ) putc('\n', tf);
15407c478bd9Sstevel@tonic-gate     }	/* End for */
15417c478bd9Sstevel@tonic-gate 
15427c478bd9Sstevel@tonic-gate     fprintf(tf, "\nfitab:\n");
15437c478bd9Sstevel@tonic-gate     for ( j = 0; j <= dev.nchtab + 128-32; j++ )  {
15447c478bd9Sstevel@tonic-gate 	fprintf(tf, " %2d", fitab[i][j] & BMASK);
15457c478bd9Sstevel@tonic-gate 	if ( j % 20 == 19 ) putc('\n', tf);
15467c478bd9Sstevel@tonic-gate     }	/* End for */
15477c478bd9Sstevel@tonic-gate 
15487c478bd9Sstevel@tonic-gate     putc('\n', tf);
15497c478bd9Sstevel@tonic-gate 
15507c478bd9Sstevel@tonic-gate }   /* End of fontprint */
15517c478bd9Sstevel@tonic-gate 
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate /*****************************************************************************/
15547c478bd9Sstevel@tonic-gate 
15557c478bd9Sstevel@tonic-gate 
1556f928ce67Sceastha char *
mapfont(char * name)1557f928ce67Sceastha mapfont(char *name)
1558f928ce67Sceastha     /* troff wanted this font */
15597c478bd9Sstevel@tonic-gate {
15607c478bd9Sstevel@tonic-gate     int		i;			/* loop index */
15617c478bd9Sstevel@tonic-gate 
15627c478bd9Sstevel@tonic-gate 
15637c478bd9Sstevel@tonic-gate /*
15647c478bd9Sstevel@tonic-gate  *
15657c478bd9Sstevel@tonic-gate  * If loadfont() can't find font *name we map it into something else that should
15667c478bd9Sstevel@tonic-gate  * be available and return a pointer to the new name. Used mostly for emulating
15677c478bd9Sstevel@tonic-gate  * devices like the APS-5.
15687c478bd9Sstevel@tonic-gate  *
15697c478bd9Sstevel@tonic-gate  */
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate 
15727c478bd9Sstevel@tonic-gate     for ( i = 0; fontmap[i].name != NULL; i++ )
15737c478bd9Sstevel@tonic-gate 	if ( strcmp(name, fontmap[i].name) == 0 )
15747c478bd9Sstevel@tonic-gate 	    return(fontmap[i].use);
15757c478bd9Sstevel@tonic-gate 
15767c478bd9Sstevel@tonic-gate     switch ( *++name )  {
15777c478bd9Sstevel@tonic-gate 	case 'I':
15787c478bd9Sstevel@tonic-gate 		return("I");
15797c478bd9Sstevel@tonic-gate 
15807c478bd9Sstevel@tonic-gate 	case 'B':
15817c478bd9Sstevel@tonic-gate 		return("B");
15827c478bd9Sstevel@tonic-gate 
15837c478bd9Sstevel@tonic-gate 	case 'X':
15847c478bd9Sstevel@tonic-gate 		return("BI");
15857c478bd9Sstevel@tonic-gate 
15867c478bd9Sstevel@tonic-gate 	default:
15877c478bd9Sstevel@tonic-gate 		return("R");
15887c478bd9Sstevel@tonic-gate     }	/* End switch */
15897c478bd9Sstevel@tonic-gate 
15907c478bd9Sstevel@tonic-gate }   /* End of mapfont */
15917c478bd9Sstevel@tonic-gate 
15927c478bd9Sstevel@tonic-gate 
15937c478bd9Sstevel@tonic-gate /*****************************************************************************/
15947c478bd9Sstevel@tonic-gate 
15957c478bd9Sstevel@tonic-gate 
1596f928ce67Sceastha static void
getdevmap(void)1597f928ce67Sceastha getdevmap(void)
15987c478bd9Sstevel@tonic-gate {
15997c478bd9Sstevel@tonic-gate 
16007c478bd9Sstevel@tonic-gate 
16017c478bd9Sstevel@tonic-gate     FILE	*fp;			/* for reading the device fontmap file */
16027c478bd9Sstevel@tonic-gate     int		i = 0;			/* number of mapping pairs we've read */
16037c478bd9Sstevel@tonic-gate     int		c;			/* for skipping lines */
16047c478bd9Sstevel@tonic-gate 
16057c478bd9Sstevel@tonic-gate 
16067c478bd9Sstevel@tonic-gate /*
16077c478bd9Sstevel@tonic-gate  *
16087c478bd9Sstevel@tonic-gate  * Looks for the device font mapping file *fontdir/dev*realdev/fontmaps/devname.
16097c478bd9Sstevel@tonic-gate  * The file, if it exists, should be an ASCII file containing pairs of one or two
16107c478bd9Sstevel@tonic-gate  * character font names per line. The first name is the font troff will be asking
16117c478bd9Sstevel@tonic-gate  * for and the second is the one we'll use. Comments are lines that begin with
16127c478bd9Sstevel@tonic-gate  * a '#' as the first non-white space character on a line. The devfontmap list
16137c478bd9Sstevel@tonic-gate  * ends with a member that has the empty string in the name field.
16147c478bd9Sstevel@tonic-gate  *
16157c478bd9Sstevel@tonic-gate  */
16167c478bd9Sstevel@tonic-gate 
16177c478bd9Sstevel@tonic-gate 
16187c478bd9Sstevel@tonic-gate     sprintf(temp, "%s/dev%s/fontmaps/%s", fontdir, realdev, devname);
16197c478bd9Sstevel@tonic-gate 
16207c478bd9Sstevel@tonic-gate     if ( devfontmap == NULL && (fp = fopen(temp, "r")) != NULL )  {
16217c478bd9Sstevel@tonic-gate 	devfontmap = (Devfontmap *) malloc(10 * sizeof(Devfontmap));
16227c478bd9Sstevel@tonic-gate 
16237c478bd9Sstevel@tonic-gate 	while ( fscanf(fp, "%s", temp) != EOF )  {
16247c478bd9Sstevel@tonic-gate 	    if ( temp[0] != '#' && strlen(temp) < 3 )
16257c478bd9Sstevel@tonic-gate 		if ( fscanf(fp, "%s", &temp[3]) == 1 && strlen(&temp[3]) < 3 )  {
16267c478bd9Sstevel@tonic-gate 		    strcpy((devfontmap + i)->name, temp);
16277c478bd9Sstevel@tonic-gate 		    strcpy((devfontmap + i)->use, &temp[3]);
16287c478bd9Sstevel@tonic-gate 		    if ( ++i % 10 == 0 )
16297c478bd9Sstevel@tonic-gate 			devfontmap = (Devfontmap *) realloc(devfontmap, (i + 10) * sizeof(Devfontmap));
16307c478bd9Sstevel@tonic-gate 		}   /* End if */
16317c478bd9Sstevel@tonic-gate 	    while ( (c = getc(fp)) != '\n' && c != EOF ) ;
16327c478bd9Sstevel@tonic-gate 	}   /* End while */
16337c478bd9Sstevel@tonic-gate 
16347c478bd9Sstevel@tonic-gate 	(devfontmap + i)->name[0] = '\0';	/* end the list we just read */
16357c478bd9Sstevel@tonic-gate 	fclose(fp);
16367c478bd9Sstevel@tonic-gate     }	/* End if */
16377c478bd9Sstevel@tonic-gate 
16387c478bd9Sstevel@tonic-gate }   /* End of getdevmap */
16397c478bd9Sstevel@tonic-gate 
16407c478bd9Sstevel@tonic-gate 
16417c478bd9Sstevel@tonic-gate /*****************************************************************************/
16427c478bd9Sstevel@tonic-gate 
16437c478bd9Sstevel@tonic-gate 
1644f928ce67Sceastha char *
mapdevfont(char * str)1645f928ce67Sceastha mapdevfont(char *str)
16467c478bd9Sstevel@tonic-gate {
16477c478bd9Sstevel@tonic-gate     int		i;
16487c478bd9Sstevel@tonic-gate 
16497c478bd9Sstevel@tonic-gate 
16507c478bd9Sstevel@tonic-gate /*
16517c478bd9Sstevel@tonic-gate  *
16527c478bd9Sstevel@tonic-gate  * Called immediately before loadfont() after an 'x font' command is recognized.
16537c478bd9Sstevel@tonic-gate  * Takes the font name that troff asked for, looks it up in the devfontmap list,
16547c478bd9Sstevel@tonic-gate  * and returns the mapped name to the caller. No mapping is done if the devfontmap
16557c478bd9Sstevel@tonic-gate  * list is empty or font *str isn't found in the list.
16567c478bd9Sstevel@tonic-gate  *
16577c478bd9Sstevel@tonic-gate  */
16587c478bd9Sstevel@tonic-gate 
16597c478bd9Sstevel@tonic-gate 
16607c478bd9Sstevel@tonic-gate     if ( devfontmap != NULL )
16617c478bd9Sstevel@tonic-gate 	for ( i = 0; (devfontmap + i)->name[0] != '\0'; i++ )
16627c478bd9Sstevel@tonic-gate 	    if ( strcmp((devfontmap + i)->name, str) == 0 )
16637c478bd9Sstevel@tonic-gate 		return((devfontmap + i)->use);
16647c478bd9Sstevel@tonic-gate 
16657c478bd9Sstevel@tonic-gate     return(str);
16667c478bd9Sstevel@tonic-gate 
16677c478bd9Sstevel@tonic-gate }   /* End of mapdevfont */
16687c478bd9Sstevel@tonic-gate 
16697c478bd9Sstevel@tonic-gate 
16707c478bd9Sstevel@tonic-gate /*****************************************************************************/
16717c478bd9Sstevel@tonic-gate 
16727c478bd9Sstevel@tonic-gate 
1673f928ce67Sceastha void
reset(void)1674f928ce67Sceastha reset(void)
16757c478bd9Sstevel@tonic-gate {
16767c478bd9Sstevel@tonic-gate 
16777c478bd9Sstevel@tonic-gate /*
16787c478bd9Sstevel@tonic-gate  *
16797c478bd9Sstevel@tonic-gate  * Resets the variables that keep track of the printer's current position, font,
16807c478bd9Sstevel@tonic-gate  * and size. Typically used after a restore/save pair (eg. when we finish with a
16817c478bd9Sstevel@tonic-gate  * page) to make sure we force the printer back into sync (in terms of the font
16827c478bd9Sstevel@tonic-gate  * and current point) before text is printed.
16837c478bd9Sstevel@tonic-gate  *
16847c478bd9Sstevel@tonic-gate  */
16857c478bd9Sstevel@tonic-gate 
16867c478bd9Sstevel@tonic-gate 
16877c478bd9Sstevel@tonic-gate     lastx = -(slop + 1);
16887c478bd9Sstevel@tonic-gate     lasty = -1;
16897c478bd9Sstevel@tonic-gate     lastfont = lastsize = -1;
16907c478bd9Sstevel@tonic-gate 
16917c478bd9Sstevel@tonic-gate }   /* End of reset */
16927c478bd9Sstevel@tonic-gate 
16937c478bd9Sstevel@tonic-gate 
16947c478bd9Sstevel@tonic-gate /*****************************************************************************/
16957c478bd9Sstevel@tonic-gate 
16967c478bd9Sstevel@tonic-gate 
1697f928ce67Sceastha void
resetpos(void)1698f928ce67Sceastha resetpos(void)
16997c478bd9Sstevel@tonic-gate {
17007c478bd9Sstevel@tonic-gate 
17017c478bd9Sstevel@tonic-gate 
17027c478bd9Sstevel@tonic-gate /*
17037c478bd9Sstevel@tonic-gate  *
17047c478bd9Sstevel@tonic-gate  * Resets the variables that keep track of the printer's current position. Used
17057c478bd9Sstevel@tonic-gate  * when there's a chance we've lost track of the printer's current position or
17067c478bd9Sstevel@tonic-gate  * done something that may have wiped it out, and we want to force dpost to set
17077c478bd9Sstevel@tonic-gate  * the printer's position before printing text or whatever. For example stroke or
17087c478bd9Sstevel@tonic-gate  * fill implicitly do a newpath, and that wipes out the current point, unless the
1709*48bbca81SDaniel Hoffman  * calls were bracketed by a gsave/grestore pair.
17107c478bd9Sstevel@tonic-gate  *
17117c478bd9Sstevel@tonic-gate  */
17127c478bd9Sstevel@tonic-gate 
17137c478bd9Sstevel@tonic-gate 
17147c478bd9Sstevel@tonic-gate     lastx = -(slop + 1);
17157c478bd9Sstevel@tonic-gate     lasty = -1;
17167c478bd9Sstevel@tonic-gate 
17177c478bd9Sstevel@tonic-gate }   /* End of resetpos */
17187c478bd9Sstevel@tonic-gate 
17197c478bd9Sstevel@tonic-gate 
17207c478bd9Sstevel@tonic-gate /*****************************************************************************/
17217c478bd9Sstevel@tonic-gate 
17227c478bd9Sstevel@tonic-gate 
1723f928ce67Sceastha static void
t_init(void)1724f928ce67Sceastha t_init(void)
17257c478bd9Sstevel@tonic-gate {
17267c478bd9Sstevel@tonic-gate     static int	initialized = FALSE;	/* only do most things once */
17277c478bd9Sstevel@tonic-gate 
17287c478bd9Sstevel@tonic-gate 
17297c478bd9Sstevel@tonic-gate /*
17307c478bd9Sstevel@tonic-gate  *
17317c478bd9Sstevel@tonic-gate  * Called from devcntrl() after an "x init" command is read. Things only work if
17327c478bd9Sstevel@tonic-gate  * we've already seen the "x res" command, and much of the stuff, including the
17337c478bd9Sstevel@tonic-gate  * call to setup, should only be done once. Restricting everything to one call of
17347c478bd9Sstevel@tonic-gate  * setup (ie. the one in the prologue) means all the input files must have been
17357c478bd9Sstevel@tonic-gate  * formatted for the same device.
17367c478bd9Sstevel@tonic-gate  *
17377c478bd9Sstevel@tonic-gate  */
17387c478bd9Sstevel@tonic-gate 
17397c478bd9Sstevel@tonic-gate 
17407c478bd9Sstevel@tonic-gate     endtext();				/* moved  - for cat'ed troff files */
17417c478bd9Sstevel@tonic-gate 
17427c478bd9Sstevel@tonic-gate     if ( initialized == FALSE )  {	/* only do this stuff once per job */
17437c478bd9Sstevel@tonic-gate 	fontinit();
17447c478bd9Sstevel@tonic-gate 	gotspecial = FALSE;
17457c478bd9Sstevel@tonic-gate 	widthfac = (float) res /dev.res;
17467c478bd9Sstevel@tonic-gate 	slop = pointslop * res / POINTS + .5;
17477c478bd9Sstevel@tonic-gate 	rvslop = res * .025;
17487c478bd9Sstevel@tonic-gate 	setup();
17497c478bd9Sstevel@tonic-gate 	initialized = TRUE;
17507c478bd9Sstevel@tonic-gate     }	/* End if */
17517c478bd9Sstevel@tonic-gate 
17527c478bd9Sstevel@tonic-gate     hpos = vpos = 0;			/* upper left corner */
17537c478bd9Sstevel@tonic-gate     setsize(t_size(10));		/* start somewhere */
17547c478bd9Sstevel@tonic-gate     reset();				/* force position and font stuff - later */
17557c478bd9Sstevel@tonic-gate 
17567c478bd9Sstevel@tonic-gate }   /* End of t_init */
17577c478bd9Sstevel@tonic-gate 
17587c478bd9Sstevel@tonic-gate 
17597c478bd9Sstevel@tonic-gate /*****************************************************************************/
17607c478bd9Sstevel@tonic-gate 
17617c478bd9Sstevel@tonic-gate 
1762f928ce67Sceastha static void
t_page(int pg)1763f928ce67Sceastha t_page(int pg)
1764f928ce67Sceastha     /* troff's current page number */
17657c478bd9Sstevel@tonic-gate {
17667c478bd9Sstevel@tonic-gate     static int	lastpg = 0;		/* last one we started - for ENDPAGE */
17677c478bd9Sstevel@tonic-gate 
17687c478bd9Sstevel@tonic-gate 
17697c478bd9Sstevel@tonic-gate /*
17707c478bd9Sstevel@tonic-gate  *
17717c478bd9Sstevel@tonic-gate  * Called whenever we've finished the last page and want to get ready for the
17727c478bd9Sstevel@tonic-gate  * next one. Also used at the end of each input file, so we have to be careful
17737c478bd9Sstevel@tonic-gate  * about what's done. The first time through (up to the redirect(pg) call) output
17747c478bd9Sstevel@tonic-gate  * goes to /dev/null because of the redirect(-1) call made in conv().
17757c478bd9Sstevel@tonic-gate  *
17767c478bd9Sstevel@tonic-gate  * Adobe now recommends that the showpage operator occur after the page level
17777c478bd9Sstevel@tonic-gate  * restore so it can be easily redefined to have side-effects in the printer's VM.
17787c478bd9Sstevel@tonic-gate  * Although it seems reasonable I haven't implemented it, because it makes other
17797c478bd9Sstevel@tonic-gate  * things, like selectively setting manual feed or choosing an alternate paper
1780*48bbca81SDaniel Hoffman  * tray, clumsy - at least on a per page basis.
17817c478bd9Sstevel@tonic-gate  *
17827c478bd9Sstevel@tonic-gate  */
17837c478bd9Sstevel@tonic-gate 
17847c478bd9Sstevel@tonic-gate 
17857c478bd9Sstevel@tonic-gate     if ( tf == stdout )			/* count the last page */
17867c478bd9Sstevel@tonic-gate 	printed++;
17877c478bd9Sstevel@tonic-gate 
17887c478bd9Sstevel@tonic-gate     endtext();				/* print the last line? */
17897c478bd9Sstevel@tonic-gate 
17907c478bd9Sstevel@tonic-gate     fprintf(tf, "cleartomark\n");
17917c478bd9Sstevel@tonic-gate     fprintf(tf, "showpage\n");
17927c478bd9Sstevel@tonic-gate     fprintf(tf, "restore\n");
17937c478bd9Sstevel@tonic-gate     fprintf(tf, "%s %d %d\n", ENDPAGE, lastpg, printed);
17947c478bd9Sstevel@tonic-gate 
17957c478bd9Sstevel@tonic-gate     redirect(pg);
17967c478bd9Sstevel@tonic-gate 
17977c478bd9Sstevel@tonic-gate     fprintf(tf, "%s %d %d\n", PAGE, pg, printed+1);
17987c478bd9Sstevel@tonic-gate     fprintf(tf, "save\n");
17997c478bd9Sstevel@tonic-gate     fprintf(tf, "mark\n");
18007c478bd9Sstevel@tonic-gate     writerequest(printed+1, tf);
18017c478bd9Sstevel@tonic-gate     fprintf(tf, "%d pagesetup\n", printed+1);
18027c478bd9Sstevel@tonic-gate     setcolor();
18037c478bd9Sstevel@tonic-gate 
18047c478bd9Sstevel@tonic-gate     lastpg = pg;			/* for the next ENDPAGE comment */
18057c478bd9Sstevel@tonic-gate     hpos = vpos = 0;			/* get ready for the next page */
18067c478bd9Sstevel@tonic-gate     reset();				/* force position and font stuff - later */
18077c478bd9Sstevel@tonic-gate 
18087c478bd9Sstevel@tonic-gate     seenpage = TRUE;
18097c478bd9Sstevel@tonic-gate 
18107c478bd9Sstevel@tonic-gate }   /* End of t_page */
18117c478bd9Sstevel@tonic-gate 
18127c478bd9Sstevel@tonic-gate 
18137c478bd9Sstevel@tonic-gate /*****************************************************************************/
18147c478bd9Sstevel@tonic-gate 
18157c478bd9Sstevel@tonic-gate 
1816f928ce67Sceastha static void
t_newline(void)1817f928ce67Sceastha t_newline(void)
18187c478bd9Sstevel@tonic-gate {
18197c478bd9Sstevel@tonic-gate 
18207c478bd9Sstevel@tonic-gate 
18217c478bd9Sstevel@tonic-gate /*
18227c478bd9Sstevel@tonic-gate  *
18237c478bd9Sstevel@tonic-gate  * Just finished the last line. All we do is set the horizontal position to 0,
18247c478bd9Sstevel@tonic-gate  * although even that probably isn't necessary.
18257c478bd9Sstevel@tonic-gate  *
18267c478bd9Sstevel@tonic-gate  */
18277c478bd9Sstevel@tonic-gate 
18287c478bd9Sstevel@tonic-gate 
18297c478bd9Sstevel@tonic-gate     hpos = 0;
18307c478bd9Sstevel@tonic-gate 
18317c478bd9Sstevel@tonic-gate }   /* End of t_newline */
18327c478bd9Sstevel@tonic-gate 
18337c478bd9Sstevel@tonic-gate 
18347c478bd9Sstevel@tonic-gate /*****************************************************************************/
18357c478bd9Sstevel@tonic-gate 
18367c478bd9Sstevel@tonic-gate 
1837f928ce67Sceastha int
t_size(int n)1838f928ce67Sceastha t_size(int n)
1839f928ce67Sceastha     /* convert this to an internal size */
18407c478bd9Sstevel@tonic-gate {
18417c478bd9Sstevel@tonic-gate     int		i;			/* loop index */
18427c478bd9Sstevel@tonic-gate 
18437c478bd9Sstevel@tonic-gate 
18447c478bd9Sstevel@tonic-gate /*
18457c478bd9Sstevel@tonic-gate  *
18467c478bd9Sstevel@tonic-gate  * Converts a point size into an internal size that can be used as an index into
18477c478bd9Sstevel@tonic-gate  * pstab[]. The internal size is one plus the index of the least upper bound of
18487c478bd9Sstevel@tonic-gate  * n in pstab[], or nsizes if n is larger than all the listed sizes.
18497c478bd9Sstevel@tonic-gate  *
18507c478bd9Sstevel@tonic-gate  */
18517c478bd9Sstevel@tonic-gate 
18527c478bd9Sstevel@tonic-gate 
18537c478bd9Sstevel@tonic-gate     if ( n <= pstab[0] )
18547c478bd9Sstevel@tonic-gate 	return(1);
18557c478bd9Sstevel@tonic-gate     else if (n >= pstab[nsizes-1])
18567c478bd9Sstevel@tonic-gate 	return(nsizes);
18577c478bd9Sstevel@tonic-gate 
18587c478bd9Sstevel@tonic-gate     for ( i = 0; n > pstab[i]; i++ ) ;
18597c478bd9Sstevel@tonic-gate 
18607c478bd9Sstevel@tonic-gate     return(i+1);
18617c478bd9Sstevel@tonic-gate 
18627c478bd9Sstevel@tonic-gate }   /* End of t_size */
18637c478bd9Sstevel@tonic-gate 
18647c478bd9Sstevel@tonic-gate 
18657c478bd9Sstevel@tonic-gate /*****************************************************************************/
18667c478bd9Sstevel@tonic-gate 
18677c478bd9Sstevel@tonic-gate 
1868f928ce67Sceastha static void
setsize(int n)1869f928ce67Sceastha setsize(int n)
1870f928ce67Sceastha     /* new internal size */
18717c478bd9Sstevel@tonic-gate {
18727c478bd9Sstevel@tonic-gate 
18737c478bd9Sstevel@tonic-gate 
18747c478bd9Sstevel@tonic-gate /*
18757c478bd9Sstevel@tonic-gate  *
18767c478bd9Sstevel@tonic-gate  * Now using internal size n, where pstab[n-1] is the best available approximation
18777c478bd9Sstevel@tonic-gate  * to the size troff asked for.
18787c478bd9Sstevel@tonic-gate  *
18797c478bd9Sstevel@tonic-gate  */
18807c478bd9Sstevel@tonic-gate 
18817c478bd9Sstevel@tonic-gate 
18827c478bd9Sstevel@tonic-gate     size = n;
18837c478bd9Sstevel@tonic-gate 
18847c478bd9Sstevel@tonic-gate }   /* End of setsize */
18857c478bd9Sstevel@tonic-gate 
18867c478bd9Sstevel@tonic-gate 
18877c478bd9Sstevel@tonic-gate /*****************************************************************************/
18887c478bd9Sstevel@tonic-gate 
18897c478bd9Sstevel@tonic-gate 
1890f928ce67Sceastha static void
t_fp(int n,char * s,char * si)1891f928ce67Sceastha t_fp(int n, char *s, char *si)
1892f928ce67Sceastha     /* n - this position */
1893f928ce67Sceastha     /* s - now has this font mounted */
1894f928ce67Sceastha     /* si - its internal number */
18957c478bd9Sstevel@tonic-gate 
18967c478bd9Sstevel@tonic-gate 
18977c478bd9Sstevel@tonic-gate {
18987c478bd9Sstevel@tonic-gate 
18997c478bd9Sstevel@tonic-gate 
19007c478bd9Sstevel@tonic-gate /*
19017c478bd9Sstevel@tonic-gate  *
19027c478bd9Sstevel@tonic-gate  * Updates nfonts and the array that keeps track of the mounted fonts. Called from
19037c478bd9Sstevel@tonic-gate  * loadfont() after an "x font pos font" command is read, and if pos is larger than
19047c478bd9Sstevel@tonic-gate  * the current value assigned to nfonts we set gotspecial to FALSE to make sure
19057c478bd9Sstevel@tonic-gate  * t_font() loads all the special fonts after the last legitimate font position.
19067c478bd9Sstevel@tonic-gate  *
19077c478bd9Sstevel@tonic-gate  */
19087c478bd9Sstevel@tonic-gate 
19097c478bd9Sstevel@tonic-gate 
19107c478bd9Sstevel@tonic-gate     fontname[n].name = s;
19117c478bd9Sstevel@tonic-gate     fontname[n].number = atoi(si);
19127c478bd9Sstevel@tonic-gate 
19137c478bd9Sstevel@tonic-gate     if ( n == lastfont )		/* force a call to t_sf() */
19147c478bd9Sstevel@tonic-gate 	lastfont = -1;
19157c478bd9Sstevel@tonic-gate 
19167c478bd9Sstevel@tonic-gate     if ( n > nfonts )  {		/* got more positions */
19177c478bd9Sstevel@tonic-gate 	nfonts = n;
19187c478bd9Sstevel@tonic-gate 	gotspecial = FALSE;
19197c478bd9Sstevel@tonic-gate     }	/* End if */
19207c478bd9Sstevel@tonic-gate 
19217c478bd9Sstevel@tonic-gate }   /* End of t_fp */
19227c478bd9Sstevel@tonic-gate 
19237c478bd9Sstevel@tonic-gate 
19247c478bd9Sstevel@tonic-gate /*****************************************************************************/
19257c478bd9Sstevel@tonic-gate 
1926f928ce67Sceastha int
t_font(char * s)1927f928ce67Sceastha t_font(char *s)
1928f928ce67Sceastha     /* use font in this position next */
19297c478bd9Sstevel@tonic-gate {
19307c478bd9Sstevel@tonic-gate     int		n;
19317c478bd9Sstevel@tonic-gate 
19327c478bd9Sstevel@tonic-gate 
19337c478bd9Sstevel@tonic-gate /*
19347c478bd9Sstevel@tonic-gate  *
19357c478bd9Sstevel@tonic-gate  * Converts the string *s into an integer and checks to make sure it's a legal
19367c478bd9Sstevel@tonic-gate  * font position. Also arranges to mount all the special fonts after the last
19377c478bd9Sstevel@tonic-gate  * legitimate font (by calling loadspecial()), provided it hasn't already been
19387c478bd9Sstevel@tonic-gate  * done.
19397c478bd9Sstevel@tonic-gate  *
19407c478bd9Sstevel@tonic-gate  */
19417c478bd9Sstevel@tonic-gate 
19427c478bd9Sstevel@tonic-gate 
19437c478bd9Sstevel@tonic-gate     n = atoi(s);
19447c478bd9Sstevel@tonic-gate 
19457c478bd9Sstevel@tonic-gate     if ( seenpage == TRUE )  {
19467c478bd9Sstevel@tonic-gate 	if ( n < 0  ||  n > nfonts )
19477c478bd9Sstevel@tonic-gate 	    error(FATAL, "illegal font position %d", n);
19487c478bd9Sstevel@tonic-gate 
19497c478bd9Sstevel@tonic-gate 	if ( gotspecial == FALSE )
19507c478bd9Sstevel@tonic-gate 	    loadspecial();
19517c478bd9Sstevel@tonic-gate     }	/* End if */
19527c478bd9Sstevel@tonic-gate 
19537c478bd9Sstevel@tonic-gate     return(n);
19547c478bd9Sstevel@tonic-gate 
19557c478bd9Sstevel@tonic-gate }   /* End of t_font */
19567c478bd9Sstevel@tonic-gate 
19577c478bd9Sstevel@tonic-gate 
19587c478bd9Sstevel@tonic-gate /*****************************************************************************/
19597c478bd9Sstevel@tonic-gate 
19607c478bd9Sstevel@tonic-gate 
1961f928ce67Sceastha static void
setfont(int n)1962f928ce67Sceastha setfont(int n)
1963f928ce67Sceastha     /* use the font mounted here */
19647c478bd9Sstevel@tonic-gate {
19657c478bd9Sstevel@tonic-gate 
19667c478bd9Sstevel@tonic-gate 
19677c478bd9Sstevel@tonic-gate /*
19687c478bd9Sstevel@tonic-gate  *
19697c478bd9Sstevel@tonic-gate  * troff wants to use the font that's been mounted in position n. All we do here
19707c478bd9Sstevel@tonic-gate  * is update the variable that keeps track of the current position. PostScript
19717c478bd9Sstevel@tonic-gate  * font changes are handled in t_sf(), and are only generated right before we're
19727c478bd9Sstevel@tonic-gate  * ready to print or draw something.
19737c478bd9Sstevel@tonic-gate  *
19747c478bd9Sstevel@tonic-gate  */
19757c478bd9Sstevel@tonic-gate 
19767c478bd9Sstevel@tonic-gate 
19777c478bd9Sstevel@tonic-gate     if ( n < 0 || n > NFONT )
19787c478bd9Sstevel@tonic-gate 	error(FATAL, "illegal font %d", n);
19797c478bd9Sstevel@tonic-gate     if ( fontname[n].name == NULL && fontname[n].number == 0)
19807c478bd9Sstevel@tonic-gate 	loaddefault();
19817c478bd9Sstevel@tonic-gate     if ( fontname[n].name == NULL && fontname[n].number == 0)
19827c478bd9Sstevel@tonic-gate 	error(FATAL,
19837c478bd9Sstevel@tonic-gate   "font %d not loaded: check 'dpost' input for 'x font %d XXX' before 'f%d'",
19847c478bd9Sstevel@tonic-gate 		n, n, n);
19857c478bd9Sstevel@tonic-gate 
19867c478bd9Sstevel@tonic-gate     font = n;
19877c478bd9Sstevel@tonic-gate 
19887c478bd9Sstevel@tonic-gate }   /* End of setfont */
19897c478bd9Sstevel@tonic-gate 
19907c478bd9Sstevel@tonic-gate 
19917c478bd9Sstevel@tonic-gate /*****************************************************************************/
19927c478bd9Sstevel@tonic-gate 
1993f928ce67Sceastha void
t_sf(void)1994f928ce67Sceastha t_sf(void)
19957c478bd9Sstevel@tonic-gate {
19967c478bd9Sstevel@tonic-gate     int		fnum;			/* internal font number */
19977c478bd9Sstevel@tonic-gate 
19987c478bd9Sstevel@tonic-gate 
19997c478bd9Sstevel@tonic-gate /*
20007c478bd9Sstevel@tonic-gate  *
20017c478bd9Sstevel@tonic-gate  * Called whenever we need to use a new font or size. Only done right before we
20027c478bd9Sstevel@tonic-gate  * print a character. The seenfonts[] array keeps track of the fonts we've used.
20037c478bd9Sstevel@tonic-gate  * Helps manage host resident fonts and the DOCUMENTFONTS comment that's put out
20047c478bd9Sstevel@tonic-gate  * at the end of the job. The array is indexed by internal number. Only works for
20057c478bd9Sstevel@tonic-gate  * fonts that have internal numbers less than or equal to MAXINTERNAL.
20067c478bd9Sstevel@tonic-gate  *
20077c478bd9Sstevel@tonic-gate  */
20087c478bd9Sstevel@tonic-gate 
20097c478bd9Sstevel@tonic-gate 
20107c478bd9Sstevel@tonic-gate     if ( fontname[font].name == NULL )
20117c478bd9Sstevel@tonic-gate 	return;
20127c478bd9Sstevel@tonic-gate 
20137c478bd9Sstevel@tonic-gate     endtext();
20147c478bd9Sstevel@tonic-gate 
20157c478bd9Sstevel@tonic-gate     if ( (fnum = fontname[font].number) > MAXINTERNAL || fnum < 0 )
20167c478bd9Sstevel@tonic-gate 	fnum = 0;
20177c478bd9Sstevel@tonic-gate 
20187c478bd9Sstevel@tonic-gate     if ( fnum > 0 && seenfonts[fnum] == 0 && hostfontdir != NULL )  {
20197c478bd9Sstevel@tonic-gate 	sprintf(temp, "%s/%s", hostfontdir, fontname[font].name);
20207c478bd9Sstevel@tonic-gate 	if ( access(temp, 04) == 0 )
20217c478bd9Sstevel@tonic-gate 	    doglobal(temp);
20227c478bd9Sstevel@tonic-gate     }	/* End if */
20237c478bd9Sstevel@tonic-gate 
20247c478bd9Sstevel@tonic-gate     if ( tf == stdout )  {
20257c478bd9Sstevel@tonic-gate 	lastfont = font;
20267c478bd9Sstevel@tonic-gate 	lastsize = size;
20277c478bd9Sstevel@tonic-gate 	if ( seenfonts[fnum] == 0 )
20287c478bd9Sstevel@tonic-gate 	    documentfonts();
20297c478bd9Sstevel@tonic-gate 	seenfonts[fnum] = 1;
20307c478bd9Sstevel@tonic-gate     }	/* End if */
20317c478bd9Sstevel@tonic-gate 
20327c478bd9Sstevel@tonic-gate     fprintf(tf, "%d %s f\n", pstab[size-1], fontname[font].name);
20337c478bd9Sstevel@tonic-gate 
20347c478bd9Sstevel@tonic-gate     if ( fontheight != 0 || fontslant != 0 )
20357c478bd9Sstevel@tonic-gate 	fprintf(tf, "%d %d changefont\n", fontslant, (fontheight != 0) ? fontheight : pstab[size-1]);
20367c478bd9Sstevel@tonic-gate 
20377c478bd9Sstevel@tonic-gate }   /* End of t_sf */
20387c478bd9Sstevel@tonic-gate 
20397c478bd9Sstevel@tonic-gate 
20407c478bd9Sstevel@tonic-gate /*****************************************************************************/
20417c478bd9Sstevel@tonic-gate 
20427c478bd9Sstevel@tonic-gate 
2043f928ce67Sceastha static void
t_charht(int n)2044f928ce67Sceastha t_charht(int n)
2045f928ce67Sceastha     /* use this as the character height */
20467c478bd9Sstevel@tonic-gate {
20477c478bd9Sstevel@tonic-gate 
20487c478bd9Sstevel@tonic-gate /*
20497c478bd9Sstevel@tonic-gate  *
20507c478bd9Sstevel@tonic-gate  * Remembers the requested height, from 'x H n'. Forces a call to t_sf(), which
20517c478bd9Sstevel@tonic-gate  * is where the real work is done, by setting lastfont to -1.
20527c478bd9Sstevel@tonic-gate  *
20537c478bd9Sstevel@tonic-gate  */
20547c478bd9Sstevel@tonic-gate 
20557c478bd9Sstevel@tonic-gate     fontheight = (n == pstab[size-1]) ? 0 : n;
20567c478bd9Sstevel@tonic-gate     lastfont = -1;
20577c478bd9Sstevel@tonic-gate 
20587c478bd9Sstevel@tonic-gate }   /* End of t_charht */
20597c478bd9Sstevel@tonic-gate 
20607c478bd9Sstevel@tonic-gate 
20617c478bd9Sstevel@tonic-gate /*****************************************************************************/
20627c478bd9Sstevel@tonic-gate 
20637c478bd9Sstevel@tonic-gate 
2064f928ce67Sceastha static void
t_slant(int n)2065f928ce67Sceastha t_slant(int n)
2066f928ce67Sceastha     /* slant characters this many degrees */
20677c478bd9Sstevel@tonic-gate {
20687c478bd9Sstevel@tonic-gate 
20697c478bd9Sstevel@tonic-gate /*
20707c478bd9Sstevel@tonic-gate  *
20717c478bd9Sstevel@tonic-gate  * Remembers the requested slant, from 'x X n'. Forces a call to t_sf(), which
20727c478bd9Sstevel@tonic-gate  * is where the real work is done, by setting lastfont to -1.
20737c478bd9Sstevel@tonic-gate  *
20747c478bd9Sstevel@tonic-gate  */
20757c478bd9Sstevel@tonic-gate 
20767c478bd9Sstevel@tonic-gate     fontslant = n;
20777c478bd9Sstevel@tonic-gate     lastfont = -1;
20787c478bd9Sstevel@tonic-gate 
20797c478bd9Sstevel@tonic-gate }   /* End of t_slant */
20807c478bd9Sstevel@tonic-gate 
20817c478bd9Sstevel@tonic-gate 
20827c478bd9Sstevel@tonic-gate /*****************************************************************************/
20837c478bd9Sstevel@tonic-gate 
20847c478bd9Sstevel@tonic-gate 
2085f928ce67Sceastha static void
t_reset(int c)2086f928ce67Sceastha t_reset(int c)
2087f928ce67Sceastha     /* pause or restart */
20887c478bd9Sstevel@tonic-gate {
20897c478bd9Sstevel@tonic-gate 
20907c478bd9Sstevel@tonic-gate /*
20917c478bd9Sstevel@tonic-gate  *
20927c478bd9Sstevel@tonic-gate  * Found an "x stop" or "x pause" command. Although nothing's done here we could
20937c478bd9Sstevel@tonic-gate  * add code to reset everything so dpost could handle multiple files formatted for
20947c478bd9Sstevel@tonic-gate  * different devices.
20957c478bd9Sstevel@tonic-gate  *
20967c478bd9Sstevel@tonic-gate  */
20977c478bd9Sstevel@tonic-gate 
20987c478bd9Sstevel@tonic-gate 
20997c478bd9Sstevel@tonic-gate }   /* End of t_reset */
21007c478bd9Sstevel@tonic-gate 
21017c478bd9Sstevel@tonic-gate 
21027c478bd9Sstevel@tonic-gate /*****************************************************************************/
21037c478bd9Sstevel@tonic-gate 
21047c478bd9Sstevel@tonic-gate 
2105f928ce67Sceastha static void
t_trailer(void)2106f928ce67Sceastha t_trailer(void)
21077c478bd9Sstevel@tonic-gate {
21087c478bd9Sstevel@tonic-gate 
21097c478bd9Sstevel@tonic-gate /*
21107c478bd9Sstevel@tonic-gate  *
21117c478bd9Sstevel@tonic-gate  * Called after we find an "x trailer" in the input file. Forcing out the last
21127c478bd9Sstevel@tonic-gate  * page is done at the end of conv(), but probably belongs here.
21137c478bd9Sstevel@tonic-gate  *
21147c478bd9Sstevel@tonic-gate  */
21157c478bd9Sstevel@tonic-gate 
21167c478bd9Sstevel@tonic-gate 
21177c478bd9Sstevel@tonic-gate     endtext();
21187c478bd9Sstevel@tonic-gate 
21197c478bd9Sstevel@tonic-gate }   /* End of t_trailer */
21207c478bd9Sstevel@tonic-gate 
21217c478bd9Sstevel@tonic-gate 
21227c478bd9Sstevel@tonic-gate /*****************************************************************************/
21237c478bd9Sstevel@tonic-gate 
21247c478bd9Sstevel@tonic-gate 
2125f928ce67Sceastha void
hgoto(int n)2126f928ce67Sceastha hgoto(int n)
2127f928ce67Sceastha     /* new horizontal position */
21287c478bd9Sstevel@tonic-gate {
21297c478bd9Sstevel@tonic-gate 
21307c478bd9Sstevel@tonic-gate 
21317c478bd9Sstevel@tonic-gate /*
21327c478bd9Sstevel@tonic-gate  *
21337c478bd9Sstevel@tonic-gate  * Want to be at this absolute horizontal position next. Actual motion commands
21347c478bd9Sstevel@tonic-gate  * are generated in oput(), charlib(), and the drawing routines.
21357c478bd9Sstevel@tonic-gate  *
21367c478bd9Sstevel@tonic-gate  */
21377c478bd9Sstevel@tonic-gate 
21387c478bd9Sstevel@tonic-gate 
21397c478bd9Sstevel@tonic-gate     hpos = n;
21407c478bd9Sstevel@tonic-gate 
21417c478bd9Sstevel@tonic-gate }   /* End of hgoto */
21427c478bd9Sstevel@tonic-gate 
21437c478bd9Sstevel@tonic-gate 
21447c478bd9Sstevel@tonic-gate /*****************************************************************************/
21457c478bd9Sstevel@tonic-gate 
21467c478bd9Sstevel@tonic-gate 
2147f928ce67Sceastha static void
hmot(int n)2148f928ce67Sceastha hmot(int n)
2149f928ce67Sceastha     /* move this far horizontally */
21507c478bd9Sstevel@tonic-gate {
21517c478bd9Sstevel@tonic-gate 
21527c478bd9Sstevel@tonic-gate /*
21537c478bd9Sstevel@tonic-gate  *
21547c478bd9Sstevel@tonic-gate  * Handles relative horizontal motion. troff's current positon, as recorded in
21557c478bd9Sstevel@tonic-gate  * in hpos, is changed by n units. Usually called right before we're supposed to
21567c478bd9Sstevel@tonic-gate  * print a character.
21577c478bd9Sstevel@tonic-gate  *
21587c478bd9Sstevel@tonic-gate  */
21597c478bd9Sstevel@tonic-gate 
21607c478bd9Sstevel@tonic-gate 
21617c478bd9Sstevel@tonic-gate     hpos += n;
21627c478bd9Sstevel@tonic-gate 
21637c478bd9Sstevel@tonic-gate }   /* End of hmot */
21647c478bd9Sstevel@tonic-gate 
21657c478bd9Sstevel@tonic-gate 
21667c478bd9Sstevel@tonic-gate /*****************************************************************************/
21677c478bd9Sstevel@tonic-gate 
21687c478bd9Sstevel@tonic-gate 
2169f928ce67Sceastha void
vgoto(int n)2170f928ce67Sceastha vgoto(int n)
2171f928ce67Sceastha     /* new vertical position */
21727c478bd9Sstevel@tonic-gate {
21737c478bd9Sstevel@tonic-gate 
21747c478bd9Sstevel@tonic-gate /*
21757c478bd9Sstevel@tonic-gate  *
21767c478bd9Sstevel@tonic-gate  * Moves vertically in troff's coordinate system to absolute position n.
21777c478bd9Sstevel@tonic-gate  *
21787c478bd9Sstevel@tonic-gate  */
21797c478bd9Sstevel@tonic-gate 
21807c478bd9Sstevel@tonic-gate 
21817c478bd9Sstevel@tonic-gate     vpos = n;
21827c478bd9Sstevel@tonic-gate 
21837c478bd9Sstevel@tonic-gate }   /* End of vgoto */
21847c478bd9Sstevel@tonic-gate 
21857c478bd9Sstevel@tonic-gate 
21867c478bd9Sstevel@tonic-gate /*****************************************************************************/
21877c478bd9Sstevel@tonic-gate 
21887c478bd9Sstevel@tonic-gate 
2189f928ce67Sceastha static void
vmot(int n)2190f928ce67Sceastha vmot(int n)
2191f928ce67Sceastha     /* move this far vertically */
21927c478bd9Sstevel@tonic-gate {
21937c478bd9Sstevel@tonic-gate 
21947c478bd9Sstevel@tonic-gate /*
21957c478bd9Sstevel@tonic-gate  *
21967c478bd9Sstevel@tonic-gate  * Handles relative vertical motion of n units in troff's coordinate system.
21977c478bd9Sstevel@tonic-gate  *
21987c478bd9Sstevel@tonic-gate  */
21997c478bd9Sstevel@tonic-gate 
22007c478bd9Sstevel@tonic-gate 
22017c478bd9Sstevel@tonic-gate     vpos += n;
22027c478bd9Sstevel@tonic-gate 
22037c478bd9Sstevel@tonic-gate }   /* End of vmot */
22047c478bd9Sstevel@tonic-gate 
22057c478bd9Sstevel@tonic-gate 
22067c478bd9Sstevel@tonic-gate /*****************************************************************************/
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate 
2209f928ce67Sceastha void
xymove(int x,int y)2210f928ce67Sceastha xymove(int x, int y)
2211f928ce67Sceastha     /* this is where we want to be */
22127c478bd9Sstevel@tonic-gate {
22137c478bd9Sstevel@tonic-gate 
22147c478bd9Sstevel@tonic-gate /*
22157c478bd9Sstevel@tonic-gate  *
22167c478bd9Sstevel@tonic-gate  * Makes sure the post-processor and printer agree about the current position.
22177c478bd9Sstevel@tonic-gate  *
22187c478bd9Sstevel@tonic-gate  */
22197c478bd9Sstevel@tonic-gate 
22207c478bd9Sstevel@tonic-gate 
22217c478bd9Sstevel@tonic-gate     hgoto(x);
22227c478bd9Sstevel@tonic-gate     vgoto(y);
22237c478bd9Sstevel@tonic-gate 
22247c478bd9Sstevel@tonic-gate     fprintf(tf, "%d %d m\n", hpos, vpos);
22257c478bd9Sstevel@tonic-gate 
22267c478bd9Sstevel@tonic-gate     lastx = hpos;
22277c478bd9Sstevel@tonic-gate     lasty = vpos;
22287c478bd9Sstevel@tonic-gate 
22297c478bd9Sstevel@tonic-gate }   /* End of xymove */
22307c478bd9Sstevel@tonic-gate 
22317c478bd9Sstevel@tonic-gate 
22327c478bd9Sstevel@tonic-gate /*****************************************************************************/
22337c478bd9Sstevel@tonic-gate 
22347c478bd9Sstevel@tonic-gate 
2235f928ce67Sceastha static void
put1s(char * s)2236f928ce67Sceastha put1s(char *s)
2237f928ce67Sceastha     /* find and print this character */
22387c478bd9Sstevel@tonic-gate {
22397c478bd9Sstevel@tonic-gate     static int		i = 0;		/* last one we found - usually */
22407c478bd9Sstevel@tonic-gate 
22417c478bd9Sstevel@tonic-gate /*
22427c478bd9Sstevel@tonic-gate  *
22437c478bd9Sstevel@tonic-gate  * *s points to the start of a two character string that represents one of troff's
22447c478bd9Sstevel@tonic-gate  * special characters. To print it we first look for *s in the chname[] array using
22457c478bd9Sstevel@tonic-gate  * chtab[i] to find the string representing character i in chname[]. If the lookup
22467c478bd9Sstevel@tonic-gate  * is successful we add 128 to i and ask put1() to finish printing the character.
22477c478bd9Sstevel@tonic-gate  * We remember the index where the last character was found because requests to
22487c478bd9Sstevel@tonic-gate  * print a special character often come in bunches (eg. drawing lines with \(ru).
22497c478bd9Sstevel@tonic-gate  *
22507c478bd9Sstevel@tonic-gate  */
22517c478bd9Sstevel@tonic-gate 
22527c478bd9Sstevel@tonic-gate 
22537c478bd9Sstevel@tonic-gate     if ( strcmp(s, &chname[chtab[i]]) != 0 )
22547c478bd9Sstevel@tonic-gate 	for ( i = 0; i < nchtab; i++ )
22557c478bd9Sstevel@tonic-gate 	    if ( strcmp(&chname[chtab[i]], s) == 0 )
22567c478bd9Sstevel@tonic-gate 		break;
22577c478bd9Sstevel@tonic-gate 
22587c478bd9Sstevel@tonic-gate     if ( i < nchtab )
22597c478bd9Sstevel@tonic-gate 	put1(i + 128);
22607c478bd9Sstevel@tonic-gate     else i = 0;
22617c478bd9Sstevel@tonic-gate 
22627c478bd9Sstevel@tonic-gate }   /* End of put1s */
22637c478bd9Sstevel@tonic-gate 
22647c478bd9Sstevel@tonic-gate 
22657c478bd9Sstevel@tonic-gate /*****************************************************************************/
22667c478bd9Sstevel@tonic-gate 
22677c478bd9Sstevel@tonic-gate 
2268f928ce67Sceastha static void
put1(int c)2269f928ce67Sceastha put1(int c)
2270f928ce67Sceastha     /* want to print this character */
22717c478bd9Sstevel@tonic-gate {
22727c478bd9Sstevel@tonic-gate 
2273f928ce67Sceastha     int			i;		/* character code from fitab */
2274f928ce67Sceastha     int			j;		/* number of fonts we've checked so far */
2275f928ce67Sceastha     int			k;		/* font we're currently looking at */
22767c478bd9Sstevel@tonic-gate     char		*pw;		/* font widthtab and */
22777c478bd9Sstevel@tonic-gate     char		*p;		/* and codetab where c was found */
22787c478bd9Sstevel@tonic-gate     int			code;		/* code used to get c printed */
22797c478bd9Sstevel@tonic-gate     int			ofont;		/* font when we started */
22807c478bd9Sstevel@tonic-gate 
22817c478bd9Sstevel@tonic-gate 
22827c478bd9Sstevel@tonic-gate /*
22837c478bd9Sstevel@tonic-gate  *
22847c478bd9Sstevel@tonic-gate  * Arranges to have character c printed. If c < 128 it's a simple ASCII character,
22857c478bd9Sstevel@tonic-gate  * otherwise it's a special character. Things done here have to agree with the way
22867c478bd9Sstevel@tonic-gate  * the font tables were built by makedev, and work as follows. First we subtract
22877c478bd9Sstevel@tonic-gate  * 32 from c because the tables don't record the non-graphic ASCII characters.
22887c478bd9Sstevel@tonic-gate  * If fitab[k][c] isn't zero the character is on font k and the value is an index
22897c478bd9Sstevel@tonic-gate  * that can be used to recover width and character code data from the other two
22907c478bd9Sstevel@tonic-gate  * tables. If fitab[k][c] is zero the character isn't defined on font k and we
22917c478bd9Sstevel@tonic-gate  * check the next font, which is found as follows. The current font is the first
22927c478bd9Sstevel@tonic-gate  * one we check, and it's followed by a circular search of all the remaining fonts
22937c478bd9Sstevel@tonic-gate  * that starts with the first special font and skips font position 0. If character
22947c478bd9Sstevel@tonic-gate  * c is found somewhere besides the current font we change to that font and use
22957c478bd9Sstevel@tonic-gate  * fitab[k][c] to locate missing data in the other two tables. The width of the
22967c478bd9Sstevel@tonic-gate  * character can be found at widthtab[k][c] while codetab[k][c] is whatever we
22977c478bd9Sstevel@tonic-gate  * need to tell the printer to have character c printed. lastc records the real
22987c478bd9Sstevel@tonic-gate  * name of the character because it's lost by the time oput() gets called but
22997c478bd9Sstevel@tonic-gate  * charlib() may need it.
23007c478bd9Sstevel@tonic-gate  *
23017c478bd9Sstevel@tonic-gate  * Took all the debugging stuff out because at least this part of the program is
23027c478bd9Sstevel@tonic-gate  * reasonably solid.
23037c478bd9Sstevel@tonic-gate  *
23047c478bd9Sstevel@tonic-gate  */
23057c478bd9Sstevel@tonic-gate 
23067c478bd9Sstevel@tonic-gate 
23077c478bd9Sstevel@tonic-gate     lastc = c;				/* charlib() needs the name not the code */
23087c478bd9Sstevel@tonic-gate     if ( (c -= 32) <= 0 )		/* probably never happens */
23097c478bd9Sstevel@tonic-gate 	return;
23107c478bd9Sstevel@tonic-gate 
23117c478bd9Sstevel@tonic-gate     k = ofont = font;
23127c478bd9Sstevel@tonic-gate 
23137c478bd9Sstevel@tonic-gate     if ( (i = fitab[k][c] & BMASK) != 0 )  {	/* it's on this font */
23147c478bd9Sstevel@tonic-gate 	p = codetab[font];
23157c478bd9Sstevel@tonic-gate 	pw = widthtab[font];
23167c478bd9Sstevel@tonic-gate     } else if ( smnt > 0 )  {		/* on special (we hope) */
23177c478bd9Sstevel@tonic-gate 	for ( k=smnt, j=0; j <= nfonts; j++, k = (k+1) % (nfonts+1) )  {
23187c478bd9Sstevel@tonic-gate 	    if ( k == 0 )  continue;
23197c478bd9Sstevel@tonic-gate 	    if ( (i = fitab[k][c] & BMASK) != 0 )  {
23207c478bd9Sstevel@tonic-gate 		p = codetab[k];
23217c478bd9Sstevel@tonic-gate 		pw = widthtab[k];
23227c478bd9Sstevel@tonic-gate 		setfont(k);
23237c478bd9Sstevel@tonic-gate 		break;
23247c478bd9Sstevel@tonic-gate 	    }	/* End if */
23257c478bd9Sstevel@tonic-gate 	}   /* End for */
23267c478bd9Sstevel@tonic-gate     }	/* End else */
23277c478bd9Sstevel@tonic-gate 
23287c478bd9Sstevel@tonic-gate     if ( i != 0 && (code = p[i] & BMASK) != 0 )  {
23297c478bd9Sstevel@tonic-gate 	lastw = widthfac * (((pw[i] & BMASK) * pstab[size-1] + unitwidth/2) / unitwidth);
23307c478bd9Sstevel@tonic-gate 	oput(code);
23317c478bd9Sstevel@tonic-gate     }	/* End if */
23327c478bd9Sstevel@tonic-gate 
23337c478bd9Sstevel@tonic-gate     if ( font != ofont )
23347c478bd9Sstevel@tonic-gate 	setfont(ofont);
23357c478bd9Sstevel@tonic-gate 
23367c478bd9Sstevel@tonic-gate }   /* End of put1 */
23377c478bd9Sstevel@tonic-gate 
23387c478bd9Sstevel@tonic-gate 
23397c478bd9Sstevel@tonic-gate /*****************************************************************************/
23407c478bd9Sstevel@tonic-gate 
23417c478bd9Sstevel@tonic-gate 
2342f928ce67Sceastha static void
oput(int c)2343f928ce67Sceastha oput(int c)
2344f928ce67Sceastha     /* want to print this character */
23457c478bd9Sstevel@tonic-gate {
23467c478bd9Sstevel@tonic-gate 
23477c478bd9Sstevel@tonic-gate /*
23487c478bd9Sstevel@tonic-gate  *
23497c478bd9Sstevel@tonic-gate  * Arranges to print the character whose code is c in the current font. All the
23507c478bd9Sstevel@tonic-gate  * actual positioning is done here, in charlib(), or in the drawing routines.
23517c478bd9Sstevel@tonic-gate  *
23527c478bd9Sstevel@tonic-gate  */
23537c478bd9Sstevel@tonic-gate 
23547c478bd9Sstevel@tonic-gate 
23557c478bd9Sstevel@tonic-gate     if ( textcount > MAXSTACK )		/* don't put too much on the stack? */
23567c478bd9Sstevel@tonic-gate 	endtext();
23577c478bd9Sstevel@tonic-gate 
23587c478bd9Sstevel@tonic-gate     if ( font != lastfont || size != lastsize )
23597c478bd9Sstevel@tonic-gate 	t_sf();
23607c478bd9Sstevel@tonic-gate 
23617c478bd9Sstevel@tonic-gate     if ( vpos != lasty )
23627c478bd9Sstevel@tonic-gate 	endline();
23637c478bd9Sstevel@tonic-gate 
23647c478bd9Sstevel@tonic-gate     starttext();
23657c478bd9Sstevel@tonic-gate 
23667c478bd9Sstevel@tonic-gate     if ( ABS(hpos - lastx) > slop )
23677c478bd9Sstevel@tonic-gate 	endstring();
23687c478bd9Sstevel@tonic-gate 
23697c478bd9Sstevel@tonic-gate     if ( isascii(c) && isprint(c) )
23707c478bd9Sstevel@tonic-gate 	switch ( c )  {
23717c478bd9Sstevel@tonic-gate 	    case '(':
23727c478bd9Sstevel@tonic-gate 	    case ')':
23737c478bd9Sstevel@tonic-gate 	    case '\\':
23747c478bd9Sstevel@tonic-gate 		    addchar('\\');
23757c478bd9Sstevel@tonic-gate 
23767c478bd9Sstevel@tonic-gate 	    default:
23777c478bd9Sstevel@tonic-gate 		    addchar(c);
23787c478bd9Sstevel@tonic-gate 	}   /* End switch */
23797c478bd9Sstevel@tonic-gate     else if ( c > 040 )
23807c478bd9Sstevel@tonic-gate 	addoctal(c);
23817c478bd9Sstevel@tonic-gate     else charlib(c);
23827c478bd9Sstevel@tonic-gate 
23837c478bd9Sstevel@tonic-gate     lastx += lastw;
23847c478bd9Sstevel@tonic-gate 
23857c478bd9Sstevel@tonic-gate }   /* End of oput */
23867c478bd9Sstevel@tonic-gate 
23877c478bd9Sstevel@tonic-gate 
23887c478bd9Sstevel@tonic-gate /*****************************************************************************/
23897c478bd9Sstevel@tonic-gate 
23907c478bd9Sstevel@tonic-gate 
2391f928ce67Sceastha static void
starttext(void)2392f928ce67Sceastha starttext(void)
23937c478bd9Sstevel@tonic-gate {
23947c478bd9Sstevel@tonic-gate 
23957c478bd9Sstevel@tonic-gate /*
23967c478bd9Sstevel@tonic-gate  * Called whenever we want to be sure we're ready to start collecting characters
23977c478bd9Sstevel@tonic-gate  * for the next call to PostScript procedure t (ie. the one that prints them). If
23987c478bd9Sstevel@tonic-gate  * textcount is positive we've already started, so there's nothing to do. The more
23997c478bd9Sstevel@tonic-gate  * complicated encoding schemes save text strings in the strings[] array and need
24007c478bd9Sstevel@tonic-gate  * detailed information about the strings when they're written to the output file
24017c478bd9Sstevel@tonic-gate  * in endtext().
24027c478bd9Sstevel@tonic-gate  *
24037c478bd9Sstevel@tonic-gate  */
24047c478bd9Sstevel@tonic-gate 
24057c478bd9Sstevel@tonic-gate 
24067c478bd9Sstevel@tonic-gate     if ( textcount < 1 )  {
24077c478bd9Sstevel@tonic-gate 	switch ( encoding )  {
24087c478bd9Sstevel@tonic-gate 	    case 0:
24097c478bd9Sstevel@tonic-gate 	    case 1:
24107c478bd9Sstevel@tonic-gate 		putc('(', tf);
24117c478bd9Sstevel@tonic-gate 		break;
24127c478bd9Sstevel@tonic-gate 
24137c478bd9Sstevel@tonic-gate 	    case 2:
24147c478bd9Sstevel@tonic-gate 	    case 3:
24157c478bd9Sstevel@tonic-gate 		strptr = strings;
24167c478bd9Sstevel@tonic-gate 		spacecount = 0;
24177c478bd9Sstevel@tonic-gate 		line[1].str = strptr;
24187c478bd9Sstevel@tonic-gate 		line[1].dx = 0;
24197c478bd9Sstevel@tonic-gate 		line[1].spaces = 0;
24207c478bd9Sstevel@tonic-gate 		line[1].start = hpos;
24217c478bd9Sstevel@tonic-gate 		line[1].width = 0;
24227c478bd9Sstevel@tonic-gate 		break;
24237c478bd9Sstevel@tonic-gate 
24247c478bd9Sstevel@tonic-gate 	    case MAXENCODING+1:			/* reverse video */
24257c478bd9Sstevel@tonic-gate 		if ( lastend == -1 )
24267c478bd9Sstevel@tonic-gate 		    lastend = hpos;
24277c478bd9Sstevel@tonic-gate 		putc('(', tf);
24287c478bd9Sstevel@tonic-gate 		break;
24297c478bd9Sstevel@tonic-gate 
24307c478bd9Sstevel@tonic-gate 	    case MAXENCODING+2:			/* follow a funny baseline */
24317c478bd9Sstevel@tonic-gate 		putc('(', tf);
24327c478bd9Sstevel@tonic-gate 		break;
24337c478bd9Sstevel@tonic-gate 	}   /* End switch */
24347c478bd9Sstevel@tonic-gate 	textcount = 1;
24357c478bd9Sstevel@tonic-gate 	lastx = stringstart = hpos;
24367c478bd9Sstevel@tonic-gate     }	/* End if */
24377c478bd9Sstevel@tonic-gate 
24387c478bd9Sstevel@tonic-gate }   /* End of starttext */
24397c478bd9Sstevel@tonic-gate 
24407c478bd9Sstevel@tonic-gate 
24417c478bd9Sstevel@tonic-gate /*****************************************************************************/
24427c478bd9Sstevel@tonic-gate 
24437c478bd9Sstevel@tonic-gate 
2444f928ce67Sceastha void
endtext(void)2445f928ce67Sceastha endtext(void)
24467c478bd9Sstevel@tonic-gate {
24477c478bd9Sstevel@tonic-gate 
24487c478bd9Sstevel@tonic-gate     int		i;			/* loop index */
24497c478bd9Sstevel@tonic-gate 
24507c478bd9Sstevel@tonic-gate 
24517c478bd9Sstevel@tonic-gate /*
24527c478bd9Sstevel@tonic-gate  *
24537c478bd9Sstevel@tonic-gate  * Generates a call to the PostScript procedure that processes all the text we've
24547c478bd9Sstevel@tonic-gate  * accumulated - provided textcount is positive.
24557c478bd9Sstevel@tonic-gate  *
24567c478bd9Sstevel@tonic-gate  */
24577c478bd9Sstevel@tonic-gate 
24587c478bd9Sstevel@tonic-gate     if ( textcount > 0 )  {		/* started working on some text */
24597c478bd9Sstevel@tonic-gate 	switch ( encoding )  {
24607c478bd9Sstevel@tonic-gate 	    case 0:
24617c478bd9Sstevel@tonic-gate 		fprintf(tf, ")%d t\n", stringstart);
24627c478bd9Sstevel@tonic-gate 		break;
24637c478bd9Sstevel@tonic-gate 
24647c478bd9Sstevel@tonic-gate 	    case 1:
24657c478bd9Sstevel@tonic-gate 		fprintf(tf, ")%d %d t\n", stringstart, lasty);
24667c478bd9Sstevel@tonic-gate 		break;
24677c478bd9Sstevel@tonic-gate 
24687c478bd9Sstevel@tonic-gate 	    case 2:
24697c478bd9Sstevel@tonic-gate 		*strptr = '\0';
24707c478bd9Sstevel@tonic-gate 		line[textcount].width = lastx - line[textcount].start;
24717c478bd9Sstevel@tonic-gate 		if ( spacecount != 0 || textcount != 1 )  {
24727c478bd9Sstevel@tonic-gate 		    for ( i = textcount; i > 0; i-- )
24737c478bd9Sstevel@tonic-gate 			fprintf(tf, "(%s)%d %d", line[i].str, line[i].spaces, line[i].width);
24747c478bd9Sstevel@tonic-gate 		    fprintf(tf, " %d %d %d t\n", textcount, stringstart, lasty);
24757c478bd9Sstevel@tonic-gate 		} else fprintf(tf, "(%s)%d %d w\n", line[1].str, stringstart, lasty);
24767c478bd9Sstevel@tonic-gate 		break;
24777c478bd9Sstevel@tonic-gate 
24787c478bd9Sstevel@tonic-gate 	    case 3:
24797c478bd9Sstevel@tonic-gate 		*strptr = '\0';
24807c478bd9Sstevel@tonic-gate 		if ( spacecount != 0 || textcount != 1 )  {
24817c478bd9Sstevel@tonic-gate 		    for ( i = textcount; i > 0; i-- )
24827c478bd9Sstevel@tonic-gate 			fprintf(tf, "(%s)%d", line[i].str, line[i].dx);
24837c478bd9Sstevel@tonic-gate 		    fprintf(tf, " %d %d %d t\n", textcount, stringstart, lasty);
24847c478bd9Sstevel@tonic-gate 		} else fprintf(tf, "(%s)%d %d w\n", line[1].str, stringstart, lasty);
24857c478bd9Sstevel@tonic-gate 		break;
24867c478bd9Sstevel@tonic-gate 
24877c478bd9Sstevel@tonic-gate 	    case MAXENCODING+1:
24887c478bd9Sstevel@tonic-gate 		fprintf(tf, ")%d ", stringstart);
24897c478bd9Sstevel@tonic-gate 		fprintf(tf, "%d %d drawrvbox ", lastend - rvslop, (int)(lastx + .5) + rvslop);
24907c478bd9Sstevel@tonic-gate 		fprintf(tf, "t\n", stringstart);
24917c478bd9Sstevel@tonic-gate 		lastend = (lastx + .5) + 2 * rvslop;
24927c478bd9Sstevel@tonic-gate 		break;
24937c478bd9Sstevel@tonic-gate 
24947c478bd9Sstevel@tonic-gate 	    case MAXENCODING+2:
24957c478bd9Sstevel@tonic-gate 		fprintf(tf, ")%d %d t\n", stringstart, lasty);
24967c478bd9Sstevel@tonic-gate 		break;
24977c478bd9Sstevel@tonic-gate 	}   /* End switch */
24987c478bd9Sstevel@tonic-gate     }	/* End if */
24997c478bd9Sstevel@tonic-gate 
25007c478bd9Sstevel@tonic-gate     textcount = 0;
25017c478bd9Sstevel@tonic-gate 
25027c478bd9Sstevel@tonic-gate }   /* End of endtext */
25037c478bd9Sstevel@tonic-gate 
25047c478bd9Sstevel@tonic-gate 
25057c478bd9Sstevel@tonic-gate /*****************************************************************************/
25067c478bd9Sstevel@tonic-gate 
25077c478bd9Sstevel@tonic-gate 
2508f928ce67Sceastha static void
endstring(void)2509f928ce67Sceastha endstring(void)
25107c478bd9Sstevel@tonic-gate {
25117c478bd9Sstevel@tonic-gate     int		dx;
25127c478bd9Sstevel@tonic-gate 
25137c478bd9Sstevel@tonic-gate /*
25147c478bd9Sstevel@tonic-gate  *
25157c478bd9Sstevel@tonic-gate  * Horizontal positions are out of sync. End the last open string, adjust the
25167c478bd9Sstevel@tonic-gate  * printer's position, and start a new string. Assumes we've already started
25177c478bd9Sstevel@tonic-gate  * accumulating text.
25187c478bd9Sstevel@tonic-gate  *
25197c478bd9Sstevel@tonic-gate  */
25207c478bd9Sstevel@tonic-gate 
25217c478bd9Sstevel@tonic-gate 
25227c478bd9Sstevel@tonic-gate     switch ( encoding )  {
25237c478bd9Sstevel@tonic-gate 	case 0:
25247c478bd9Sstevel@tonic-gate 	case 1:
25257c478bd9Sstevel@tonic-gate 	    fprintf(tf, ")%d(", stringstart);
25267c478bd9Sstevel@tonic-gate 	    textcount++;
25277c478bd9Sstevel@tonic-gate 	    lastx = stringstart = hpos;
25287c478bd9Sstevel@tonic-gate 	    break;
25297c478bd9Sstevel@tonic-gate 
25307c478bd9Sstevel@tonic-gate 	case 2:
25317c478bd9Sstevel@tonic-gate 	case 3:
25327c478bd9Sstevel@tonic-gate 	    dx = hpos - lastx;
25337c478bd9Sstevel@tonic-gate 	    if ( spacecount++ == 0 )
25347c478bd9Sstevel@tonic-gate 		line[textcount].dx = dx;
25357c478bd9Sstevel@tonic-gate 	    if ( line[textcount].dx != dx )  {
25367c478bd9Sstevel@tonic-gate 		*strptr++ = '\0';
25377c478bd9Sstevel@tonic-gate 		line[textcount].width = lastx - line[textcount].start;
25387c478bd9Sstevel@tonic-gate 		line[++textcount].str = strptr;
25397c478bd9Sstevel@tonic-gate 		*strptr++ = ' ';
25407c478bd9Sstevel@tonic-gate 		line[textcount].dx = dx;
25417c478bd9Sstevel@tonic-gate 		line[textcount].start = lastx;
25427c478bd9Sstevel@tonic-gate 		line[textcount].width = 0;
25437c478bd9Sstevel@tonic-gate 		line[textcount].spaces = 1;
25447c478bd9Sstevel@tonic-gate 	    } else {
25457c478bd9Sstevel@tonic-gate 		*strptr++ = ' ';
25467c478bd9Sstevel@tonic-gate 		line[textcount].spaces++;
25477c478bd9Sstevel@tonic-gate 	    }	/* End else */
25487c478bd9Sstevel@tonic-gate 	    lastx += dx;
25497c478bd9Sstevel@tonic-gate 	    break;
25507c478bd9Sstevel@tonic-gate 
25517c478bd9Sstevel@tonic-gate 	case MAXENCODING+1:
25527c478bd9Sstevel@tonic-gate 	    fprintf(tf, ")%d(", stringstart);
25537c478bd9Sstevel@tonic-gate 	    textcount++;
25547c478bd9Sstevel@tonic-gate 	    lastx = stringstart = hpos;
25557c478bd9Sstevel@tonic-gate 	    break;
25567c478bd9Sstevel@tonic-gate 
25577c478bd9Sstevel@tonic-gate 	case MAXENCODING+2:
25587c478bd9Sstevel@tonic-gate 	    endtext();
25597c478bd9Sstevel@tonic-gate 	    starttext();
25607c478bd9Sstevel@tonic-gate 	    break;
25617c478bd9Sstevel@tonic-gate 
25627c478bd9Sstevel@tonic-gate     }	/* End switch */
25637c478bd9Sstevel@tonic-gate 
25647c478bd9Sstevel@tonic-gate }   /* End of endstring */
25657c478bd9Sstevel@tonic-gate 
25667c478bd9Sstevel@tonic-gate 
25677c478bd9Sstevel@tonic-gate /*****************************************************************************/
25687c478bd9Sstevel@tonic-gate 
25697c478bd9Sstevel@tonic-gate 
2570f928ce67Sceastha static void
endline(void)2571f928ce67Sceastha endline(void)
25727c478bd9Sstevel@tonic-gate {
25737c478bd9Sstevel@tonic-gate 
25747c478bd9Sstevel@tonic-gate /*
25757c478bd9Sstevel@tonic-gate  *
25767c478bd9Sstevel@tonic-gate  * The vertical position has changed. Dump any accumulated text, then adjust
25777c478bd9Sstevel@tonic-gate  * the printer's vertical position.
25787c478bd9Sstevel@tonic-gate  *
25797c478bd9Sstevel@tonic-gate  */
25807c478bd9Sstevel@tonic-gate 
25817c478bd9Sstevel@tonic-gate 
25827c478bd9Sstevel@tonic-gate     endtext();
25837c478bd9Sstevel@tonic-gate 
25847c478bd9Sstevel@tonic-gate     if ( encoding == 0 || encoding == MAXENCODING+1 )
25857c478bd9Sstevel@tonic-gate 	fprintf(tf, "%d %d m\n", hpos, vpos);
25867c478bd9Sstevel@tonic-gate 
25877c478bd9Sstevel@tonic-gate     lastx = stringstart = lastend = hpos;
25887c478bd9Sstevel@tonic-gate     lasty = vpos;
25897c478bd9Sstevel@tonic-gate 
25907c478bd9Sstevel@tonic-gate }   /* End of endline */
25917c478bd9Sstevel@tonic-gate 
25927c478bd9Sstevel@tonic-gate 
25937c478bd9Sstevel@tonic-gate /*****************************************************************************/
25947c478bd9Sstevel@tonic-gate 
25957c478bd9Sstevel@tonic-gate 
2596f928ce67Sceastha static void
addchar(int c)2597f928ce67Sceastha addchar(int c)
2598f928ce67Sceastha     /* next character in current string */
25997c478bd9Sstevel@tonic-gate {
26007c478bd9Sstevel@tonic-gate 
26017c478bd9Sstevel@tonic-gate /*
26027c478bd9Sstevel@tonic-gate  *
26037c478bd9Sstevel@tonic-gate  * Does whatever is needed to add character c to the current string.
26047c478bd9Sstevel@tonic-gate  *
26057c478bd9Sstevel@tonic-gate  */
26067c478bd9Sstevel@tonic-gate 
26077c478bd9Sstevel@tonic-gate 
26087c478bd9Sstevel@tonic-gate     switch ( encoding )  {
26097c478bd9Sstevel@tonic-gate 	case 0:
26107c478bd9Sstevel@tonic-gate 	case 1:
26117c478bd9Sstevel@tonic-gate 	    putc(c, tf);
26127c478bd9Sstevel@tonic-gate 	    break;
26137c478bd9Sstevel@tonic-gate 
26147c478bd9Sstevel@tonic-gate 	case 2:
26157c478bd9Sstevel@tonic-gate 	case 3:
26167c478bd9Sstevel@tonic-gate 	    *strptr++ = c;
26177c478bd9Sstevel@tonic-gate 	    break;
26187c478bd9Sstevel@tonic-gate 
26197c478bd9Sstevel@tonic-gate 	case MAXENCODING+1:
26207c478bd9Sstevel@tonic-gate 	case MAXENCODING+2:
26217c478bd9Sstevel@tonic-gate 	    putc(c, tf);
26227c478bd9Sstevel@tonic-gate 	    break;
26237c478bd9Sstevel@tonic-gate     }	/* End switch */
26247c478bd9Sstevel@tonic-gate 
26257c478bd9Sstevel@tonic-gate }   /* End of addchar */
26267c478bd9Sstevel@tonic-gate 
26277c478bd9Sstevel@tonic-gate 
26287c478bd9Sstevel@tonic-gate /*****************************************************************************/
26297c478bd9Sstevel@tonic-gate 
26307c478bd9Sstevel@tonic-gate 
2631f928ce67Sceastha static void
addoctal(int c)2632f928ce67Sceastha addoctal(int c)
2633f928ce67Sceastha     /* add it as an octal escape */
26347c478bd9Sstevel@tonic-gate {
26357c478bd9Sstevel@tonic-gate 
26367c478bd9Sstevel@tonic-gate 
26377c478bd9Sstevel@tonic-gate /*
26387c478bd9Sstevel@tonic-gate  *
26397c478bd9Sstevel@tonic-gate  * Adds c to the current string as an octal escape \ddd.
26407c478bd9Sstevel@tonic-gate  *
26417c478bd9Sstevel@tonic-gate  */
26427c478bd9Sstevel@tonic-gate 
26437c478bd9Sstevel@tonic-gate 
26447c478bd9Sstevel@tonic-gate     switch ( encoding )  {
26457c478bd9Sstevel@tonic-gate 	case 0:
26467c478bd9Sstevel@tonic-gate 	case 1:
26477c478bd9Sstevel@tonic-gate 	    fprintf(tf, "\\%o", c);
26487c478bd9Sstevel@tonic-gate 	    break;
26497c478bd9Sstevel@tonic-gate 
26507c478bd9Sstevel@tonic-gate 	case 2:
26517c478bd9Sstevel@tonic-gate 	case 3:
26527c478bd9Sstevel@tonic-gate 	    sprintf(strptr, "\\%o", c);
26537c478bd9Sstevel@tonic-gate 	    strptr += strlen(strptr);
26547c478bd9Sstevel@tonic-gate 	    break;
26557c478bd9Sstevel@tonic-gate 
26567c478bd9Sstevel@tonic-gate 	case MAXENCODING+1:
26577c478bd9Sstevel@tonic-gate 	case MAXENCODING+2:
26587c478bd9Sstevel@tonic-gate 	    fprintf(tf, "\\%o", c);
26597c478bd9Sstevel@tonic-gate 	    break;
26607c478bd9Sstevel@tonic-gate     }	/* End switch */
26617c478bd9Sstevel@tonic-gate 
26627c478bd9Sstevel@tonic-gate }   /* End of addoctal */
26637c478bd9Sstevel@tonic-gate 
26647c478bd9Sstevel@tonic-gate 
26657c478bd9Sstevel@tonic-gate /*****************************************************************************/
26667c478bd9Sstevel@tonic-gate 
26677c478bd9Sstevel@tonic-gate 
2668f928ce67Sceastha static void
charlib(int code)2669f928ce67Sceastha charlib(int code)
2670f928ce67Sceastha     /* either 1 or 2 */
26717c478bd9Sstevel@tonic-gate {
26727c478bd9Sstevel@tonic-gate     char	*name;			/* name of the character */
26737c478bd9Sstevel@tonic-gate     char	tname[10];		/* in case it's a single ASCII character */
26747c478bd9Sstevel@tonic-gate 
26757c478bd9Sstevel@tonic-gate 
26767c478bd9Sstevel@tonic-gate /*
26777c478bd9Sstevel@tonic-gate  *
26787c478bd9Sstevel@tonic-gate  * Called from oput() for characters having codes less than 040. Special files
26797c478bd9Sstevel@tonic-gate  * that define PostScript procedures for certain characters can be found in
26807c478bd9Sstevel@tonic-gate  * directory *fontdir/devpost/charlib. If there's a file that has the same name as
26817c478bd9Sstevel@tonic-gate  * the character we're trying to print it's copied to the output file, otherwise
26827c478bd9Sstevel@tonic-gate  * nothing, except some positioning, is done.
26837c478bd9Sstevel@tonic-gate  *
26847c478bd9Sstevel@tonic-gate  * All character definitions are only made once. Subsequent requests to print the
26857c478bd9Sstevel@tonic-gate  * character generate a call to a procedure that begins with the prefix build_ and
26867c478bd9Sstevel@tonic-gate  * ends with the character's name. Special characters that are assigned codes
26877c478bd9Sstevel@tonic-gate  * other than 1 are assumed to have additional data files that should be copied
26887c478bd9Sstevel@tonic-gate  * to the output file immediately after the build_ call. Those data files should
26897c478bd9Sstevel@tonic-gate  * end in the suffix .map, and usually will be a hex representation of a bitmap.
26907c478bd9Sstevel@tonic-gate  *
26917c478bd9Sstevel@tonic-gate  */
26927c478bd9Sstevel@tonic-gate 
26937c478bd9Sstevel@tonic-gate 
26947c478bd9Sstevel@tonic-gate     endtext();
26957c478bd9Sstevel@tonic-gate 
26967c478bd9Sstevel@tonic-gate     if ( lastc < 128 )  {		/* just a simple ASCII character */
26977c478bd9Sstevel@tonic-gate 	sprintf(tname, "%.3o", lastc);
26987c478bd9Sstevel@tonic-gate 	name = tname;
26997c478bd9Sstevel@tonic-gate     } else name = &chname[chtab[lastc - 128]];
27007c478bd9Sstevel@tonic-gate 
27017c478bd9Sstevel@tonic-gate     if ( downloaded[lastc] == 0 )  {
27027c478bd9Sstevel@tonic-gate 	sprintf(temp, "%s/dev%s/charlib/%s", fontdir, realdev, name);
27037c478bd9Sstevel@tonic-gate 	if ( access(temp, 04) == 0 && doglobal(temp) == TRUE )  {
27047c478bd9Sstevel@tonic-gate 	    downloaded[lastc] = 1;
27057c478bd9Sstevel@tonic-gate 	    t_sf();
27067c478bd9Sstevel@tonic-gate 	}   /* End if */
27077c478bd9Sstevel@tonic-gate     }	/* End if */
27087c478bd9Sstevel@tonic-gate 
27097c478bd9Sstevel@tonic-gate     if ( downloaded[lastc] == 1 )  {
27107c478bd9Sstevel@tonic-gate 	xymove(hpos, vpos);
27117c478bd9Sstevel@tonic-gate 	fprintf(tf, "%d build_%s\n", (int) lastw, name);
27127c478bd9Sstevel@tonic-gate 	if ( code != 1 )  {		/* get the bitmap or whatever */
27137c478bd9Sstevel@tonic-gate 	    sprintf(temp, "%s/dev%s/charlib/%s.map", fontdir, realdev, name);
27147c478bd9Sstevel@tonic-gate 	    if ( access(temp, 04) == 0 && tf == stdout )
27157c478bd9Sstevel@tonic-gate 		cat(temp);
27167c478bd9Sstevel@tonic-gate 	}   /* End if */
27177c478bd9Sstevel@tonic-gate 	fprintf(tf, "%d %d m\n", stringstart = hpos + lastw, vpos);
27187c478bd9Sstevel@tonic-gate     }	/* End if */
27197c478bd9Sstevel@tonic-gate 
27207c478bd9Sstevel@tonic-gate }   /* End of charlib */
27217c478bd9Sstevel@tonic-gate 
27227c478bd9Sstevel@tonic-gate 
27237c478bd9Sstevel@tonic-gate /*****************************************************************************/
27247c478bd9Sstevel@tonic-gate 
27257c478bd9Sstevel@tonic-gate 
2726f928ce67Sceastha int
doglobal(char * name)2727f928ce67Sceastha doglobal(char *name)
2728f928ce67Sceastha     /* copy this to the output - globally */
27297c478bd9Sstevel@tonic-gate {
27307c478bd9Sstevel@tonic-gate     int		val = FALSE;		/* returned to the caller */
27317c478bd9Sstevel@tonic-gate 
27327c478bd9Sstevel@tonic-gate 
27337c478bd9Sstevel@tonic-gate /*
27347c478bd9Sstevel@tonic-gate  *
27357c478bd9Sstevel@tonic-gate  * Copies file *name to the output file and brackets it with whatever commands are
27367c478bd9Sstevel@tonic-gate  * needed to have it exported to the global environment. TRUE is returned if we
27377c478bd9Sstevel@tonic-gate  * successfully add file *name to the output file.
27387c478bd9Sstevel@tonic-gate  *
27397c478bd9Sstevel@tonic-gate  */
27407c478bd9Sstevel@tonic-gate 
27417c478bd9Sstevel@tonic-gate 
27427c478bd9Sstevel@tonic-gate     if ( tf == stdout )  {
27437c478bd9Sstevel@tonic-gate 	endtext();
27447c478bd9Sstevel@tonic-gate 	fprintf(tf, "cleartomark restore\n");
27457c478bd9Sstevel@tonic-gate 	fprintf(tf, "%s", BEGINGLOBAL);
27467c478bd9Sstevel@tonic-gate 	val = cat(name);
27477c478bd9Sstevel@tonic-gate 	fprintf(tf, "%s", ENDGLOBAL);
27487c478bd9Sstevel@tonic-gate 	fprintf(tf, "save mark\n");
27497c478bd9Sstevel@tonic-gate 	reset();
27507c478bd9Sstevel@tonic-gate     }	/* End if */
27517c478bd9Sstevel@tonic-gate 
27527c478bd9Sstevel@tonic-gate     return(val);
27537c478bd9Sstevel@tonic-gate 
27547c478bd9Sstevel@tonic-gate }   /* End of doglobal */
27557c478bd9Sstevel@tonic-gate 
27567c478bd9Sstevel@tonic-gate 
27577c478bd9Sstevel@tonic-gate /*****************************************************************************/
27587c478bd9Sstevel@tonic-gate 
27597c478bd9Sstevel@tonic-gate 
2760f928ce67Sceastha static void
documentfonts(void)2761f928ce67Sceastha documentfonts(void)
27627c478bd9Sstevel@tonic-gate {
27637c478bd9Sstevel@tonic-gate     FILE	*fp_in;			/* PostScript font name read from here */
27647c478bd9Sstevel@tonic-gate     FILE	*fp_out;		/* and added to this file */
27657c478bd9Sstevel@tonic-gate 
27667c478bd9Sstevel@tonic-gate 
27677c478bd9Sstevel@tonic-gate /*
27687c478bd9Sstevel@tonic-gate  *
27697c478bd9Sstevel@tonic-gate  * Whenever a new font is used we try to record the appropriate PostScript font
27707c478bd9Sstevel@tonic-gate  * name in *temp_file for the DOCUMENTFONTS comment that's put out in done().
27717c478bd9Sstevel@tonic-gate  * By default PostScript font names are found in /usr/lib/font/devpost. Fonts
27727c478bd9Sstevel@tonic-gate  * that have a .name file are recorded in *temp_file. The first string in that
27737c478bd9Sstevel@tonic-gate  * file is expected to be that font's (long) PostScript name.
27747c478bd9Sstevel@tonic-gate  *
27757c478bd9Sstevel@tonic-gate  */
27767c478bd9Sstevel@tonic-gate 
27777c478bd9Sstevel@tonic-gate 
27787c478bd9Sstevel@tonic-gate     if ( temp_file == NULL )		/* generate a temp file name */
27797c478bd9Sstevel@tonic-gate 	if ( (temp_file = tempnam(TEMPDIR, "dpost")) == NULL )
27807c478bd9Sstevel@tonic-gate 	    return;
27817c478bd9Sstevel@tonic-gate 
27827c478bd9Sstevel@tonic-gate     sprintf(temp, "%s/dev%s/%s.name", fontdir, realdev, fontname[font].name);
27837c478bd9Sstevel@tonic-gate 
27847c478bd9Sstevel@tonic-gate     if ( (fp_in = fopen(temp, "r")) != NULL )  {
27857c478bd9Sstevel@tonic-gate 	if ( (fp_out = fopen(temp_file, "a")) != NULL )  {
27867c478bd9Sstevel@tonic-gate 	    if ( fscanf(fp_in, "%s", temp) == 1 )  {
27877c478bd9Sstevel@tonic-gate 		if ( docfonts++ == 0 )
27887c478bd9Sstevel@tonic-gate 		    fprintf(fp_out, "%s", DOCUMENTFONTS);
27897c478bd9Sstevel@tonic-gate 		else if ( (docfonts - 1) % 8  == 0 )
27907c478bd9Sstevel@tonic-gate 		    fprintf(fp_out, "\n%s", CONTINUECOMMENT);
27917c478bd9Sstevel@tonic-gate 		fprintf(fp_out, " %s", temp);
27927c478bd9Sstevel@tonic-gate 	    }	/* End if */
27937c478bd9Sstevel@tonic-gate 	    fclose(fp_out);
27947c478bd9Sstevel@tonic-gate 	}   /* End if */
27957c478bd9Sstevel@tonic-gate 	fclose(fp_in);
27967c478bd9Sstevel@tonic-gate     }	/* End if */
27977c478bd9Sstevel@tonic-gate 
27987c478bd9Sstevel@tonic-gate }   /* End of documentfonts */
27997c478bd9Sstevel@tonic-gate 
28007c478bd9Sstevel@tonic-gate 
28017c478bd9Sstevel@tonic-gate /*****************************************************************************/
28027c478bd9Sstevel@tonic-gate 
28037c478bd9Sstevel@tonic-gate 
2804f928ce67Sceastha static void
redirect(int pg)2805f928ce67Sceastha redirect(int pg)
2806f928ce67Sceastha     /* next page we're printing */
28077c478bd9Sstevel@tonic-gate {
28087c478bd9Sstevel@tonic-gate     static FILE	*fp_null = NULL;	/* if output is turned off */
28097c478bd9Sstevel@tonic-gate 
28107c478bd9Sstevel@tonic-gate 
28117c478bd9Sstevel@tonic-gate /*
28127c478bd9Sstevel@tonic-gate  *
28137c478bd9Sstevel@tonic-gate  * If we're not supposed to print page pg, tf will be directed to /dev/null,
28147c478bd9Sstevel@tonic-gate  * otherwise output goes to stdout.
28157c478bd9Sstevel@tonic-gate  *
28167c478bd9Sstevel@tonic-gate  */
28177c478bd9Sstevel@tonic-gate 
28187c478bd9Sstevel@tonic-gate 
28197c478bd9Sstevel@tonic-gate     if ( pg >= 0 && in_olist(pg) == ON )
28207c478bd9Sstevel@tonic-gate 	tf = stdout;
28217c478bd9Sstevel@tonic-gate     else if ( (tf = fp_null) == NULL )
28227c478bd9Sstevel@tonic-gate 	tf = fp_null = fopen("/dev/null", "w");
28237c478bd9Sstevel@tonic-gate 
28247c478bd9Sstevel@tonic-gate }   /* End of redirect */
2825