1: /*
   2:  * DVI previewer for X.
   3:  *
   4:  * Eric Cooper, CMU, September 1985.
   5:  *
   6:  * Code derived from dvi-imagen.c.
   7:  *
   8:  * Modified for X.10 by Bob Scheifler, MIT LCS, January 1986.
   9:  *
  10:  */
  11: #ifndef lint
  12: static char *dv_c = "$Header: dv.c,v 10.5 86/02/01 15:44:22 tony Rel $";
  13: #endif 	lint
  14: 
  15: #include <sys/types.h>
  16: #include <X/Xlib.h>
  17: #include <stdio.h>
  18: #include <ctype.h>
  19: #include "dvi.h"
  20: #include "pxl.h"
  21: 
  22: /* These are probably site dependent */
  23: #define FONT_DIRECTORY  "/usr/lib/tex/fonts"
  24: #define FONT_SUFFIX ".%dpxl"
  25: 
  26: #define PAPER_WIDTH ROUNDUP(17*pixels_per_inch,shrink_factor*2)
  27: #define PAPER_HEIGHT    ROUNDUP(11*pixels_per_inch,shrink_factor)
  28: #define X_PAGE_OFFSET   ROUNDUP(pixels_per_inch,shrink_factor)
  29: #define Y_PAGE_OFFSET   ROUNDUP(pixels_per_inch,shrink_factor)
  30: 
  31: #define pixel_round(x)      ((long) (conv * (double) (x) + 0.5))
  32: #define dvi_round(x)        ((long) ((double) (x) / conv + 0.5))
  33: 
  34: #define one(fp)     num (fp, 1)
  35: #define two(fp)     num (fp, 2)
  36: #define stwo(fp)    snum(fp, 2)
  37: #define four(fp)    num (fp, 4)
  38: #define sfour(fp)   snum(fp, 4)
  39: 
  40: typedef unsigned char ubyte;
  41: 
  42: struct frame {
  43:     long pxl_h, dvi_h, pxl_v, dvi_v, w, x, y, z;
  44: };
  45: 
  46: struct frame *stack;
  47: int stackp;
  48: 
  49: #define PXL_H   stack[stackp].pxl_h
  50: #define PXL_V   stack[stackp].pxl_v
  51: #define DVI_H   stack[stackp].dvi_h
  52: #define DVI_V   stack[stackp].dvi_v
  53: #define WW      stack[stackp].w
  54: #define XX      stack[stackp].x
  55: #define YY      stack[stackp].y
  56: #define ZZ      stack[stackp].z
  57: 
  58: #define DBG_BITMAP  0x1
  59: #define DBG_DVI     0x2
  60: #define DBG_ALL     (DBG_BITMAP|DBG_DVI)
  61: 
  62: /*
  63:  * Command line flags.
  64:  */
  65: int debug = 0;
  66: int list_fonts = 0;
  67: 
  68: int pixels_per_inch = 300;
  69: int shrink_factor = 4;
  70: 
  71: FILE *dvi_file;             /* user's file */
  72: 
  73: int font_not_found = 0;
  74: struct font *current_font = NULL;   /* ptr into circular list of fonts */
  75: #define MAX_OPEN_FONTS 12
  76: int n_open_fonts = 0;           /* for LRU management of fonts */
  77: 
  78: /*
  79:  * DVI preamble and postamble information.
  80:  */
  81: char job_id[300];
  82: int total_pages, maxstack;
  83: int current_page;
  84: double fraction, conv;
  85: long numerator, denominator, magnification;
  86: 
  87: /*
  88:  * Offset in DVI file of last page, set in read_postamble().
  89:  */
  90: long last_page_offset;
  91: 
  92: /*
  93:  * Table of page offsets in DVI file, indexed by page number - 1.
  94:  * Initialized in prepare_pages().
  95:  */
  96: long *page_offset;
  97: 
  98: #define xdvi_width 15
  99: #define xdvi_height 15
 100: #define xdvi_x_hot 7
 101: #define xdvi_y_hot 7
 102: static short xdvi_bits[] = {
 103:    0x0080, 0x01c0, 0x03e0, 0x06b0,
 104:    0x0c98, 0x188c, 0x3086, 0x7fff,
 105:    0x3086, 0x188c, 0x0c98, 0x06b0,
 106:    0x03e0, 0x01c0, 0x0080};
 107: 
 108: Window win;
 109: int forepix, backpix, highpix;
 110: 
 111: long screen_w, screen_h, page_w, page_h;
 112: long min_x, max_x, min_y, max_y, base_x, base_y;
 113: long smin_x, smax_x, smin_y, smax_y;
 114: int redisplay = 0;
 115: 
 116: unsigned long num();
 117: long snum();
 118: 
 119: extern char reverse_byte[];
 120: char *malloc(), *calloc(), *index();
 121: 
 122: main(argc, argv)
 123:     int argc;
 124:     char **argv;
 125: {
 126:     char *prog, *file;
 127:     char *display = NULL;
 128:     char *option;
 129:     OpaqueFrame frame;
 130:     int reverse = 0;
 131:     int bwidth = 2;
 132:     char *fore_color;
 133:     char *back_color;
 134:     char *high_color;
 135:     char *brdr_color;
 136:     char *mous_color;
 137:     char *geometry = NULL, def[32];
 138:     int backmap, bdrmap, mouspix;
 139:     Color cdef;
 140: 
 141:     prog = *argv++;
 142:     argc--;
 143:     if ((option = XGetDefault(prog, "ReverseVideo")) &&
 144:         strcmp(option, "on") == 0)
 145:         reverse = 1;
 146:     if (option = XGetDefault(prog, "BorderWidth"))
 147:         bwidth = atoi(option);
 148:     fore_color = XGetDefault(prog, "ForeGround");
 149:     back_color = XGetDefault(prog, "BackGround");
 150:     high_color = XGetDefault(prog, "Highlight");
 151:     brdr_color = XGetDefault(prog, "Border");
 152:     mous_color = XGetDefault(prog, "Mouse");
 153:     file = NULL;
 154:         while (argc) {
 155:         if (strncmp(*argv, "-d", 2) == 0)
 156:             debug = isdigit(argv[0][2]) ? atoi(&argv[0][2]) : DBG_ALL;
 157:         else if (strcmp(*argv, "-l") == 0)
 158:             list_fonts = 1;
 159:         else if (strcmp(*argv, "-s") == 0 && argc > 1) {
 160:             argv++;
 161:             argc--;
 162:             shrink_factor = atoi(*argv);
 163:             if (shrink_factor <= 0) goto usage;
 164:         } else if (strcmp(*argv, "-p") == 0 && argc > 1) {
 165:             argv++;
 166:             argc--;
 167:             pixels_per_inch = atoi(*argv);
 168:             if (pixels_per_inch <= 0) goto usage;
 169:         } else if (strcmp(*argv, "-rv") == 0) {
 170:             reverse = 1;
 171:         } else if (strcmp(*argv, "-fg") == 0 && argc > 1) {
 172:             argv++;
 173:             argc--;
 174:             fore_color = *argv;
 175:         } else if (strcmp(*argv, "-bg") == 0 && argc > 1) {
 176:             argv++;
 177:             argc--;
 178:             back_color = *argv;
 179:         } else if (strcmp(*argv, "-hl") == 0 && argc > 1) {
 180:             argv++;
 181:             argc--;
 182:             high_color = *argv;
 183:         } else if (strcmp(*argv, "-bd") == 0 && argc > 1) {
 184:             argv++;
 185:             argc--;
 186:             brdr_color = *argv;
 187:         } else if (strcmp(*argv, "-ms") == 0 && argc > 1) {
 188:             argv++;
 189:             argc--;
 190:             mous_color = *argv;
 191:         } else if (**argv == '=') {
 192:             geometry = *argv;
 193:         } else if (**argv != '-') {
 194:             if (index(*argv, ':') != NULL)
 195:                 display = *argv;
 196:             else
 197:                 file = *argv;
 198:         } else {
 199:             usage:
 200:             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");
 201:             exit(1);
 202:         }
 203:         argv++;
 204:         argc--;
 205:     }
 206:         if (file == NULL)
 207:         goto usage;
 208:     if ((dvi_file = fopen(file, "r")) == NULL) {
 209:         int n = strlen(file);
 210:         char *dvi_name;
 211: 
 212:         if (strcmp(file + n - sizeof(".dvi") + 1, ".dvi") == 0) {
 213:             perror(file);
 214:             exit(1);
 215:         }
 216:         dvi_name = malloc((unsigned) n + sizeof(".dvi"));
 217:         sprintf(dvi_name, "%s.dvi", file);
 218:         if ((dvi_file = fopen(dvi_name, "r")) == NULL) {
 219:             perror(dvi_name);
 220:             exit(1);
 221:         }
 222:     }
 223:     process_preamble();
 224:     find_postamble();
 225:     read_postamble();
 226:     prepare_pages();
 227:     init_page();
 228:     if (XOpenDisplay(display) == NULL) {
 229:         fprintf(stderr, "Can't open display %s!\n", display);
 230:         exit(1);
 231:     }
 232:     if (reverse) {
 233:         forepix = WhitePixel;
 234:         highpix = WhitePixel;
 235:         backpix = BlackPixel;
 236:         backmap = BlackPixmap;
 237:         bdrmap = WhitePixmap;
 238:         mouspix = WhitePixel;
 239:     } else {
 240:         forepix = BlackPixel;
 241:         highpix = BlackPixel;
 242:         backpix = WhitePixel;
 243:         backmap = WhitePixmap;
 244:         bdrmap = BlackPixmap;
 245:         mouspix = BlackPixel;
 246:     }
 247:     if (DisplayCells() > 2) {
 248:         if (fore_color && XParseColor(fore_color, &cdef) &&
 249:             XGetHardwareColor(&cdef))
 250:             forepix = cdef.pixel;
 251:         if (back_color && XParseColor(back_color, &cdef) &&
 252:             XGetHardwareColor(&cdef)) {
 253:             backpix = cdef.pixel;
 254:             backmap = XMakeTile(backpix);
 255:         }
 256:         if (high_color && XParseColor(high_color, &cdef) &&
 257:             XGetHardwareColor(&cdef))
 258:             highpix = cdef.pixel;
 259:         if (brdr_color && XParseColor(brdr_color, &cdef) &&
 260:             XGetHardwareColor(&cdef))
 261:             bdrmap = XMakeTile(cdef.pixel);
 262:         if (mous_color && XParseColor(mous_color, &cdef) &&
 263:             XGetHardwareColor(&cdef))
 264:             mouspix = cdef.pixel;
 265:     }
 266:     frame.bdrwidth = bwidth;
 267:     frame.height = page_h;
 268:     if (frame.height + (bwidth << 1) > DisplayHeight())
 269:         frame.height = DisplayHeight() - (bwidth << 1);
 270:     frame.width = page_w;
 271:     if (frame.width + (bwidth << 1) > DisplayWidth())
 272:         frame.width = DisplayWidth() - (bwidth << 1);
 273:     frame.border = bdrmap;
 274:     frame.background = backmap;
 275:     frame.x = 0;
 276:     frame.y = 0;
 277:     sprintf(def, "=%dx%d+0+0", frame.width, frame.height);
 278:     win = XCreate("DVI Previewer", prog, geometry, def, &frame, 50, 50);
 279:     screen_h = frame.height;
 280:     screen_w = frame.width;
 281:     XMapWindow(win);
 282:     XSelectInput(win, KeyPressed|ButtonPressed|ExposeWindow|ExposeRegion);
 283:     XDefineCursor(win,
 284:         XCreateCursor(xdvi_width, xdvi_height, xdvi_bits, xdvi_bits,
 285:               xdvi_x_hot, xdvi_y_hot, mouspix, backpix, GXcopy));
 286:     do_pages();
 287:     stop_output(0);
 288: }
 289: 
 290: /*
 291: **      process_preamble reads the information in the preamble and stores
 292: **      it into global variables for later use.
 293: */
 294: process_preamble()
 295: {
 296:         ubyte   k;
 297: 
 298:         if (one(dvi_file) != PRE)
 299:         error("xdvi: DVI file doesn't start with preamble");
 300:     if (one(dvi_file) != 2)
 301:         error("xdvi: Wrong version of DVI output for this program");
 302:     numerator     = four(dvi_file);
 303:     denominator   = four(dvi_file);
 304:     magnification = four(dvi_file);
 305:     fraction = (((double) numerator * magnification)
 306:                                      / ((double) denominator * 1000.));
 307:     define_conv();
 308:     k = one(dvi_file);
 309:     fread(job_id, sizeof(char), k, dvi_file);
 310:     job_id[k] = '\0';
 311: }
 312: 
 313: define_conv ()
 314: {
 315:     conv = ((fraction * pixels_per_inch) / 100000) / (2.54 * shrink_factor);
 316: }
 317: 
 318: /*
 319: **      find_postamble locates the beginning of the postamble
 320: **	and leaves the file ready to start reading at that location.
 321: */
 322: find_postamble()
 323: {
 324:     ubyte byte;
 325:     long offset = -4;        /* At least 4 TRAILERS */
 326: 
 327:     do {
 328:         offset -= 1;
 329:         fseek(dvi_file, offset, 2);
 330:         byte = one(dvi_file);
 331:     } while (byte == TRAILER);
 332:     if (byte != 2)
 333:         error("xdvi: Wrong version of DVI output for this program");
 334:     offset -= 4;
 335:     fseek(dvi_file, offset, 2);
 336:     fseek(dvi_file, sfour(dvi_file), 0);
 337: }
 338: 
 339: /*
 340: **      read_postamble reads the information in the postamble,
 341: **	storing it into global variables.
 342: **      It also takes care of reading in all of the PXL files for the fonts
 343: **      used in the job.
 344: */
 345: read_postamble()
 346: {
 347:         ubyte   cmnd;
 348:     int page_width, page_height;
 349: 
 350:         if (one(dvi_file) != POST)
 351:         error("xdvi: Postamble doesn't begin with POST");
 352:     last_page_offset = four(dvi_file);
 353:     if (numerator != four(dvi_file)
 354:               ||  denominator != four(dvi_file)
 355:           ||  magnification != four(dvi_file))
 356:         error("xdvi: Postamble doesn't match preamble");
 357:     page_height = pixel_round(four(dvi_file));
 358:     page_width = pixel_round(four(dvi_file));
 359:     maxstack = two(dvi_file);
 360:     total_pages = two(dvi_file);
 361:     do {
 362:         switch(cmnd = one(dvi_file)) {
 363:             case FNTDEF1:
 364:             case FNTDEF2:
 365:             case FNTDEF3:
 366:             case FNTDEF4:
 367:             define_font(cmnd);
 368:             break;
 369:         case POSTPOST:
 370:             break;
 371:         default:
 372:             error("xdvi: Non-fntdef cmnd found in postamble");
 373:         }
 374:     } while (cmnd != POSTPOST);
 375:     if (font_not_found)
 376:         error("xdvi: Not all PXL files were found");
 377:     list_fonts = 0;
 378: }
 379: 
 380: prepare_pages()
 381: {
 382:     int i;
 383: 
 384:         stack = (struct frame *) malloc((unsigned) sizeof(struct frame) * (maxstack+1));
 385:         if (stack == NULL)
 386:         error("xdvi: Can't allocate stack space (%d frames)", maxstack);
 387:     page_offset = (long *) malloc((unsigned) total_pages * sizeof(long));
 388:         if (page_offset == NULL)
 389:         error("xdvi: Can't allocate page directory (%d pages)", total_pages);
 390:     i = total_pages;
 391:     page_offset[--i] = last_page_offset;
 392:     fseek(dvi_file, last_page_offset, 0);
 393:     /*
 394: 	 * Follow back pointers through pages in the DVI file,
 395: 	 * storing the offsets in the page_offset table.
 396: 	 */
 397:     while (i > 0) {
 398:         num(dvi_file, 1+4+(9*4));
 399:         fseek(dvi_file, page_offset[--i] = four(dvi_file), 0);
 400:     }
 401: }
 402: 
 403: /*
 404: **      define_font reads the rest of the fntdef command and then reads in
 405: **      the specified PXL file, adding it to the global linked-list holding
 406: **      all of the fonts used in the job.
 407: */
 408: define_font(cmnd)
 409:     ubyte cmnd;
 410: {
 411:         register struct font *fontp;
 412:     int len;
 413:     int unmodsize;
 414:     float realsize;
 415:     int size;
 416:         long checksum;
 417: 
 418:     fontp = (struct font *) malloc((unsigned) sizeof(struct font));
 419:     if (fontp == NULL)
 420:         error("xdvi: Can't allocate memory for font");
 421:     fontp->TeXnumber = num(dvi_file, cmnd - FNTDEF1 + 1);
 422:     checksum = four(dvi_file);
 423:     fontp->scale = four(dvi_file);
 424:     fontp->design = four(dvi_file);
 425:     len = one(dvi_file) + one(dvi_file);
 426:     fontp->fontname = malloc(len + 10); /* leave space for magnification */
 427:     fread(fontp->fontname, sizeof(char), len, dvi_file);
 428:     fontp->fontname[len] = '\0';
 429:     fontp->file = NULL;
 430: /*
 431: **	In the actual implementation, scaled-size/design-size hasn't been
 432: **	stored with sufficient precision, hence the messing around to find
 433: **	its actual value.
 434: */
 435:     realsize = (magnification/1000.)*((float) fontp->scale / fontp->design);
 436:     unmodsize = (realsize * 1000) + 0.5;
 437:     /* a real hack to correct for rounding in some cases */
 438:     switch (unmodsize) {
 439:         case 1095:
 440:         realsize = 1.095445;    /* stephalf */
 441:         break;
 442:         case 1315:
 443:         realsize = 1.314534;    /* stepihalf */
 444:         break;
 445:         case 2074:
 446:         realsize = 2.0736;  /* stepiv */
 447:         break;
 448:         case 2488:
 449:         realsize = 2.48832; /* stepv */
 450:         break;
 451:         case 2986:
 452:         realsize = 2.985984;    /* stepiv */
 453:         break;
 454:     }
 455:     /*
 456: 	 * the remaining magnification steps are represented
 457: 	 * with sufficient accuracy already
 458: 	 */
 459:     size = (realsize * pixels_per_inch * 5) + 0.5;
 460:     sprintf(&fontp->fontname[len], FONT_SUFFIX, size);
 461:     if (!open_pxl_file(fontp))
 462:         return;
 463:     read_glyphs(fontp);
 464:     if (current_font == NULL) {
 465:         fontp->next = fontp;
 466:         fontp->prev = fontp;
 467:     } else {
 468:         fontp->next = current_font;
 469:         fontp->prev = current_font->prev;
 470:         current_font->prev->next = fontp;
 471:         current_font->prev = fontp;
 472:     }
 473:     current_font = fontp;
 474: }
 475: 
 476: open_pxl_file(font)
 477:     struct font *font;
 478: {
 479:     char filename[300];
 480:     extern int errno;
 481: 
 482:     if (font->file == NULL) {
 483:         sprintf(filename, "%s/%s",
 484:                 FONT_DIRECTORY, font->fontname);
 485:         if (n_open_fonts == MAX_OPEN_FONTS)
 486:             close_lru();
 487:         font->file = fopen(filename, "r");
 488:         if (font->file == NULL) {
 489:             font_not_found = 1;
 490:             printf("%s [not found]\n", font->fontname);
 491:             return (0);
 492:         }
 493:         n_open_fonts += 1;
 494:     }
 495:     if (list_fonts)
 496:         printf("%s\n", font->fontname);
 497:     return (1);
 498: }
 499: 
 500: read_pxl_bitmap(ch, g)
 501:     ubyte ch;
 502:     register struct glyph *g;
 503: {
 504:     register struct bitmap *bitmap;
 505:     register int file_bytes_wide;
 506:     register char *ptr;
 507:     register int i, j;
 508: 
 509:     bitmap = &g->bitmap;
 510: 
 511:     /* in file, bitmap rows are multiples of 32 bits wide */
 512:     file_bytes_wide = ROUNDUP(bitmap->w, BITS_PER_LONG)*BYTES_PER_LONG;
 513:     /* width must be multiple of 16 bits for raster_op */
 514:     bitmap->bytes_wide = ROUNDUP(bitmap->w, BITS_PER_SHORT)*BYTES_PER_SHORT;
 515:     ptr = bitmap->bits = malloc((unsigned) bitmap->h * bitmap->bytes_wide);
 516:     if (ptr == NULL)
 517:         error("xdvi: Can't allocate bitmap for character %d of font %s (%d by %d)",
 518:             ch, current_font->fontname, bitmap->h, bitmap->w);
 519:     if (!open_pxl_file(current_font))
 520:         error("xdvi: Can't find font file %s", current_font->fontname);
 521:     fseek(current_font->file, g->addr, 0);
 522:     for (i = 0; i < bitmap->h; i += 1)
 523:         for (j = 0; j < file_bytes_wide; j += 1)
 524:             if (j < bitmap->bytes_wide)
 525:                 *ptr++ = reverse_byte[one(current_font->file)];
 526:             else
 527:                 one(current_font->file);
 528:     if (shrink_factor != 1)
 529:         shrink_bitmap(bitmap, shrink_factor, shrink_factor);
 530:     if (debug & DBG_BITMAP)
 531:         print_char(ch, g);
 532: }
 533: 
 534: /*
 535:  * Find font #n and move it to the head of the list.
 536:  */
 537: change_font(n)
 538:     unsigned long n;
 539: {
 540:         register struct font *fontp;
 541: 
 542:     fontp = current_font;
 543:     for (;;) {
 544:         if (fontp->TeXnumber == n)
 545:                         break;
 546:         fontp = fontp->next;
 547:         if (fontp == current_font)
 548:             error("xdvi: Non-existent font #%d", n);
 549:     }
 550:     if (current_font == fontp)
 551:         return;
 552:     fontp->prev->next = fontp->next;
 553:     fontp->next->prev = fontp->prev;
 554:     fontp->next = current_font;
 555:     fontp->prev = current_font->prev;
 556:     current_font->prev->next = fontp;
 557:     current_font->prev = fontp;
 558:     current_font = fontp;
 559: }
 560: 
 561: /*
 562:  * Close the PXL file for the least recently used font.
 563:  */
 564: close_lru()
 565: {
 566:         register struct font *f;
 567: 
 568:     f = current_font->prev;
 569:     for (;;) {
 570:         if (f->file != NULL)
 571:                         break;
 572:         f = f->prev;
 573:         if (f == current_font->prev)
 574:             error("xdvi: Can't find an open PXL file to close");
 575:     }
 576:     fclose(f->file);
 577:     f->file = NULL;
 578:     n_open_fonts -= 1;
 579: }
 580: 
 581: reset_fonts()
 582: {
 583:         register struct font *f;
 584:     register struct glyph *g;
 585: 
 586:     f = current_font;
 587:     for (;;) {
 588:         open_pxl_file(f);
 589:         for (g = &f->glyph[0]; g < &f->glyph[MAXCHARS]; g += 1) {
 590:         if (g->bitmap.bits) free(g->bitmap.bits);
 591:         }
 592:         read_glyphs(f);
 593:         f = f->next;
 594:         if (f == current_font) break;
 595:     }
 596: }
 597: 
 598: read_glyphs (fontp)
 599:         register struct font *fontp;
 600: {
 601:     register struct glyph *g;
 602:         long checksum, magnify, design_size, font_dir_ptr, pxl_id_word;
 603: 
 604:     /* seek to trailer info */
 605:     fseek(fontp->file, (long) -(5 * BYTES_PER_LONG), 2);
 606:         checksum = four(fontp->file);
 607:         magnify = four(fontp->file);
 608:         design_size = four(fontp->file);
 609:         font_dir_ptr = sfour(fontp->file) * 4;
 610:         pxl_id_word = four(fontp->file);
 611: #ifdef lint
 612:     magnify = design_size = pxl_id_word = magnify;
 613: #endif
 614:     /* seek to font directory */
 615:     fseek(fontp->file, font_dir_ptr, 0);
 616:     for (g = &fontp->glyph[0]; g < &fontp->glyph[MAXCHARS]; g += 1) {
 617:         g->bitmap.bits = NULL;
 618:         g->bitmap.w = two(fontp->file); /* leave this for shrink_bitmap */
 619:         g->bitmap.h = two(fontp->file); /* leave this for shrink_bitmap */
 620:         g->x = stwo(fontp->file) / shrink_factor;
 621:         g->y = stwo(fontp->file) / shrink_factor;
 622:         g->addr = four(fontp->file) * 4;
 623:         /*
 624: 		**  The TFM-width word is kind of funny in the units
 625: 		**  it is expressed in.  It works this way:
 626: 		**
 627: 		**  If a glyph has width 'w' in a font with design-size
 628: 		**  'd' (both in same units), the TFM-width word is
 629: 		**
 630: 		**                    (w/d) * 2^20
 631: 		**
 632: 		**  Therefore, in order to find the glyph width in
 633: 		**  DVI units (1 / 2^16 points), we take the design-size
 634: 		**  'd' (in DVI's), the magnification 'm' of the PXL file
 635: 		**  and the TFM-width word 't' to the width (in DVI's)
 636: 		**  as follows:
 637: 		**
 638: 		**                     dmt
 639: 		**                w = -----
 640: 		**                    2^20
 641: 		**
 642: 		**  But the magnification of the PXL file is just the
 643: 		**  scaled size 's' over the design size, so the final
 644: 		**  expression for the width is
 645: 		**
 646: 		**                     st
 647: 		**                w = ----
 648: 		**                    2^20
 649: 		**
 650: 		*/
 651:         g->dvi_adv =
 652:             ((double) fontp->scale * four(fontp->file)) / (1 << 20);
 653:         g->pxl_adv = pixel_round(g->dvi_adv);
 654:     }
 655: }
 656: 
 657: #define nope(str)       error("xdvi: %s not implemented", str)
 658: #define correct()       (PXL_H = pixel_round(DVI_H))
 659: 
 660: do_pages()
 661: {
 662:         ubyte ch;
 663: 
 664:     min_x = 0;
 665:     min_y = 0;
 666:     max_x = screen_w;
 667:     max_y = screen_h;
 668:     base_x = min_x;
 669:     base_y = min_y;
 670:     current_page = 0;
 671:     for (;;) {
 672:         ch = one(dvi_file);
 673:         if (debug & DBG_DVI)
 674:             print_dvi(ch);
 675:         if (ch <= SETCHAR0 + 127) {
 676:             set_char(ch);
 677:             DVI_H += current_font->glyph[ch].dvi_adv;
 678:             PXL_H += current_font->glyph[ch].pxl_adv;
 679:             correct();
 680:         } else if (FNTNUM0 <= ch  &&  ch <= FNTNUM0 + 63) {
 681:             change_font((unsigned long) (ch - FNTNUM0));
 682:         } else {
 683:             long a, b;
 684: 
 685:             switch (ch) {
 686:                 case SET1:
 687:                 nope("SET1");
 688:                 break;
 689: 
 690:                 case SETRULE:
 691:                 a = sfour(dvi_file); b = sfour(dvi_file);
 692:                 if (a > 0  &&  b > 0) {
 693:                     correct();
 694:                     set_rule(pixel_round(a), pixel_round(b));
 695:                 }
 696:                 DVI_H += b;
 697:                 PXL_H =  pixel_round(DVI_H);
 698:                 break;
 699: 
 700:                 case PUT1:
 701:                 nope("PUT1");
 702:                 break;
 703: 
 704:                 case PUTRULE:
 705:                 a = sfour(dvi_file); b = sfour(dvi_file);
 706:                 if (a > 0  &&  b > 0) {
 707:                     correct();
 708:                     set_rule(pixel_round(a), pixel_round(b));
 709:                 }
 710:                 break;
 711: 
 712:                 case NOP:
 713:                 break;
 714: 
 715:                 case BOP:
 716:                 num(dvi_file, 11*4);
 717:                 stackp = 0;
 718:                 DVI_H = dvi_round(X_PAGE_OFFSET);
 719:                 PXL_H = X_PAGE_OFFSET;
 720:                 DVI_V = dvi_round(Y_PAGE_OFFSET);
 721:                 PXL_V = Y_PAGE_OFFSET;
 722:                 WW = XX = YY = ZZ = 0;
 723:                 begin_page();
 724:                 break;
 725: 
 726:                 case EOP:
 727:                 if (stackp > 0)
 728:                     error("Stack not empty at EOP (%d)",
 729:                            stackp);
 730:                 end_page();
 731:                 if (ftell(dvi_file) > last_page_offset)
 732:                     return;
 733:                 break;
 734: 
 735:                 case PUSH:
 736:                 stackp++;
 737:                 if (stackp > maxstack)
 738:                     error("xdvi: More PUSHes than were promised");
 739:                 stack[stackp] = stack[stackp - 1];
 740:                 break;
 741: 
 742:                 case POP:
 743:                 stackp--;
 744:                 if (stackp < 0)
 745:                     error("xdvi: More POPs than PUSHes");
 746:                 break;
 747: 
 748:                 case RIGHT1:
 749:                 case RIGHT2:
 750:                 case RIGHT3:
 751:                 case RIGHT4:
 752:                 DVI_H += snum(dvi_file, ch - RIGHT1 + 1);
 753:                 PXL_H = pixel_round(DVI_H);
 754:                 break;
 755: 
 756:                 case X0:
 757:                 case X1:
 758:                 case X2:
 759:                 case X3:
 760:                 case X4:
 761:                 if (ch != X0)
 762:                     XX = snum(dvi_file, ch - X0);
 763:                 DVI_H += XX;
 764:                 PXL_H += pixel_round(XX);
 765:                 correct();
 766:                 break;
 767: 
 768:                 case W0:
 769:                 case W1:
 770:                 case W2:
 771:                 case W3:
 772:                 case W4:
 773:                 if (ch != W0)
 774:                     WW = snum(dvi_file, ch - W0);
 775:                 DVI_H += WW;
 776:                 PXL_H = pixel_round(DVI_H);
 777:                 break;
 778: 
 779:                 case Y0:
 780:                 case Y1:
 781:                 case Y2:
 782:                 case Y3:
 783:                 case Y4:
 784:                 if (ch != Y0)
 785:                     YY = snum(dvi_file, ch - Y0);
 786:                 DVI_V += YY;
 787:                 PXL_V = pixel_round(DVI_V);
 788:                 break;
 789: 
 790:                 case Z0:
 791:                 case Z1:
 792:                 case Z2:
 793:                 case Z3:
 794:                 case Z4:
 795:                 if (ch != Z0)
 796:                     ZZ = snum(dvi_file, ch - Z0);
 797:                 DVI_V += ZZ;
 798:                 PXL_V = pixel_round(DVI_V);
 799:                 break;
 800: 
 801:                 case DOWN1:
 802:                 case DOWN2:
 803:                 case DOWN3:
 804:                 case DOWN4:
 805:                 DVI_V += snum(dvi_file, ch - DOWN1 + 1);
 806:                 PXL_V = pixel_round(DVI_V);
 807:                 break;
 808: 
 809:                 case FNT1:
 810:                 case FNT2:
 811:                 case FNT3:
 812:                 case FNT4:
 813:                 change_font(num(dvi_file, ch - FNT1 + 1));
 814:                 break;
 815: 
 816:                 case XXX1:
 817:                 case XXX2:
 818:                 case XXX3:
 819:                 case XXX4:
 820:                 a = num(dvi_file, ch - XXX1 + 1);
 821:                 if(a > 0)
 822:                     special((unsigned long) a);
 823:                 break;
 824: 
 825:                 case FNTDEF1:
 826:                 case FNTDEF2:
 827:                 case FNTDEF3:
 828:                 case FNTDEF4:
 829:                 fseek(dvi_file, (long) (12 + ch - FNTDEF1 + 1), 1);
 830:                 a = one(dvi_file) + one(dvi_file);
 831:                 fseek(dvi_file, (long) a, 1);
 832:                 break;
 833: 
 834:                 case PRE:
 835:                 error("xdvi: Shouldn't happen: PRE encountered.");
 836:                 break;
 837: 
 838:                 case POST:
 839:                 error("xdvi: Shouldn't happen: POST encountered.");
 840:                 break;
 841: 
 842:                 case POSTPOST:
 843:                 error("xdvi: Shouldn't happen: POSTPOST encountered.");
 844:                 break;
 845: 
 846:                 default:
 847:                 error("xdvi: Unknown op-code %d, offset %d",
 848:                     ch, ftell(dvi_file));
 849:             } /* end switch*/
 850:         } /* end else (ch not a SETCHAR or FNTNUM) */
 851:     } /* end for */
 852: }
 853: 
 854: set_char(ch)
 855:     ubyte ch;
 856: {
 857:     register struct glyph *g;
 858: 
 859:     g = &current_font->glyph[ch];
 860:     if (g->bitmap.bits == NULL)
 861:         read_pxl_bitmap(ch, g);
 862:     put_bitmap(&g->bitmap, (PXL_H - g->x), (PXL_V - g->y), forepix);
 863: }
 864: 
 865: set_rule(h, w)
 866:     long h, w;
 867: {
 868:     /* (w,h) specifies lower left corner of rule box */
 869:     put_rectangle(PXL_H, PXL_V - h, w, h, forepix);
 870: }
 871: 
 872: begin_page()
 873: {
 874:     if (debug)
 875:         return;
 876:     if (!redisplay)
 877:         clear_page();
 878:     put_border(0, 0, page_w, page_h, 1);
 879: }
 880: 
 881: end_page()
 882: {
 883:     int ch, arg, sign, number, next_page;
 884:     XEvent event;
 885:     char *string;
 886:     int nbytes;
 887: 
 888: #ifdef lint
 889:     number = 0;
 890: #endif
 891:     if (debug) {
 892:         if (++current_page == total_pages)
 893:             exit(0);
 894:         return;
 895:     }
 896:     if (redisplay) {
 897:         min_x = smin_x;
 898:         max_x = smax_x;
 899:         min_y = smin_y;
 900:         max_y = smax_y;
 901:         redisplay = 0;
 902:     }
 903:     arg = 0;
 904:     for (;;) {
 905:         XNextEvent (&event);
 906:         switch (event.type) {
 907:         case ExposeWindow:
 908:             screen_h = ((XExposeEvent *)(&event))->height;
 909:             screen_w = ((XExposeEvent *)(&event))->width;
 910:             max_x = min_x + screen_w;
 911:             max_y = min_y + screen_h;
 912:             string = "\f";
 913:             nbytes = 1;
 914:             break;
 915:         case ExposeRegion:
 916:             smin_x = min_x;
 917:             smax_x = max_x;
 918:             smin_y = min_y;
 919:             smax_y = max_y;
 920:             min_x = min_x + ((XExposeEvent *)(&event))->x;
 921:             min_y = min_y + ((XExposeEvent *)(&event))->y;
 922:             max_x = min_x + ((XExposeEvent *)(&event))->width;
 923:             max_y = min_y + ((XExposeEvent *)(&event))->height;
 924:             redisplay = 1;
 925:             string = "\f";
 926:             nbytes = 1;
 927:             break;
 928:         case ButtonPressed:
 929:             {
 930:             short detail = ((XButtonPressedEvent *) (&event))->detail;
 931:             switch (detail & ValueMask) {
 932:             case LeftButton:
 933:             if (detail & ShiftMask)
 934:                 string = "l";
 935:             else
 936:                 string = "b";
 937:             nbytes = 1;
 938:             break;
 939:             case MiddleButton:
 940:             if (detail & ShiftMask)
 941:                 string = "u";
 942:             else
 943:                 string = "d";
 944:             nbytes = 1;
 945:             break;
 946:             case RightButton:
 947:             if (detail & ShiftMask)
 948:                 string = "r";
 949:             else
 950:                 string = "f";
 951:             nbytes = 1;
 952:             break;
 953:             }
 954:             }
 955:             break;
 956:         case KeyPressed:
 957:             string = XLookupMapping (&event, &nbytes);
 958:             break;
 959:         }
 960:         if (nbytes == 0) continue;
 961:         if (nbytes > 1) goto bad;
 962:         switch (ch = *string) {
 963:             case 'q':
 964:             case '\003':    /* control-C */
 965:             case '\004':    /* control-D */
 966:             stop_output(0);
 967:             break;
 968:             case 'n':
 969:             case 'f':
 970:             case ' ':
 971:             /* scroll forward */
 972:             min_x = 0;
 973:             min_y = 0;
 974:             max_x = screen_w;
 975:             max_y = screen_h;
 976:             next_page = current_page + 1;
 977:             break;
 978:             case 'p':
 979:             case 'b':
 980:             case '\b':
 981:             /* scroll backward */
 982:             min_x = 0;
 983:             min_y = 0;
 984:             max_x = screen_w;
 985:             max_y = screen_h;
 986:             next_page = current_page - 1;
 987:             break;
 988:             case 'u':
 989:             if (min_y == 0) goto bad;
 990:             min_y -= screen_h;
 991:             if (min_y < 0)
 992:                 min_y = 0;
 993:             base_y = min_y;
 994:             max_y = min_y + screen_h;
 995:             next_page = current_page;
 996:             break;
 997:             case 'd':
 998:             if (min_y >= page_h - screen_h) goto bad;
 999:             min_y += screen_h;
1000:             if (min_y > page_h - screen_h)
1001:                 min_y = page_h - screen_h;
1002:             if (min_y < 0)
1003:                 min_y = 0;
1004:             base_y = min_y;
1005:             max_y = min_y + screen_h;
1006:             next_page = current_page;
1007:             break;
1008:             case 'l':
1009:             if (min_x == 0) goto bad;
1010:             min_x -= screen_w;
1011:             if (min_x < 0)
1012:                 min_x = 0;
1013:             base_x = min_x;
1014:             max_x = min_x + screen_w;
1015:             next_page = current_page;
1016:             break;
1017:             case 'r':
1018:             if (min_x >= page_w - screen_w) goto bad;
1019:             min_x += screen_w;
1020:             if (min_x > page_w - screen_w)
1021:                 min_x = page_w - screen_w;
1022:             if (min_x < 0)
1023:                 min_x = 0;
1024:             base_x = min_x;
1025:             max_x = min_x + screen_w;
1026:             next_page = current_page;
1027:             break;
1028:             case 's':
1029:             if (!arg) {
1030:                 int shrink = shrink_factor;
1031:                 long fac1, fac2;
1032:                 shrink_factor = 1;
1033:                 fac1 = ROUNDUP(PAPER_WIDTH, screen_w);
1034:                 fac2 = ROUNDUP(PAPER_HEIGHT, screen_h);
1035:                 if (fac1 < fac2)
1036:                 number = fac2;
1037:                 else
1038:                 number = fac1;
1039:                 shrink_factor = shrink;
1040:             }
1041:             if (number <= 0) goto bad;
1042:             if (number != shrink_factor) {
1043:                 shrink_factor = number;
1044:                 min_x = 0;
1045:                 min_y = 0;
1046:                 max_x = screen_w;
1047:                 max_y = screen_h;
1048:                 init_page();
1049:                 define_conv();
1050:                 reset_fonts();
1051:             }
1052:             case '\f':
1053:             /* redisplay current page */
1054:             next_page = current_page;
1055:             break;
1056:             case '\r':
1057:             case '\n':
1058:             /* go to relative page */
1059:             min_x = 0;
1060:             min_y = 0;
1061:             max_x = screen_w;
1062:             max_y = screen_h;
1063:             next_page = current_page + (arg ? number : 1);
1064:             break;
1065:             case 'g':
1066:             /* go to absolute page */
1067:             min_x = 0;
1068:             min_y = 0;
1069:             max_x = screen_w;
1070:             max_y = screen_h;
1071:             next_page = (arg ? number : total_pages) - 1;
1072:             break;
1073:             case '0': case '1': case '2': case '3': case '4':
1074:             case '5': case '6': case '7': case '8': case '9':
1075:             if (! arg) {
1076:                 arg = 1;
1077:                 sign = 1;
1078:                 number = 0;
1079:             }
1080:             number = 10*number + sign*(ch - '0');
1081:             continue;
1082:             case '-':
1083:             if (! arg) {
1084:                 arg = 1;
1085:                 sign = -1;
1086:                 number = 0;
1087:                 continue;
1088:             } else
1089:                 goto bad;
1090:             default:
1091:             goto bad;
1092:         }
1093:         if (0 <= next_page && next_page < total_pages) {
1094:             current_page = next_page;
1095:             fseek(dvi_file, page_offset[current_page], 0);
1096:             break;
1097:         }
1098:     bad:
1099:         XFeep(0);
1100:         arg = 0;        /* throw away numeric argument */
1101:         continue;
1102:     }
1103: }
1104: 
1105: special(nbytes)
1106:     unsigned long nbytes;
1107: {
1108:     char *cmd;
1109:     int i;
1110: 
1111:     cmd = malloc((unsigned) nbytes+1);
1112:     if (cmd == NULL)
1113:         error("xdvi: Can't allocate memory for special (%d bytes)", nbytes);
1114:     for (i = 0; i < nbytes; i += 1)
1115:         cmd[i] = getc(dvi_file);
1116:     cmd[i] = '\0';
1117:     fprintf(stderr, "special ``%s'' not implemented\n", cmd);
1118:     free(cmd);
1119: }
1120: 
1121: /*
1122: **
1123: **      Read size bytes from the FILE fp, constructing them into a
1124: **      signed/unsigned integer.
1125: **
1126: */
1127: unsigned long
1128: num(fp, size)
1129:     register FILE *fp;
1130:     register int size;
1131: {
1132:         register int i;
1133:     register long x;
1134: 
1135:     x = 0;
1136:     for (i = 0; i < size; i += 1)
1137:         x = x * 0x100 + (unsigned) getc(fp);
1138:     return (x);
1139: }
1140: 
1141: long
1142: snum(fp, size)
1143:     register FILE *fp;
1144:     register int size;
1145: {
1146:         register int i;
1147:     register long x;
1148: 
1149:     x = getc(fp) & 0xff;
1150:     if (x & 0x80)
1151:             x -= 0x100;
1152:     for (i = 1; i < size; i += 1)
1153:         x = x * 0x100 + (unsigned) getc(fp);
1154:     return (x);
1155: }
1156: 
1157: stop_output(sig)
1158: {
1159:     exit(sig);
1160: }
1161: 
1162: /* VARARGS1 */
1163: error(message, a, b, c, d, e, f)
1164:     char *message;
1165: {
1166:     fprintf(stderr, message, a, b, c, d, e, f);
1167:     putc('\n', stderr);
1168:     exit(1);
1169: }
1170: 
1171: init_page()
1172: {
1173:     page_h = PAPER_HEIGHT;
1174:     page_w = PAPER_WIDTH;
1175: }
1176: 
1177: clear_page()
1178: {
1179:     XClear(win);
1180: }
1181: 
1182: put_border(x, y, w, h, t)
1183:     long x, y, w, h, t;
1184: {
1185:     put_rectangle(x, y, w, t, highpix);
1186:     put_rectangle(x, y, t, h, highpix);
1187:     put_rectangle(x, y + h - t, w, t, highpix);
1188:     put_rectangle(x + w - t, y, t, h, highpix);
1189: }
1190: 
1191: put_rectangle(x, y, w, h, pix)
1192:     long x, y, w, h;
1193:     int pix;
1194: {
1195:     if (x < max_x && x + w >= min_x && y < max_y && y + h >= min_y)
1196:         XPixSet(win, x - base_x, y - base_y, w, h, pix);
1197: }
1198: 
1199: put_bitmap(bitmap, x, y, pix)
1200:     register struct bitmap *bitmap;
1201:     register long x, y;
1202:     int pix;
1203: {
1204:     if (x < max_x && x + bitmap->w >= min_x &&
1205:         y < max_y && y + bitmap->h >= min_y)
1206:         XBitmapBitsPut(win, x - base_x, y - base_y,
1207:                 bitmap->w, bitmap->h, (char *) bitmap->bits,
1208:                 pix, backpix, NULL, GXcopy, AllPlanes);
1209: }
1210: 
1211: sample(bitmap, x, y, w, h)
1212:     register struct bitmap *bitmap;
1213:     int x, y, w, h;
1214: {
1215:     register char *ptr, *endp;
1216:     register int b, i, j, m, n;
1217: 
1218:     ptr = bitmap->bits
1219:         + (y * bitmap->bytes_wide)
1220:         + (x / BITS_PER_BYTE);
1221:     endp = bitmap->bits + (bitmap->h * bitmap->bytes_wide);
1222:     b = (1 << (x % BITS_PER_BYTE));
1223:     n = 0;
1224:     for (i = 0; i < h && ptr < endp; i += 1, ptr += bitmap->bytes_wide)
1225:         for (m = b, j = 0; j < w; j += 1, m <<= 1)
1226:             if (*ptr & m)
1227:                 n += 1;
1228:     return (n >= (i * w) / 3);
1229: }
1230: 
1231: shrink_bitmap(bitmap, x_factor, y_factor)
1232:     register struct bitmap *bitmap;
1233:     int x_factor, y_factor;
1234: {
1235:     char *shrunk_bits;
1236:     int shrunk_height, shrunk_width, shrunk_bytes_wide;
1237:     register char *ptr;
1238:     char *cp;
1239:     register int x, y, b, m;
1240: 
1241:     shrunk_height = ROUNDUP(bitmap->h, y_factor);
1242:     shrunk_width = ROUNDUP(bitmap->w, x_factor);
1243:     shrunk_bytes_wide = ROUNDUP(shrunk_width, BITS_PER_SHORT)*BYTES_PER_SHORT;
1244:         /* width must be multiple of 16 bits for raster_op */
1245:     ptr = shrunk_bits = calloc((unsigned) shrunk_height * shrunk_bytes_wide, 1);
1246:     if (ptr == NULL)
1247:         error("Can't allocate shrunken bitmap (%d by %d)",
1248:             shrunk_height, shrunk_width);
1249:     for (y = 0; y < bitmap->h; y += y_factor) {
1250:         b = 0;
1251:         m = (1 << 0);
1252:         cp = ptr;
1253:         for (x = 0; x < bitmap->w; x += x_factor) {
1254:             if (sample(bitmap, x, y, x_factor, y_factor))
1255:                 *ptr |= m;
1256:             else
1257:                 *ptr &= ~m;
1258:             b += 1;
1259:             m <<= 1;
1260:             if (b % BITS_PER_BYTE == 0) {
1261:                 b = 0;
1262:                 m = (1 << 0);
1263:                 ptr += 1;
1264:             }
1265:         }
1266:         ptr = cp + shrunk_bytes_wide;
1267:     }
1268:     free(bitmap->bits);
1269:     bitmap->bits = shrunk_bits;
1270:     bitmap->h = shrunk_height;
1271:     bitmap->w = shrunk_width;
1272:     bitmap->bytes_wide = shrunk_bytes_wide;
1273: }
1274: 
1275: print_char(ch, g)
1276:     ubyte ch;
1277:     struct glyph *g;
1278: {
1279:     printf("char %d", ch);
1280:     if (isprint(ch))
1281:         printf(" (%c)", ch);
1282:     putchar('\n');
1283:     printf("x = %d, y = %d, pxl = %d, dvi = %d\n",
1284:         g->x, g->y, g->pxl_adv, g->dvi_adv);
1285:     print_bitmap(&g->bitmap);
1286: }
1287: 
1288: print_bitmap(bitmap)
1289:     register struct bitmap *bitmap;
1290: {
1291:     register char *ptr;
1292:     register int x, y, i;
1293: 
1294:     ptr = bitmap->bits;
1295:     if (ptr == NULL)
1296:         return;
1297:     printf("w = %d, h = %d, bytes wide = %d\n",
1298:         bitmap->w, bitmap->h, bitmap->bytes_wide);
1299:     for (y = 0; y < bitmap->h; y += 1) {
1300:         for (x = 0; x < bitmap->bytes_wide; x += 1) {
1301:             for (i = 0; i < BITS_PER_BYTE; i += 1)
1302:                 if (*ptr & (1 << i))
1303:                     putchar('@');
1304:                 else
1305:                     putchar(' ');
1306:             ptr += 1;
1307:         }
1308:         putchar('\n');
1309:     }
1310: }
1311: 
1312: print_dvi(ch)
1313:     ubyte ch;
1314: {
1315:     printf("%4d %4d ", PXL_H, PXL_V);
1316:     if (ch <= SETCHAR0 + 127) {
1317:         printf("SETCHAR%-3d", ch - SETCHAR0);
1318:         if (isprint(ch))
1319:             printf(" (%c)", ch);
1320:     } else if (FNTNUM0 <= ch  &&  ch <= FNTNUM0 + 63) {
1321:         printf("FNTNUM%d", ch - FNTNUM0);
1322:     } else {
1323:         switch (ch) {
1324:             case SET1:
1325:             printf("SET1");
1326:             break;
1327:             case SETRULE:
1328:             printf("SETRULE");
1329:             break;
1330:             case PUT1:
1331:             printf("PUT1");
1332:             break;
1333:             case PUTRULE:
1334:             printf("PUTRULE");
1335:             break;
1336:             case NOP:
1337:             printf("NOP");
1338:             break;
1339:             case BOP:
1340:             printf("BOP");
1341:             break;
1342:             case EOP:
1343:             printf("EOP");
1344:             break;
1345:             case PUSH:
1346:             printf("PUSH");
1347:             break;
1348:             case POP:
1349:             printf("POP");
1350:             break;
1351:             case RIGHT1:
1352:             case RIGHT2:
1353:             case RIGHT3:
1354:             case RIGHT4:
1355:             printf("RIGHT%d", ch - RIGHT1 + 1);
1356:             break;
1357:             case X0:
1358:             case X1:
1359:             case X2:
1360:             case X3:
1361:             case X4:
1362:             printf("X%d", ch - X0);
1363:             break;
1364:             case W0:
1365:             case W1:
1366:             case W2:
1367:             case W3:
1368:             case W4:
1369:             printf("W%d", ch - W0);
1370:             break;
1371:             case Y0:
1372:             case Y1:
1373:             case Y2:
1374:             case Y3:
1375:             case Y4:
1376:             printf("Y%d", ch - Y0);
1377:             break;
1378:             case Z0:
1379:             case Z1:
1380:             case Z2:
1381:             case Z3:
1382:             case Z4:
1383:             printf("Z%d", ch - Z0);
1384:             break;
1385:             case DOWN1:
1386:             case DOWN2:
1387:             case DOWN3:
1388:             case DOWN4:
1389:             printf("DOWN%d", ch - DOWN1 + 1);
1390:             break;
1391:             case FNT1:
1392:             case FNT2:
1393:             case FNT3:
1394:             case FNT4:
1395:             printf("FNT%d", ch - FNT1 + 1);
1396:             break;
1397:             case XXX1:
1398:             case XXX2:
1399:             case XXX3:
1400:             case XXX4:
1401:             printf("XXX%d", ch - XXX1 + 1);
1402:             break;
1403:             case FNTDEF1:
1404:             case FNTDEF2:
1405:             case FNTDEF3:
1406:             case FNTDEF4:
1407:             printf("FNTDEF%d", ch - FNTDEF1 + 1);
1408:             break;
1409:             case PRE:
1410:             printf("PRE");
1411:             break;
1412:             case POST:
1413:             printf("POST");
1414:             break;
1415:             case POSTPOST:
1416:             printf("POSTPOST");
1417:             break;
1418:             default:
1419:             error("xdvi: Unknown op-code %d, offset %d",
1420:                 ch, ftell(dvi_file));
1421:         } /* end switch*/
1422:     } /* end else (ch not a SETCHAR or FNTNUM) */
1423:     putchar('\n');
1424: }

