home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / s / stex2-18.zip / SeeTeX / libtex / dvistate.c < prev    next >
C/C++ Source or Header  |  1990-07-10  |  6KB  |  244 lines

  1. /*
  2.  * Copyright (c) 1987, 1989 University of Maryland
  3.  * Department of Computer Science.  All rights reserved.
  4.  * Permission to copy for any purpose is hereby granted
  5.  * so long as this copyright notice remains intact.
  6.  */
  7.  
  8. #ifndef lint
  9. 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 $";
  10. #endif
  11.  
  12. /*
  13.  * dvistate - basic DVI machine interpreter
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include "types.h"
  18. #include "conv.h"
  19. #include "dvicodes.h"
  20. #include "error.h"
  21. #include "fio.h"
  22. #include "font.h"
  23. #include "gripes.h"
  24. #include "postamble.h"
  25. #include "search.h"
  26. #include "seek.h"
  27. #include "dvistate.h"
  28.  
  29. struct dvi_state ds;
  30.  
  31. /* yech, statics! */
  32. static struct font *(*s_deffnt)();
  33. static int s_dpi;
  34. static int s_errs;
  35.  
  36. static void pre(), post(), fntdef();
  37.  
  38. char *malloc();
  39.  
  40. /*
  41.  * Read through the postamble and the preamble and set up the
  42.  * global DVI state.  Each font is passed to (*fontfn)().
  43.  * Upon return, the input file (fp) is positioned at the beginning
  44.  * of the first page.
  45.  *
  46.  * dpi is the resolution of the printer in pixels (dots) per inch,
  47.  * and xoffset and yoffset are the values from the -X and -Y flags
  48.  * (default zero).  We add 1000 to each offset (since the offsets
  49.  * are in 1/1000ths of an inch), and then multiply by dpi and divide
  50.  * by 1000, to get the actual offset.
  51.  *
  52.  * If a device introduces a constant offset, e.g., of .25 inch
  53.  * horizontally and .31 inch vertically, the caller can compensate
  54.  * by passing (xflag - 2500) and (yflag - 3100).
  55.  */
  56. void
  57. DVISetState(fp, fontfn, dpi, xoffset, yoffset)
  58.     FILE *fp;
  59.     struct font *(*fontfn)();
  60.     int dpi, xoffset, yoffset;
  61. {
  62.  
  63.     /* make sure fseek() will work */
  64.     if ((ds.ds_fp = SeekFile(fp)) == NULL)
  65.         error(1, -1, "unable to copy input to temp file (disk full?)");
  66.  
  67.     /* h and v must be deferred until we have a conversion */
  68.     ds.ds_fresh.hh = ((1000 + (i32)xoffset) * dpi) / 1000;
  69.     ds.ds_fresh.vv = ((1000 + (i32)yoffset) * dpi) / 1000;
  70.  
  71.     ds.ds_fonts = SCreate(sizeof(struct font *));
  72.     if (ds.ds_fonts == NULL)
  73.         error(1, 0, "cannot create font table (out of memory?)");
  74.     s_errs = 0;
  75.     s_dpi = dpi;
  76.     s_deffnt = fontfn;
  77.     ScanPostAmble(ds.ds_fp, post, fntdef);
  78.     if (s_errs)
  79.         GripeMissingFontsPreventOutput(s_errs);
  80.     pre();
  81. }
  82.  
  83. /*
  84.  * Read the preamble and apply sanity checks.
  85.  * The presence of a preamble is virtually certain,
  86.  * since we have already found and read a postamble.
  87.  */
  88. static void
  89. pre()
  90. {
  91.     register int n;
  92.     register FILE *fp = ds.ds_fp;
  93.  
  94.     rewind(fp);
  95.     if (GetByte(fp) != Sign8(DVI_PRE))
  96.         GripeMissingOp("PRE");
  97.     if (GetByte(fp) != Sign8(DVI_VERSION))
  98.         GripeMismatchedValue("version number");
  99.     if (GetLong(fp) != ds.ds_num)
  100.         GripeMismatchedValue("numerator");
  101.     if (GetLong(fp) != ds.ds_denom)
  102.         GripeMismatchedValue("denominator");
  103.     if (GetLong(fp) != ds.ds_dvimag)
  104.         GripeMismatchedValue("\\magnification");
  105.     n = UnSign8(GetByte(fp));
  106.     while (--n >= 0)
  107.         (void) GetByte(fp);
  108. }
  109.  
  110. /*
  111.  * Store the relevant information from the DVI postamble.
  112.  */
  113. static void
  114. post(p)
  115.     register struct PostAmbleInfo *p;
  116. {
  117.     register int n;
  118.  
  119.     ds.ds_prevpage = p->pai_PrevPagePointer;
  120.     ds.ds_num = p->pai_Numerator;
  121.     ds.ds_denom = p->pai_Denominator;
  122.     ds.ds_dvimag = p->pai_DVIMag;
  123.     ds.ds_maxheight = p->pai_TallestPageHeight;
  124.     ds.ds_maxwidth = p->pai_WidestPageWidth;
  125.     ds.ds_npages = p->pai_NumberOfPages;
  126.  
  127.     /* set the global conversion factor */
  128.     SetConversion(s_dpi,
  129.         ds.ds_usermag, ds.ds_num, ds.ds_denom, ds.ds_dvimag);
  130.  
  131.     ds.ds_fresh.h = toSP(ds.ds_fresh.hh);
  132.     ds.ds_fresh.v = toSP(ds.ds_fresh.vv);
  133. #ifdef unneeded            /* counting on init-to-zero ... */
  134.     ds.ds_fresh.w = 0;
  135.     ds.ds_fresh.x = 0;
  136.     ds.ds_fresh.y = 0;
  137.     ds.ds_fresh.z = 0;
  138. #endif
  139.     /* make the stack */
  140.     n = p->pai_DVIStackSize * sizeof(DviStack);
  141.     if ((ds.ds_stack = (struct dvi_stack *)malloc((unsigned)n)) == NULL)
  142.         GripeOutOfMemory(n, "DVI stack");
  143.     ds.ds_sp = ds.ds_stack;
  144. }
  145.  
  146. /*
  147.  * Handle a font definition from the postamble.
  148.  */
  149. static void
  150. fntdef(p)
  151.     register struct PostAmbleFont *p;
  152. {
  153.     register struct font *f, **fp;
  154.     int def = S_CREATE | S_EXCL;
  155.  
  156.     fp = (struct font **)SSearch(ds.ds_fonts, p->paf_DVIFontIndex, &def);
  157.     if (fp == NULL) {
  158.         if (def & S_COLL)
  159.             GripeFontAlreadyDefined(p->paf_DVIFontIndex);
  160.         else
  161.             error(1, 0, "cannot stash font %ld (out of memory?)",
  162.                 (long)p->paf_DVIFontIndex);
  163.         /* NOTREACHED */
  164.     }
  165.  
  166.     /* apply driver function to get font */
  167.     f = (*s_deffnt)(p->paf_name, p->paf_DVIMag, p->paf_DVIDesignSize);
  168.     if (f == NULL) {
  169.         s_errs++;
  170.         return;
  171.     }
  172.     *fp = f;
  173.  
  174.     /* match checksums, unless one is (or both are) zero */
  175.     if (p->paf_DVIChecksum && f->f_checksum &&
  176.         p->paf_DVIChecksum != f->f_checksum)
  177.         GripeDifferentChecksums(f->f_path, p->paf_DVIChecksum,
  178.             f->f_checksum);
  179. }
  180.  
  181. /*
  182.  * Given a font index, return the corresponding pointer.
  183.  */
  184. struct font *
  185. DVIFindFont(n)
  186.     i32 n;
  187. {
  188.     int x = S_LOOKUP;
  189.     char *p;
  190.  
  191.     if ((p = SSearch(ds.ds_fonts, n, &x)) == NULL) {
  192.         GripeNoSuchFont(n);
  193.         /* NOTREACHED */
  194.     }
  195.     return (*(struct font **)p);
  196. }
  197.  
  198. /*
  199.  * Handle a rule: read width and height, then call the given function.
  200.  * If `advance', move dvi position afterwards.
  201.  */
  202. void
  203. DVIRule(fn, advance)
  204.     void (*fn)();
  205.     int advance;
  206. {
  207.     register i32 h, w, ww;
  208.     register FILE *fp = ds.ds_fp;
  209.  
  210.     fGetLong(fp, h);
  211.     fGetLong(fp, ww);
  212.     h = ConvRule(h);
  213.     w = ConvRule(ww);
  214.     (*fn)(h, w);
  215.     if (advance) {
  216.         dvi_hh += w;
  217.         dvi_h += ww;
  218.         w = fromSP(dvi_h);
  219.         FIXDRIFT(dvi_hh, w);
  220.     }
  221. }
  222.  
  223. /*
  224.  * Handle a BOP: read the ten \count values and the previous page pointer,
  225.  * reset DVI position, and call the given function.
  226.  */
  227. void
  228. DVIBeginPage(fn)
  229.     void (*fn)();
  230. {
  231.     register int i;
  232.     i32 count[10];
  233.  
  234.     for (i = 0; i < 10; i++)
  235.         count[i] = GetLong(ds.ds_fp);
  236.     ds.ds_prevpage = GetLong(ds.ds_fp);
  237.  
  238.     /* reset DVI page position and stack pointer, then call driver */
  239.     ds.ds_cur = ds.ds_fresh;
  240.     ds.ds_sp = ds.ds_stack;
  241.  
  242.     (*fn)(count);
  243. }
  244.