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