Defined functions

begin_page defined in line 872; used 1 times
change_font defined in line 537; used 2 times
clear_page defined in line 1177; used 1 times
close_lru defined in line 564; used 1 times
define_conv defined in line 313; used 2 times
define_font defined in line 408; used 1 times
do_pages defined in line 660; used 1 times
end_page defined in line 881; used 1 times
error defined in line 1163; used 25 times
find_postamble defined in line 322; used 1 times
init_page defined in line 1171; used 2 times
main defined in line 122; never used
num defined in line 1127; used 9 times
open_pxl_file defined in line 476; used 3 times
prepare_pages defined in line 380; used 1 times
print_bitmap defined in line 1288; used 1 times
print_char defined in line 1275; used 1 times
print_dvi defined in line 1312; used 1 times
process_preamble defined in line 294; used 1 times
put_bitmap defined in line 1199; used 1 times
put_border defined in line 1182; used 1 times
put_rectangle defined in line 1191; used 5 times
read_glyphs defined in line 598; used 2 times
read_postamble defined in line 345; used 1 times
read_pxl_bitmap defined in line 500; used 1 times
reset_fonts defined in line 581; used 1 times
sample defined in line 1211; used 1 times
set_char defined in line 854; used 1 times
set_rule defined in line 865; used 2 times
shrink_bitmap defined in line 1231; used 1 times
snum defined in line 1141; used 9 times
special defined in line 1105; used 1 times
stop_output defined in line 1157; used 2 times

