BSD 4_3 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 1 Feb 1986 05:45:07 +0000 (21:45 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 1 Feb 1986 05:45:07 +0000 (21:45 -0800)
Work on file usr/contrib/X/xdvi/dv.c
Work on file usr/contrib/X/xdvi/dvi.h
Work on file usr/contrib/X/xdvi/mktable.c
Work on file usr/contrib/X/xdvi/pxl.h

Synthesized-from: CSRG/cd1/4.3

usr/contrib/X/xdvi/dv.c [new file with mode: 0644]
usr/contrib/X/xdvi/dvi.h [new file with mode: 0644]
usr/contrib/X/xdvi/mktable.c [new file with mode: 0644]
usr/contrib/X/xdvi/pxl.h [new file with mode: 0644]

diff --git a/usr/contrib/X/xdvi/dv.c b/usr/contrib/X/xdvi/dv.c
new file mode 100644 (file)
index 0000000..6d5f54b
--- /dev/null
@@ -0,0 +1,1424 @@
+/*
+ * DVI previewer for X.
+ *
+ * Eric Cooper, CMU, September 1985.
+ *
+ * Code derived from dvi-imagen.c.
+ *
+ * Modified for X.10 by Bob Scheifler, MIT LCS, January 1986.
+ *
+ */
+#ifndef lint
+static char *dv_c = "$Header: dv.c,v 10.5 86/02/01 15:44:22 tony Rel $";
+#endif         lint
+
+#include <sys/types.h>
+#include <X/Xlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "dvi.h"
+#include "pxl.h"
+
+/* These are probably site dependent */
+#define FONT_DIRECTORY "/usr/lib/tex/fonts"
+#define FONT_SUFFIX    ".%dpxl"
+
+#define PAPER_WIDTH    ROUNDUP(17*pixels_per_inch,shrink_factor*2)
+#define PAPER_HEIGHT   ROUNDUP(11*pixels_per_inch,shrink_factor)
+#define X_PAGE_OFFSET  ROUNDUP(pixels_per_inch,shrink_factor)
+#define Y_PAGE_OFFSET  ROUNDUP(pixels_per_inch,shrink_factor)
+
+#define pixel_round(x)      ((long) (conv * (double) (x) + 0.5))
+#define dvi_round(x)        ((long) ((double) (x) / conv + 0.5))
+
+#define one(fp)     num (fp, 1)
+#define two(fp)     num (fp, 2)
+#define stwo(fp)    snum(fp, 2)
+#define four(fp)    num (fp, 4)
+#define sfour(fp)   snum(fp, 4)
+
+typedef unsigned char ubyte;
+
+struct frame {
+       long pxl_h, dvi_h, pxl_v, dvi_v, w, x, y, z;
+};
+
+struct frame *stack;
+int stackp;
+
+#define PXL_H   stack[stackp].pxl_h
+#define PXL_V   stack[stackp].pxl_v
+#define DVI_H   stack[stackp].dvi_h
+#define DVI_V   stack[stackp].dvi_v
+#define WW      stack[stackp].w
+#define XX      stack[stackp].x
+#define YY      stack[stackp].y
+#define ZZ      stack[stackp].z
+
+#define DBG_BITMAP     0x1
+#define DBG_DVI                0x2
+#define DBG_ALL                (DBG_BITMAP|DBG_DVI)
+
+/*
+ * Command line flags.
+ */
+int debug = 0;
+int list_fonts = 0;
+
+int pixels_per_inch = 300;
+int shrink_factor = 4;
+
+FILE *dvi_file;                                /* user's file */
+
+int font_not_found = 0;
+struct font *current_font = NULL;      /* ptr into circular list of fonts */
+#define MAX_OPEN_FONTS 12
+int n_open_fonts = 0;                  /* for LRU management of fonts */
+
+/*
+ * DVI preamble and postamble information.
+ */
+char job_id[300];
+int total_pages, maxstack;
+int current_page;
+double fraction, conv;
+long numerator, denominator, magnification;
+
+/*
+ * Offset in DVI file of last page, set in read_postamble().
+ */
+long last_page_offset;
+
+/*
+ * Table of page offsets in DVI file, indexed by page number - 1.
+ * Initialized in prepare_pages().
+ */
+long *page_offset;
+
+#define xdvi_width 15
+#define xdvi_height 15
+#define xdvi_x_hot 7
+#define xdvi_y_hot 7
+static short xdvi_bits[] = {
+   0x0080, 0x01c0, 0x03e0, 0x06b0,
+   0x0c98, 0x188c, 0x3086, 0x7fff,
+   0x3086, 0x188c, 0x0c98, 0x06b0,
+   0x03e0, 0x01c0, 0x0080};
+
+Window win;
+int forepix, backpix, highpix;
+
+long screen_w, screen_h, page_w, page_h;
+long min_x, max_x, min_y, max_y, base_x, base_y;
+long smin_x, smax_x, smin_y, smax_y;
+int redisplay = 0;
+
+unsigned long num();
+long snum();
+
+extern char reverse_byte[];
+char *malloc(), *calloc(), *index();
+
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       char *prog, *file;
+       char *display = NULL;
+       char *option;
+       OpaqueFrame frame;
+       int reverse = 0;
+       int bwidth = 2;
+       char *fore_color;
+       char *back_color;
+       char *high_color;
+       char *brdr_color;
+       char *mous_color;
+       char *geometry = NULL, def[32];
+       int backmap, bdrmap, mouspix;
+       Color cdef;
+
+       prog = *argv++;
+       argc--;
+       if ((option = XGetDefault(prog, "ReverseVideo")) &&
+           strcmp(option, "on") == 0)
+               reverse = 1;
+       if (option = XGetDefault(prog, "BorderWidth"))
+               bwidth = atoi(option);
+       fore_color = XGetDefault(prog, "ForeGround");
+       back_color = XGetDefault(prog, "BackGround");
+       high_color = XGetDefault(prog, "Highlight");
+       brdr_color = XGetDefault(prog, "Border");
+       mous_color = XGetDefault(prog, "Mouse");
+       file = NULL;
+        while (argc) {
+               if (strncmp(*argv, "-d", 2) == 0)
+                       debug = isdigit(argv[0][2]) ? atoi(&argv[0][2]) : DBG_ALL;
+               else if (strcmp(*argv, "-l") == 0)
+                       list_fonts = 1;
+               else if (strcmp(*argv, "-s") == 0 && argc > 1) {
+                       argv++;
+                       argc--;
+                       shrink_factor = atoi(*argv);
+                       if (shrink_factor <= 0) goto usage;
+               } else if (strcmp(*argv, "-p") == 0 && argc > 1) {
+                       argv++;
+                       argc--;
+                       pixels_per_inch = atoi(*argv);
+                       if (pixels_per_inch <= 0) goto usage;
+               } else if (strcmp(*argv, "-rv") == 0) {
+                       reverse = 1;
+               } else if (strcmp(*argv, "-fg") == 0 && argc > 1) {
+                       argv++;
+                       argc--;
+                       fore_color = *argv;
+               } else if (strcmp(*argv, "-bg") == 0 && argc > 1) {
+                       argv++;
+                       argc--;
+                       back_color = *argv;
+               } else if (strcmp(*argv, "-hl") == 0 && argc > 1) {
+                       argv++;
+                       argc--;
+                       high_color = *argv;
+               } else if (strcmp(*argv, "-bd") == 0 && argc > 1) {
+                       argv++;
+                       argc--;
+                       brdr_color = *argv;
+               } else if (strcmp(*argv, "-ms") == 0 && argc > 1) {
+                       argv++;
+                       argc--;
+                       mous_color = *argv;
+               } else if (**argv == '=') {
+                       geometry = *argv;
+               } else if (**argv != '-') {
+                       if (index(*argv, ':') != NULL)
+                               display = *argv;
+                       else
+                               file = *argv;
+               } else {
+                   usage:
+                       fprintf(stderr, "Usage: xdvi [-s <shrink>] [-p <pixels>] [-l] [-rv] [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] [-ms <color>] [=<geometry>] [host:display] dvi_file\n");
+                       exit(1);
+               }
+               argv++;
+               argc--;
+       }
+        if (file == NULL)
+               goto usage;
+       if ((dvi_file = fopen(file, "r")) == NULL) {
+               int n = strlen(file);
+               char *dvi_name;
+
+               if (strcmp(file + n - sizeof(".dvi") + 1, ".dvi") == 0) {
+                       perror(file);
+                       exit(1);
+               }
+               dvi_name = malloc((unsigned) n + sizeof(".dvi"));
+               sprintf(dvi_name, "%s.dvi", file);
+               if ((dvi_file = fopen(dvi_name, "r")) == NULL) {
+                       perror(dvi_name);
+                       exit(1);
+               }
+       }
+       process_preamble();
+       find_postamble();
+       read_postamble();
+       prepare_pages();
+       init_page();
+       if (XOpenDisplay(display) == NULL) {
+               fprintf(stderr, "Can't open display %s!\n", display);
+               exit(1);
+       }
+       if (reverse) {
+               forepix = WhitePixel;
+               highpix = WhitePixel;
+               backpix = BlackPixel;
+               backmap = BlackPixmap;
+               bdrmap = WhitePixmap;
+               mouspix = WhitePixel;
+       } else {
+               forepix = BlackPixel;
+               highpix = BlackPixel;
+               backpix = WhitePixel;
+               backmap = WhitePixmap;
+               bdrmap = BlackPixmap;
+               mouspix = BlackPixel;
+       }
+       if (DisplayCells() > 2) {
+               if (fore_color && XParseColor(fore_color, &cdef) &&
+                       XGetHardwareColor(&cdef))
+                       forepix = cdef.pixel;
+               if (back_color && XParseColor(back_color, &cdef) &&
+                       XGetHardwareColor(&cdef)) {
+                       backpix = cdef.pixel;
+                       backmap = XMakeTile(backpix);
+               }
+               if (high_color && XParseColor(high_color, &cdef) &&
+                       XGetHardwareColor(&cdef))
+                       highpix = cdef.pixel;
+               if (brdr_color && XParseColor(brdr_color, &cdef) &&
+                       XGetHardwareColor(&cdef))
+                       bdrmap = XMakeTile(cdef.pixel);
+               if (mous_color && XParseColor(mous_color, &cdef) &&
+                       XGetHardwareColor(&cdef))
+                       mouspix = cdef.pixel;
+       }
+       frame.bdrwidth = bwidth;
+       frame.height = page_h;
+       if (frame.height + (bwidth << 1) > DisplayHeight())
+           frame.height = DisplayHeight() - (bwidth << 1);
+       frame.width = page_w;
+       if (frame.width + (bwidth << 1) > DisplayWidth())
+           frame.width = DisplayWidth() - (bwidth << 1);
+       frame.border = bdrmap;
+       frame.background = backmap;
+       frame.x = 0;
+       frame.y = 0;
+       sprintf(def, "=%dx%d+0+0", frame.width, frame.height);
+       win = XCreate("DVI Previewer", prog, geometry, def, &frame, 50, 50);
+       screen_h = frame.height;
+       screen_w = frame.width;
+       XMapWindow(win);
+       XSelectInput(win, KeyPressed|ButtonPressed|ExposeWindow|ExposeRegion);
+       XDefineCursor(win,
+           XCreateCursor(xdvi_width, xdvi_height, xdvi_bits, xdvi_bits,
+                         xdvi_x_hot, xdvi_y_hot, mouspix, backpix, GXcopy));
+       do_pages();
+       stop_output(0);
+}
+
+/*
+**      process_preamble reads the information in the preamble and stores
+**      it into global variables for later use.
+*/
+process_preamble()
+{
+        ubyte   k;
+
+        if (one(dvi_file) != PRE)
+               error("xdvi: DVI file doesn't start with preamble");
+       if (one(dvi_file) != 2)
+               error("xdvi: Wrong version of DVI output for this program");
+       numerator     = four(dvi_file);
+       denominator   = four(dvi_file);
+       magnification = four(dvi_file);
+       fraction = (((double) numerator * magnification)
+                                        / ((double) denominator * 1000.));
+       define_conv();
+       k = one(dvi_file);
+       fread(job_id, sizeof(char), k, dvi_file);
+       job_id[k] = '\0';
+}
+
+define_conv ()
+{
+       conv = ((fraction * pixels_per_inch) / 100000) / (2.54 * shrink_factor);
+}
+
+/*
+**      find_postamble locates the beginning of the postamble
+**     and leaves the file ready to start reading at that location.
+*/
+find_postamble()
+{
+       ubyte byte;
+       long offset = -4;        /* At least 4 TRAILERS */
+
+       do {
+               offset -= 1;
+               fseek(dvi_file, offset, 2);
+               byte = one(dvi_file);
+       } while (byte == TRAILER);
+       if (byte != 2)
+               error("xdvi: Wrong version of DVI output for this program");
+       offset -= 4;
+       fseek(dvi_file, offset, 2);
+       fseek(dvi_file, sfour(dvi_file), 0);
+}
+
+/*
+**      read_postamble reads the information in the postamble,
+**     storing it into global variables.
+**      It also takes care of reading in all of the PXL files for the fonts
+**      used in the job.
+*/
+read_postamble()
+{
+        ubyte   cmnd;
+       int page_width, page_height;
+
+        if (one(dvi_file) != POST)
+           error("xdvi: Postamble doesn't begin with POST");
+       last_page_offset = four(dvi_file);
+       if (numerator != four(dvi_file)
+                 ||  denominator != four(dvi_file)
+                 ||  magnification != four(dvi_file))
+           error("xdvi: Postamble doesn't match preamble");
+       page_height = pixel_round(four(dvi_file));
+       page_width = pixel_round(four(dvi_file));
+       maxstack = two(dvi_file);
+       total_pages = two(dvi_file);
+       do {
+           switch(cmnd = one(dvi_file)) {
+               case FNTDEF1:
+               case FNTDEF2:
+               case FNTDEF3:
+               case FNTDEF4:
+                   define_font(cmnd);
+                   break;
+               case POSTPOST:
+                   break;
+               default:
+                   error("xdvi: Non-fntdef cmnd found in postamble");
+           }
+       } while (cmnd != POSTPOST);
+       if (font_not_found)
+               error("xdvi: Not all PXL files were found");
+       list_fonts = 0;
+}
+
+prepare_pages()
+{
+       int i;
+
+        stack = (struct frame *) malloc((unsigned) sizeof(struct frame) * (maxstack+1));
+        if (stack == NULL)
+               error("xdvi: Can't allocate stack space (%d frames)", maxstack);
+       page_offset = (long *) malloc((unsigned) total_pages * sizeof(long));
+        if (page_offset == NULL)
+               error("xdvi: Can't allocate page directory (%d pages)", total_pages);
+       i = total_pages;
+       page_offset[--i] = last_page_offset;
+       fseek(dvi_file, last_page_offset, 0);
+       /*
+        * Follow back pointers through pages in the DVI file,
+        * storing the offsets in the page_offset table.
+        */
+       while (i > 0) {
+               num(dvi_file, 1+4+(9*4));
+               fseek(dvi_file, page_offset[--i] = four(dvi_file), 0);
+       }
+}
+
+/*
+**      define_font reads the rest of the fntdef command and then reads in
+**      the specified PXL file, adding it to the global linked-list holding
+**      all of the fonts used in the job.
+*/
+define_font(cmnd)
+       ubyte cmnd;
+{
+        register struct font *fontp;
+       int len;
+       int unmodsize;
+       float realsize;
+       int size;
+        long checksum;
+
+       fontp = (struct font *) malloc((unsigned) sizeof(struct font));
+       if (fontp == NULL)
+               error("xdvi: Can't allocate memory for font");
+       fontp->TeXnumber = num(dvi_file, cmnd - FNTDEF1 + 1);
+       checksum = four(dvi_file);
+       fontp->scale = four(dvi_file);
+       fontp->design = four(dvi_file);
+       len = one(dvi_file) + one(dvi_file);
+       fontp->fontname = malloc(len + 10);     /* leave space for magnification */
+       fread(fontp->fontname, sizeof(char), len, dvi_file);
+       fontp->fontname[len] = '\0';
+       fontp->file = NULL;
+/*
+**     In the actual implementation, scaled-size/design-size hasn't been
+**     stored with sufficient precision, hence the messing around to find
+**     its actual value.
+*/
+       realsize = (magnification/1000.)*((float) fontp->scale / fontp->design);
+       unmodsize = (realsize * 1000) + 0.5;
+       /* a real hack to correct for rounding in some cases */
+       switch (unmodsize) {
+           case 1095:
+               realsize = 1.095445;    /* stephalf */
+               break;
+           case 1315:
+               realsize = 1.314534;    /* stepihalf */
+               break;
+           case 2074:
+               realsize = 2.0736;      /* stepiv */
+               break;
+           case 2488:
+               realsize = 2.48832;     /* stepv */
+               break;
+           case 2986:
+               realsize = 2.985984;    /* stepiv */
+               break;
+       }
+       /*
+        * the remaining magnification steps are represented
+        * with sufficient accuracy already
+        */
+       size = (realsize * pixels_per_inch * 5) + 0.5;
+       sprintf(&fontp->fontname[len], FONT_SUFFIX, size);
+       if (!open_pxl_file(fontp))
+               return;
+       read_glyphs(fontp);
+       if (current_font == NULL) {
+               fontp->next = fontp;
+               fontp->prev = fontp;
+       } else {
+               fontp->next = current_font;
+               fontp->prev = current_font->prev;
+               current_font->prev->next = fontp;
+               current_font->prev = fontp;
+       }
+       current_font = fontp;
+}
+
+open_pxl_file(font)
+       struct font *font;
+{
+       char filename[300];
+       extern int errno;
+
+       if (font->file == NULL) {
+               sprintf(filename, "%s/%s",
+                               FONT_DIRECTORY, font->fontname);
+               if (n_open_fonts == MAX_OPEN_FONTS)
+                       close_lru();
+               font->file = fopen(filename, "r");
+               if (font->file == NULL) {
+                       font_not_found = 1;
+                       printf("%s [not found]\n", font->fontname);
+                       return (0);
+               }
+               n_open_fonts += 1;
+       }
+       if (list_fonts)
+               printf("%s\n", font->fontname);
+       return (1);
+}
+
+read_pxl_bitmap(ch, g)
+       ubyte ch;
+       register struct glyph *g;
+{
+       register struct bitmap *bitmap;
+       register int file_bytes_wide;
+       register char *ptr;
+       register int i, j;
+
+       bitmap = &g->bitmap;
+
+       /* in file, bitmap rows are multiples of 32 bits wide */
+       file_bytes_wide = ROUNDUP(bitmap->w, BITS_PER_LONG)*BYTES_PER_LONG;
+       /* width must be multiple of 16 bits for raster_op */
+       bitmap->bytes_wide = ROUNDUP(bitmap->w, BITS_PER_SHORT)*BYTES_PER_SHORT;
+       ptr = bitmap->bits = malloc((unsigned) bitmap->h * bitmap->bytes_wide);
+       if (ptr == NULL)
+               error("xdvi: Can't allocate bitmap for character %d of font %s (%d by %d)",
+                       ch, current_font->fontname, bitmap->h, bitmap->w);
+       if (!open_pxl_file(current_font))
+               error("xdvi: Can't find font file %s", current_font->fontname);
+       fseek(current_font->file, g->addr, 0);
+       for (i = 0; i < bitmap->h; i += 1)
+               for (j = 0; j < file_bytes_wide; j += 1)
+                       if (j < bitmap->bytes_wide)
+                               *ptr++ = reverse_byte[one(current_font->file)];
+                       else
+                               one(current_font->file);
+       if (shrink_factor != 1)
+               shrink_bitmap(bitmap, shrink_factor, shrink_factor);
+       if (debug & DBG_BITMAP)
+               print_char(ch, g);
+}
+
+/*
+ * Find font #n and move it to the head of the list.
+ */
+change_font(n)
+       unsigned long n;
+{
+        register struct font *fontp;
+
+       fontp = current_font;
+       for (;;) {
+               if (fontp->TeXnumber == n)
+                        break;
+               fontp = fontp->next;
+               if (fontp == current_font)
+                       error("xdvi: Non-existent font #%d", n);
+       }
+       if (current_font == fontp)
+               return;
+       fontp->prev->next = fontp->next;
+       fontp->next->prev = fontp->prev;
+       fontp->next = current_font;
+       fontp->prev = current_font->prev;
+       current_font->prev->next = fontp;
+       current_font->prev = fontp;
+       current_font = fontp;
+}
+
+/*
+ * Close the PXL file for the least recently used font.
+ */
+close_lru()
+{
+        register struct font *f;
+
+       f = current_font->prev;
+       for (;;) {
+               if (f->file != NULL)
+                        break;
+               f = f->prev;
+               if (f == current_font->prev)
+                       error("xdvi: Can't find an open PXL file to close");
+       }
+       fclose(f->file);
+       f->file = NULL;
+       n_open_fonts -= 1;
+}
+
+reset_fonts()
+{
+        register struct font *f;
+       register struct glyph *g;
+
+       f = current_font;
+       for (;;) {
+           open_pxl_file(f);
+           for (g = &f->glyph[0]; g < &f->glyph[MAXCHARS]; g += 1) {
+               if (g->bitmap.bits) free(g->bitmap.bits);
+           }
+           read_glyphs(f);
+           f = f->next;
+           if (f == current_font) break;
+       }
+}
+
+read_glyphs (fontp)
+        register struct font *fontp;
+{
+       register struct glyph *g;
+        long checksum, magnify, design_size, font_dir_ptr, pxl_id_word;
+
+       /* seek to trailer info */
+       fseek(fontp->file, (long) -(5 * BYTES_PER_LONG), 2);
+        checksum = four(fontp->file);
+        magnify = four(fontp->file);
+        design_size = four(fontp->file);
+        font_dir_ptr = sfour(fontp->file) * 4;
+        pxl_id_word = four(fontp->file);
+#ifdef lint
+       magnify = design_size = pxl_id_word = magnify;
+#endif
+       /* seek to font directory */
+       fseek(fontp->file, font_dir_ptr, 0);
+       for (g = &fontp->glyph[0]; g < &fontp->glyph[MAXCHARS]; g += 1) {
+               g->bitmap.bits = NULL;
+               g->bitmap.w = two(fontp->file); /* leave this for shrink_bitmap */
+               g->bitmap.h = two(fontp->file); /* leave this for shrink_bitmap */
+               g->x = stwo(fontp->file) / shrink_factor;
+               g->y = stwo(fontp->file) / shrink_factor;
+               g->addr = four(fontp->file) * 4;
+               /*
+               **  The TFM-width word is kind of funny in the units
+               **  it is expressed in.  It works this way:
+               **
+               **  If a glyph has width 'w' in a font with design-size
+               **  'd' (both in same units), the TFM-width word is
+               **
+               **                    (w/d) * 2^20
+               **
+               **  Therefore, in order to find the glyph width in
+               **  DVI units (1 / 2^16 points), we take the design-size
+               **  'd' (in DVI's), the magnification 'm' of the PXL file
+               **  and the TFM-width word 't' to the width (in DVI's)
+               **  as follows:
+               **
+               **                     dmt
+               **                w = -----
+               **                    2^20
+               **
+               **  But the magnification of the PXL file is just the
+               **  scaled size 's' over the design size, so the final
+               **  expression for the width is
+               **
+               **                     st
+               **                w = ----
+               **                    2^20
+               **
+               */      
+               g->dvi_adv =
+                       ((double) fontp->scale * four(fontp->file)) / (1 << 20);
+               g->pxl_adv = pixel_round(g->dvi_adv);
+       }
+}
+
+#define nope(str)       error("xdvi: %s not implemented", str)
+#define correct()       (PXL_H = pixel_round(DVI_H))
+
+do_pages()
+{
+        ubyte ch;
+
+       min_x = 0;
+       min_y = 0;
+       max_x = screen_w;
+       max_y = screen_h;
+       base_x = min_x;
+       base_y = min_y;
+       current_page = 0;
+       for (;;) {
+               ch = one(dvi_file);
+               if (debug & DBG_DVI)
+                       print_dvi(ch);
+               if (ch <= SETCHAR0 + 127) {
+                       set_char(ch);
+                       DVI_H += current_font->glyph[ch].dvi_adv;
+                       PXL_H += current_font->glyph[ch].pxl_adv;
+                       correct();
+               } else if (FNTNUM0 <= ch  &&  ch <= FNTNUM0 + 63) {
+                       change_font((unsigned long) (ch - FNTNUM0));
+               } else {
+                       long a, b;
+
+                       switch (ch) {
+                           case SET1:
+                               nope("SET1");
+                               break;
+
+                           case SETRULE:
+                               a = sfour(dvi_file); b = sfour(dvi_file);
+                               if (a > 0  &&  b > 0) {
+                                   correct();
+                                   set_rule(pixel_round(a), pixel_round(b));
+                               }
+                               DVI_H += b;
+                               PXL_H =  pixel_round(DVI_H);
+                               break;
+
+                           case PUT1:
+                               nope("PUT1");
+                               break;
+
+                           case PUTRULE:
+                               a = sfour(dvi_file); b = sfour(dvi_file);
+                               if (a > 0  &&  b > 0) {
+                                   correct();
+                                   set_rule(pixel_round(a), pixel_round(b));
+                               }
+                               break;
+
+                           case NOP:
+                               break;
+
+                           case BOP:
+                               num(dvi_file, 11*4);
+                               stackp = 0;
+                               DVI_H = dvi_round(X_PAGE_OFFSET);
+                               PXL_H = X_PAGE_OFFSET;
+                               DVI_V = dvi_round(Y_PAGE_OFFSET);
+                               PXL_V = Y_PAGE_OFFSET;
+                               WW = XX = YY = ZZ = 0;
+                               begin_page();
+                               break;
+
+                           case EOP:
+                               if (stackp > 0)
+                                   error("Stack not empty at EOP (%d)",
+                                          stackp);
+                               end_page();
+                               if (ftell(dvi_file) > last_page_offset)
+                                   return;
+                               break;
+
+                           case PUSH:
+                               stackp++;
+                               if (stackp > maxstack)
+                                   error("xdvi: More PUSHes than were promised");
+                               stack[stackp] = stack[stackp - 1];
+                               break;
+
+                           case POP:
+                               stackp--;
+                               if (stackp < 0)
+                                   error("xdvi: More POPs than PUSHes");
+                               break;
+
+                           case RIGHT1:
+                           case RIGHT2:
+                           case RIGHT3:
+                           case RIGHT4:
+                               DVI_H += snum(dvi_file, ch - RIGHT1 + 1);
+                               PXL_H = pixel_round(DVI_H);
+                               break;
+
+                           case X0:
+                           case X1:
+                           case X2:
+                           case X3:
+                           case X4:
+                               if (ch != X0)
+                                   XX = snum(dvi_file, ch - X0);
+                               DVI_H += XX;
+                               PXL_H += pixel_round(XX);
+                               correct();
+                               break;
+
+                           case W0:
+                           case W1:
+                           case W2:
+                           case W3:
+                           case W4:
+                               if (ch != W0)
+                                   WW = snum(dvi_file, ch - W0);
+                               DVI_H += WW;
+                               PXL_H = pixel_round(DVI_H);
+                               break;
+
+                           case Y0:
+                           case Y1:
+                           case Y2:
+                           case Y3:
+                           case Y4:
+                               if (ch != Y0)
+                                   YY = snum(dvi_file, ch - Y0);
+                               DVI_V += YY;
+                               PXL_V = pixel_round(DVI_V);
+                               break;
+
+                           case Z0:
+                           case Z1:
+                           case Z2:
+                           case Z3:
+                           case Z4:
+                               if (ch != Z0)
+                                   ZZ = snum(dvi_file, ch - Z0);
+                               DVI_V += ZZ;
+                               PXL_V = pixel_round(DVI_V);
+                               break;
+
+                           case DOWN1:
+                           case DOWN2:
+                           case DOWN3:
+                           case DOWN4:
+                               DVI_V += snum(dvi_file, ch - DOWN1 + 1);
+                               PXL_V = pixel_round(DVI_V);
+                               break;
+
+                           case FNT1:
+                           case FNT2:
+                           case FNT3:
+                           case FNT4:
+                               change_font(num(dvi_file, ch - FNT1 + 1));
+                               break;
+
+                           case XXX1:
+                           case XXX2:
+                           case XXX3:
+                           case XXX4:
+                               a = num(dvi_file, ch - XXX1 + 1);
+                               if(a > 0)
+                                   special((unsigned long) a);
+                               break;
+
+                           case FNTDEF1:
+                           case FNTDEF2:
+                           case FNTDEF3:
+                           case FNTDEF4:
+                               fseek(dvi_file, (long) (12 + ch - FNTDEF1 + 1), 1);
+                               a = one(dvi_file) + one(dvi_file);
+                               fseek(dvi_file, (long) a, 1);
+                               break;
+
+                           case PRE:
+                               error("xdvi: Shouldn't happen: PRE encountered.");
+                               break;
+
+                           case POST:
+                               error("xdvi: Shouldn't happen: POST encountered.");
+                               break;
+
+                           case POSTPOST:
+                               error("xdvi: Shouldn't happen: POSTPOST encountered.");
+                               break;
+
+                           default:
+                               error("xdvi: Unknown op-code %d, offset %d",
+                                       ch, ftell(dvi_file));
+                       } /* end switch*/
+               } /* end else (ch not a SETCHAR or FNTNUM) */
+       } /* end for */
+}
+
+set_char(ch)
+       ubyte ch;
+{
+       register struct glyph *g;
+
+       g = &current_font->glyph[ch];
+       if (g->bitmap.bits == NULL)
+               read_pxl_bitmap(ch, g);
+       put_bitmap(&g->bitmap, (PXL_H - g->x), (PXL_V - g->y), forepix);
+}
+
+set_rule(h, w)
+       long h, w;
+{
+       /* (w,h) specifies lower left corner of rule box */
+       put_rectangle(PXL_H, PXL_V - h, w, h, forepix);
+}
+
+begin_page()
+{
+       if (debug)
+               return;
+       if (!redisplay)
+           clear_page();
+       put_border(0, 0, page_w, page_h, 1);
+}
+
+end_page()
+{
+       int ch, arg, sign, number, next_page;
+       XEvent event;
+       char *string;
+       int nbytes;
+
+#ifdef lint
+       number = 0;
+#endif
+       if (debug) {
+               if (++current_page == total_pages)
+                       exit(0);
+               return;
+       }
+       if (redisplay) {
+           min_x = smin_x;
+           max_x = smax_x;
+           min_y = smin_y;
+           max_y = smax_y;
+           redisplay = 0;
+       }
+       arg = 0;
+       for (;;) {
+               XNextEvent (&event);
+               switch (event.type) {
+               case ExposeWindow:
+                   screen_h = ((XExposeEvent *)(&event))->height;
+                   screen_w = ((XExposeEvent *)(&event))->width;
+                   max_x = min_x + screen_w;
+                   max_y = min_y + screen_h;
+                   string = "\f";
+                   nbytes = 1;
+                   break;
+               case ExposeRegion:
+                   smin_x = min_x;
+                   smax_x = max_x;
+                   smin_y = min_y;
+                   smax_y = max_y;
+                   min_x = min_x + ((XExposeEvent *)(&event))->x;
+                   min_y = min_y + ((XExposeEvent *)(&event))->y;
+                   max_x = min_x + ((XExposeEvent *)(&event))->width;
+                   max_y = min_y + ((XExposeEvent *)(&event))->height;
+                   redisplay = 1;
+                   string = "\f";
+                   nbytes = 1;
+                   break;
+               case ButtonPressed:
+                   {
+                   short detail = ((XButtonPressedEvent *) (&event))->detail;
+                   switch (detail & ValueMask) {
+                   case LeftButton:
+                       if (detail & ShiftMask)
+                           string = "l";
+                       else
+                           string = "b";
+                       nbytes = 1;
+                       break;
+                   case MiddleButton:
+                       if (detail & ShiftMask)
+                           string = "u";
+                       else
+                           string = "d";
+                       nbytes = 1;
+                       break;
+                   case RightButton:
+                       if (detail & ShiftMask)
+                           string = "r";
+                       else
+                           string = "f";
+                       nbytes = 1;
+                       break;
+                   }
+                   }
+                   break;
+               case KeyPressed:
+                   string = XLookupMapping (&event, &nbytes);
+                   break;
+               }
+               if (nbytes == 0) continue;
+               if (nbytes > 1) goto bad;
+               switch (ch = *string) {
+                   case 'q':
+                   case '\003':        /* control-C */
+                   case '\004':        /* control-D */
+                       stop_output(0);
+                       break;
+                   case 'n':
+                   case 'f':
+                   case ' ':
+                       /* scroll forward */
+                       min_x = 0;
+                       min_y = 0;
+                       max_x = screen_w;
+                       max_y = screen_h;
+                       next_page = current_page + 1;
+                       break;
+                   case 'p':
+                   case 'b':
+                   case '\b':
+                       /* scroll backward */
+                       min_x = 0;
+                       min_y = 0;
+                       max_x = screen_w;
+                       max_y = screen_h;
+                       next_page = current_page - 1;
+                       break;
+                   case 'u':
+                       if (min_y == 0) goto bad;
+                       min_y -= screen_h;
+                       if (min_y < 0)
+                           min_y = 0;
+                       base_y = min_y;
+                       max_y = min_y + screen_h;
+                       next_page = current_page;
+                       break;
+                   case 'd':
+                       if (min_y >= page_h - screen_h) goto bad;
+                       min_y += screen_h;
+                       if (min_y > page_h - screen_h)
+                           min_y = page_h - screen_h;
+                       if (min_y < 0)
+                           min_y = 0;
+                       base_y = min_y;
+                       max_y = min_y + screen_h;
+                       next_page = current_page;
+                       break;
+                   case 'l':
+                       if (min_x == 0) goto bad;
+                       min_x -= screen_w;
+                       if (min_x < 0)
+                           min_x = 0;
+                       base_x = min_x;
+                       max_x = min_x + screen_w;
+                       next_page = current_page;
+                       break;
+                   case 'r':
+                       if (min_x >= page_w - screen_w) goto bad;
+                       min_x += screen_w;
+                       if (min_x > page_w - screen_w)
+                           min_x = page_w - screen_w;
+                       if (min_x < 0)
+                           min_x = 0;
+                       base_x = min_x;
+                       max_x = min_x + screen_w;
+                       next_page = current_page;
+                       break;
+                   case 's':
+                       if (!arg) {
+                           int shrink = shrink_factor;
+                           long fac1, fac2;
+                           shrink_factor = 1;
+                           fac1 = ROUNDUP(PAPER_WIDTH, screen_w);
+                           fac2 = ROUNDUP(PAPER_HEIGHT, screen_h);
+                           if (fac1 < fac2)
+                               number = fac2;
+                           else
+                               number = fac1;
+                           shrink_factor = shrink;
+                       }
+                       if (number <= 0) goto bad;
+                       if (number != shrink_factor) {
+                           shrink_factor = number;
+                           min_x = 0;
+                           min_y = 0;
+                           max_x = screen_w;
+                           max_y = screen_h;
+                           init_page();
+                           define_conv();
+                           reset_fonts();
+                       }
+                   case '\f':
+                       /* redisplay current page */
+                       next_page = current_page;
+                       break;
+                   case '\r':
+                   case '\n':
+                       /* go to relative page */
+                       min_x = 0;
+                       min_y = 0;
+                       max_x = screen_w;
+                       max_y = screen_h;
+                       next_page = current_page + (arg ? number : 1);
+                       break;
+                   case 'g':
+                       /* go to absolute page */
+                       min_x = 0;
+                       min_y = 0;
+                       max_x = screen_w;
+                       max_y = screen_h;
+                       next_page = (arg ? number : total_pages) - 1;
+                       break;
+                   case '0': case '1': case '2': case '3': case '4':
+                   case '5': case '6': case '7': case '8': case '9':
+                       if (! arg) {
+                               arg = 1;
+                               sign = 1;
+                               number = 0;
+                       }
+                       number = 10*number + sign*(ch - '0');
+                       continue;
+                   case '-':
+                       if (! arg) {
+                               arg = 1;
+                               sign = -1;
+                               number = 0;
+                               continue;
+                       } else
+                               goto bad;
+                   default:
+                       goto bad;
+               }
+               if (0 <= next_page && next_page < total_pages) {
+                       current_page = next_page;
+                       fseek(dvi_file, page_offset[current_page], 0);
+                       break;
+               }
+       bad:
+               XFeep(0);
+               arg = 0;                /* throw away numeric argument */
+               continue;
+       }
+}
+
+special(nbytes)
+       unsigned long nbytes;
+{
+       char *cmd;
+       int i;
+
+       cmd = malloc((unsigned) nbytes+1);
+       if (cmd == NULL)
+               error("xdvi: Can't allocate memory for special (%d bytes)", nbytes);
+       for (i = 0; i < nbytes; i += 1)
+               cmd[i] = getc(dvi_file);
+       cmd[i] = '\0';
+       fprintf(stderr, "special ``%s'' not implemented\n", cmd);
+       free(cmd);
+}
+
+/*
+**
+**      Read size bytes from the FILE fp, constructing them into a
+**      signed/unsigned integer.
+**
+*/
+unsigned long
+num(fp, size)
+       register FILE *fp;
+       register int size;
+{
+        register int i;
+       register long x;
+
+       x = 0;
+       for (i = 0; i < size; i += 1)
+               x = x * 0x100 + (unsigned) getc(fp);
+       return (x);
+}
+
+long
+snum(fp, size)
+       register FILE *fp;
+       register int size;
+{
+        register int i;
+       register long x;
+
+       x = getc(fp) & 0xff;
+       if (x & 0x80)
+               x -= 0x100;
+       for (i = 1; i < size; i += 1)
+           x = x * 0x100 + (unsigned) getc(fp);
+       return (x);
+}
+
+stop_output(sig)
+{
+       exit(sig);
+}
+
+/* VARARGS1 */
+error(message, a, b, c, d, e, f)
+       char *message;
+{
+       fprintf(stderr, message, a, b, c, d, e, f);
+       putc('\n', stderr);
+       exit(1);
+}
+
+init_page()
+{
+       page_h = PAPER_HEIGHT;
+       page_w = PAPER_WIDTH;
+}
+
+clear_page()
+{
+       XClear(win);
+}
+
+put_border(x, y, w, h, t)
+       long x, y, w, h, t;
+{
+       put_rectangle(x, y, w, t, highpix);
+       put_rectangle(x, y, t, h, highpix);
+       put_rectangle(x, y + h - t, w, t, highpix);
+       put_rectangle(x + w - t, y, t, h, highpix);
+}
+
+put_rectangle(x, y, w, h, pix)
+       long x, y, w, h;
+       int pix;
+{
+       if (x < max_x && x + w >= min_x && y < max_y && y + h >= min_y)
+               XPixSet(win, x - base_x, y - base_y, w, h, pix);
+}
+
+put_bitmap(bitmap, x, y, pix)
+       register struct bitmap *bitmap;
+       register long x, y;
+       int pix;
+{
+       if (x < max_x && x + bitmap->w >= min_x &&
+           y < max_y && y + bitmap->h >= min_y)
+               XBitmapBitsPut(win, x - base_x, y - base_y,
+                               bitmap->w, bitmap->h, (char *) bitmap->bits,
+                               pix, backpix, NULL, GXcopy, AllPlanes);
+}
+
+sample(bitmap, x, y, w, h)
+       register struct bitmap *bitmap;
+       int x, y, w, h;
+{
+       register char *ptr, *endp;
+       register int b, i, j, m, n;
+
+       ptr = bitmap->bits
+               + (y * bitmap->bytes_wide)
+               + (x / BITS_PER_BYTE);
+       endp = bitmap->bits + (bitmap->h * bitmap->bytes_wide);
+       b = (1 << (x % BITS_PER_BYTE));
+       n = 0;
+       for (i = 0; i < h && ptr < endp; i += 1, ptr += bitmap->bytes_wide)
+               for (m = b, j = 0; j < w; j += 1, m <<= 1)
+                       if (*ptr & m)
+                               n += 1;
+       return (n >= (i * w) / 3);
+}
+
+shrink_bitmap(bitmap, x_factor, y_factor)
+       register struct bitmap *bitmap;
+       int x_factor, y_factor;
+{
+       char *shrunk_bits;
+       int shrunk_height, shrunk_width, shrunk_bytes_wide;
+       register char *ptr;
+       char *cp;
+       register int x, y, b, m;
+
+       shrunk_height = ROUNDUP(bitmap->h, y_factor);
+       shrunk_width = ROUNDUP(bitmap->w, x_factor);
+       shrunk_bytes_wide = ROUNDUP(shrunk_width, BITS_PER_SHORT)*BYTES_PER_SHORT;
+               /* width must be multiple of 16 bits for raster_op */
+       ptr = shrunk_bits = calloc((unsigned) shrunk_height * shrunk_bytes_wide, 1);
+       if (ptr == NULL)
+               error("Can't allocate shrunken bitmap (%d by %d)",
+                       shrunk_height, shrunk_width);
+       for (y = 0; y < bitmap->h; y += y_factor) {
+               b = 0;
+               m = (1 << 0);
+               cp = ptr;
+               for (x = 0; x < bitmap->w; x += x_factor) {
+                       if (sample(bitmap, x, y, x_factor, y_factor))
+                               *ptr |= m;
+                       else
+                               *ptr &= ~m;
+                       b += 1;
+                       m <<= 1;
+                       if (b % BITS_PER_BYTE == 0) {
+                               b = 0;
+                               m = (1 << 0);
+                               ptr += 1;
+                       }
+               }
+               ptr = cp + shrunk_bytes_wide;
+       }
+       free(bitmap->bits);
+       bitmap->bits = shrunk_bits;
+       bitmap->h = shrunk_height;
+       bitmap->w = shrunk_width;
+       bitmap->bytes_wide = shrunk_bytes_wide;
+}
+
+print_char(ch, g)
+       ubyte ch;
+       struct glyph *g;
+{
+       printf("char %d", ch);
+       if (isprint(ch))
+               printf(" (%c)", ch);
+       putchar('\n');
+       printf("x = %d, y = %d, pxl = %d, dvi = %d\n",
+               g->x, g->y, g->pxl_adv, g->dvi_adv);
+       print_bitmap(&g->bitmap);
+}
+
+print_bitmap(bitmap)
+       register struct bitmap *bitmap;
+{
+       register char *ptr;
+       register int x, y, i;
+
+       ptr = bitmap->bits;
+       if (ptr == NULL)
+               return;
+       printf("w = %d, h = %d, bytes wide = %d\n",
+               bitmap->w, bitmap->h, bitmap->bytes_wide);
+       for (y = 0; y < bitmap->h; y += 1) {
+               for (x = 0; x < bitmap->bytes_wide; x += 1) {
+                       for (i = 0; i < BITS_PER_BYTE; i += 1)
+                               if (*ptr & (1 << i))
+                                       putchar('@');
+                               else
+                                       putchar(' ');
+                       ptr += 1;
+               }
+               putchar('\n');
+       }
+}
+
+print_dvi(ch)
+       ubyte ch;
+{
+       printf("%4d %4d ", PXL_H, PXL_V);
+       if (ch <= SETCHAR0 + 127) {
+               printf("SETCHAR%-3d", ch - SETCHAR0);
+               if (isprint(ch))
+                       printf(" (%c)", ch);
+       } else if (FNTNUM0 <= ch  &&  ch <= FNTNUM0 + 63) {
+               printf("FNTNUM%d", ch - FNTNUM0);
+       } else {
+               switch (ch) {
+                   case SET1:
+                       printf("SET1");
+                       break;
+                   case SETRULE:
+                       printf("SETRULE");
+                       break;
+                   case PUT1:
+                       printf("PUT1");
+                       break;
+                   case PUTRULE:
+                       printf("PUTRULE");
+                       break;
+                   case NOP:
+                       printf("NOP");
+                       break;
+                   case BOP:
+                       printf("BOP");
+                       break;
+                   case EOP:
+                       printf("EOP");
+                       break;
+                   case PUSH:
+                       printf("PUSH");
+                       break;
+                   case POP:
+                       printf("POP");
+                       break;
+                   case RIGHT1:
+                   case RIGHT2:
+                   case RIGHT3:
+                   case RIGHT4:
+                       printf("RIGHT%d", ch - RIGHT1 + 1);
+                       break;
+                   case X0:
+                   case X1:
+                   case X2:
+                   case X3:
+                   case X4:
+                       printf("X%d", ch - X0);
+                       break;
+                   case W0:
+                   case W1:
+                   case W2:
+                   case W3:
+                   case W4:
+                       printf("W%d", ch - W0);
+                       break;
+                   case Y0:
+                   case Y1:
+                   case Y2:
+                   case Y3:
+                   case Y4:
+                       printf("Y%d", ch - Y0);
+                       break;
+                   case Z0:
+                   case Z1:
+                   case Z2:
+                   case Z3:
+                   case Z4:
+                       printf("Z%d", ch - Z0);
+                       break;
+                   case DOWN1:
+                   case DOWN2:
+                   case DOWN3:
+                   case DOWN4:
+                       printf("DOWN%d", ch - DOWN1 + 1);
+                       break;
+                   case FNT1:
+                   case FNT2:
+                   case FNT3:
+                   case FNT4:
+                       printf("FNT%d", ch - FNT1 + 1);
+                       break;
+                   case XXX1:
+                   case XXX2:
+                   case XXX3:
+                   case XXX4:
+                       printf("XXX%d", ch - XXX1 + 1);
+                       break;
+                   case FNTDEF1:
+                   case FNTDEF2:
+                   case FNTDEF3:
+                   case FNTDEF4:
+                       printf("FNTDEF%d", ch - FNTDEF1 + 1);
+                       break;
+                   case PRE:
+                       printf("PRE");
+                       break;
+                   case POST:
+                       printf("POST");
+                       break;
+                   case POSTPOST:
+                       printf("POSTPOST");
+                       break;
+                   default:
+                       error("xdvi: Unknown op-code %d, offset %d",
+                               ch, ftell(dvi_file));
+               } /* end switch*/
+       } /* end else (ch not a SETCHAR or FNTNUM) */
+       putchar('\n');
+}
diff --git a/usr/contrib/X/xdvi/dvi.h b/usr/contrib/X/xdvi/dvi.h
new file mode 100644 (file)
index 0000000..4134a05
--- /dev/null
@@ -0,0 +1,58 @@
+/* $Header: dvi.h,v 10.5 86/02/01 15:44:52 tony Rel $ */
+
+#define SETCHAR0    0
+#define SET1        128
+#define SETRULE     132
+#define PUT1        133
+#define PUTRULE     137
+#define NOP         138
+#define BOP         139
+#define EOP         140
+#define PUSH        141
+#define POP         142
+#define RIGHT1      143
+#define RIGHT2      144
+#define RIGHT3      145
+#define RIGHT4      146
+#define W0          147
+#define W1          148
+#define W2          149
+#define W3          150
+#define W4          151
+#define X0          152
+#define X1          153
+#define X2          154
+#define X3          155
+#define X4          156
+#define DOWN1       157
+#define DOWN2       158
+#define DOWN3       159
+#define DOWN4       160
+#define Y0          161
+#define Y1          162
+#define Y2          163
+#define Y3          164
+#define Y4          165
+#define Z0          166
+#define Z1          167
+#define Z2          168
+#define Z3          169
+#define Z4          170
+#define FNTNUM0     171
+#define FNT1        235
+#define FNT2        236
+#define FNT3        237
+#define FNT4        238
+#define XXX1        239
+#define XXX2        240
+#define XXX3        241
+#define XXX4        242
+#define FNTDEF1     243
+#define FNTDEF2     244
+#define FNTDEF3     245
+#define FNTDEF4     246
+#define PRE         247
+#define POST        248
+#define POSTPOST    249
+
+#define TRAILER     223     /* Trailing bytes at end of file */
diff --git a/usr/contrib/X/xdvi/mktable.c b/usr/contrib/X/xdvi/mktable.c
new file mode 100644 (file)
index 0000000..ff50685
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef lint
+static char *mktable_c = "$Header: mktable.c,v 10.5 86/02/01 15:44:59 tony Rel $";
+#endif         lint
+
+#include <stdio.h>
+
+char reverse_byte[0x100] = { 0 };
+
+main()
+{
+       seed_table();
+       fill_in_table();
+       print_table();
+}
+
+seed_table()
+{
+       int i = 0;
+       int j = 0x100/2;
+       int b = 0;
+
+       for (;;) {
+               reverse_byte[i] = b;
+               if (j == 0)
+                       break;
+               i = 2*i + 1;
+               b = b + j;
+               j = j/2;
+       }
+}
+
+fill_in_table()
+{
+       int b;
+
+       for (b = 1; b < 0x100-2; b += 1)
+               reverse_byte[b+1] =
+                       reverse_byte[b] ^ reverse_byte[b^(b+1)];
+}
+
+print_table()
+{
+       int b;
+
+       printf("char reverse_byte[0x100] = {\n\t");
+       b = 0;
+       for (;;) {
+               printf("0x%02x", reverse_byte[b] & 0xff);
+               b += 1;
+               if (b == 0x100) {
+                       printf("\n};\n");
+                       return;
+               } else if (b % 8 == 0) {
+                       printf(",\n\t");
+               } else {
+                       printf(", ");
+               }
+       }
+}
diff --git a/usr/contrib/X/xdvi/pxl.h b/usr/contrib/X/xdvi/pxl.h
new file mode 100644 (file)
index 0000000..4133567
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *     Written by Eric C. Cooper, CMU
+ *
+ */
+/* $Header: pxl.h,v 10.5 86/02/01 15:45:03 tony Rel $ */
+
+#define BITS_PER_LONG 32
+#define BITS_PER_SHORT 16
+#define BITS_PER_BYTE 8
+
+#define BYTES_PER_LONG (BITS_PER_LONG/BITS_PER_BYTE)
+#define BYTES_PER_SHORT (BITS_PER_SHORT/BITS_PER_BYTE)
+
+#define SHORTS_PER_LONG (BITS_PER_LONG/BITS_PER_SHORT)
+
+#define ROUNDUP(x,y) (((x)+(y)-1)/(y))
+
+/*
+ * Raster ops.
+ */
+#define ROP_CLEAR      0
+#define ROP_ERASE      2
+#define ROP_COPYREV    3
+#define ROP_COPY       12
+#define ROP_PAINT      14
+#define ROP_FILL       15
+
+/*
+ * Bitmap structure for raster ops.
+ */    
+struct bitmap{
+       short h, w;             /* height and width in pixels */
+       short bytes_wide;       /* scan-line width in bytes */
+       char *bits;             /* pointer to the bits */
+};
+
+#define MAXCHARS 128           /* make 256 for 8 bit characters */
+
+/*
+ * Per-character information.
+ * There is one of these for each character in a font.
+ * All fields are filled in at font definition time,
+ * except for the bitmap, which is "faulted in"
+ * when the character is first referenced.
+ */
+struct glyph {
+       long addr;              /* address of bitmap in PXL file */
+       long dvi_adv;           /* DVI units to move reference point */
+       short x, y;             /* x and y offset in pixels */
+       struct bitmap bitmap;   /* bitmap for character */
+       short pxl_adv;          /* pixels to move reference point */
+};
+
+/*
+ * The layout of a font information block.
+ * There is one of these for every loaded font or
+ * magnification thereof.
+ *
+ * Also note the strange units.  The design size is in 1/2^20 point
+ * units (also called micro-points), and the individual character widths
+ * are in the TFM file in 1/2^20 ems units, i.e. relative to the design size.
+ */
+
+struct font {
+       struct font *next;              /* link to next font info block */
+       struct font *prev;              /* link to previous font info block */
+       int TeXnumber;                  /* font number (in DVI file) */
+       int scale;                      /* scaled size in DVI units */
+       int design;                     /* design size in DVI units */
+       char *fontname;                 /* PXL file name */
+       FILE *file;                     /* open PXL file or NULL */
+       struct glyph glyph[MAXCHARS];
+};