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