summaryrefslogtreecommitdiff
path: root/dviware/dvibook/libtex/dvistate.c
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/dvibook/libtex/dvistate.c')
-rw-r--r--dviware/dvibook/libtex/dvistate.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/dviware/dvibook/libtex/dvistate.c b/dviware/dvibook/libtex/dvistate.c
new file mode 100644
index 0000000000..b11f3f10cc
--- /dev/null
+++ b/dviware/dvibook/libtex/dvistate.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 1987, 1989 University of Maryland
+ * Department of Computer Science. All rights reserved.
+ * Permission to copy for any purpose is hereby granted
+ * so long as this copyright notice remains intact.
+ */
+
+#ifndef lint
+static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/lib/RCS/dvistate.c,v 1.1 89/08/22 21:49:03 chris Exp $";
+#endif
+
+/*
+ * dvistate - basic DVI machine interpreter
+ */
+
+#include <stdio.h>
+#include "types.h"
+#include "conv.h"
+#include "dvicodes.h"
+#include "error.h"
+#include "fio.h"
+#include "font.h"
+#include "gripes.h"
+#include "postamble.h"
+#include "search.h"
+#include "seek.h"
+#include "dvistate.h"
+
+struct dvi_state ds;
+
+/* yech, statics! */
+static struct font *(*s_deffnt)();
+static int s_dpi;
+static int s_errs;
+
+static void pre(), post(), fntdef();
+
+char *malloc();
+
+/*
+ * Read through the postamble and the preamble and set up the
+ * global DVI state. Each font is passed to (*fontfn)().
+ * Upon return, the input file (fp) is positioned at the beginning
+ * of the first page.
+ *
+ * dpi is the resolution of the printer in pixels (dots) per inch,
+ * and xoffset and yoffset are the values from the -X and -Y flags
+ * (default zero). We add 1000 to each offset (since the offsets
+ * are in 1/1000ths of an inch), and then multiply by dpi and divide
+ * by 1000, to get the actual offset.
+ *
+ * If a device introduces a constant offset, e.g., of .25 inch
+ * horizontally and .31 inch vertically, the caller can compensate
+ * by passing (xflag - 2500) and (yflag - 3100).
+ */
+void
+DVISetState(fp, fontfn, dpi, xoffset, yoffset)
+ FILE *fp;
+ struct font *(*fontfn)();
+ int dpi, xoffset, yoffset;
+{
+
+ /* make sure fseek() will work */
+ if ((ds.ds_fp = SeekFile(fp)) == NULL)
+ error(1, -1, "unable to copy input to temp file (disk full?)");
+
+ /* h and v must be deferred until we have a conversion */
+ ds.ds_fresh.hh = ((1000 + (i32)xoffset) * dpi) / 1000;
+ ds.ds_fresh.vv = ((1000 + (i32)yoffset) * dpi) / 1000;
+
+ ds.ds_fonts = SCreate(sizeof(struct font *));
+ if (ds.ds_fonts == NULL)
+ error(1, 0, "cannot create font table (out of memory?)");
+ s_errs = 0;
+ s_dpi = dpi;
+ s_deffnt = fontfn;
+ ScanPostAmble(ds.ds_fp, post, fntdef);
+ if (s_errs)
+ GripeMissingFontsPreventOutput(s_errs);
+ pre();
+}
+
+/*
+ * Read the preamble and apply sanity checks.
+ * The presence of a preamble is virtually certain,
+ * since we have already found and read a postamble.
+ */
+static void
+pre()
+{
+ register int n;
+ register FILE *fp = ds.ds_fp;
+
+ rewind(fp);
+ if (GetByte(fp) != Sign8(DVI_PRE))
+ GripeMissingOp("PRE");
+ if (GetByte(fp) != Sign8(DVI_VERSION))
+ GripeMismatchedValue("version number");
+ if (GetLong(fp) != ds.ds_num)
+ GripeMismatchedValue("numerator");
+ if (GetLong(fp) != ds.ds_denom)
+ GripeMismatchedValue("denominator");
+ if (GetLong(fp) != ds.ds_dvimag)
+ GripeMismatchedValue("\\magnification");
+ n = UnSign8(GetByte(fp));
+ while (--n >= 0)
+ (void) GetByte(fp);
+}
+
+/*
+ * Store the relevant information from the DVI postamble.
+ */
+static void
+post(p)
+ register struct PostAmbleInfo *p;
+{
+ register int n;
+
+ ds.ds_prevpage = p->pai_PrevPagePointer;
+ ds.ds_num = p->pai_Numerator;
+ ds.ds_denom = p->pai_Denominator;
+ ds.ds_dvimag = p->pai_DVIMag;
+ ds.ds_maxheight = p->pai_TallestPageHeight;
+ ds.ds_maxwidth = p->pai_WidestPageWidth;
+ ds.ds_npages = p->pai_NumberOfPages;
+
+ /* set the global conversion factor */
+ SetConversion(s_dpi,
+ ds.ds_usermag, ds.ds_num, ds.ds_denom, ds.ds_dvimag);
+
+ ds.ds_fresh.h = toSP(ds.ds_fresh.hh);
+ ds.ds_fresh.v = toSP(ds.ds_fresh.vv);
+#ifdef unneeded /* counting on init-to-zero ... */
+ ds.ds_fresh.w = 0;
+ ds.ds_fresh.x = 0;
+ ds.ds_fresh.y = 0;
+ ds.ds_fresh.z = 0;
+#endif
+ /* make the stack */
+ n = p->pai_DVIStackSize * sizeof(DviStack);
+ if ((ds.ds_stack = (struct dvi_stack *)malloc((unsigned)n)) == NULL)
+ GripeOutOfMemory(n, "DVI stack");
+ ds.ds_sp = ds.ds_stack;
+}
+
+/*
+ * Handle a font definition from the postamble.
+ */
+static void
+fntdef(p)
+ register struct PostAmbleFont *p;
+{
+ register struct font *f, **fp;
+ int def = S_CREATE | S_EXCL;
+
+ fp = (struct font **)SSearch(ds.ds_fonts, p->paf_DVIFontIndex, &def);
+ if (fp == NULL) {
+ if (def & S_COLL)
+ GripeFontAlreadyDefined(p->paf_DVIFontIndex);
+ else
+ error(1, 0, "cannot stash font %ld (out of memory?)",
+ (long)p->paf_DVIFontIndex);
+ /* NOTREACHED */
+ }
+
+ /* apply driver function to get font */
+ f = (*s_deffnt)(p->paf_name, p->paf_DVIMag, p->paf_DVIDesignSize);
+ if (f == NULL) {
+ s_errs++;
+ return;
+ }
+ *fp = f;
+
+ /* match checksums, unless one is (or both are) zero */
+ if (p->paf_DVIChecksum && f->f_checksum &&
+ p->paf_DVIChecksum != f->f_checksum)
+ GripeDifferentChecksums(f->f_path, p->paf_DVIChecksum,
+ f->f_checksum);
+}
+
+/*
+ * Given a font index, return the corresponding pointer.
+ */
+struct font *
+DVIFindFont(n)
+ i32 n;
+{
+ int x = S_LOOKUP;
+ char *p;
+
+ if ((p = SSearch(ds.ds_fonts, n, &x)) == NULL) {
+ GripeNoSuchFont(n);
+ /* NOTREACHED */
+ }
+ return (*(struct font **)p);
+}
+
+/*
+ * Handle a rule: read width and height, then call the given function.
+ * If `advance', move dvi position afterwards.
+ */
+void
+DVIRule(fn, advance)
+ void (*fn)();
+ int advance;
+{
+ register i32 h, w, ww;
+ register FILE *fp = ds.ds_fp;
+
+ fGetLong(fp, h);
+ fGetLong(fp, ww);
+ h = ConvRule(h);
+ w = ConvRule(ww);
+ (*fn)(h, w);
+ if (advance) {
+ dvi_hh += w;
+ dvi_h += ww;
+ w = fromSP(dvi_h);
+ FIXDRIFT(dvi_hh, w);
+ }
+}
+
+/*
+ * Handle a BOP: read the ten \count values and the previous page pointer,
+ * reset DVI position, and call the given function.
+ */
+void
+DVIBeginPage(fn)
+ void (*fn)();
+{
+ register int i;
+ i32 count[10];
+
+ for (i = 0; i < 10; i++)
+ count[i] = GetLong(ds.ds_fp);
+ ds.ds_prevpage = GetLong(ds.ds_fp);
+
+ /* reset DVI page position and stack pointer, then call driver */
+ ds.ds_cur = ds.ds_fresh;
+ ds.ds_sp = ds.ds_stack;
+
+ (*fn)(count);
+}