dviselect (Part 3 of 6)
Skip Montanaro
montnaro at sprite.crd.ge.com
Tue Nov 14 08:21:32 AEST 1989
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 3 (of 6)."
# Contents: lib/conv.c lib/dviclass.c lib/error.c lib/findpost.c
# lib/fio.c lib/font.c lib/font_subr.c
# Wrapped by montnaro at sprite on Sat Nov 11 17:13:29 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f lib/conv.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"lib/conv.c\"
else
echo shar: Extracting \"lib/conv.c\" \(1325 characters\)
sed "s/^X//" >lib/conv.c <<'END_OF_lib/conv.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved. Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/conv.c,v 1.3 89/02/13 14:30:55 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Conversions.
X */
X
X#include "types.h"
X#include "conv.h"
X
XConv Conversion;
X
Xdouble DMagFactor();
X
X/*
X * Set a conversion (possibly the global conversion).
X */
Xvoid
XCSetConversion(c, dpi, usermag, num, denom, dvimag)
X register struct conversion *c;
X int dpi, usermag;
X i32 num, denom, dvimag;
X{
X double ddpi = dpi;
X
X c->c_mag = DMagFactor((int) dvimag) * DMagFactor(usermag);
X c->c_dpi = ddpi;
X
X /*
X * The conversion facture is figured as follows: there are exactly
X * num/denom DVI units per decimicron, and 254000 decimicrons per
X * inch, and dpi pixels per inch. Then we have to adjust this by
X * the stated magnification.
X */
X c->c_fromsp = (num / 254000.0) * (ddpi / denom) * c->c_mag;
X
X /*
X * c->c_tosp is 1/c->c_fromsp, but we will invert the expression
X * above in the hopes of some extra accuracy.
X *
X * IS THIS ANY GOOD? I NEED A NUMERICAL ANALYST!
X */
X c->c_tosp = (254000.0 / num) * (denom / ddpi) * (1.0 / c->c_mag);
X}
END_OF_lib/conv.c
if test 1325 -ne `wc -c <lib/conv.c`; then
echo shar: \"lib/conv.c\" unpacked with wrong size!
fi
chmod +x lib/conv.c
# end of overwriting check
fi
if test -f lib/dviclass.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"lib/dviclass.c\"
else
echo shar: Extracting \"lib/dviclass.c\" \(3242 characters\)
sed "s/^X//" >lib/dviclass.c <<'END_OF_lib/dviclass.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved. Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/dviclass.c,v 1.3 89/02/13 14:30:57 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * dviclass - DVI code classification tables.
X */
X
X#include "dviclass.h"
X
X/* shorthand---in lowercase for contrast (read on!) */
X#define four(x) x, x, x, x
X#define six(x) four(x), x, x
X#define sixteen(x) four(x), four(x), four(x), four(x)
X#define sixty_four(x) sixteen(x), sixteen(x), sixteen(x), sixteen(x)
X#define one_twenty_eight(x) sixty_four(x), sixty_four(x)
X
X/*
X * This table contains the byte length of the single operand, or DPL_NONE
X * if no operand, or if it cannot be decoded this way.
X *
X * The sequences UNS1, UNS2, UNS3, SGN4 (`SEQ_U') and SGN1, SGN2, SGN3,
X * SGN4 (`SEQ_S') are rather common, and so we define macros for these.
X */
X#define SEQ_U DPL_UNS1, DPL_UNS2, DPL_UNS3, DPL_SGN4
X#define SEQ_S DPL_SGN1, DPL_SGN2, DPL_SGN3, DPL_SGN4
X
Xchar dvi_oplen[256] = {
X one_twenty_eight(DPL_NONE),
X /* characters 0 through 127 */
X SEQ_U, /* DVI_SET1 through DVI_SET4 */
X DPL_NONE, /* DVI_SETRULE */
X SEQ_U, /* DVI_PUT1 through DVI_PUT4 */
X DPL_NONE, /* DVI_PUTRULE */
X DPL_NONE, /* DVI_NOP */
X DPL_NONE, /* DVI_BOP */
X DPL_NONE, /* DVI_EOP */
X DPL_NONE, /* DVI_PUSH */
X DPL_NONE, /* DVI_POP */
X SEQ_S, /* DVI_RIGHT1 through DVI_RIGHT4 */
X DPL_NONE, /* DVI_W0 */
X SEQ_S, /* DVI_W1 through DVI_W4 */
X DPL_NONE, /* DVI_X0 */
X SEQ_S, /* DVI_X1 through DVI_X4 */
X SEQ_S, /* DVI_DOWN1 through DVI_DOWN4 */
X DPL_NONE, /* DVI_Y0 */
X SEQ_S, /* DVI_Y1 through DVI_Y4 */
X DPL_NONE, /* DVI_Z0 */
X SEQ_S, /* DVI_Z1 through DVI_Z4 */
X sixty_four(DPL_NONE), /* DVI_FNTNUM0 through DVI_FNTNUM63 */
X SEQ_U, /* DVI_FNT1 through DVI_FNT4 */
X SEQ_U, /* DVI_XXX1 through DVI_XXX4 */
X SEQ_U, /* DVI_FNTDEF1 through DVI_FNTDEF4 */
X DPL_NONE, /* DVI_PRE */
X DPL_NONE, /* DVI_POST */
X DPL_NONE, /* DVI_POSTPOST */
X six(DPL_NONE) /* 250 through 255 */
X};
X
Xchar dvi_dt[256] = {
X one_twenty_eight(DT_CHAR),
X /* characters 0 through 127 */
X four(DT_SET), /* DVI_SET1 through DVI_SET4 */
X DT_SETRULE, /* DVI_SETRULE */
X four(DT_PUT), /* DVI_PUT1 through DVI_PUT4 */
X DT_PUTRULE, /* DVI_PUTRULE */
X DT_NOP, /* DVI_NOP */
X DT_BOP, /* DVI_BOP */
X DT_EOP, /* DVI_EOP */
X DT_PUSH, /* DVI_PUSH */
X DT_POP, /* DVI_POP */
X four(DT_RIGHT), /* DVI_RIGHT1 through DVI_RIGHT4 */
X DT_W0, /* DVI_W0 */
X four(DT_W), /* DVI_W1 through DVI_W4 */
X DT_X0, /* DVI_X0 */
X four(DT_X), /* DVI_X1 through DVI_X4 */
X four(DT_DOWN), /* DVI_DOWN1 through DVI_DOWN4 */
X DT_Y0, /* DVI_Y0 */
X four(DT_Y), /* DVI_Y1 through DVI_Y4 */
X DT_Z0, /* DVI_Z0 */
X four(DT_Z), /* DVI_Z1 through DVI_Z4 */
X sixty_four(DT_FNTNUM), /* DVI_FNTNUM0 through DVI_FNTNUM63 */
X four(DT_FNT), /* DVI_FNT1 through DVI_FNT4 */
X four(DT_XXX), /* DVI_XXX1 through DVI_XXX4 */
X four(DT_FNTDEF), /* DVI_FNTDEF1 through DVI_FNTDEF4 */
X DT_PRE, /* DVI_PRE */
X DT_POST, /* DVI_POST */
X DT_POSTPOST, /* DVI_POSTPOST */
X six(DT_UNDEF) /* 250 through 255 */
X};
END_OF_lib/dviclass.c
if test 3242 -ne `wc -c <lib/dviclass.c`; then
echo shar: \"lib/dviclass.c\" unpacked with wrong size!
fi
chmod +x lib/dviclass.c
# end of overwriting check
fi
if test -f lib/error.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"lib/error.c\"
else
echo shar: Extracting \"lib/error.c\" \(2104 characters\)
sed "s/^X//" >lib/error.c <<'END_OF_lib/error.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved. Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/error.c,v 1.3 89/02/13 14:30:59 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Print an error message with an optional system error number, and
X * optionally quit.
X *
X * THIS CODE IS SYSTEM DEPENDENT UNLESS varargs WORKS WITH vprintf
X * OR _doprnt. It should work properly under System V using vprintf.
X * (If you have vprintf, define HAVE_VPRINTF.)
X */
X
X#include <stdio.h>
X#include <varargs.h>
X
X#ifdef lint
X
X/* VARARGS3 ARGSUSED */
Xerror(quit, e, fmt) int quit, e; char *fmt; {;}
X
X/* VARARGS1 ARGSUSED */
Xpanic(fmt) char *fmt; { exit(1); /* NOTREACHED */ }
X
X#else lint
X
Xextern char *ProgName;
Xextern int errno;
Xextern char *sys_errlist[];
Xextern int sys_nerr;
X
Xerror(va_alist)
X va_dcl
X{
X va_list l;
X int quit, e;
X char *fmt;
X
X (void) fflush(stdout); /* sync error messages */
X (void) fprintf(stderr, "%s: ", ProgName);
X va_start(l);
X /* pick up the constant arguments: quit, errno, printf format */
X quit = va_arg(l, int);
X e = va_arg(l, int);
X if (e < 0)
X e = errno;
X fmt = va_arg(l, char *);
X#if defined(sys5) || defined(HAVE_VPRINTF)
X (void) vfprintf(stderr, fmt, l);
X#else
X _doprnt(fmt, l, stderr);
X#endif
X va_end(l);
X if (e) {
X if (e < sys_nerr)
X (void) fprintf(stderr, ": %s", sys_errlist[e]);
X else
X (void) fprintf(stderr, ": Unknown error code %d", e);
X }
X (void) putc('\n', stderr);
X (void) fflush(stderr); /* just in case */
X if (quit)
X exit(quit);
X}
X
Xpanic(va_alist)
X va_dcl
X{
X va_list l;
X char *fmt;
X
X (void) fflush(stdout);
X (void) fprintf(stderr, "%s: panic: ", ProgName);
X va_start(l);
X /* pick up the constant argument: printf format */
X fmt = va_arg(l, char *);
X#if defined(sys5) || defined(HAVE_VPRINTF)
X (void) vfprintf(stderr, fmt, l);
X#else
X _doprnt(fmt, l, stderr);
X#endif
X va_end(l);
X (void) putc('\n', stderr);
X (void) fflush(stderr);
X abort();
X}
X
X#endif /* lint */
END_OF_lib/error.c
if test 2104 -ne `wc -c <lib/error.c`; then
echo shar: \"lib/error.c\" unpacked with wrong size!
fi
chmod +x lib/error.c
# end of overwriting check
fi
if test -f lib/findpost.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"lib/findpost.c\"
else
echo shar: Extracting \"lib/findpost.c\" \(3945 characters\)
sed "s/^X//" >lib/findpost.c <<'END_OF_lib/findpost.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved. Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/findpost.c,v 1.4 89/02/13 14:31:00 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * FindPostAmble - Find the postamble of a DVI file.
X *
X * N.B.: This routine assumes that ftell() returns byte offsets,
X * not magic cookies.
X */
X
X#include <stdio.h>
X#include "types.h"
X#include "dvicodes.h"
X#include "fio.h"
X
X/*
X * I am making the assumption that 530 bytes will always be enough
X * to find the end of the DVI file. 12 should suffice, as there
X * should be at most seven DVI_FILLER bytes, preceded by the version
X * number, preceded by the four byte postamble pointer; but at least
X * one VMS TeX must pad to a full `sector'.
X */
X/*
X * The above is not correct. The DVItype program, as authoritative on
X * DVI format, states regarding postambles:
X *
X * The [last] byte is followed by four or more bytes that are all
X * equal to the decimal number 223 (i.e., 337 in octal). TeX puts
X * out four to seven of these trailing bytes, until the total length
X * of the file is a multiple of four bytes, since this works out
X * best on machines that pack four bytes per word; but any number
X * of 223's is allowed, as long as there are at least four of them.
X *
X * Thus assuming "at most seven DVI_FILLER bytes" is wrong. In fact,
X * PC-TeX seems to put out liberal amounts of DVI_FILLER at the end.
X *
X * The original code was efficient, but had to assume a certain
X * number of bytes. Since the postamble is only read once anyway,
X * efficiency is not really a consideration. Plus, like I always
X * say, it's better to get the right answer slowly than the wrong
X * answer fast....
X *
X * Vahe Sarkissian, UCLA Math. Sci., 4/13/88.
X */
X
X#ifdef ORIGINAL_CODE
X#ifdef vms
X#define POSTSIZE 530 /* make only VMS pay for its errors; */
X#else
X#define POSTSIZE 16 /* others get to use something reasonable */
X#endif
X
Xlong ftell();
X
XFindPostAmble(f)
X register FILE *f;
X{
X register long offset;
X register char *p;
X register int i;
X register i32 n;
X char postbuf[POSTSIZE];
X
X /*
X * Avoid fseek'ing beyond beginning of file; it may
X * give odd results.
X */
X fseek(f, 0L, 2); /* seek to end */
X offset = ftell(f) - POSTSIZE; /* and compute where to go next */
X if (offset < 0L) /* but make sure it is positive */
X offset = 0L;
X fseek(f, offset, 0);
X p = postbuf;
X for (i = 0; i < POSTSIZE; i++) {
X *p++ = getc(f);
X if (feof(f)) {
X p--;
X break;
X }
X }
X
X /*
X * Now search backwards for the VERSION byte. The postamble
X * pointer will be four bytes behind that.
X */
X while (--i >= 0) {
X if (UnSign8(*--p) == DVI_VERSION)
X goto foundit;
X if (UnSign8(*p) != DVI_FILLER)
X break;
X }
X return (-1); /* cannot find postamble ptr */
X
Xfoundit:
X /*
X * Change offset from the position at the beginning of postbuf
X * to the position of the VERSION byte, and seek to four bytes
X * before that. Then get a long and use its value to seek to
X * the postamble itself.
X */
X offset += p - postbuf;
X fseek(f, offset - 4L, 0);
X fGetLong(f, n);
X offset = n;
X fseek(f, offset, 0);
X return (0); /* success */
X}
X
X#else !ORIGINAL_CODE
X
XFindPostAmble(f)
X register FILE *f;
X{
X register long offset;
X register i32 n;
X
X offset = -4; /* At least four bytes of DVI_FILLER must be present. */
X do {
X offset -= 1;
X (void) fseek(f, offset, 2);
X n = fgetbyte(f);
X } while (n == DVI_FILLER);
X
X if (n != DVI_VERSION)
X return (-1); /* Bad version of DVI file */
X
X /*
X * Position file four bytes before DVI_VERSION byte,
X * and read a long. Use that long to seek to the
X * beginning of the postamble itself.
X */
X offset -= 4;
X (void) fseek(f, offset, 2);
X fGetLong(f, n);
X offset = n;
X (void) fseek(f, offset, 0);
X return (0); /* success */
X}
X#endif ORIGINAL_CODE
END_OF_lib/findpost.c
if test 3945 -ne `wc -c <lib/findpost.c`; then
echo shar: \"lib/findpost.c\" unpacked with wrong size!
fi
chmod +x lib/findpost.c
# end of overwriting check
fi
if test -f lib/fio.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"lib/fio.c\"
else
echo shar: Extracting \"lib/fio.c\" \(965 characters\)
sed "s/^X//" >lib/fio.c <<'END_OF_lib/fio.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved. Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/fio.c,v 1.3 89/02/13 14:31:01 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * File I/O subroutines for getting bytes, words, 3bytes, and longwords.
X */
X
X#include <stdio.h>
X#include "types.h"
X#include "fio.h"
X
Xstatic char eofmsg[] = "unexpected EOF";
X
X/* for symmetry: */
X#define fGetByte(fp, r) ((r) = getc(fp))
X#define Sign32(i) (i)
X
X#define make(name, func, signextend) \
Xi32 \
Xname(fp) \
X register FILE *fp; \
X{ \
X register i32 n; \
X \
X func(fp, n); \
X if (feof(fp)) \
X error(1, 0, eofmsg); \
X return (signextend(n)); \
X}
X
Xmake(GetByte, fGetByte, Sign8)
Xmake(GetWord, fGetWord, Sign16)
Xmake(Get3Byte, fGet3Byte, Sign24)
Xmake(GetLong, fGetLong, Sign32)
END_OF_lib/fio.c
if test 965 -ne `wc -c <lib/fio.c`; then
echo shar: \"lib/fio.c\" unpacked with wrong size!
fi
chmod +x lib/fio.c
# end of overwriting check
fi
if test -f lib/font.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"lib/font.c\"
else
echo shar: Extracting \"lib/font.c\" \(9825 characters\)
sed "s/^X//" >lib/font.c <<'END_OF_lib/font.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved. Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/font.c,v 1.6 89/02/13 14:31:02 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Routines for working with fonts. In particular, the configuration
X * dependent code is here.
X *
X * Specific fonts (GF, PXL, etc.) have functions in separate files.
X */
X
X#include <stdio.h>
X#include <errno.h>
X#include <sys/file.h>
X#include "types.h"
X#include "conv.h"
X#include "font.h"
X
X/*
X * Define the default configuration file.
X * Also define the maximum path name length.
X */
X#ifndef FONTDESC
X you need to define FONTDESC in the compile line
X#endif
X
X#define PATHLEN 1024
X
X/*
X * A font configuration. The font list is ordered.
X *
X * A specifier is typically a particular print engine, since
X * different engines need slightly different fonts.
X */
Xstruct fontconf {
X struct fontconf *fc_next;
X struct fontops *fc_ops;
X char *fc_path; /* path, with metacharacters */
X char *fc_spec; /* specifier */
X int fc_slop; /* slop value */
X};
X
X/*
X * EQ is a fast way to check for string equivalence.
X */
X#define EQ(a, b) (*(a) == *(b) && strcmp(a, b) == 0)
X
X/*
X * Private variables.
X */
Xstatic int didinit; /* true => initialised already */
Xstatic char *cfname; /* config file name, for errors */
Xstatic int cfline; /* config file line, likewise */
Xstatic struct fontops *fontops;/* font operations code: list head */
Xstatic struct fontconf *fonts; /* font list */
Xstatic struct fontconf **nextfc;/* used during initialisation */
Xstatic char spec_any[] = "*"; /* the `anything' specifier */
X
X/*
X * Imports.
X */
Xextern int errno;
Xchar *getenv(), *malloc(), *strsave();
X#ifndef sys5
Xchar *sprintf();
X#endif
X
Xstatic readconf();
Xstatic setfont();
Xstatic badcf();
Xstatic struct font *getafont(); /* get a font and optional rasters */
X
X/*
X * Here, alas, we know about all the kinds of fonts.
X * This also means that every DVI interpreter pulls in
X * the full set of font manipulation routines.
X *
X * PERHAPS THIS SHOULD BE CONFIGURABLE.
X */
X#define ADDFONT(x) { \
X extern struct fontops x; \
X x.fo_next = fontops; \
X fontops = &x; \
X}
X
Xfontinit(file)
X char *file;
X{
X
X if (didinit) {
X /*
X * Could free the old configuration and fire up
X * a new one, but for now . . .
X */
X error(1, 0, "attempt to reinit fonts");
X /* NOTREACHED */
X }
X didinit++;
X ADDFONT(boxops);
X ADDFONT(blankops);
X ADDFONT(invisops);
X ADDFONT(pxlops);
X ADDFONT(pkops);
X ADDFONT(gfops);
X nextfc = &fonts;
X if (file == NULL)
X if ((file = getenv(CONFENV)) == NULL)
X file = FONTDESC;
X readconf(file);
X}
X
X/*
X * A proto resembles a fontspec (indeed, it is a prototype
X * fontspec) but is not quite the same. It is used to gather
X * the information needed per fontspec before allocating
X * the fontspec itself.
X */
Xstruct proto {
X char *p_type;
X char *p_spec;
X char *p_slop;
X char *p_path;
X};
X
X/*
X * Read the named configuration file. The file is split into
X * lines, and lines are split into words; if the first word is
X * "font", this is a fontconf, and we read the remainder of the
X * words and make a fontconf entry.
X */
Xstatic
Xreadconf(name)
X char *name;
X{
X register FILE *f; /* config file */
X register char **p; /* pointer into word vector */
X register int c;
X char line[1024]; /* input line */
X char *v[100]; /* word vector */
X struct proto proto; /* prototype fontconf */
X
X#define GETWORD(x, ifnone) \
X if (--c <= 0) \
X badcf(ifnone); \
X else \
X (x) = *p++
X
X if ((f = fopen(name, "r")) == NULL)
X error(1, errno, "cannot read font configuration file \"%s\"",
X name);
X cfname = name;
X cfline = 0;
X while (fgets(line, sizeof (line), f) != NULL) {
X cfline++;
X if ((c = strlen(line)) > 0) {
X if (line[--c] != '\n')
X badcf("line too long");
X line[c] = 0;
X }
X if ((c = split(line, v, sizeof (v) / sizeof (*v))) < 0)
X badcf("too many words");
X p = v;
X /* skip things that are not fonts */
X if (c == 0 || !EQ(*p, "font"))
X continue;
X p++;
X GETWORD(proto.p_type, "missing font typename");
X GETWORD(proto.p_spec, "missing font spec (engine)");
X GETWORD(proto.p_slop, "missing slop value");
X GETWORD(proto.p_path, "need pathname");
X (void) setfont(&proto);
X }
X}
X
X/*
X * Find a font's operations, given its name.
X */
Xstatic struct fontops *
Xfindops(name)
X register char *name;
X{
X register struct fontops *fo;
X
X for (fo = fontops; fo != NULL; fo = fo->fo_next)
X if (EQ(fo->fo_name, name))
X return (fo);
X return (NULL);
X}
X
X/*
X * Turn a prototype fontconf into a real one.
X */
Xstatic int
Xsetfont(p)
X register struct proto *p;
X{
X register struct fontconf *fc;
X struct fontops *ops = findops(p->p_type);
X
X if (ops == NULL) {
X error(0, 0,
X "\"%s\", line %d: unknown font type \"%s\" ignored",
X cfname, cfline, p->p_type);
X return (-1);
X }
X if ((fc = (struct fontconf *) malloc(sizeof (*fc))) == NULL)
X error(1, errno,
X "out of memory for font configuration (sorry)");
X fc->fc_ops = ops;
X fc->fc_next = NULL;
X fc->fc_path = strsave(p->p_path);
X fc->fc_spec = EQ(p->p_spec, spec_any) ? NULL : strsave(p->p_spec);
X fc->fc_slop = atoi(p->p_slop);
X if (fc->fc_slop < 1) /* quietly enforce proper slops */
X fc->fc_slop = 1;
X *nextfc = fc;
X nextfc = &fc->fc_next;
X return (0);
X}
X
X/*
X * Complain about a problem in the configuration file.
X */
Xstatic
Xbadcf(why)
X char *why;
X{
X
X error(1, 0, "\"%s\", line %d: %s", cfname, cfline, why);
X /* NOTREACHED */
X}
X
X/*
X * Turn a prototype path, name, and magnification into a full
X * path.
X */
Xstatic
Xpave(result, proto, name, mag)
X char *result, *proto, *name;
X int mag;
X{
X register int c;
X register char *s, *d, *p;
X char num[30];
X
X d = result;
X p = proto;
X s = NULL;
X num[0] = 0; /* will need changing for other bases */
X
X while (p != NULL) {
X /*
X * If sourcing from s, take its next character, and
X * insert it directly. Otherwise take the next path
X * character and interpret it.
X */
X if (s != NULL) {
X if ((c = *s++) == 0) {
X s = NULL;
X continue;
X }
X goto put;
X }
X if ((c = *p++) == 0)
X p = NULL;
X if (c != '%')
X goto put;
X
X switch (c = *p++) {
X
X case 'f':
X case 'n':
X case 's':
X s = name;
X continue;
X
X case 'd':
X case 'm':
X if (num[0] == 0)
X (void) sprintf(num, "%d", mag);
X s = num;
X continue;
X
X case 0:
X c = '%';
X p--;
X /* FALLTHROUGH */
X }
Xput:
X if (d - result >= PATHLEN)
X error(1, 0, "font path `%s' too long (sorry)", proto);
X *d++ = c;
X }
X}
X
X
X/*
X * Given a font name and size, return the first font that fits, along
X * with its name (via fname). If we cannot find such a font, we set
X * *fname to point to a `canonical' example font name, unless there are
X * are no fonts for the device, in which case we set *fname to NULL.
X */
Xstruct font *
XGetFont(nm, dvimag, dvidsz, dev, fname)
X char *nm;
X i32 dvimag, dvidsz;
X char *dev, **fname;
X{
X
X return (getafont(nm, dvimag, dvidsz, dev, fname, 1));
X}
X
X/*
X * Same as GetFont, but caller promises never to ask for rasters.
X */
Xstruct font *
XGetRasterlessFont(nm, dvimag, dvidsz, dev, fname)
X char *nm;
X i32 dvimag, dvidsz;
X char *dev, **fname;
X{
X
X return (getafont(nm, dvimag, dvidsz, dev, fname, 0));
X}
X
X/*
X * NEED TO THINK ABOUT gf NAMING CONVENTIONS HERE: ARE THEY LIKE pxl?
X * WHAT ABOUT OTHERS?
X */
Xstatic struct font *
Xgetafont(nm, dvimag, dvidsz, dev, fname, wantrast)
X char *nm;
X i32 dvimag, dvidsz;
X char *dev, **fname;
X int wantrast;
X{
X register int slop, fmag;
X register struct font *f;
X register struct fontconf *fc;
X register char *path;
X static char firstpath[PATHLEN], laterpath[PATHLEN];
X double mag;
X int scaled;
X
X extern Conv Conversion;
X
X if (!didinit)
X fontinit((char *) NULL);
X
X /*
X * The equation below means, approximately, `the font is
X * magnified by the ratio of the actual size dvimag to the
X * design size dvidsz, and then further scaled by the
X * global magnification.' We multiply this by the printer's
X * resolution in dots per inch, then use the per-font
X * conversion factor to convert a dots-per-inch value to
X * a font name `%m' magnification (extension).
X */
X mag = (double) dvimag / (double) dvidsz;
X scaled = mag * 1000.0 + 0.5;
X mag *= Conversion.c_mag * Conversion.c_dpi;
X
X path = firstpath;
X for (fc = fonts; fc != NULL; fc = fc->fc_next) {
X if (dev != NULL && fc->fc_spec != NULL &&
X !EQ(dev, fc->fc_spec))
X continue;
X fmag = mag * fc->fc_ops->fo_dpitomag + 0.5;
X for (slop = 0; slop < fc->fc_slop; slop++) {
X pave(path, fc->fc_path, nm, fmag + slop);
X if (access(path, R_OK) == 0)
X goto found;
X
X
X /* if someone could explain this, I'd appreicate it.
X On ultrix 2.2, checking R_OK on a RO filesyste
X fails, with the following errno. Why? */
X
X if ( errno == EROFS ) {
X goto found;
X }
X
X if (slop) {
X pave(path, fc->fc_path, nm, fmag - slop);
X if (access(path, R_OK) == 0)
X goto found;
X if ( errno == EROFS ) {
X goto found;
X }
X }
X path = laterpath;
X }
X }
X
X /* not found */
X if (path == firstpath) { /* never got to try any paths */
X *fname = NULL;
X errno = ENXIO;
X } else {
X *fname = firstpath;
X errno = ENOENT;
X }
X return (NULL);
X
Xfound:
X *fname = path;
X
X /* allocate space for the per-font info, and read it in */
X f = (struct font *) malloc(sizeof (struct font));
X if (f == NULL)
X return (NULL);
X f->f_flags = wantrast ? FF_RASTERS : 0;
X f->f_ops = fc->fc_ops;
X f->f_path = strsave(path);
X f->f_font = strsave(nm);
X f->f_dvimag = dvimag;
X f->f_dvidsz = dvidsz;
X f->f_scaled = scaled;
X f->f_checksum = 0; /* in case the font reader cannot get one */
X errno = 0;
X if ((*f->f_ops->fo_read)(f)) {
X int e = errno; /* paranoid */
X
X free(f->f_path); f -> f_path = 0;
X free(f->f_font); f -> f_font = 0;
X free((char *) f); f = 0;
X errno = e;
X return (NULL);
X }
X return (f);
X}
END_OF_lib/font.c
if test 9825 -ne `wc -c <lib/font.c`; then
echo shar: \"lib/font.c\" unpacked with wrong size!
fi
chmod +x lib/font.c
# end of overwriting check
fi
if test -f lib/font_subr.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"lib/font_subr.c\"
else
echo shar: Extracting \"lib/font_subr.c\" \(4984 characters\)
sed "s/^X//" >lib/font_subr.c <<'END_OF_lib/font_subr.c'
X/*
X * Copyright (c) 1987 University of Maryland Department of Computer Science.
X * All rights reserved. Permission to copy for any purpose is hereby granted
X * so long as this copyright notice remains intact.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Header: /home/reed/grunwald/Projects/Iptex/lib/RCS/font_subr.c,v 1.5 89/02/13 14:31:04 grunwald Exp Locker: grunwald $";
X#endif
X
X/*
X * Subroutines common to all fonts.
X */
X
X#include "font.h"
X
Xstatic struct glyph *freeglyphs;
X
Xchar *malloc();
Xextern errno;
X
X/*
X * Set up the font structures to note that a font has glyphs in
X * the half-open interval [low, high).
X *
X * SHOULD I ALLOW ADDITIONS TO THE RANGE VIA SUBSEQUENT CALLS TO
X * FontHasGlyphs?
X */
XFontHasGlyphs(f, low, high)
X register struct font *f;
X register int low, high;
X{
X register struct glyph **gp;
X
X /* record bounds */
X f->f_lowch = low;
X f->f_highch = high;
X
X /*
X * Allocate space for all the glyph pointers, and set
X * them all to NULL.
X */
X if (low >= high) /* no glyphs */
X gp = NULL;
X else {
X gp = (struct glyph **) malloc((unsigned) (high - low) *
X sizeof (*gp));
X if (gp == NULL)
X return (-1);
X }
X f->f_glybase = gp;
X f->f_gly = gp - low;
X while (++low <= high)
X *gp++ = NULL;
X return (0);
X}
X
X/*
X * AllocGlyph allocates a new glyph. ReleaseGlyph puts one onto the free
X * list. We maintain a local list of free glyphs.
X */
X#define ReleaseGlyph(g) \
X ((g)->g_un.g_next = freeglyphs, freeglyphs = (g))
X
Xstatic struct glyph *
XAllocGlyph(n)
X int n;
X{
X register struct glyph *g;
X register int i;
X
X if ((g = freeglyphs) == NULL) {
X g = (struct glyph *) malloc((unsigned) (128 * sizeof (*g)));
X if (g == NULL)
X error(1, errno, "out of glyph memory");
X g += (i = 128);
X while (--i >= 0) {
X g--;
X ReleaseGlyph(g);
X }
X }
X freeglyphs = g->g_un.g_next;
X g->g_flags = 0;
X g->g_raster = NULL;
X g->g_index = n;
X return (g);
X}
X
X/*
X * Free one glyph.
X */
Xvoid
XFreeGlyph(f, n)
X struct font *f;
X register int n;
X{
X register struct glyph *g;
X
X if (n < f->f_lowch || n >= f->f_highch)
X return;
X#ifdef notdef
X (*f->f_ops->fo_freegly)(f, n, n);
X#endif
X if ((g = f->f_gly[n]) == NULL)
X return;
X if (g->g_raster != NULL) {
X free(g->g_raster); g -> g_raster = 0;
X }
X ReleaseGlyph(g);
X}
X
X/*
X * Free a font.
X */
Xvoid
XFreeFont(f)
X register struct font *f;
X{
X register struct glyph *g;
X register int i;
X
X#ifdef notdef
X (*f->f_ops->fo_freegly)(f, f->f_lowch, f->f_highch);
X#endif
X for (i = f->f_lowch; i < f->f_highch; i++) {
X if ((g = f->f_gly[i]) == NULL)
X continue;
X if (g->g_raster != NULL) {
X free(g->g_raster); g -> g_raster = 0;
X }
X ReleaseGlyph(g);
X }
X if (f->f_glybase != NULL) {
X free((char *) f->f_glybase); g -> g_raster = 0;
X }
X (*f->f_ops->fo_freefont)(f);
X free(f->f_path); f -> f_path = 0;
X free(f->f_font); f -> f_font = 0;
X free((char *) f); f = 0;
X}
X
X/*
X * Get glyph `c' in font `f'. We pull in a few adjacent glyphs here
X * under the (perhaps naive) assumption that things will go faster
X * that way.
X *
X * TODO:
X * try different adjacency values
X * make adjacency a font attribute? (or an op)
X */
X#define ADJ 8 /* must be a power of 2 */
X#define GET_ADJ(c, l, h) ((h) = ADJ + ((l) = (c) & ~(ADJ - 1)))
X
Xstruct glyph *
XGetGlyph(f, c)
X register struct font *f;
X int c;
X{
X register int i, h, l;
X
X GET_ADJ(c, l, h);
X if (l < f->f_lowch)
X l = f->f_lowch;
X if (h > f->f_highch)
X h = f->f_highch;
X if (l >= h)
X return (NULL);
X for (i = l; i < h; i++)
X if (f->f_gly[i] == NULL)
X f->f_gly[i] = AllocGlyph(i);
X
X if ((*f->f_ops->fo_getgly)(f, l, h)) {
X /*
X * I do not know what to do about this just yet, so:
X */
X panic("getgly fails and I am confused ... help!");
X }
X
X /*
X * Apply the appropriate scale factor to the TFM widths.
X * This makes them come out in scaled points, instead of FIXes.
X */
X ScaleGlyphs(f, l, h); /* ??? */
X
X return (f->f_gly[c]);
X}
X
X/*
X * Get the raster for glyph g in font f at rotation r.
X */
Xchar *
XGetRaster(g, f, r)
X register struct glyph *g;
X register struct font *f;
X int r;
X{
X int l, h;
X
X /* abort if caller did not ask for rasters in advance */
X if ((f->f_flags & FF_RASTERS) == 0)
X panic("GetRaster(%s)", f->f_path);
X
X /*
X * If there is no raster, get one. Blank characters,
X * however, never have rasters.
X */
X if (g->g_raster == NULL) {
X if (!HASRASTER(g))
X return (NULL);
X /*
X * THE FOLLOWING DEPENDS ON THE ADJACENCY MATCHING THAT IN
X * GetGlyph() ABOVE.
X */
X GET_ADJ(g->g_index, l, h);
X if (l < f->f_lowch)
X l = f->f_lowch;
X if (h > f->f_highch)
X h = f->f_highch;
X if ((*f->f_ops->fo_rasterise)(f, l, h))
X error(1, 0, "rasterise fails (out of memory?)");
X }
X if (g->g_rotation != r)
X SetRotation(g, r);
X return (g->g_raster);
X}
X
X/*
X * Return a TeX-style font name, including scale factor.
X * SHOULD I BOTHER WITH \magstep STYLE NAMES?
X */
Xchar *
XFont_TeXName(f)
X register struct font *f;
X{
X static char result[200];
X
X if (f->f_scaled == 1000)
X return (f->f_font);
X sprintf(result, "%s scaled %d", f->f_font, f->f_scaled);
X return (result);
X}
END_OF_lib/font_subr.c
if test 4984 -ne `wc -c <lib/font_subr.c`; then
echo shar: \"lib/font_subr.c\" unpacked with wrong size!
fi
chmod +x lib/font_subr.c
# end of overwriting check
fi
echo shar: End of archive 3 \(of 6\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 6 archives.
echo "Now do 'make dviselect'"
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Skip Montanaro (montanaro at crdgw1.ge.com)
More information about the Alt.sources
mailing list