|
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 g
Length: 8930 (0x22e2) Types: TextFile Names: »gf.c«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦this⟧ »./DVIware/obsolete/mitdrivers/dvi2ps/gf.c«
#ifndef USEPXL #include <stdio.h> #define false 0 #define true 1 /* This file contains routines for reading character descriptions from GF files (the output of Metafont). The following functions are defined: gettochar() finds the next character, returns its code (reduced modulo 256 if necessary), and sets global variables min_m, max_m, min_n, max_n. A result of -1 indicates that there are no more characters and the postamble has been found. readbits() After a character is found, this routine fills array bits[] with the character image. The image is represented in Postscript format: the bits are packed into bytes (most significant bit first), and the bytes scan the image left-to-right, bottom-to-top. Set globals num_cols, num_rows, x_offset, y_offset (the latter give the offset of the origin from the upper bottom corner of the image, up being a positive y_offset). readpost() After the postamble is found, this routine reads it and sets the remaining global variables declared below. seekpost() rapidly finds the postamble by random accessing the file. seekchar(c) uses fseek() to find a character with code c (modulo 256), returning a nonzero result if successful. Global variables are set as they are by gettochar. GF files may contain many characters with the same code, in which case subsequent calls to seekchar(c) with the same c will find the other versions. This routine should only be called after readpost(). No random access is attempted if seekpost() and seekchar() are not used. */ #define int32 long /* used when at least 32 bits are required */ int min_m, max_m, min_n, max_n; /* bounding box for character */ int32 charfam; /* high order bytes of character code */ int font_min_m, font_max_m, font_min_n, font_max_n; /* overall bounds */ int32 designsize; /* font size in points scaled by 1<<20 */ int32 checksum; /* should match TFM file and DVI file */ int32 hppp, vppp; /* horizontal and vertical pixels/point scaled 1<<16 */ int char_wd[256]; /* character width in pixels, rounded if necessary */ int32 tfm_wd[256]; /* width as a fraction of designsize scaled 1<<20 */ char char_exists[256]; /* nonzero entries indicate presence of a char_loc */ int gf_bc, gf_ec; /* first and last nonzero char_exists entries */ int32 char_pointer[256]; /* used by seekchar() */ int32 backpointer; /* set by gettochar() for use by seekchar() */ void gf_beginc(); /* prepare to paint white at (min_m,max_n) */ void gf_paint(); /* paint d pixels and switch colors */ void gf_skip(); /* finish a row and skip d rows */ void gf_endc(); /* finish the last row */ extern void bad_gf(); /* aborts the program if the gf file is invalid */ FILE *gfin=stdin; /* change this externally if necessary */ /* The following macros describe gf file format */ #define paint_0 0 #define last_paint 63 #define paint1 64 #define paint2 65 #define paint3 66 #define boc 67 #define boc1 68 #define eoc 69 #define skip0 70 #define skip1 71 #define skip2 72 #define skip3 73 #define new_row_0 74 #define last_new_row 238 #define xxx1 239 #define xxx2 240 #define xxx3 241 #define xxx4 242 #define yyy 243 #define no_op 244 #define char_loc 245 #define char_loc0 246 #define pre 247 #define post 248 #define postpost 249 #define undefined_cases 250: case 251: case 252: case 253: case 254: case 255 #define gf_version 131 /* All gf file input goes through the following routines */ #define getbyte() (getc(gfin)&0xff) /* int getbyte() { int b; b=getc(gfin)&0xff; printf("Getting %d\n",b); return b; } */ #define skip1byte() getc(gfin) int get2bytes() { register int ans; ans=getbyte()<<8; ans+=getbyte(); return ans; } int32 get3bytes() { register int32 ans; ans=getbyte()<<16; ans+=getbyte()<<8; ans+=getbyte(); return ans; } int32 get4bytes() { register int32 ans; ans=getbyte()<<24; ans+=getbyte()<<16; ans+=getbyte()<<8; ans+=getbyte(); return ans; } void skip_bytes(n) int n; { while (n-- >0) skip1byte(); } /* In the unlikely event of a character code outside of the range 0..255, the high order bytes are placed in the global variable charfam. If no boc command is encountered, the result is -1 and the last byte read is guaranteed to be the post command. */ int gettochar() { int32 c; /* the character code to be returned */ register int x; /* temporary */ for(;;) switch(getbyte()) { case yyy: skip1byte(); /* intended to fall through 3 times */ case paint3: case skip3: skip1byte(); case paint2: case skip2: skip1byte(); case paint1: case skip1: skip1byte(); continue; case boc: c=get4bytes(); backpointer=get4bytes(); min_m=get4bytes(); max_m=get4bytes(); min_n=get4bytes(); max_n=get4bytes(); charfam = c<0 ? -((-c)>>8) : c>>8; return c&0377; case boc1: c=getbyte(); backpointer= -1; x=getbyte(); /* del_m */ max_m=getbyte(); min_m=max_m-x; x=getbyte(); /* del_n */ max_n=getbyte(); min_n=max_n-x; return c; case pre: if (getbyte()!=gf_version) bad_gf(1); skip_bytes(getbyte()); continue; case xxx1: skip_bytes(getbyte()); continue; case xxx2: skip_bytes(get2bytes()); continue; case xxx3: skip_bytes((int) get3bytes()); continue; case xxx4: skip_bytes((int) get4bytes()); continue; case post: return -1; case char_loc: case char_loc0: case postpost: case undefined_cases: bad_gf(2); default: /* do nothing */; } } /* readbits reads a raster description from the gf file and uses the external routines to actually process the raster information. */ void readbits() { register unsigned char b; gf_beginc(); for (;;) { b=getbyte(); if (b<=last_paint) gf_paint(b-paint_0); if (b<new_row_0) switch(b) { case paint1: gf_paint(getbyte()); continue; case paint2: gf_paint(get2bytes()); continue; case paint3: gf_paint((int) get3bytes()); continue; case boc: case boc1: bad_gf(3); case eoc: goto finish; case skip0: gf_skip(0); continue; case skip1: gf_skip(getbyte()); continue; case skip2: gf_skip(get2bytes()); continue; case skip3: gf_skip((int) get3bytes()); continue; } else if (b<=last_new_row) { gf_skip(0); gf_paint(b-new_row_0); } else switch(b) { case xxx1: skip_bytes(getbyte()); continue; case xxx2: skip_bytes(get2bytes()); continue; case xxx3: skip_bytes((int) get3bytes()); continue; case xxx4: skip_bytes((int) get4bytes()); continue; case yyy: get4bytes(); continue; case no_op: continue; default: bad_gf(4); } } finish: gf_endc(); } void readpost() { int i, b, c; get4bytes(); /* ignore back pointer to font-wide xxx commands */ designsize=get4bytes(); checksum=get4bytes(); hppp=get4bytes(); vppp=get4bytes(); font_min_m=get4bytes(); font_max_m=get4bytes(); font_min_n=get4bytes(); font_max_n=get4bytes(); for(i=0; i<256; i++) { char_exists[i]=false; char_wd[i]=0; tfm_wd[i]=0; char_pointer[i]= -1; } gf_bc=255; gf_ec=0; for (;;) { b=getbyte(); c=getbyte(); if (b==char_loc0) char_wd[c]=getbyte(); else if (b==char_loc) { char_wd[c]=(get4bytes()+0100000)>>16; get4bytes(); /* skip dy */ } else break; tfm_wd[c]=get4bytes(); char_pointer[c]=get4bytes(); char_exists[c]=true; if (gf_bc>c) gf_bc=c; if (gf_ec<c) gf_ec=c; } } void seekpost() { int c; fseek(gfin, -5L, 2); /* skip four 223's */ do { c=getbyte(); fseek(gfin, -2L, 1); } while (c==223); if (c!=gf_version) bad_gf(5); /* check version number */ fseek(gfin, -3L, 1); /* back up to the pointer */ if (fseek(gfin, (long) get4bytes(), 0) < 0) bad_gf(6); if (getbyte()!=post) bad_gf(7); } int seekchar(c) int c; { if (c<0 || c>255 || char_pointer[c]<0) return false; if (fseek(gfin, char_pointer[c], 0) < 0) bad_gf(8); if (gettochar()!=c) bad_gf(9); char_pointer[c]=backpointer; return true; } #define BITBUFSIZE 20000 unsigned char bits[BITBUFSIZE]; int num_cols, num_rows, num_bytes, x_offset, y_offset; #define row_start(n) (&(bits[(n-min_n)*rowbytes])) #define m_byte(m) ((m-min_m)>>3) /* byte within within a row containing bit m */ #define m_bit(m) (7-(m-min_m)&07) /* bit within byte for a given m */ static int rowbytes, gf_m0, gf_m, gf_n, paint_switch; static unsigned char *row_ptr; void gf_beginc() { num_cols=max_m-min_m+1; num_rows=max_n-min_n+1; x_offset= -min_m; y_offset= -min_n; rowbytes=(num_cols+7)/8; num_bytes=num_rows*rowbytes; if (num_bytes>=BITBUFSIZE) bad_gf(10); /* really, should allocate a bigger one */ gf_m=gf_m0=min_m; gf_n=max_n; row_ptr=row_start(max_n); bzero(bits, num_bytes); paint_switch=0; } void gf_paint(d) register int d; { if (d>0) { if (paint_switch) while (d-- >0) { row_ptr[m_byte(gf_m)] |= 1<<m_bit(gf_m); gf_m++; } else gf_m += d; } paint_switch ^= 1; } void gf_skip(d) int d; { gf_n -= d+1; gf_m=gf_m0; row_ptr=row_start(gf_n); paint_switch=0; } void gf_endc() { /* do nothing */ } #endif