|
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 i
Length: 11232 (0x2be0) Types: TextFile Names: »imagen1.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/laser-setters/mctex/imagen/imagen1.c«
/* * Copyright (c) 1987, 1989 University of Maryland * Department of Computer Science. All rights reserved. * Permission to copy for any purpose is hereby granted * so long as this copyright notice remains intact. */ #ifndef lint static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/imagen/RCS/imagen1.c,v 3.2 89/09/01 13:56:54 chris Exp $"; #endif /* * DVI to Imagen driver * * Reads DVI version 2 files and converts to imPRESS commands for spooling to * the Imagen (via ipr). * * TODO: * think about fonts with characters outside [0..127] */ #include <stdio.h> #include "types.h" #include "conv.h" #include "dviclass.h" #include "dvicodes.h" #include "error.h" #include "fio.h" #include "font.h" #include "gripes.h" #include "dvistate.h" #include "imagen.h" #include "imPcodes.h" char *ProgName; extern char *optarg; extern int optind; /* Globals */ char serrbuf[BUFSIZ]; /* buffer for stderr */ /* * We store Imagen font family numbers in the f_int field the font * routines allocate for us. */ #define f_family f_un.f_int int LFlag; /* -l => landscape mode */ int ReversePages; /* -p => [no] page reversal */ int SFlag; /* -s => silent (no page numbers) */ int Debug; /* -D => debug flag */ int ImHH; /* Imagen horizontal position */ int ImVV; /* Imagen vertical position */ int ImFamily; /* Imagen current-font number */ char *PrintEngine; /* e.g., canon, ricoh */ char *DVIFileName; /* name of input DVI file */ void DownLoadGlyph(); /* Put byte and two-byte (word) value to the Imagen */ #undef putbyte #define putbyte(b) ((void) putchar(b)) #define putword(w) (putbyte((int)(w) >> 8), putbyte((int)(w))) /* * Set the Imagen's h & v positions. It is currently at ImHH, ImVV. * * This is invoked from within the main put-characters-on-page loop and * should go fast. */ #define SetPosition(h, v) { \ if (ImHH != (h)) { \ if (ImHH == (h) - 1) \ putbyte(imP_Forw); \ else if (ImHH == (h) + 1) \ putbyte(imP_Backw); \ else { \ putbyte(imP_SetHAbs); \ putword(h); \ } \ ImHH = (h); \ } \ if (ImVV != (v)) { \ putbyte(imP_SetVAbs); \ putword(v); \ ImVV = (v); \ } \ } int AllocateFamily() { static int nextfamily; /* next available Imagen glyph-family index */ if (nextfamily == MaxImFamily) error(0, 0, "\ WARNING: out of Imagen font family indicies;\n\ \toutput will probably resemble freshly scrambled eggs."); return (nextfamily++); } /* * Assign a unique Imagen family to each font in the DVI file. */ struct font * DefineFont(name, dvimag, dvidsz) char *name; i32 dvimag, dvidsz; { register struct font *f; char *path; f = GetFont(name, dvimag, dvidsz, PrintEngine, &path); if (f == NULL) { GripeCannotGetFont(name, dvimag, dvidsz, PrintEngine, path); return (NULL); } f->f_family = AllocateFamily(); if (Debug) { (void) fprintf(stderr, "[%s -> %s]\n", Font_TeXName(f), path); (void) fflush(stderr); } return (f); } /* * Start a new page (interpreter found a DVI_BOP). */ void BeginPage(count) i32 *count; { if (!SFlag) { static int beenhere; if (beenhere) (void) putc(' ', stderr); else beenhere = 1; (void) fprintf(stderr, "[%ld", (long)count[0]); (void) fflush(stderr); } putbyte(imP_Page); ImHH = 0; ImVV = 0; } /* * End the page (interpreter found a DVI_EOP). */ void EndPage() { if (!SFlag) { (void) putc(']', stderr); (void) fflush(stderr); } putbyte(imP_EndPage); } /* * Perform a \special. * This version ignores all, with a warning. */ void DoSpecial(len) i32 len; { error(0, 0, "warning: ignoring \\special"); (void) fseek(ds.ds_fp, (long)len, 1); } /* * Set a rule at dvi_hh, dvi_vv. */ void SetRule(h, w) register i32 h, w; { /* put the rule out */ SetPosition(dvi_hh, dvi_vv); (void) putchar(imP_Rule); putword(w); putword(h); putword(-h + 1); } /* * Check the range of a character, to be sure the device can handle it. * Called for DVI_SET and DVI_PUT opcodes only. */ int CheckChar(c) i32 c; { if ((ui32)c > 127) { error(0, 0, "Warning: character code %ld too big for Imagen", (long)c); return (1); } return (0); } /* * Main page loop. This reads one page of the DVI file. * Returns 1 for EOP and 0 for end of last page (POST). */ int PageLoop() { static struct font NoFont; /* font with zero pspace, etc */ register int c; register i32 p; register struct font *f = &NoFont; register FILE *fp = ds.ds_fp; int doingpage = 0, advance; if (ReversePages) if (ds.ds_prevpage == -1) return (0); /* Mark 10:31 (kilroy was here) */ else (void) fseek(fp, ds.ds_prevpage, 0); /* * This would be a `for (;;)', but that makes the function * crawl off the right of the screen. * * We handle ordinary characters early, as they are the * most common opcodes in DVI files, and doing so makes the * loop run faster. */ loop: c = fgetbyte(fp); if (DVI_IsChar(c)) { register struct glyph *g; p = c; advance = 1; do_char: g = GLYPH(f, p); if (!GVALID(g)) { GripeBadGlyph(p, f); goto loop; } if ((g->g_flags & GF_SEEN) == 0) DownLoadGlyph((int)p, f, g); if (HASRASTER(g)) { /* workaround for Imagen bug */ SetPosition(dvi_hh, dvi_vv); if (ImFamily != f->f_family) { putbyte(imP_SetFamily); putbyte(f->f_family); ImFamily = f->f_family; } putbyte((int)p); ImHH += g->g_pixwidth; } if (advance) { dvi_h += g->g_tfmwidth; dvi_hh += g->g_pixwidth; p = fromSP(dvi_h); FIXDRIFT(dvi_hh, p); } goto loop; } if (c == EOF) /* unexpected end of DVI file */ GripeUnexpectedDVIEOF(); /* * Gather up a parameter, if known. */ switch (DVI_OpLen(c)) { case DPL_NONE: break; case DPL_SGN1: p = fgetbyte(fp); p = Sign8(p); break; case DPL_SGN2: fGetWord(fp, p); p = Sign16(p); break; case DPL_SGN3: fGet3Byte(fp, p); p = Sign24(p); break; case DPL_SGN4: fGetLong(fp, p); break; case DPL_UNS1: p = fgetbyte(fp); p = UnSign8(p); break; case DPL_UNS2: fGetWord(fp, p); p = UnSign16(p); break; case DPL_UNS3: fGet3Byte(fp, p); p = UnSign24(p); break; default: panic("DVI_OpLen(%d) = %d", c, DVI_OpLen(c)); /* NOTREACHED */ } /* * Now switch on the type. */ switch (DVI_DT(c)) { case DT_SET: advance = 1; if (CheckChar(p)) goto loop; goto do_char; case DT_PUT: advance = 0; if (CheckChar(p)) goto loop; goto do_char; case DT_SETRULE: DVIRule(SetRule, 1); goto loop; case DT_PUTRULE: DVIRule(SetRule, 0); goto loop; case DT_NOP: goto loop; case DT_BOP: if (doingpage) GripeUnexpectedOp("BOP (already in page)"); DVIBeginPage(BeginPage); doingpage = 1; goto loop; case DT_EOP: if (!doingpage) GripeUnexpectedOp("EOP (no BOP)"); EndPage(); return (1); case DT_PUSH: *ds.ds_sp++ = ds.ds_cur; goto loop; case DT_POP: ds.ds_cur = *--ds.ds_sp; goto loop; case DT_W0: p = dvi_w; goto right; case DT_W: dvi_w = p; goto right; case DT_X0: p = dvi_x; goto right; case DT_X: dvi_x = p; goto right; case DT_RIGHT: right: dvi_h += p; if (F_SMALLH(f, p)) { dvi_hh += fromSP(p); p = fromSP(dvi_h); FIXDRIFT(dvi_hh, p); } else dvi_hh = fromSP(dvi_h); goto loop; case DT_Y0: p = dvi_y; goto down; case DT_Y: dvi_y = p; goto down; case DT_Z0: p = dvi_z; goto down; case DT_Z: dvi_z = p; goto down; case DT_DOWN: down: dvi_v += p; if (F_SMALLV(f, p)) { dvi_vv += fromSP(p); p = fromSP(dvi_v); FIXDRIFT(dvi_vv, p); } else dvi_vv = fromSP(dvi_v); goto loop; case DT_FNTNUM: f = DVIFindFont((i32)(c - DVI_FNTNUM0)); goto loop; case DT_FNT: f = DVIFindFont(p); goto loop; case DT_XXX: DoSpecial(p); goto loop; case DT_FNTDEF: SkipFontDef(fp); goto loop; case DT_PRE: GripeUnexpectedOp("PRE"); /* NOTREACHED */ case DT_POST: if (doingpage) { GripeUnexpectedOp("POST (no EOP)"); /* NOTREACHED */ } return (0); case DT_POSTPOST: GripeUnexpectedOp("POSTPOST"); /* NOTREACHED */ case DT_UNDEF: GripeUndefinedOp(c); /* NOTREACHED */ default: panic("DVI_DT(%d) = %d", c, DVI_DT(c)); /* NOTREACHED */ } /* NOTREACHED */ } main(argc, argv) int argc; register char **argv; { register int c; int xoff = 0, yoff = 0; /* margins from -X and -Y */ int dpi = DefaultDPI; /* resolution from -r */ FILE *fp = stdin; setbuf(stderr, serrbuf); ProgName = *argv; ds.ds_usermag = 1000; ds.ds_maxdrift = DefaultMaxDrift; ReversePages = 1; /* default is to reverse pages */ PrintEngine = "canon"; DVIFileName = "`stdin'"; while ((c = getopt(argc, argv, "d:e:lm:pr:sDX:Y:")) != EOF) { switch (c) { case 'd': /* max drift value */ ds.ds_maxdrift = atoi(optarg); break; case 'e': /* engine */ PrintEngine = optarg; break; case 'l': /* landscape mode */ LFlag++; break; case 'm': /* magnification */ ds.ds_usermag = atoi(optarg); break; case 'p': /* toggle page reversal */ ReversePages = !ReversePages; break; case 'r': /* resolution */ dpi = atoi(optarg); break; case 's': /* silent */ SFlag++; break; case 'D': Debug++; break; case 'X': /* x offset, in 1/1000 inch increments */ xoff = atoi(optarg); break; case 'Y': /* y offset */ yoff = atoi(optarg); break; case '?': (void) fprintf(stderr, "Usage: %s [-ls] [more options, see manual] [file]\n", ProgName); (void) fflush(stderr); exit(1); } } if (optind < argc) if ((fp = fopen(DVIFileName = argv[optind], "r")) == NULL) error(1, -1, "can't open %s", DVIFileName); DVISetState(fp, DefineFont, dpi, xoff, yoff); ImFamily = -1; /* probably 0, but this is safer */ /* All set! */ (void) printf("@document(language imPRESS, name \"%s\")", DVIFileName); if (LFlag) { putbyte(imP_SetHVSystem); putbyte(0x55); /* origin=ulc, h:v=90, h:x=90 */ putbyte(imP_SetAdvDirs); putbyte(0); /* main=0 (degrees), secondary=90 */ } while (PageLoop()) /* void */; if (!SFlag) { (void) fprintf(stderr, "\n"); (void) fflush(stderr); } putbyte(imP_EOF); (void) fflush(stdout); if (ferror(stdout)) error(1, -1, "error writing imPRESS output"); exit(0); /* NOTREACHED */ } /* * Download the character c of font f (glyph=g). * The value of c is guaranteed to be in [0..127]. */ void DownLoadGlyph(c, f, g) int c; struct font *f; register struct glyph *g; { register char *p; register int i, j, w; g->g_pixwidth = fromSP(g->g_tfmwidth); g->g_flags |= GF_SEEN; if (!HASRASTER(g)) /* never load dull glyphs */ return; /* (imagen cannot handle them) */ if (!LFlag) { w = 0; p = RASTER(g, f, ROT_NORM); } else { w = 1 << 14; p = RASTER(g, f, ROT_RIGHT); } w |= (f->f_family << 7) | c; /* Define the character */ putbyte(imP_DefGlyph); /* a.k.a. BGLY */ putword(w); /* rotation, family, member */ putword(g->g_pixwidth); /* advance */ putword(g->g_width); /* width */ putword(g->g_xorigin); /* left offset */ putword(g->g_height); /* height */ putword(g->g_yorigin); /* top-offset */ /* * Now put out the bitmap. */ w = (g->g_width + 7) >> 3; for (i = g->g_height; --i >= 0;) for (j = w; --j >= 0;) putbyte(*p++); FreeRaster(g); }