|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 10872 (0x2a78) Types: TextFile Names: »dvi_init.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/crt-viewers/X/xdvi/dvi_init.c«
/* * DVI previewer for X. * * Eric Cooper, CMU, September 1985. * * Code derived from dvi-imagen.c. * * Modification history: * 1/1986 Modified for X.10 by Bob Scheifler, MIT LCS. * 7/1988 Modified for X.11 by Mark Eichin, MIT * 12/1988 Added 'R' option, toolkit, magnifying glass * --Paul Vojta, UC Berkeley. * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto * 4/1989 Modified for System V by Donald Richardson, Clarkson Univ. * 3/1990 Added VMS support --Scott Allendorf, U of Iowa * * Compilation options: * SYSV compile for System V * VMS compile for VMS * X10 compile for X10 * NOTOOL compile without toolkit (X11 only) * BUTTONS compile with buttons on the side of the window (needs toolkit) * MSBITFIRST store bitmaps internally with most significant bit first * BMSHORT store bitmaps in shorts instead of bytes * BMLONG store bitmaps in longs instead of bytes * ALTFONT default for -altfont option * A4 use European size paper */ #include <stdio.h> #include <ctype.h> #include "xdvi.h" #include "dvi.h" #include <sys/stat.h> #define dvi_oops(str) longjmp(dvi_env, (int) str); #define XtOffset(type, field) ((unsigned int)&(((type)NULL)->field)) static struct stat fstatbuf; /* mechanism to see if file was */ time_t dvi_time; /* modified since last usage */ struct font *current_font = NULL; /* ptr into linked list of fonts */ ubyte maxchar; static Boolean font_not_found; static struct font **old_fonts; /* used by read_postamble */ int n_fonts_left = 32767; /* for LRU management of fonts */ char *realloc(); /* * DVI preamble and postamble information. */ int current_page; Boolean spec_warn; int total_pages; double fraction; int maxstack; static char job_id[300]; static long numerator, denominator, magnification; /* * Table of page offsets in DVI file, indexed by page number - 1. * Initialized in prepare_pages(). */ long *page_offset; /* * Offset in DVI file of last page, set in read_postamble(). */ static long last_page_offset; #ifdef sun char *sprintf(); #endif char *malloc(); FILE *pxl_open(); /* * define_font reads the rest of the fntdef command and then reads in * the specified pixel file, adding it to the global linked-list holding * all of the fonts used in the job. */ static void define_font(cmnd) ubyte cmnd; { register struct font *fontp; struct font **fontpp = old_fonts; struct font *fontp1; int len; int design; int size; fontp = (struct font *) malloc((unsigned) sizeof(struct font)); if (fontp == NULL) oops("Can't allocate memory for font"); fontp->TeXnumber = num(dvi_file, (ubyte) cmnd - FNTDEF1 + 1); (void) four(dvi_file); /* checksum */ fontp->scale = four(dvi_file); design = four(dvi_file); len = one(dvi_file) + one(dvi_file); fontp->fontname = malloc((unsigned) len + 1); Fread(fontp->fontname, sizeof(char), len, dvi_file); fontp->fontname[len] = '\0'; if(debug & DBG_PK) Printf("Define font \"%s\" scale=%d design=%d\n", fontp->fontname, fontp->scale, design); fontp->size = size = ((double) fontp->scale / design * magnification * pixels_per_inch * 0.005) + 0.5; fontp->scale = fontp->scale * fraction; /* * reuse font if possible */ for (;;) { fontp1 = *fontpp; if (fontp1 == NULL) { read_font_index_proc read_font_index; char *font_found; int size_found; int dpi = (size + 2) / 5; if (n_fonts_left == 0) close_a_file(); fontp->file = pxl_open(fontp->fontname, &font_found, size, &size_found, &fontp->factor, &fontp->filename, &read_font_index); if (fontp->file == NULL) { Fprintf(stderr, "Can't find font %s.\n", fontp->fontname); font_not_found = True; return; } --n_fonts_left; if (font_found != NULL) { Fprintf(stderr, "Can't find font %s; using %s instead at %d dpi\n", fontp->fontname, font_found, dpi); free(fontp->fontname); fontp->fontname = font_found; } else if (25 * size_found > 26 * size || 25 * size > 26 * size_found) Fprintf(stderr, "Can't find font %s at %d dpi; using %d dpi instead.\n", fontp->fontname, dpi, (size_found + 2) / 5); fontp->factor = fontp->factor * size / size_found; maxchar = 255; (*read_font_index)(fontp); while (maxchar > 0 && fontp->glyph[maxchar].addr == 0) --maxchar; if (maxchar < 255) fontp = (struct font *) realloc((char *) fontp, XtOffset(struct font *, glyph[(int) maxchar + 1])); fontp->maxchar = maxchar; break; } if (strcmp(fontp->fontname, fontp1->fontname) == 0 && size == fontp1->size) { *fontpp = fontp1->next; free(fontp->fontname); free((char *) fontp); fontp = fontp1; if (list_fonts) fputs("(reusing) ",stdout); break; } fontpp = &fontp1->next; } if (old_fonts == ¤t_font) old_fonts = &fontp->next; fontp->next = current_font; current_font = fontp; if (list_fonts) puts(fontp->fontname); } /* * process_preamble reads the information in the preamble and stores * it into global variables for later use. */ static process_preamble() { ubyte k; if (one(dvi_file) != PRE) dvi_oops("DVI file doesn't start with preamble"); if (one(dvi_file) != 2) dvi_oops("Wrong version of DVI output for this program"); numerator = four(dvi_file); denominator = four(dvi_file); magnification = four(dvi_file); fraction = (((double) numerator * magnification) / ((double) denominator * 1000.)); fraction = fraction * (((long) pixels_per_inch)<<16) / 254000; k = one(dvi_file); Fread(job_id, sizeof(char), (int) k, dvi_file); job_id[k] = '\0'; } /* * find_postamble locates the beginning of the postamble * and leaves the file ready to start reading at that location. */ static find_postamble() { ubyte byte; Fseek(dvi_file, (long) -4, 2); while (four(dvi_file) != ((long) TRAILER << 24 | TRAILER << 16 | TRAILER << 8 | TRAILER)) Fseek(dvi_file, (long) -5, 1); Fseek(dvi_file, (long) -5, 1); for (;;) { byte = one(dvi_file); if (byte != TRAILER) break; Fseek(dvi_file, (long) -2, 1); } if (byte != 2) dvi_oops("Wrong version of DVI output for this program"); Fseek(dvi_file, (long) -5, 1); Fseek(dvi_file, sfour(dvi_file), 0); } /* * read_postamble reads the information in the postamble, * storing it into global variables. * It also takes care of reading in all of the pixel files for the fonts * used in the job. */ static read_postamble() { ubyte cmnd; if (one(dvi_file) != POST) dvi_oops("Postamble doesn't begin with POST"); last_page_offset = four(dvi_file); if (numerator != four(dvi_file) || denominator != four(dvi_file) || magnification != four(dvi_file)) dvi_oops("Postamble doesn't match preamble"); /* read largest box height and width */ unshrunk_page_h = (spellfour(dvi_file) >> 16) + pixels_per_inch; if (unshrunk_page_h < unshrunk_paper_h) unshrunk_page_h = unshrunk_paper_h; unshrunk_page_w = (spellfour(dvi_file) >> 16) + pixels_per_inch; if (unshrunk_page_w < unshrunk_paper_w) unshrunk_page_w = unshrunk_paper_w; maxstack = two(dvi_file); total_pages = two(dvi_file); old_fonts = ¤t_font; font_not_found = False; do { switch(cmnd = one(dvi_file)) { case FNTDEF1: case FNTDEF2: case FNTDEF3: case FNTDEF4: define_font(cmnd); break; case POSTPOST: break; default: dvi_oops("Non-fntdef command found in postamble"); } } while (cmnd != POSTPOST); if (font_not_found) dvi_oops("Not all pixel files were found"); /* * free up fonts no longer in use */ { struct font *fontp = *old_fonts; struct font *fontp1; register struct glyph *g; *old_fonts = NULL; while (fontp != NULL) { if (fontp->file != NULL) { Fclose(fontp->file); ++n_fonts_left; } free(fontp->fontname); free(fontp->filename); for (g = fontp->glyph; g <= fontp->glyph + fontp->maxchar; ++g) { if (g->bitmap.bits) free(g->bitmap.bits); if (g->bitmap2.bits) free(g->bitmap2.bits); } fontp1 = fontp->next; free((char *) fontp); fontp = fontp1; } } } static prepare_pages() { int i; stack = (struct frame *) malloc((unsigned) sizeof(struct frame) * (maxstack+1)); if (stack == NULL) oops("Can't allocate stack space (%d frames)", maxstack); page_offset = (long *) malloc((unsigned) total_pages * sizeof(long)); if (page_offset == NULL) oops("Can't allocate page directory (%d pages)", total_pages); i = total_pages; page_offset[--i] = last_page_offset; Fseek(dvi_file, last_page_offset, 0); /* * Follow back pointers through pages in the DVI file, * storing the offsets in the page_offset table. */ while (i > 0) { Fseek(dvi_file, (long) (1+4+(9*4)), 1); Fseek(dvi_file, page_offset[--i] = four(dvi_file), 0); } } init_page() { page_w = ROUNDUP(unshrunk_page_w, mane.shrinkfactor) + 2; page_h = ROUNDUP(unshrunk_page_h, mane.shrinkfactor) + 2; } /* * init_dvi_file is the main subroutine for reading the startup information * from the dvi file. */ static init_dvi_file() { (void) fstat(fileno(dvi_file), &fstatbuf); dvi_time = fstatbuf.st_mtime; process_preamble(); find_postamble(); read_postamble(); prepare_pages(); init_page(); if (current_page >= total_pages) current_page = total_pages - 1; spec_warn = True; } /** ** open_dvi_file opens the dvi file and calls init_dvi_file() to ** initialize it. **/ open_dvi_file() { char *errmsg; if ((dvi_file = fopen(dvi_name, OPEN_MODE)) == NULL) { int n = strlen(dvi_name); char *file = dvi_name; if (strcmp(dvi_name + n - sizeof(".dvi") + 1, ".dvi") == 0) { perror(dvi_name); exit(1); } dvi_name = malloc((unsigned) n + sizeof(".dvi")); Sprintf(dvi_name, "%s.dvi", file); if ((dvi_file = fopen(dvi_name, OPEN_MODE)) == NULL) { perror(dvi_name); exit(1); } } if (errmsg = (char *) setjmp(dvi_env)) oops(errmsg); init_dvi_file(); } /** ** Release all shrunken bitmaps for all fonts. **/ reset_fonts() { register struct font *f; register struct glyph *g; for (f = current_font; f != NULL; f = f->next) for (g = f->glyph; g <= f->glyph + f->maxchar; ++g) if (g->bitmap2.bits) { free(g->bitmap2.bits); g->bitmap2.bits = NULL; } } /** ** Check for changes in dvi file. **/ Boolean check_dvi_file() { if (dvi_file == NULL || fstat(fileno(dvi_file), &fstatbuf) != 0 || fstatbuf.st_mtime != dvi_time) { if (dvi_file) Fclose(dvi_file); free((char *) stack); free((char *) page_offset); dvi_file = fopen(dvi_name, OPEN_MODE); if (dvi_file == NULL) dvi_oops("Cannot reopen dvi file."); if (list_fonts) putchar('\n'); init_dvi_file(); redraw_page(); return False; } return True; }