Defined variables

backpix defined in line 109; used 6 times
base_x defined in line 112; used 5 times
base_y defined in line 112; used 5 times
conv defined in line 84; used 3 times
current_font defined in line 74; used 27 times
current_page defined in line 83; used 12 times
debug defined in line 65; used 5 times
denominator defined in line 85; used 3 times
dv_c defined in line 12; never used
font_not_found defined in line 73; used 2 times
forepix defined in line 109; used 5 times
fraction defined in line 84; used 2 times
highpix defined in line 109; used 7 times
job_id defined in line 81; used 2 times
last_page_offset defined in line 90; used 4 times
list_fonts defined in line 66; used 3 times
magnification defined in line 85; used 4 times
max_x defined in line 112; used 14 times
max_y defined in line 112; used 14 times
maxstack defined in line 82; used 4 times
min_x defined in line 112; used 29 times
min_y defined in line 112; used 29 times
n_open_fonts defined in line 76; used 3 times
numerator defined in line 85; used 3 times
page_h defined in line 111; used 6 times
page_offset defined in line 96; used 5 times
page_w defined in line 111; used 6 times
pixels_per_inch defined in line 68; used 8 times
redisplay defined in line 114; used 4 times
screen_h defined in line 111; used 17 times
screen_w defined in line 111; used 17 times
shrink_factor defined in line 69; used 17 times
smax_x defined in line 113; used 2 times
smax_y defined in line 113; used 2 times
smin_x defined in line 113; used 2 times
smin_y defined in line 113; used 2 times
stack defined in line 46; used 12 times
stackp defined in line 47; used 17 times
total_pages defined in line 82; used 7 times
win defined in line 108; used 7 times
xdvi_bits defined in line 102; used 2 times
  • in line 284(2)

