/* %W% %G% %U% */ /****************************************************************************/ /****************************************************************************/ /** **/ /** "dviimp.c" **/ /** **/ /****************************************************************************/ /****************************************************************************/ /** **/ /** Accepts TeX File as Input and Produces imPRESS. **/ /** **/ /****************************************************************************/ /****************************************************************************/ /** **/ /** NON-HOST SOFTWARE RELEASE. This is not copyrighted and **/ /** provided free to the public domain. **/ /** **/ /****************************************************************************/ /****************************************************************************/ # include # include /************************************************************************/ /* */ /* System Dependencies. Strive to make this code portable */ /* across SYSTEM V, SYSTEM III, and Bsd 4.x */ /* */ /************************************************************************/ #ifdef SYSV #define sys5 #else #ifdef SYSIII #define sys5 #endif #endif #ifdef sys5 # include # define index(s,c) strchr(s,c) # define rindex(s,c) strrchr(s,c) # define bcopy(a,b,c) memcpy(b,a,c) # define bzero(a,b) memset(a,0,b) #else # include #endif /* The output of TEX, called a DVI file, consists */ /* of a number of commands which keep track of where */ /* every character is to be placed and what font is */ /* being used. The information is grouped by pages. */ #define VERTCHR0 0 #define SET1 128 #define SET2 129 #define SET3 130 #define SET4 131 #define VERTRULE 132 #define HORZCHAR 133 #define HORZRULE 137 #define NOP 138 #define BOP 139 /* beginning of page */ #define EOP 140 /* end of page */ #define PST 248 /* postamble --info */ #define POSTPOST 249 /* end of fonts in postamble*/ #define PRE 247 /* preamble --info */ #define PUSH 141 #define POP 142 #define FONT 238 #define W4 151 #define W3 150 #define W2 149 #define W1 148 #define W0 147 #define X4 156 #define X3 155 #define X2 154 #define X1 153 #define X0 152 #define Y4 165 #define Y3 164 #define Y2 163 #define Y1 162 #define Y0 161 #define Z4 170 #define Z3 169 #define Z2 168 #define Z1 167 #define Z0 166 #define FONT0 171 /* FONTNUMs range from 171 to 234 */ #define FONT63 234 #define FNTDF1 243 #define FNTDF2 244 #define FNTDF3 245 #define FNTDF4 246 #define RIGHT1 143 #define RIGHT2 144 #define RIGHT3 145 #define RIGHT4 146 #define DOWN1 157 #define DOWN2 158 #define DOWN3 159 #define DOWN4 160 #define FNT1 235 #define FNT2 236 #define FNT3 237 #define FNT4 238 #define XXX1 239 #define XXX2 240 #define XXX3 241 #define XXX4 242 #define DVI_END_OFFSET (-1) /********************************************************/ /* */ /* Constants for the GF file format */ /* */ /********************************************************/ # define GF_PT0 0 /* Paint commands */ # define GF_PT1 64 # define GF_PT2 65 # define GF_PT3 66 # define GF_BOC 67 /* Beginning of char */ # define GF_BOC1 68 # define GF_EOC 69 /* End of character */ # define GF_SKIP0 70 # define GF_SKIP1 71 # define GF_SKIP2 72 # define GF_SKIP3 73 # define GF_ROW0 74 /* New row command */ # define GF_ROW164 238 # define GF_XXX1 239 # define GF_XXX2 240 # define GF_XXX3 241 # define GF_XXX4 242 # define GF_YYY 243 # define GF_NOOP 244 # define GF_CLC 245 /* Character location */ # define GF_CLC0 246 # define GF_PRE 247 /* Preamble */ # define GF_POST 248 /* Postamble */ # define GF_PPOST 249 /* Post-post command */ # define GF_ID 131 /* GF format id byte */ # define GF_END_BYTE 223 /* last bytes in GF file*/ /************************************************************************/ /* */ /* IMAGEN imPress Commands */ /* */ /************************************************************************/ #define iSP 128 /* advance one space */ #define iSP1 129 /* advance one space + 1 pixel */ #define iMPLUS 131 /* Move one pixel forward */ #define iMMINUS 132 /* Move one pixel back */ #define iMMOVE 133 /* Move in main advance direction */ #define iSMOVE 134 /* Move in secondary advance direction */ #define iABS_H 135 /* Move to H position */ #define iREL_H 136 /* Move in H direction */ #define iABS_V 137 /* Move to V position */ #define iREL_V 138 /* Move in V direction */ #define iCLIP_REGION 140 /* Define a region to be clipped */ #define iUNCLIP_REGION 141 /* Reset clipping region */ #define iCIRC_ARC 150 /* Define a circular path */ #define iELLIPSE_ARC 151 /* Define an eliptical path */ #define iCIRC_SEGM 160 /* Define a pie-shaped path */ #define iBRULE 193 /* print a rule */ #define iCRLF 197 /* move to beginning of next line */ #define iBGLY 199 /* define a downloaded glyph */ #define iSET_HV_SYSTEM 205 /* Define new coordinate system */ #define iSET_ADV_DIRS 206 /* Define advance directions */ #define iSET_FAMILY 207 /* Use the family given */ #define iSET_IL 208 /* define the space between lines */ #define iSET_BOL 209 /* define the beginning of a line */ #define iSET_SP 210 /* define the space between words */ #define iPUSH 211 /* push state variables on the stack */ #define iPOP 212 /* pop state variables off the stack */ #define iPAGE 213 /* Set H and V to 0 */ #define iSET_PUSH_MASK 214 /* Specify which variables to save */ #define iENDPAGE 219 /* print the current page */ #define iC_FAMILY_TABLE 221 /* Define a family table */ #define iC_MAP 222 /* Create a member map */ #define iSET_PUM 225 /* append or replace current path */ #define iC_PATH 230 /* Define a path of segmants */ #define iSET_TEXTURE 231 /* Select a texture for drawing */ #define iSET_PEN 232 /* Select a pen width in pixels */ #define iFILL_PATH 233 /* shade the area inside a path */ #define iDRAW_PATH 234 /* draw the current path */ #define iBITMAP 235 /* Print a full bitmap */ #define iSET_MAGNIFICATION 236 /* magnify the page by 1, 2, 4 */ #define iDEFINE_MACRO 242 /* define a macro */ #define iEXECUTE_MACRO 243 /* execute the named macro */ #define iCALL_INSTANCE 246 /* execute an emulator */ #define iNOOP 254 /* no operation */ #define iEOF 255 /* end of impress document */ #ifndef RESOLUTION #define RESOLUTION 300 /* Printer Resolution */ #endif RESOLUTION #ifndef RSTDirectory #define RSTDirectory "/usr/lib/tex/fonts/rst" #endif RSTDirectory #ifndef PXLDirectory #define PXLDirectory "/usr/lib/tex/fonts/pxl" #endif PXLDirectory #ifndef GFDirectory #define GFDirectory "/usr/lib/tex/fonts/gf" #endif GFDirectory #ifndef TFMDirectory #define TFMDirectory "/usr/lib/tex/fonts" #endif TFMDirectory #ifndef RESDirectory #define RESDirectory "/usr/lib/tex/fonts/resident" #endif RESDirectory #define RES_FILE "resident" /* Name of resident map directory */ # define MAX_FILENAME 35 # define MAX_STRING 256 /* strings are shorter than this*/ /************************************************************************/ /* */ /* All of TeX's output is in scaled points, which are equal to */ /* 2^-16 printer points. (This is verified by making sure the */ /* numerator and denemoinator values in the Postamble are set */ /* set correctly. If they aren't, all of this code is blown away) */ /* */ /************************************************************************/ typedef long SCALED_POINT; typedef long FIXED_POINT; typedef unsigned short GASCII; /* */ /* These values are hardcoded */ /* into TeX. */ /* */ # define POST_NUMERATOR 25400000 # define POST_DENOMINATOR 473628672 /************************************************************************/ /* */ /* Scaled Points to Pixels */ /* */ /* There are 2^16 scaled point per exact point */ /* and there are 72.27 exact points per inch */ /* */ /* */ /* 1ept 1in Pixels */ /* SCALED POINT . ------ . ------- . ------- = PIXELS */ /* 2E16SP 72.27ept Inch */ /* */ /************************************************************************/ # define SPtoPIX(X,RES) ( ((((X)/7227L) * RES * 100L ) + (1<<15) )>> 16 ) /************************************************************************/ /* */ /* Fix Points to Scaled Point */ /* */ /* There are 2^16 scaled point per exact point */ /* and there are 2^20 fix points per exact point */ /* */ /* */ /* FIX POINT >> 4 = SCALED POINT */ /* */ /************************************************************************/ # define FPtoSP(X) ( ((X)>>4) ) /************************************************************************/ /* */ /* Fix Points to Pixels */ /* */ /* There are 2^20 fix point per exact point */ /* and there are 72.27 exact points per inch */ /* */ /* */ /* 1ept 1in Pixels */ /* SCALED POINT . ------ . ------- . ------- = PIXELS */ /* 2^20SP 72.27ept Inch */ /* */ /************************************************************************/ # define FPtoPIX(X,RES) ( ( (((X)/7227L) * RES * 100L ) + (1<<19) )>> 20 ) /************************************************************************/ /* */ /* Pixels to Scaled Points */ /* */ /* There are 2^16 scaled point per exact point */ /* and there are 72.27 exact points per inch */ /* */ /* */ /* 1ept 1in Pixels */ /* SCALED POINT . ------ . ------- . ------- = PIXELS */ /* 2E16SP 72.27ept Inch */ /* */ /************************************************************************/ # define PIXtoSP(X,RES) ( (( (long)((X)<<16) * 7227L) / RES) / 100 ) #define TRUE (1) #define FALSE (0) #define CperFont 256 /* Maximum characters per font */ /* */ /* Macros for reading unsigned */ /* integers from the DVI file */ /* */ #define DviRdU1() ( DviRd1() & 0377 ) #define DviRdU2() ( DviRd2() & 0177777 ) #define DviRdU3() ( DviRd3() & 077777777 ) #define DviRdU4() ( DviRd4() & 037777777777 ) #define FontRdU1() ( FontRd1() & 0377 ) #define ImWrtS(adr) WrtS(adr,strlen(adr)) #define LOWERCASE(C) ( (C) - 'A' + 'a' ) /************************************************************************/ /* */ /* Glyph directory entry. There is one of these for each */ /* character defined in the font. */ /* */ /************************************************************************/ struct gd { /* Glyph directory parameters */ long gd_roff; /* Offset to raster data in file */ short gd_H; /* Height of the glyph */ short gd_W; /* Width of the glyph */ short gd_X; /* Horizontal offset */ short gd_Y; /* Vertical offset */ }; /************************************************************************/ /* */ /* Glyph information */ /* */ /************************************************************************/ struct fg { /* Glyph width information */ SCALED_POINT fg_rwid;/* Spacing width of character in SP's */ short fg_pwid;/* Spacing width of character in pixels */ char fg_load;/* True if glyph is loaded already */ }; /************************************************************************/ /* */ /* Font structure. There is one of these structures alloacted */ /* for each font definition in the postamble. */ /* */ /************************************************************************/ struct font { struct font *f_next; /* Pointer to next font on the list */ char f_name[15]; /* Name specified in DVI file */ char f_filnam[MAX_FILENAME]; /* Name of raster file or resident font */ FILE *f_strm; /* Stream pointer for raster file */ int f_fc; /* First character defined in the font */ int f_lc; /* Last character defined in the font */ struct gd *f_gd; /* Pointer to glyph directory in memory */ long f_mag; /* Font magnification: */ /* DVIMag * scale/dessignsize */ FIXED_POINT f_dessig; /* Font design size */ FIXED_POINT f_scale; /* scale size */ long f_checksum; /* font checksum */ char f_type; /* Type of font */ long f_dvinum; /* Font number used in dvi file */ char f_impnum; /* Font number used in imPress */ struct fg f_fg[CperFont]; /* Per-character data */ } *FontH; /* Head of list of fonts */ struct font *CurFont; /* */ /* Types of font files */ /* */ # define UNKNOWN 0 # define NON_EXIST 1 # define PXL 2 # define RST 3 # define RESIDENT 4 # define GF 5 # define TFM 6 #define MAXOPNF 10 /* Maximum number of font files open at once */ #define PAGE_HEIGHT 110 /* In tenths of inches */ #define PAGE_WIDTH 85 #define RULE_HEIGHT 2 /* Minimum rule height (pixels) */ #define RULE_WIDTH 2 /* Minimum rule height (pixels) */ char *pgmname; /* name of this program */ int NumOpnF; /* Number of font files open */ int PixPerIn; /* number of pixels per inch */ FILE *DviIn; /* Stream for dvi (input) file */ FILE *ImOut; /* Stream for impress file */ long DVIMag; /* Overall mag in thousandths */ int ImX, ImY; /* Impress positions in pixels */ int Im_family = -1; /* Current impress family */ /************************************************************************/ /* */ /* Variable command line options */ /* */ int landscape = FALSE; /* Landscape option */ int Debug = FALSE; /* Debug option */ int quiet = FALSE; /* Quiet option */ char RSTDir[256]; /* Directory with RST files */ char PXLDir[256]; /* Directory with PXL files */ char GFDir[256]; /* Direcory with GF files */ char TFMDir[256]; /* Directory for TFM files */ char RESDir[256]; /* Directory for resident files */ char *Copies = NULL; /* Number of copies */ char *Banner = NULL; /* Name for header page */ long PixH; /* max length of paper */ long PixW; /* max width of paper */ char *OutFile = NULL; /* Output file name */ char *InFile = NULL; /* Input file name */ /* */ int firstpage = -1000; /* first page to be printed */ int lastpage = 1000; /* last page to be printed */ int specpage = FALSE; /* true if page range specified */ int oddpage = TRUE; /* true if odd pages */ int evenodd = FALSE; /* true if doing double sided */ int transpose = FALSE; /* true if print pages backwards*/ /* */ int fnum = 1; /* starting family number */ int map_num = 1; /* starting map number */ /* */ /************************************************************************/ long LastPage; /* Pointer to last page in DVI file */ struct page_ptr { /* Used in ordering pages */ int pg_number; /* this pages number */ long pg_offset; /* offset in dvi to start of page */ }; struct page_ptr *PageList; /* This will be the list of pages */ struct page_ptr *CurPage; /* Current Page being printed */ /****************************************************************/ /* */ /* Constants for dealing with fonts */ /* */ /****************************************************************/ # define MAX_PXL_CHARS 128 /* Max chars in PXL raster file */ # define PXL_RESOLUTION 200 /* Pixels per inch constant */ # define PXL_VERSION 1001 /* Version stamp for PXL files */ # define PXL_FUDGE 5 /* Try PXL filenames with the */ /* mag/quotient fudged by +/- */ /* this amount */ # define RST_VERSION 0 # define RST_ID "Rast" # define RST_EXTENSION ".r" # define GF_EXTENSION ".gf" # define PXL_EXTENSION "pxl" # define TFM_EXTENSION ".tfm" # define MAX_FONTS 100 /* Never more fonts in FIF */ # define MAX_CHARS CperFont /* Never more chars in a font */ # define CHARS_IN_FAMILY 128 /* Max number of chars in */ /* family */ # define MAX_C_HEIGHT 200 /* Maximum char height */ # define MAX_C_WIDTH 200 /* Maximum char width */ # define MAX_MAPS 256 # define MAX_FAMILIES 128 typedef struct { /* Struct for giving character order */ /* of a particular type of font */ char co_file[MAX_FILENAME]; /* file containing map */ int co_mapnum; /* imPress map number */ /* 0 if not loaded */ int co_mapsize; /* number of maps used */ } CHARORDER; typedef struct { char m_name[MAX_FILENAME]; /* font name */ int m_number; /* character order index */ } MAP_INDEX; int max_map = 0; /* Number of resident fonts */ MAP_INDEX map_base[MAX_FONTS]; /* structure for resident fonts */ int max_order = 0; /* Number of res. char orderings*/ CHARORDER order_base[MAX_FONTS]; char *DviRdS(); int DviRd1(), DviRd2(); long DviRd3(), DviRd4(); char *FontRdS(); int FontRd1(), FontRd2(); long FontRd3(), FontRd4(); extern char *sprintf(); char *malloc1(); /* */ /* Environment Stack */ /* */ struct env { SCALED_POINT e_h; SCALED_POINT e_v; SCALED_POINT e_w; SCALED_POINT e_x; SCALED_POINT e_y; SCALED_POINT e_z; } *Environments, *EnvPtr; /* */ /* Current Environment */ /* */ SCALED_POINT E_H; SCALED_POINT E_V; SCALED_POINT E_W; SCALED_POINT E_X; SCALED_POINT E_Y; SCALED_POINT E_Z; /************************************************************************/ /* */ /* igetopt(argc, argv, optstring) */ /* */ /* Similar to system V getopt(3) */ /* */ /************************************************************************/ int optind = 1; /* next argv to process */ int opterr = 0; /* Non-zero disables errors msgs*/ char *optarg = NULL; /* Pointer to option argument */ static char *next_opt = NULL; /* Pointer to next option */ /* If NULL, grab next argv */ int igetopt(argc, argv, optstring) int argc; /* number or arguments */ char **argv; /* array or arguments */ char *optstring; /* option string */ { char *option; /* current option found */ char *match; /* matched option in optstring */ int return_code; /* Value to be returned */ /* */ /* Get the next option */ /* */ if ( next_opt == NULL ) { /* */ /* No more arguments */ /* */ if ( optind >= argc ) return( EOF ); next_opt = argv[optind]; /* */ /* End of options */ /* */ if ( *next_opt != '-' ) return( EOF ); /* */ /* Single '-', end of opts */ /* */ if ( *(++next_opt) == '\0' ) return( EOF ); optind++; } option = next_opt; /* */ /* Case of '--' */ /* Force end of options */ /* */ if ( *option == '-' ) return( EOF ); /* */ /* See if option is in optstring */ /* */ if ( (match=index(optstring, *option)) == NULL ) { if ( opterr == 0 ) fprintf(stderr, "Illegal option '%c'\n", *option); next_opt = option + 1; if ( *next_opt == '\0' ) next_opt = NULL; return( (int) '?' ); } return_code = (int) ( *option++ ); /* */ /* Argument follows this option */ /* */ if ( *(++match) == ':' ) { /* */ /* Set optarg to proper value */ /* */ if ( *option != '\0' ) optarg = option; else if ( optind < argc ) optarg = argv[optind++]; else { if ( opterr == 0 ) fprintf(stderr, "Option error: missing argument for '%c'\n", return_code); optarg = ""; } /* */ /* Locate the next option */ /* */ next_opt = NULL; } else { next_opt = option; if ( *next_opt == '\0' ) next_opt = NULL; } return( return_code ); } /************************************************************************/ /* */ /* main( argc, argv) */ /* */ /* Parse options. Initialize files, variables. Print each page. */ /* Clean up. Exit. */ /* */ /************************************************************************/ # define OPTIONS "12E:F:R:S:b:c:di:sTD:tLP:q" main(argc,argv) int argc; char *argv[]; { int name_out; /* Used in resident font name */ pgmname = argv[0]; /* ID Ourself for Our Messages! */ PixPerIn = RESOLUTION; /* set up defaults */ RSTDir[0] = '\0'; PXLDir[0] = '\0'; GFDir[0] = '\0'; TFMDir[0] = '\0'; RESDir[0] = '\0'; OutFile = NULL; parse_options( argc, argv ); /* */ /* Set up the input file */ /* */ if ( optind == argc ) { InFile = "stdin"; DviIn = stdin; } else { InFile = argv[optind]; if ( ++optind!= argc ) { fprintf(stderr, "%s: More than one file specified\n", pgmname); GoAway(); } if ((DviIn = fopen(InFile, "r")) == NULL) { fprintf(stderr, "%s: ", pgmname); perror(InFile); GoAway(); } } /* */ /* Set up the output file */ /* */ if (OutFile == NULL) { OutFile = "stdout"; ImOut = stdout; } else { if ((ImOut = fopen(OutFile, "w")) == NULL) { fprintf(stderr, "%s:", pgmname); perror(OutFile); GoAway(); /*NOTREACHED*/ } } if ( RSTDir[0] == '\0' ) sprintf(RSTDir, "%s", RSTDirectory); if ( PXLDir[0] == '\0' ) sprintf(PXLDir, "%s", PXLDirectory); if ( GFDir[0] == '\0' ) sprintf(GFDir, "%s", GFDirectory); if ( TFMDir[0] == '\0' ) sprintf(TFMDir, "%s", TFMDirectory); if ( RESDir[0] == '\0' ) sprintf(RESDir, "%s", RESDirectory); if (Debug) { fprintf(stderr, "Input %s Output %s\n", InFile, OutFile); fprintf(stderr, "Resolution %d, Font directory %s\n", PixPerIn, RSTDir); fprintf(stderr, "Pxl directory %s\n", PXLDir); fprintf(stderr, "GF directory %s\n", GFDir); fprintf(stderr, "TFM directory %s\n", TFMDir); fprintf(stderr, "RES directory %s\n", RESDir); } init_resident(); /* * size of printable area */ PixH = (PixPerIn*PAGE_HEIGHT)/10; PixW = (PixPerIn*PAGE_WIDTH)/10; ImWrtS("@Document(language impress,"); ImWrtS("Name \""); if (Banner) ImWrtS(Banner); else ImWrtS(InFile); ImWrtS("\""); if (Copies) { ImWrtS(", copies "); ImWrtS(Copies); } ImWrtS(")"); /* */ /* Set space size to 2 pixels */ /* Then SP1 will be 3 pixels */ /* */ ImWrt1(iSET_SP); ImWrt2(2); if ( landscape ) { long xxx; xxx = PixH; PixH = PixW; PixW = xxx; ImWrt1(iSET_HV_SYSTEM); ImWrt1((char)((2 << 5) + 5)); } RdPost(); /* Read information at end of dvi file */ sort_pages(); CurPage = PageList; while (CurPage->pg_offset != DVI_END_OFFSET) { if ( in_list(CurPage->pg_number) ) do_page(CurPage->pg_offset); /* Print the page */ CurPage++; } ImWrt1(iEOF); /* End of file */ ImWrt1(0xC6); ImWrt1(0xCF); ImWrt1(0xCE); ImWrt1(0xD4); name_out = FALSE; for ( CurFont=FontH ; CurFont!=NULL ; CurFont=CurFont->f_next ) { if ( CurFont->f_type == RESIDENT ) { if ( name_out ) ImWrt1(','); ImWrtS(CurFont->f_name); name_out = TRUE; } } ImWrt1(0xC6); ImWrt1(0xCF); ImWrt1(0xCE); ImWrt1(0xD4); if ( ImOut != stdout ) { if ( fclose(ImOut) == EOF) { fprintf(stderr, "%s: ",pgmname); perror("Impress file"); GoAway(); } } if ( quiet == FALSE ) fprintf(stderr, "%s: Output left on %s\n", pgmname,OutFile); return( 0 ); } /************************************************************************/ /* */ /* parse_options() */ /* */ /* Initialize resident font database */ /* */ /************************************************************************/ parse_options( argc, argv ) int argc; char **argv; { int option; /* Current option */ while( (option=igetopt(argc,argv, OPTIONS) ) != EOF ) { switch( (char) option ) { case '1': specpage = TRUE; evenodd = TRUE; oddpage = TRUE; break; case '2': specpage = TRUE; evenodd = TRUE; oddpage = FALSE; break; case 'E': lastpage = atoi(optarg); specpage = TRUE; break; case 'F': fnum = atoi(optarg); map_num = fnum; break; case 'R': PixPerIn = atoi(optarg); break; case 'S': firstpage = atoi(optarg); specpage = TRUE; break; case 'b': Banner = optarg; break; case 'c': Copies = optarg; break; case 'L': landscape = TRUE; break; case 'd': Debug = TRUE; break; case 'i': OutFile = optarg; break; case 'D': strcpy(RSTDir, optarg); break; case 'P': strcpy(PXLDir, optarg); break; case 't': transpose = TRUE; break; case 'q': quiet = TRUE; break; case '?': fprintf(stderr, "%s : Usage [%s] file\n", pgmname, OPTIONS); GoAway(); /*NOTREACHED*/ } } } /************************************************************************/ /* */ /* init_resident() */ /* */ /* Initialize resident font database */ /* Reads the resident directory information */ /* */ /************************************************************************/ init_resident() { char res_name[MAX_FILENAME]; /* Resident font file name */ FILE *res_fp; /* File pointer for res. font */ int c; /* input character */ char in_line[MAX_STRING]; /* input line from file */ char *input; /* current position on in_line */ char *start_char; /* first non-blank on in_line */ int i; /* incrementor */ char comment[MAX_STRING]; /* comment field of in_line */ char map_file[MAX_STRING]; /* name oof character map file */ sprintf(res_name, "%s/%s", RESDir, RES_FILE); if ( (res_fp=fopen(res_name, "r")) == NULL ) { max_map = 0; fprintf(stderr, "%s : No resident fonts used\n", pgmname); return; } while (TRUE) { /* */ /* Read in a line of text */ /* */ input = in_line; i = 0; while ( (c=getc(res_fp)) != '\n' ) { if ( c == EOF ) break; if ( ilastpage) ) return(0); return(1); } /************************************************************************/ /* */ /* do_page( long ) */ /* */ /* Given an offset into the Dvi file, print the page starting */ /* at that offset. */ /* */ /************************************************************************/ do_page(page_offset) long page_offset; { register unsigned int code; SCALED_POINT h, w; CurFont = 0; if ( fseek(DviIn, page_offset, 0) == -1 ) { fprintf(stderr, "Bad seek to %ld\n", page_offset); perror(InFile); GoAway(); } EnvPtr = Environments; while((code = DviRdU1()) != EOP) { if (code <= 127) { DoChar(code, 1); continue; } if (code >= FONT0 && code <= FONT63) { GetFont((long) (code - FONT0)); continue; } if (code == FNT1) { GetFont((long) (DviRdU1())); continue; } switch(code) { case NOP: break; case SET1: code = DviRdU1(); DoChar(code, 1); break; case PRE: fseek(DviIn, (long)((4*sizeof(long)) + 1), 1); fseek(DviIn, (long) (DviRd1()), 1); break; case BOP: if ( quiet == FALSE ) fprintf(stderr, "[%ld]\n", DviRd4()); else DviRd4(); fseek(DviIn, (long)(10 * sizeof(long)), 1); EnvPtr = Environments; E_H = 0; E_V = 0; E_W = E_X = E_Y = E_Z = 0; ImX = ImY = 0; /* Impress positions start out at 0 */ ImWrt1(iPAGE); break; case PUSH: EnvPtr->e_h = E_H; EnvPtr->e_v = E_V; EnvPtr->e_w = E_W; EnvPtr->e_x = E_X; EnvPtr->e_y = E_Y; EnvPtr->e_z = E_Z; EnvPtr++; break; case POP: --EnvPtr; E_H = EnvPtr->e_h; E_V = EnvPtr->e_v; E_W = EnvPtr->e_w; E_X = EnvPtr->e_x; E_Y = EnvPtr->e_y; E_Z = EnvPtr->e_z; break; case HORZRULE: h = DviRd4(); DoRule(h, DviRd4()); break; case VERTRULE: h = DviRd4(); w = DviRd4(); DoRule(h, w); E_H += w; /* Update width */ break; case HORZCHAR: DoChar(DviRdU1(), 0); break; case FONT: GetFont(DviRd4()); break; case FNTDF4: (void) DviRd1(); /* Font definitions */ case FNTDF3: (void) DviRd1(); /* already picked up in the */ case FNTDF2: (void) DviRd1(); /* postamble */ case FNTDF1: (void) DviRd1(); fseek(DviIn, (long)(3*sizeof(long)), 1); fseek(DviIn, (long)(DviRdU1() + DviRdU1()), 1 ); break; case X1: E_H += E_X = DviRd1(); break; case X2: E_H += E_X = DviRd2(); break; case X3: E_H += E_X = DviRd3(); break; case X4: E_H += E_X = DviRd4(); break; case X0: E_H += E_X; break; case W1: E_H += E_W = DviRd1(); break; case W2: E_H += E_W = DviRd2(); break; case W3: E_H += E_W = DviRd3(); break; case W4: E_H += E_W = DviRd4(); break; case W0: E_H += E_W; break; case Y1: E_V += E_Y = DviRd1(); break; case Y2: E_V += E_Y = DviRd2(); break; case Y3: E_V += E_Y = DviRd3(); break; case Y4: E_V += E_Y = DviRd4(); break; case Y0: E_V += E_Y; break; case Z1: E_V += E_Z = DviRd1(); break; case Z2: E_V += E_Z = DviRd2(); break; case Z3: E_V += E_Z = DviRd3(); break; case Z4: E_V += E_Z = DviRd4(); break; case Z0: E_V += E_Z; break; case DOWN1: E_V += DviRd1(); break; case DOWN2: E_V += DviRd2(); break; case DOWN3: E_V += DviRd3(); break; case DOWN4: E_V += DviRd4(); break; case RIGHT1: E_H += DviRd1(); break; case RIGHT2: E_H += DviRd2(); break; case RIGHT3: E_H += DviRd3(); break; case RIGHT4: E_H += DviRd4(); break; case XXX1: DoSpecial(1); break; case XXX2: DoSpecial(2); break; case XXX3: DoSpecial(3); break; case XXX4: DoSpecial(4); break; default: fprintf(stderr, "%s: Bad DVI op code %d (3)\n", pgmname, code); GoAway(); /*NOTREACHED*/ } } ImWrt1(iENDPAGE); /* End of page */ } DoChar(c, update) unsigned int c; int update; /* Whether to update location */ { struct fg *fg; /* Font glyph */ if (CurFont == 0) { fprintf(stderr,"%s: No font specified\n",pgmname); GoAway(); /*NOTREACHED*/ } if (CurFont->f_type == NON_EXIST) return; if (c >= CperFont) { fprintf(stderr, "%s: Character 0%o out of range\n", pgmname,c); return; } fg = &CurFont->f_fg[c]; /* * Update the position if necessary. If it would be off the * page print an error message and don't output the character, * but still keep track of the current horizontal position. */ if (UpdPos()) { if ( isprint(c) ) fprintf(stderr, "char %c\n", c); else fprintf(stderr, "char 0%o\n", (int) c); if (update) E_H += fg->fg_rwid; return; } /* */ /* See if character is loaded yet. */ /* */ if ( !fg->fg_load ) { /* */ /* See if font is loaded yet */ /* */ if ( CurFont->f_type == UNKNOWN ) FindFont(); if ( CurFont->f_type == RESIDENT ) fg->fg_load = TRUE; else if ( CurFont->f_type != TFM ) { if ( !LoadC((int) c)) { fprintf(stderr, "%s : Warning - attempt to print non-existent char\n", pgmname); fprintf(stderr, "\tchar 0%o in font %s\n", (int) c, CurFont->f_name); } else fg->fg_load = TRUE; } if ( !fg->fg_load ) { if (update) E_H += fg->fg_rwid; return; } } /* */ /* See if impress family number is the */ /* same. */ /* */ if ((CurFont->f_impnum + (c/CHARS_IN_FAMILY)) != Im_family) { Im_family = CurFont->f_impnum + (c/CHARS_IN_FAMILY); ImWrt1(iSET_FAMILY); ImWrt1(Im_family); } ImWrt1((int) (c % CHARS_IN_FAMILY)); ImX += fg->fg_pwid; /* Keep track of the impress position */ if (update) E_H += fg->fg_rwid; } /************************************************************************/ /* */ /* Do special operations from tex */ /* */ /* This command is an ascii string that has the following format: */ /* */ /* overlay(filename) */ /* insert(filename) */ /* */ /* filename is the operating system representation of a file. */ /* */ /* The file is included directly into the imPress output. It may */ /* start with a @...(...) which will be stripped off. */ /* */ /* Insert is used to insert the file at the current page */ /* postition. */ /* */ /* Overlay will end the current page and start at the top */ /* of the next page. */ /* */ /************************************************************************/ #define white(x) (x==' ' || x=='\t') #define INSERT 1 #define OVERLAY 2 #define EMULATOR 3 DoSpecial(n) int n; { unsigned long size; /* Size of the special string */ int tempi,optype; char *emulator; /* emulator string */ char *c; /* Temporary character pointer */ char *command; /* special command - overlay or insert */ char *in_string; /* Inputted special character string */ char *left_paran; /* Position of first left paranthesis */ char *special_name; /* File name for special file */ FILE *special_fp; /* File pointer for special file */ switch (n) { case 1: size = (unsigned long) DviRdU1(); break; case 2: size = (unsigned long) DviRdU2(); break; case 3: size = (unsigned long) DviRdU3(); break; case 4: size = DviRdU4(); break; } if (size > 132) { fprintf(stderr, "%s: special command > 132 characters\n", pgmname); fseek(DviIn, (long) size, 1); return; } /* */ /* Read in the special string */ /* */ in_string = malloc1((unsigned)(size+1) ); fread( in_string, sizeof(char), (int)size, DviIn); in_string[size] = '\0'; /* check for leading and trailing prens */ if (!index(in_string, '(') || !rindex(in_string, ')')){ fprintf(stderr, "%s: incorrect special format\n",pgmname); free(in_string); return; } command = in_string; while( white(*command) ) command++; /* skip leading white space */ left_paran = command; while ( (!white(*left_paran)) && (*left_paran != '(') ) left_paran++; /* skip non white till ( or white */ *left_paran = '\0'; for ( c=command ; c!=left_paran ; c++ ) if ( isupper(*c) ) *c = LOWERCASE(*c); if (!strcmp("insert", command)) optype = INSERT; else if (!strcmp("overlay", command)) optype = OVERLAY; else if ( !strcmp("emulator", command)) optype = EMULATOR; else { fprintf(stderr, "%s: special command operation must be 'insert' or 'overlay'\n", pgmname); free(in_string); return; } if ( optype == EMULATOR ) { emulator = ++left_paran; for ( c= ++left_paran ; *c!='\0' ; c++ ) { if ( *c=='(' ) break; } *c = '\0'; left_paran = c; } special_name = ++left_paran; while(white(*special_name)) special_name++; for ( c=special_name ; *c!='\0' ; c++ ) { if ( white(*c) || *c== ')' ) break; } *c = '\0'; /* make a string of it */ if ( (special_fp=fopen(special_name ,"r")) == NULL) { fprintf(stderr, "%s: ",pgmname); perror(special_name); free(in_string); return; } free(in_string); /* no longer need this */ UpdPos(); ImWrt1(iPUSH); switch (optype){ case EMULATOR: ImWrt1(iCALL_INSTANCE); ImWrtS(emulator); break; case OVERLAY: ImWrt1(iPAGE); ImWrt1(iSET_HV_SYSTEM); ImWrt1(0100); break; case INSERT: ImWrt1(iSET_HV_SYSTEM); ImWrt1(0140); break; } tempi = getc(special_fp); if ( ((char) tempi) == '@' ) { while ((tempi = getc(special_fp)) != EOF) { if (((char) tempi) == ')' ) break; } } while ((tempi = getc(special_fp)) != EOF) ImWrt1(tempi); if ( (optype == OVERLAY) || (optype == EMULATOR) ) ImWrt1(iENDPAGE); ImWrt1(iPOP); fclose(special_fp); } /* * Draw a rule at current position */ DoRule(height, width) SCALED_POINT height, width; /* Bottom left corner */ { int hi, wi; /* Height and width (in pixels) */ if (height <= 0 || width <= 0) return; if (UpdPos()) /* Update the position if needed */ fprintf(stderr,"rule\n"); /* Part of "off page" error msg */ hi = SPtoPIX(height, PixPerIn); if (hi < RULE_HEIGHT) hi = RULE_HEIGHT; wi = SPtoPIX(width, PixPerIn); if (wi < RULE_WIDTH) wi = RULE_WIDTH; ImWrt1(iBRULE); ImWrt2(wi); ImWrt2(hi); ImWrt2(-(hi-1)); } UpdPos() { int xpos, ypos; /* Where we want the printer */ /* to be in pixels on the page */ int xoff, yoff; /* How far off it is in pixels */ xpos = SPtoPIX(E_H, PixPerIn); /* Where we want the Canon */ if (xpos < 0 || xpos > PixW) { fprintf(stderr, "%s: Off page, horz pos : ",pgmname); return TRUE; /* Indicate error */ } ypos = SPtoPIX(E_V, PixPerIn); if (ypos < 0 || ypos > PixH) { fprintf(stderr, "%s: Off page, vert pos : ",pgmname); return TRUE; /* Indicate error */ } xoff = xpos - ImX; /* How far off it is now */ if (xoff != 0) { /* If too far, move it */ switch ( xoff ) { case 1: ImWrt1(iMPLUS); break; case -1: ImWrt1(iMMINUS); break; case 2: ImWrt1(iSP); break; case 3: ImWrt1(iSP1); break; default: ImWrt1(iMMOVE); ImWrt2(xoff); } ImX = xpos; } yoff = ypos - ImY; if (yoff != 0) { ImWrt1(iREL_V); ImWrt2(yoff); ImY = ypos; } return FALSE; /* Indicate no error */ } GetFont(dvi_font_num) long dvi_font_num; { register struct font *fp; for (fp = FontH; fp != 0; fp = fp->f_next) { if (fp->f_dvinum == dvi_font_num) { CurFont = fp; return; } } fprintf(stderr, "%s: Font number %ld not declared\n", pgmname, dvi_font_num); GoAway(); } /************************************************************************/ /* */ /* sort_pages() */ /* */ /* This routine will read in all of the pointers to the pages */ /* in the file, and then sort them. */ /* */ /************************************************************************/ int lessthan; int greaterthan; sort_pages() { struct page_ptr *PagePtr; extern int page_cmp(); PagePtr = PageList; fseek(DviIn, LastPage, 0 ); PagePtr->pg_offset = LastPage; if ( transpose == TRUE ) { lessthan = 1; greaterthan = -1; } else { lessthan = -1; greaterthan = 1; } while ( 1 ) { if ( DviRdU1() != BOP ) { fprintf(stderr, "%s: Ill formed dvi file\n", pgmname); exit(1); } PagePtr->pg_number = DviRd4(); PagePtr++; fseek(DviIn, (long)(9 * 4), 1); PagePtr->pg_offset = DviRd4(); if ( PagePtr->pg_offset == DVI_END_OFFSET ) break; fseek(DviIn, PagePtr->pg_offset, 0); } qsort((char *)PageList, (PagePtr-PageList), sizeof(struct page_ptr), page_cmp); } page_cmp(p1, p2) struct page_ptr *p1, *p2; { if ( p1->pg_number < p2->pg_number ) return(lessthan); return(greaterthan); } /* * Read the postamble - font information and such at the end of the .dvi file * * The Postamble is of the form: * * post - 1 byte command * p - 4 byte pointer to last BOP in dvi file * num - 4 byte numerator * den - 4 byte denominator ( these are a fraction by which all * dimensions in the DVI file can be multiplied * in order to get lengths in units of 10**-7 meters) * mag - 4 byte 1000 magnification of DVI dimensions * l - 4 byte height + depth of tallest page * u - 4 byte width of widest page * s - 2 byte maximum stack depth * t - 2 byte total number of pages * * post_post - 1 byte command * q - 4 byte pointer to the post command * i - 1 byte id byte, currently set to 2 * ending stuff - 4 to 7 bytes each containing the number 223 * * are of the form * * c - 4 byte checksum * s - 4 byte scale factor for chars in this font * d - 4 byte design size * a - 1 byte length of directory name * l - 1 byte length of filename * n - (a+l) byte filename * noop - optional noops may follow this font definition */ #define DVI_END_BYTE 223 #define DVI_ID 2 RdPost() { long val; register struct font *fp; int namelen; char *p; long MaxH, MaxW; /* Maximum page dimensions */ fseek(DviIn, -1L, 2); /* Last byte of file */ /* */ /* Read end until non end byte */ /* is found */ /* */ while ((val = DviRdU1()) == DVI_END_BYTE) fseek(DviIn, -2L, 1); if (val != DVI_ID) { fprintf(stderr, "%s: Bad DVI version %ld\n", pgmname,val); GoAway(); /*NOTREACHED*/ } fseek(DviIn, -5L, 1); /* Pointer to postamble */ fseek(DviIn, (long) DviRd4(), 0); /* Begin of postamble */ if (DviRdU1() != PST) { fprintf(stderr, "%s: DVI postamble not found (DVI82)\n", pgmname); GoAway(); } LastPage = DviRd4(); /* Begin of last page */ /* */ /* The scaling numerator and denominator */ /* are a fraction to convert DVI scaled */ /* point units to 10^-7 meters. */ /* These are checked to make sure that the */ /* version of TeX that generated the DVI */ /* file has not been modified. */ /* */ if ( DviRd4() != POST_NUMERATOR ) { fprintf(stderr, "%s : DVI file is not in scaled point format!\n", pgmname); exit(1); } if ( DviRd4() != POST_DENOMINATOR ) { fprintf(stderr, "%s : DVI file is not in scaled point format!\n", pgmname); exit(1); } DVIMag = DviRd4(); /* Overall file magnification */ MaxH = SPtoPIX(DviRd4(), PixPerIn); MaxW = SPtoPIX(DviRd4(), PixPerIn); if ( MaxH > PixH ) { fprintf(stderr, "%s : height of paper mismatch\n", pgmname); fprintf(stderr, "\tpaper is %d milli-inches\n", ((PixH * 10)/PixPerIn) ); fprintf(stderr, "\tTex pages are %d milli-inches\n", ((MaxH * 10)/PixPerIn) ); } if ( MaxW > PixW ) { fprintf(stderr, "%s : width of paper mismatch\n", pgmname); fprintf(stderr, "\tpaper is %d milli-inches\n", ((PixW * 10)/PixPerIn) ); fprintf(stderr, "\tTex pages are %d milli-inches\n", ((MaxW * 10)/PixPerIn) ); } Environments = (struct env *) malloc1( ((DviRd2() + 1) * sizeof (struct env) ) ); PageList = (struct page_ptr *) malloc1( (unsigned) ((DviRd2()+2) * sizeof(struct page_ptr)) ); /* * Now read the information about the fonts used in this file. */ FontH = 0; while ((val = DviRdU1()) != POSTPOST) { fp = (struct font *) malloc1(sizeof (struct font)); bzero((char *) fp, sizeof(struct font)); fp->f_type = UNKNOWN; fp->f_next = FontH; FontH = fp; switch ( val ) { case FNTDF1: fp->f_dvinum = DviRd1(); break; case FNTDF2: fp->f_dvinum = DviRd2(); break; case FNTDF3: fp->f_dvinum = DviRd3(); break; case FNTDF4: fp->f_dvinum = DviRd4(); break; } fp->f_checksum = DviRd4(); fp->f_scale = DviRd4(); fp->f_dessig = DviRd4(); fp->f_mag = ((((fp->f_scale*100) + (fp->f_dessig/2L) ) /fp->f_dessig) * DVIMag)/100; namelen = DviRdU1() + DviRdU1(); DviRdS(fp->f_name, namelen); /* Name */ fp->f_name[namelen] = '\0'; p = rindex(fp->f_name, '.'); if (p != 0) *p = 0; } } /* * This routine finds the correct raster image file. This is done by searching * two directory paths to allow seperation of different naming conventions. * The TeX normal naming convention and format is for a PXL file pool that has * a magnification/resolution Quotent. The IMAGEN normal way is an RST file * that is in a directory specificly for a particular resolution at a number of * magnifications indicated by the possible 2 digit number after the .Rxx of * the name. * * We first look for resident fonts, then PXL, then RST fonts, then TFM widths. */ FindFont() { int i; FILE *file_stream; if ( quiet == FALSE ) fprintf(stderr, "Font '%s' at magnification %d\n", CurFont->f_name, CurFont->f_mag); CurFont->f_impnum = fnum; /* The impress family number for this font */ if ( fnum >= MAX_FAMILIES ) { fprintf(stderr, "%s : Using too many fonts for imPress!\n", pgmname ); exit(2); } /* CurFont->f_impnum = fnum; /* The impress family number for this font */ /* */ /* See if it is a resident font */ /* */ if ( is_resident() == 0 ) { CurFont->f_type = RESIDENT; if ( quiet == FALSE ) fprintf(stderr, "\tResident font %s found\n", CurFont->f_name); fnum += (MAX_CHARS/CHARS_IN_FAMILY); if ( CurFont->f_mag != 1000 ) fprintf(stderr, "%s : Warning: magnification of %d ignored in font %s\n", pgmname, CurFont->f_mag, CurFont->f_filnam); sprintf(CurFont->f_filnam, "%s/%s%s", TFMDir, CurFont->f_name, TFM_EXTENSION); RdTFMFont(); return; } /* */ /* See if it is a GF file */ /* */ sprintf(CurFont->f_filnam, "%s/%s%s", GFDir, CurFont->f_name, GF_EXTENSION ); if ((file_stream = fopen(CurFont->f_filnam, "r")) != NULL) { fclose(file_stream); /* fnum += (CperFont/CHARS_IN_FAMILY); */ CurFont->f_type = GF; if ( quiet == FALSE ) fprintf(stderr, "\tGF file '%s'\n", CurFont->f_filnam); RdGFFont(); fnum += (CurFont->f_lc-CurFont->f_fc+CHARS_IN_FAMILY-1)/ CHARS_IN_FAMILY; return; } /* */ /* See if it is a PXL file */ /* Try mag/quotient. If it doesn't work */ /* try varying the PXL mag/quotient */ /* magnification. */ /* */ sprintf(CurFont->f_filnam, "%s/%s.%ld%s",PXLDir, CurFont->f_name, (long) ((CurFont->f_mag*PixPerIn)/PXL_RESOLUTION), PXL_EXTENSION ); if ((file_stream = fopen(CurFont->f_filnam, "r")) != NULL) { fclose(file_stream); fnum += (MAX_PXL_CHARS/CHARS_IN_FAMILY); CurFont->f_type = PXL; if ( quiet == FALSE ) fprintf(stderr, "\tPXL file '%s'\n", CurFont->f_filnam); RdPFont(); return; } for ( i=(-PXL_FUDGE) ; i<=PXL_FUDGE ; i++ ) { sprintf(CurFont->f_filnam, "%s/%s.%ld%s",PXLDir, CurFont->f_name, (long) (((CurFont->f_mag*PixPerIn)/PXL_RESOLUTION)+i), PXL_EXTENSION ); if ((file_stream = fopen(CurFont->f_filnam, "r")) != NULL) { fclose(file_stream); fnum += (MAX_PXL_CHARS/CHARS_IN_FAMILY); CurFont->f_type = PXL; if ( quiet == FALSE ) fprintf(stderr, "\tPXL file '%s'\n", CurFont->f_filnam); RdPFont(); return; } } /* */ /* See if the file is an RST file. */ /* */ sprintf(CurFont->f_filnam, "%s/%s%s%d", RSTDir, CurFont->f_name, RST_EXTENSION, CurFont->f_mag/100); if ((file_stream=fopen(CurFont->f_filnam, "r")) != NULL ) { fclose(file_stream); fnum += (MAX_CHARS/CHARS_IN_FAMILY); CurFont->f_type = RST; if ( quiet == FALSE ) fprintf(stderr, "\tRST file '%s'\n", CurFont->f_filnam); RdFont(); return; } /* */ /* See if there is a TFM file */ /* */ sprintf(CurFont->f_filnam, "%s/%s%s", TFMDir, CurFont->f_name, TFM_EXTENSION); if ((file_stream=fopen(CurFont->f_filnam, "r")) != NULL ) { fclose(file_stream); fnum += (MAX_PXL_CHARS/CHARS_IN_FAMILY); CurFont->f_type = TFM; if ( quiet == FALSE ) fprintf(stderr, "\tTFM file '%s'\n", CurFont->f_filnam); RdTFMFont(); return; } fprintf(stderr, "%s : %s: unable to find font\n", pgmname, CurFont->f_name); strcpy(CurFont->f_filnam, CurFont->f_name); CurFont->f_type = NON_EXIST; } /****************************************************************/ /* */ /* is_resident() */ /* */ /* Determine if the current font is a resident one */ /* */ /****************************************************************/ is_resident() { int i; /* incrementor */ CHARORDER *cur_order; /* Current character ordering */ for ( i=0 ; if_name, map_base[i].m_name, strlen(map_base[i].m_name) ) == 0 ) break; } if ( i==max_map ) return(1); cur_order = &(order_base[map_base[i].m_number]); CurFont->f_fc = 0; CurFont->f_lc = MAX_CHARS; /* */ /* See if imPress map is sent yet */ /* */ if ( cur_order->co_mapnum == 0 ) out_map(); for ( i=0 ; ico_mapsize ; i++ ) { ImWrt1(iC_FAMILY_TABLE); ImWrt1(CurFont->f_impnum + i); ImWrt1(1); ImWrt1(cur_order->co_mapnum + i); ImWrtS(CurFont->f_name); ImWrt1(0); /* end of filename */ } return(0); } /****************************************************************/ /* */ /* out_map( CHARORDER * ) */ /* */ /* Output a map for the given resident font */ /* */ /****************************************************************/ struct map_triples { int map_start; GASCII map_gascii; int map_count; }; out_map( ordering ) CHARORDER *ordering; { int i,j; /* incrementor */ int map_cnt; /* Num of triples in this map */ struct map_triples triples[CHARS_IN_FAMILY + 1]; struct map_triples *map_ptr; GASCII gascii[MAX_CHARS]; GASCII *g_ptr; FILE *order_fp; /* file pointer for order file */ char order_name[MAX_FILENAME]; /* full filename */ char *input; /* current position of in_line */ char in_line[MAX_STRING]; /* inputted line of text */ char *start_char; /* first non-blank on line */ int c; /* inputted character */ int hi_gascii, lo_gascii; /* inputted gascii number */ int position; /* position of this gascii */ char comment[MAX_STRING]; /* comment portion of line */ sprintf(order_name, "%s/%s", RESDir, ordering->co_file); if ( (order_fp=fopen(order_name, "r")) == NULL ) { perror(order_name); exit(1); } bzero( (char *) gascii, sizeof(GASCII) * MAX_CHARS); while (TRUE) { input = in_line; while ( (c=getc(order_fp)) != '\n' ) { if ( c == EOF ) break; *input++ = c; } if ( c == EOF ) break; *input = '\0'; start_char = in_line; while ( (*start_char==' ') || (*start_char=='\t') ) start_char++; /* Blank line */ if ( start_char == input ) continue; /* Comment line */ if ( *start_char == '#' ) continue; /* Identifier string */ if ( *start_char == '=' ) { continue; } if (sscanf(start_char, "%d.%d %d%s", &hi_gascii, &lo_gascii, &position, comment) < 3 ) { fprintf(stderr, "%s : Bad input line in file %s", pgmname, order_name); fputs(in_line, stderr); exit(1); } gascii[position] = hi_gascii*256 + lo_gascii; } fclose(order_fp); /* */ /* A font is divided over a set of */ /* imPress families. For each */ /* family, a seperate map is */ /* output. DoChar() handles making */ /* sure the proper family is loaded*/ /* */ ordering->co_mapnum = map_num; for ( j=0 ; j<(MAX_CHARS/CHARS_IN_FAMILY) ; j++ ) { int map_base; map_base = CHARS_IN_FAMILY * j; /* */ /* Determine how many triples are in */ /* this map. */ /* */ map_ptr = triples; map_ptr->map_start = 0; map_ptr->map_gascii = 0; map_ptr->map_count = 0; for ( i=0,g_ptr= &gascii[map_base] ; imap_start) == (*g_ptr-map_ptr->map_gascii ) ) map_ptr->map_count = (i+1)-map_ptr->map_start; else { map_ptr++; map_ptr->map_start = i; map_ptr->map_gascii = *g_ptr; map_ptr->map_count = 1; } } /* */ /* Output this map */ /* */ map_cnt = map_ptr - triples; ImWrt1(iC_MAP); ImWrt1(map_num++); ImWrt1(map_cnt); for ( map_ptr= &triples[1],i=0 ; imap_start % CHARS_IN_FAMILY); ImWrt2(map_ptr->map_gascii); ImWrt1(map_ptr->map_count); } } ordering->co_mapsize = map_num - ordering->co_mapnum; } /****************************************************************/ /* */ /* RdFont() */ /* */ /* Read the preamble of an RST file. */ /* */ /****************************************************************/ RdFont() { char tmpstr[100]; long rstmag; /* mag stored in raster file */ int cmpmag; struct gd *gd; struct fg *fg; int c; long width; long gd_offset; /* file offset to glyph dir. */ int font_resolution; /* resolution of this font */ FontOpn(); FontRdS(tmpstr, 8); if (strncmp(tmpstr, RST_ID, strlen(RST_ID)) != 0) { fprintf(stderr, "%s: %s is not a raster file\n", pgmname, CurFont->f_filnam); FontCls(); GoAway(); } (void) FontRd2(); /* Number of bytes in preamble */ if (FontRd1() != RST_VERSION) { fprintf(stderr, "%s: Font %s version is not %d!\n", pgmname, CurFont->f_filnam, RST_VERSION); GoAway(); } gd_offset = FontRd3(); /* glyph directory ptr. */ CurFont->f_fc = FontRd2(); /* First char defined */ CurFont->f_lc = FontRd2(); /* Last char defined */ if (CurFont->f_lc - CurFont->f_fc + 1 > CperFont) { fprintf(stderr, "%s: Font %s has too many characters!\n", pgmname, CurFont->f_filnam); GoAway(); } /* * The magnification is stored in thousandths. If we just * multiply by the magnification and divide by 1000 we may * get an overflow. On the other hand if we divide by 1000 * first we lose precision. So we compromise by dividing * by 100 and then multiplying by one-tenth the magnification. */ rstmag = FontRd4(); /* Font magnification */ if (rstmag == 0) rstmag = 1000; /* 1000 is the default */ rstmag = ( rstmag + 50 ) / 100; cmpmag = (CurFont->f_mag + 50) / 100; if ( rstmag != cmpmag ) { fprintf(stderr, "%s: Raster and DVI magnifications do not match for font %s, \ DVI superseding, output may be improperly aligned\n",pgmname, CurFont->f_filnam); fprintf(stderr, "rstmag = %d mag = %d\n", rstmag, CurFont->f_mag); } CurFont->f_mag = (CurFont->f_mag + 5) / 10; CurFont->f_dessig = FontRd4(); /* Design size */ fseek(CurFont->f_strm, (long) 16, 1); font_resolution = FontRd2(); fseek(CurFont->f_strm, gd_offset, 0); CurFont->f_gd = (struct gd *) malloc1((int)((CurFont->f_lc - CurFont->f_fc + 1) * sizeof (struct gd))); for (c=CurFont->f_fc, gd=CurFont->f_gd, fg = &CurFont->f_fg[CurFont->f_fc]; c <= CurFont->f_lc; c++, gd++, fg++) { gd->gd_H = FontRd2(); /* H */ gd->gd_W = FontRd2(); /* W */ gd->gd_Y = FontRd2(); /* Y */ gd->gd_X = FontRd2(); /* X */ width = (FontRd4()/100) * CurFont->f_mag; /* Stored in fix-points */ fg->fg_pwid = FPtoPIX(width, font_resolution); fg->fg_rwid = FPtoSP(width); gd->gd_roff = FontRd3(); /* Offset in file to raster data */ } } /****************************************************************/ /* */ /* RdTFMFont() */ /* */ /* Read a TFM file */ /* */ /****************************************************************/ RdTFMFont() { struct fg *fg; int c; long lh; int nw; long in_widths[MAX_PXL_CHARS]; long fpsize; FontOpn(); FontRd2(); /* skip the length of the file */ lh = FontRd2(); /* length of the header data */ CurFont->f_fc = FontRd2(); /* smallest char code */ CurFont->f_lc = FontRd2(); /* largest char code */ nw = FontRd2(); /* number of words in width tbl */ fseek(CurFont->f_strm, (long) (24), 0); if (CurFont->f_checksum != FontRd4()) { fprintf(stderr, "%s: Warning, checksum of font %s", pgmname, CurFont->f_name); fprintf(stderr, " does not match TFM file\n"); } CurFont->f_dessig = FontRd4(); fseek(CurFont->f_strm, (long) ((lh * 4)+24) , 0); for ( fg= &CurFont->f_fg[CurFont->f_fc], c=CurFont->f_fc ; c<=CurFont->f_lc ; c++, fg++ ) { fg->fg_pwid = FontRd1(); (void) FontRd3(); } for ( c=0 ; cf_scale>>16); } for ( fg= &CurFont->f_fg[CurFont->f_fc], c=CurFont->f_fc ; c<=CurFont->f_lc ; c++, fg++ ) { fg->fg_rwid = FPtoSP(in_widths[fg->fg_pwid]); fg->fg_pwid = FPtoPIX(in_widths[fg->fg_pwid], PixPerIn); } FontCls(); } /****************************************************************/ /* */ /* RdPFont() */ /* */ /* Read the global font info out of a PXL file */ /* */ /****************************************************************/ RdPFont() { struct gd *gd; struct fg *fg; int c; long width, fpsize; long gd_offset; /* offset to glyph directory */ FontOpn(); if (FontRd4() != PXL_VERSION) { fprintf(stderr, "%s: file %s is ill-formed PXL file (1)\n", pgmname, CurFont->f_filnam); FontCls(); GoAway(); } /* */ /* Go back five words from the */ /* end of the file. */ /* */ fseek(CurFont->f_strm,(long)-(5*sizeof(long)), 2); (void) FontRd4(); /* Checksum */ CurFont->f_scale = FontRd4(); if (CurFont->f_scale == 0) CurFont->f_scale = 1000; CurFont->f_dessig = FontRd4(); gd_offset = FontRd4() * 4; /* glyph directory ptr*/ if ((FontRd4() != PXL_VERSION)) { fprintf(stderr, "%s: file %s is ill-formed PXL file (2)\n", pgmname, CurFont->f_filnam); GoAway(); } CurFont->f_fc = 0; CurFont->f_lc = MAX_PXL_CHARS - 1; CurFont->f_gd = (struct gd *) malloc1((int)((CurFont->f_lc - CurFont->f_fc + 1) * sizeof (struct gd))); fseek(CurFont->f_strm, gd_offset, 0); fpsize = (CurFont->f_dessig + (1 << 19))/(1 << 20); for ( c=0, gd=CurFont->f_gd, fg= &CurFont->f_fg[CurFont->f_fc]; cgd_W = FontRd2(); /* W */ gd->gd_H = FontRd2(); /* H */ gd->gd_X = FontRd2(); /* X */ gd->gd_Y = FontRd2(); /* Y */ gd->gd_roff = FontRd4()*4; /* Offset in file to raster data */ width = FontRd4(); width = (width + 512L)/1024L; width = (width * CurFont->f_scale * fpsize)/1000; width = (width * (long)(PXL_RESOLUTION))/PixPerIn; width <<= 10; /* Stored in fix-points */ fg->fg_pwid = FPtoPIX(width, PixPerIn); fg->fg_rwid = FPtoSP(width); } } /****************************************************************/ /* */ /* RdGFFont() */ /* */ /* Read the global font info out of a GF file */ /* */ /****************************************************************/ RdGFFont() { int val; int k; long dx[CperFont]; long pointer[CperFont]; long width[CperFont]; struct fg *fg; struct gd *gd; long lwidth; FontOpn(); if (FontRdU1() != GF_PRE) { fprintf(stderr, "%s: file %s is ill-formed GF file (1)\n", pgmname, CurFont->f_filnam); FontCls(); GoAway(); } fseek(CurFont->f_strm, -1L, 2); /* Last byte of file */ /* */ /* Read end until non end byte */ /* is found */ /* */ while ((val = FontRdU1()) == GF_END_BYTE) fseek(CurFont->f_strm, -2L, 1); if (val != GF_ID) { fprintf(stderr, "%s: Bad GF version %ld\n", pgmname,val); GoAway(); /*NOTREACHED*/ } fseek(CurFont->f_strm, -5L, 1); /* Pointer to postamble */ fseek(CurFont->f_strm, (long) FontRd4(), 0); /* Begin of postamble */ if (FontRdU1() != GF_POST) { fprintf(stderr, "%s: GF postamble not found\n", pgmname); GoAway(); } (void) FontRd4(); /* Back pointer ignored */ CurFont->f_dessig = FontRd4(); (void) FontRd4(); /* Checksum */ (void) FontRd4(); /* hppp */ (void) FontRd4(); /* vppp */ FontRd4(); FontRd4(); FontRd4(); FontRd4(); CurFont->f_fc = CperFont; CurFont->f_lc = 0; for ( k=FontRdU1() ; ( (k==GF_CLC) || (k==GF_CLC0) ) ; k=FontRdU1() ) { if ( k==GF_CLC ) { k = FontRdU1(); dx[k] = FontRd4(); FontRd4(); } else if ( k==GF_CLC0 ) { k = FontRdU1(); dx[k] = FontRdU1(); } if ( k < CurFont->f_fc ) CurFont->f_fc = k; if ( k > CurFont->f_lc ) CurFont->f_lc = k; width[k] = FontRd4(); pointer[k] = FontRd4(); k = GF_NOOP; } CurFont->f_gd = (struct gd *) malloc1((int)((CurFont->f_lc - CurFont->f_fc + 1) * sizeof (struct gd))); for ( k=CurFont->f_fc ; k<=CurFont->f_lc ; k++ ) { fg = &CurFont->f_fg[k]; gd = &CurFont->f_gd[k]; lwidth = width[k] * ( (CurFont->f_dessig + (1<<19))/(1<<20) ); fg->fg_rwid = FPtoSP(lwidth); fg->fg_pwid = dx[k]; gd->gd_roff = pointer[k]; /* Offset in file to raster data */ } } /****************************************************************/ /* */ /* FontOpn() FontCls() */ /* */ /* Routines for opening and closing Font files. These */ /* will keep a maximum of MAXOPNF open at any given */ /* time. FontOpn() opens the CurFont file. */ /* */ /****************************************************************/ FontOpn() { /* */ /* If it is already open, return */ /* */ if (CurFont->f_strm != NULL) return; if (NumOpnF >= MAXOPNF) { struct font *fp1; /* If so, then close one */ for ( fp1=FontH; fp1!=0; fp1=fp1->f_next ) { if (fp1->f_strm != NULL) { (void) fclose(fp1->f_strm); fp1->f_strm = NULL; NumOpnF--; break; } } } if ( (CurFont->f_strm=fopen(CurFont->f_filnam, "r")) == NULL) { fprintf(stderr,"%s: ", pgmname); perror(CurFont->f_filnam); GoAway(); } NumOpnF++; /* Increment number of open fonts */ } FontCls() { if (CurFont->f_strm != NULL) { (void) fclose(CurFont->f_strm); CurFont->f_strm = NULL; NumOpnF--; /* Decrement number of open fonts */ } } /************************************************************************/ /* */ /* LoadC( char ) */ /* */ /* Download the bitmap of a character */ /* */ /************************************************************************/ char in_rast[MAX_C_WIDTH * MAX_C_HEIGHT]; char tmp_rast[MAX_C_WIDTH * MAX_C_HEIGHT]; LoadC(c) int c; { int pindex; int zindex; int i,j; int pwidth; int rwidth; register struct gd *gd; int size; char *rot_90(); char rotate; FontOpn(); /* Make sure the file is open */ gd = &CurFont->f_gd[c - CurFont->f_fc]; fseek(CurFont->f_strm, gd->gd_roff, 0); switch ( CurFont->f_type ) { case GF: GF_bitmap(gd, in_rast); break; case PXL: pwidth = (((gd->gd_W+31)/32) * 4); rwidth = (gd->gd_W+7)/8; if ( (gd->gd_H * pwidth) == 0 ) return(0); FontRdS(tmp_rast, (gd->gd_H * pwidth)); for ( i=0 ; igd_H; i++ ) { pindex = i * pwidth; zindex = i * rwidth; for (j=0; jgd_H * ((gd->gd_W+7)/8); if ( size == 0 ) return(0); FontRdS(in_rast, size); /* Read bitmap */ break; } if ( landscape ) { rot_90(in_rast, tmp_rast, gd); rotate = 0100; } else rotate = 0; ImWrt1(iBGLY); /* Big glyph */ ImWrt1((CurFont->f_impnum>>1)|rotate); ImWrt1(((CurFont->f_impnum&01)<<7) | c); ImWrt2(CurFont->f_fg[c].fg_pwid); ImWrt2(gd->gd_W); ImWrt2(gd->gd_X); ImWrt2(gd->gd_H); ImWrt2(gd->gd_Y); if ( landscape ) WrtS(tmp_rast, (gd->gd_H * ((gd->gd_W+7)/8)) ); else WrtS(in_rast, (gd->gd_H * ((gd->gd_W+7)/8)) ); return(TRUE); } /************************************************************************/ /* */ /* GF_bitmap( struct *gd, char* ) */ /* */ /* Read the bitmap out of a GF file */ /* */ /************************************************************************/ char btab[9] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 }; # define PAINT_ON ( 1 ) # define PAINT_OFF ( -1 ) GF_bitmap(gd, storage) struct gd *gd; char *storage; { int i, j; /* Incrementors */ /********************************************************/ /* */ /* STATE VARIABLES */ /* */ int dis; /* Distance to paint pixels on or off */ int w; /* Current paint start position */ int n; /* Number of bytes output on this row */ int val; /* Current byte being output */ int paint; /* Flag indicating whether painting */ /* */ /********************************************************/ char *ptr1; /* Will point to in_rast array */ char *ptr2; /* Will point to tmp_rast array */ int width; /* Current width of character */ int height; /* Max height of character */ int max_width; /* Max width of character */ int min_n; /* temp min height */ int bytes_per_row; /* Max bytes per row */ int byte_width; /* Actual bytes per row */ long gf_command; /* Command from the GF file */ long gf_param; /* Parameter after GF command */ /* */ /* Pass xxx and yyy commands */ /* */ while ( 1 ) { gf_command = FontRdU1(); if ( gf_command == GF_YYY ) { FontRd4(); continue; } if ( (gf_commandGF_XXX4) ) break; gf_param = 0; switch ( gf_command ) { case GF_XXX4: gf_param = FontRdU1(); case GF_XXX3: gf_param = (gf_param*256) + FontRdU1(); case GF_XXX2: gf_param = (gf_param*256) + FontRdU1(); case GF_XXX1: gf_param = (gf_param*256) + FontRdU1(); } fseek(CurFont->f_strm, gf_param, 1); } if ( gf_command==GF_BOC ) { FontRd4(); /* Ignor character no. */ FontRd4(); /* Ignore offset */ gd->gd_X = -FontRd4(); /* min_m */ gd->gd_W = FontRd4() + gd->gd_X + 1; /* max_m + min_m + 1 */ min_n = FontRd4(); gd->gd_Y = FontRd4(); /* max_n */ gd->gd_H = gd->gd_Y - min_n + 1; /* max_n - min_n + 1 */ } else /* gf_command == GF_BOC1 */ { FontRdU1(); /* Ignore character no. */ gd->gd_W = FontRdU1() + 1; /* del_m + 1 */ gd->gd_X = gd->gd_W - FontRdU1() - 1; /* del_m - max_m */ gd->gd_H = FontRdU1() + 1; /* del_n + 1 */ gd->gd_Y = FontRdU1(); /* max_n */ } width = 0; height = 0; max_width = 0; paint = PAINT_OFF; dis = 0; n = 0; val = 0; w = 0; ptr2 = tmp_rast; bytes_per_row = (gd->gd_W + 7) / 8; for ( gf_command=FontRdU1() ; gf_command!=GF_EOC ; gf_command=FontRdU1() ) { if ( gf_command>=GF_PT0 && gf_command<=GF_PT2 ) { /* */ /* Parse the GF parameter */ /* */ if ( gf_command < GF_PT1 ) gf_param = gf_command - GF_PT0; else { gf_param = FontRdU1(); if ( gf_command == GF_PT2 ) gf_param = FontRdU1() + gf_param * 256; } /* */ /* Adjust the width variable */ /* */ width += gf_param; /* */ /* If paint was off, simply adjust */ /* the state variables */ /* */ if ( paint == PAINT_OFF ) { w = gf_param; paint = PAINT_ON; } /* */ /* If paint was on, then output */ /* the bytes between the current */ /* paint on position and the paint */ /* off position */ /* */ else { w += dis; /* Current paint on pos */ dis = w + gf_param; /* Current paint distance*/ /* */ /* Loop while outputting full */ /* bytes */ /* */ while ( n=8 ) { if ( w >= 8 ) w -= 8; else { val += btab[w]; w = 0; } *ptr2++ = val; dis -= 8; val = 0; n++; } if ( dis < 8 ) { val = val + btab[w] - btab[dis]; } paint = PAINT_OFF; } } else if ( gf_command>=GF_ROW0 && gf_command<=GF_ROW164 ) { /* */ /* Parse the GF parameter */ /* */ gf_param = gf_command - GF_ROW0; /* */ /* Adjust the height and width */ /* */ height++; if ( width > max_width ) max_width = width; width = gf_param; /* */ /* Finish off the current row */ /* */ while ( n++ < bytes_per_row ) { *ptr2++ = val; val = 0; } /* */ /* Reset the state variables */ /* */ paint = PAINT_ON; dis = 0; n = 0; w = gf_param; } else if ( gf_command>=GF_SKIP0 && gf_command max_width ) max_width = width; width = 0; /* */ /* Finish off the current row */ /* */ while ( n++ < bytes_per_row ) { *ptr2++ = val; val = 0; } /* */ /* Skip the rows requested */ /* */ while ( gf_param-- ) { for ( n=0 ; nf_strm, (long) gf_param, 1); continue; case GF_YYY: fseek(CurFont->f_strm, 4L, 1); continue; case GF_NOOP: continue; default: fprintf(stderr, "%s: Unrecognized GF command\n", pgmname); fprintf(stderr, "\tlocation %ld in %s\n", ftell(CurFont->f_strm), CurFont->f_filnam); GoAway(); } } } /* */ /* Finish off the last row */ /* */ while ( n++ < bytes_per_row ) { *ptr2++ = val; val = 0; } /* */ /* The width and height of a character */ /* specified in the BOC command are */ /* maximum boundaries. The minimum */ /* boundaries are outputted, so the */ /* outputted array must be adjusted */ /* */ if ( width > 0 ) height++; if ( width > max_width ) max_width = width; byte_width = (max_width + 7) / 8; ptr2 = tmp_rast; ptr1 = in_rast; for ( i=0 ; igd_H ; i++ ) { for ( j=0 ; jgd_W = max_width; gd->gd_H = height; } /************************************************************************/ /* */ /* rot_90( char *, struct gd *) */ /* */ /* Rotate a bitmap of a character 90 degrees. The glyph */ /* directory is also modified accordingly */ /* */ /************************************************************************/ char * rot_90( o_bitmap, gdd) char *o_bitmap; struct gd *gdd; { unsigned size; char *n_bitmap; /* new bitmap */ char *c; int n_h, n_w; /* new height, width */ int n_x, n_y; /* new left, top offset */ int o_byte_w; /* old byte width */ int n_byte_w; /* new byte width */ int i,j; char bit_w; /* current bitmask */ int from_byte; /* from this byte */ int to_byte; /* to this byte */ static unsigned char bitmask[8] = { 0200, 0100, 040, 020, 010, 04, 02, 01 }; size = gdd->gd_W * ( (gdd->gd_H+7) / 8 ); n_bitmap = malloc1(size); for ( c=n_bitmap ; c<(n_bitmap+size) ; c++ ) *c = 0; n_w = 0; n_h = 0; /* * Determine the width in bytes */ o_byte_w = ( gdd->gd_W + 7 ) / 8; n_byte_w = ( gdd->gd_H + 7 ) / 8; /* * Scan rows of old bitmap */ for ( i=0 ; igd_W ; i++ ) { /* * Scan columns of old bitmap backwards */ for ( j=(gdd->gd_H-1) ; j>=0 ; j-- ) { /* * Locate one bit in old bitmap */ from_byte = j * o_byte_w + i / 8; bit_w = bitmask[i % 8]; /* * If nonzero, put it into new bitmap */ if ( o_bitmap[from_byte] & bit_w ) { to_byte = n_h * n_byte_w + n_w / 8; n_bitmap[to_byte] |= bitmask[n_w % 8]; } /* * Increment the new bitmap counters */ if ( ++n_w == gdd->gd_H ) { n_w = 0; n_h++; } } } n_h = gdd->gd_W; n_w = gdd->gd_H; n_x = gdd->gd_H - gdd->gd_Y; n_y = gdd->gd_X; gdd->gd_H = n_h; gdd->gd_W = n_w; gdd->gd_X = n_x; gdd->gd_Y = n_y; return(n_bitmap); } /************************************************************************/ /* */ /* Routines for reading from the DVI file. */ /* */ /************************************************************************/ char * DviRdS(adr, len) char *adr; int len; { if (len) { if (fread(adr, 1, len, DviIn) == NULL) { fprintf(stderr, "%s: Input error RdS()\n",pgmname); GoAway(); } } } int DviRd1() { int word; word = getc(DviIn); if (word == EOF) { perror("DVI file"); fprintf(stderr, "%s: Unexpected EOF in DviRd1()\n",pgmname); fprintf(stderr, "at position %ld\n", ftell(DviIn)); GoAway(); } if (word > 127) /* Force sign extension */ word -= 256; return word; } int DviRd2() { register int word; word = DviRd1() << 8; return( word | (DviRd1() & 0xff) ); } long DviRd3() { register long word; word = ((long) DviRd2()) << 8; return( word | (((long)DviRd1()) & 0xffL) ); } long DviRd4() { register long lword; lword = ((long) DviRd2()) << 16; return( lword | (((long)DviRd2()) & 0xffffL) ); } /************************************************************************/ /* */ /* Routines for reading from the Current font file. */ /* */ /************************************************************************/ char * FontRdS(adr, len) char *adr; int len; { if (len) { if (fread(adr, 1, len, CurFont->f_strm) == NULL) { fprintf(stderr, "%s: Input error FontRdS()\n",pgmname); GoAway(); } } } int FontRd1() { int word; word = getc(CurFont->f_strm); if (word == EOF) { fprintf(stderr, "%s: Unexpected EOF in FontRd1()\n",pgmname); GoAway(); /*NOTREACHED*/ } if (word > 127) /* Force sign extension */ word -= 256; return word; } int FontRd2() { register int word; word = FontRd1() << 8; return( word | (FontRd1() & 0xff) ); } long FontRd3() { register long word; word = ((long) FontRd2()) << 8; return( word | (((long)FontRd1()) & 0xffL) ); } long FontRd4() { register long lword; lword = ((long) FontRd2()) << 16; return( lword | (((long)FontRd2()) & 0xffffL) ); } /************************************************************************/ /* */ /* Impress writing routines. These will write out 1, 2, or */ /* a string of bytes to the imPress file */ /* */ /************************************************************************/ ImWrt1(c) int c; { if (putc(c&0377, ImOut) == EOF) { if ( ferror(ImOut) ) { fprintf(stderr, "%s: Output error in Wrt1()\n", pgmname); GoAway(); } } } ImWrt2(c) int c; { ImWrt1((c>>8)&0377); ImWrt1(c&0377); } WrtS(adr, len) char *adr; int len; { if ( len ) if (fwrite(adr, 1, len, ImOut) == NULL) { fprintf(stderr, "%s: Output error in WrtS()\n",pgmname); GoAway(); } } char * malloc1(len) int len; { char *s, *malloc(); if ((s = malloc((unsigned) len)) == NULL) { fprintf(stderr, "%s: Can't allocate %d bytes\n", pgmname, len); GoAway(); } return s; } GoAway() { exit(1); }