Defined struct's

frame defined in line 42; used 6 times

Defined typedef's

ubyte defined in line 40; used 9 times

Defined macros

DBG_ALL defined in line 60; used 1 times
DBG_BITMAP defined in line 58; used 2 times
DBG_DVI defined in line 59; used 2 times
DVI_H defined in line 51; used 10 times
DVI_V defined in line 52; used 7 times
FONT_DIRECTORY defined in line 23; used 1 times
FONT_SUFFIX defined in line 24; used 1 times
MAX_OPEN_FONTS defined in line 75; used 1 times
PAPER_HEIGHT defined in line 27; used 2 times
PAPER_WIDTH defined in line 26; used 2 times
PXL_H defined in line 49; used 10 times
PXL_V defined in line 50; used 7 times
WW defined in line 53; used 3 times
XX defined in line 54; used 4 times
X_PAGE_OFFSET defined in line 28; used 2 times
YY defined in line 55; used 3 times
Y_PAGE_OFFSET defined in line 29; used 2 times
ZZ defined in line 56; used 3 times
correct defined in line 658; used 4 times
dvi_round defined in line 32; used 2 times
four defined in line 37; used 19 times
nope defined in line 657; used 2 times
one defined in line 34; used 13 times
pixel_round defined in line 31; used 15 times
sfour defined in line 38; used 6 times
stwo defined in line 36; used 2 times
two defined in line 35; used 4 times
xdvi_height defined in line 99; used 1 times
xdvi_width defined in line 98; used 1 times
xdvi_x_hot defined in line 100; used 1 times
xdvi_y_hot defined in line 101; used 1 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4731
Valid CSS Valid XHTML 1.0 Strict