|
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 f
Length: 23688 (0x5c88) Types: TextFile Names: »fonts.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/laser-setters/dvi-to-ps/TeXPS/dvitps/src/fonts.c«
/* Copyright 1988 Stephan v. Bechtolsheim */ /* This file is part of the TeXPS Software Package. The TeXPS Software Package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the TeXPS Software Package General Public License for full details. Everyone is granted permission to copy, modify and redistribute the TeXPS Software Package, but only under the conditions described in the TeXPS Software Package General Public License. A copy of this license is supposed to have been given to you along with TeXPS Software Package so you can know your rights and responsibilities. It should be in a file named CopyrightLong. Among other things, the copyright notice and this notice must be preserved on all copies. */ /* Basic font handling */ #include <stdio.h> #include <sys/types.h> #include <sys/file.h> #include "defs.h" #include "dvitps.h" #include "units.h" #include "extfil.h" #include "fontd.h" #include "emit.h" #include "tfm.h" #include "dvi-com.h" /* Externals. */ extern char *SetUpHashTable(); extern char *LookUpKeyInHashTableE(); extern char *LocateFileWithPath(); extern char *Malloc(); extern void SetFontFileName(); extern void ReadGfFileInfo(); extern void ReadPkFileInfo(); extern void ReadPxlFileInfo(); extern void ReadPdrFileInfo(); extern void NewPsFont(); extern TFM_S_P ReadTfmFileUsePath(); extern EX_FILES ExDvi; extern EX_FILES Ex_PsOutput; extern char *texfonts_default; extern char *StrcpyAlloc(); extern char *GetBytes(); extern char *getenv(); extern int CurFontNumber; extern FFP FontFilePriorities[4]; extern char TryThisFontFileName[256]; extern int FontsFindError; extern int Verbose; extern int DriverMag; extern int Resolution; extern int ListFontSearch; extern double ConvertPosPoints(); extern double ConvertPosPointsNoDriverMag(); extern FE_P Fonts[MAX_FONTS]; extern FE_P CurFontPointer; /* Subdirectory for finding the font files. */ extern char TryThisFontFileDir[256]; extern char *FontsSearchPathCommandLine; /* Data structure for FontFileSearchLoop() to report back the result of its search process. */ typedef struct ffs { int ffs_found; /* TRUE if a font file was found and therefore all the following fields are loaded. FALSE otherwise. */ int ffs_type; /* Indicator what font type, CF_* */ char *ffs_fn; /* Full and expanded file name of gf, pk, pxl or pdr file. */ } FFS; FFS FontFileSearchLoop(); /* Hash table to locate fonts. Hash key is the concatenation of font name, size font is used at, and the checksum. */ char *FontHashTable; /* This is what is stored in the hash table: the normalized font number. */ typedef struct fh_struct { int fh_number; } FH, *FH_P; int NextFontIndex; /* Next free font index. */ void FontNewDviFile(); void SubstituteAFont(); /* * This array maps the font number from the current dvi file * to the driver internal font number. -1 means that this * entry is free (which is an error, because it means that the * mapping is not possible). Otherwise the entry is the font number * to which the font number in the dvi file is translated to. */ int DviFileFontMap[MAX_FONTS]; /* * FontFileSearchLoop * ****************** * This procedure searches for a font file. * * f_n: font name * f_a: area length * f_mag: font magnification. * RET: An FFS structure with ffs_found set as follows: * TRUE: the font file was found (and also all the other fields are set). * FALSE: the font file was not found. */ FFS FontFileSearchLoop(f_n, f_a, f_mag) char *f_n; int f_a; double f_mag; { int priority; /* Loop index */ int try_type; /* Type of font file tried out */ int found_a_type; /* TRUE, when there is a type of given priority. */ int ty; /* Type */ char buffer[256]; FFS ret; /* Loop through all possibilities for font files (gf, pk, pxl and pdr). Priorities are set by the user. */ for (priority = 0; priority <= 3; priority++){ found_a_type = FALSE; /* Find which file type has that priority. */ for (ty=0; ty<=3; ty++) { if (FontFilePriorities[ty].ffp_p == priority) { found_a_type = TRUE; try_type = ty; break; } } /* No font file type found with that priority. It's time to quit. */ if (!found_a_type) { ret.ffs_found = FALSE; return(ret); } /* * Now set the font file name, and then look for the file. * If (area in dvi-file empty) then * use FontPath to look for file; * else * use name as it is in the dvi file; * fi; */ SetFontFileName(try_type, f_mag, f_n); sprintf (buffer, "%s%s", TryThisFontFileDir, TryThisFontFileName); #ifdef DEBUG fprintf (stderr, "%% FontFileSearchLoop(): looking for \"%s\"\n", buffer); #endif if (f_a == 0) { if ((ret.ffs_fn = LocateFileWithPath(buffer, FontFilePriorities[try_type].ffp_s, NULL, ListFontSearch)) != NULL) { ret.ffs_type = try_type; ret.ffs_found = TRUE; return(ret); } } else { /* "area" is defined for this font. */ if (access (TryThisFontFileName, R_OK) == 0) { ret.ffs_type = try_type; ret.ffs_found = TRUE; ret.ffs_fn = StrcpyAlloc(TryThisFontFileName); return(ret); } } } /* for priority = ... */ /* Here we come only if ALL four font file types are used in an installation and NO font file was found, which matches the specified magnifications, etc. This bug was discovered by anderson@sapir.cog.jhu.edu. It bombed out when the font substitution mechanism was tested processing the documentation. */ ret.ffs_found = FALSE; return (ret); } /* * FontNewDviFile * ************** * Call this routine if a new dvi file is started, and all the font business * which relates to one particular .dvi file, must be reset now. */ void FontNewDviFile() { int i; for (i=0; i<MAX_FONTS; i++) DviFileFontMap[i] = -1; } /* * InitFontHandling * **************** * Initalize font handling. * In particular sets up all the search paths etc. This procedure is only * called once in the beginning. */ void InitFontHandling() { int i, cf; char *fp; NextFontIndex = 0; FontHashTable = SetUpHashTable (50, sizeof(FH), "Font name hash table"); FontNewDviFile(); /* Clear the search path specications in the font priority array. */ for (i=0; i<=3; i++) FontFilePriorities[i].ffp_s = NULL; /* Initialize font array. */ for (i=0; i<MAX_FONTS; i++) Fonts[i] = NULL; /* CF_PXL, CF_GF, CF_PK and CF_PDR */ for (cf=0; cf<=3; cf++) { switch (cf) { /* Consult font type specific environment variables first. */ case CF_GF: fp = getenv ("TEXFONTS_DVITPS_GF"); break; case CF_PK: fp = getenv ("TEXFONTS_DVITPS_PK"); break; case CF_PXL: fp = getenv ("TEXFONTS_DVITPS_PXL"); break; case CF_PDR: fp = getenv ("TEXFONTS_DVITPS_PDR"); break; default: Fatal ("InitFontHandling(): switch"); } /* switch */ /* -A option overrides everything. */ if (FontsSearchPathCommandLine != NULL) fp = FontsSearchPathCommandLine; /* Still nothing! */ if (fp == NULL) { if ((fp=getenv("TEXFONTS_DVITPS")) == NULL) { if ((fp=getenv("TEXFONTS")) == NULL) fp = texfonts_default; } } if (fp == NULL) Fatal ("InitFontHandling(): X-1"); FontFilePriorities[cf].ffp_s = StrcpyAlloc(fp); } } /* Font substitution information is stored in this table. This table has 7 entries, because there are (including \magstep 0 and \magstephalf) 7 \magsteps. */ struct fsub { double fs_basemag; /* Base magnfication, 1.0, 1.099, 1.2 etc. */ double fs_fontmag; /* Font magnification to be used. */ int fs_gf_pk_ext; /* gf and pk file extension. */ int fs_pxl_ext; /* pxl file extension. */ } Fsub_table[7]; /* * InitFontSubstitutionBusiness * **************************** * Initialize font substitution business. */ void InitFontSubstitutionBusiness() { int i; if (DriverMag == 0) Fatal ("InitFontSubstitutionBusiness(): DriverMag == 0"); /* Load the base magnifications. */ Fsub_table[0].fs_basemag = 1.0; Fsub_table[1].fs_basemag = 1.095; Fsub_table[2].fs_basemag = 1.2; for (i=3; i<=6; i++) Fsub_table[i].fs_basemag = 1.2 * Fsub_table[i-1].fs_basemag; /* Compute font magnifications which compensate for global magnifications. */ for (i=0; i<=6; i++) Fsub_table[i].fs_fontmag = Fsub_table[i].fs_basemag / (DriverMag / 1000.0); /* Load the standard file extensions (gf,pk files and pxl files) which depend on the current resolution. */ for (i=0; i<=6; i++) { Fsub_table[i].fs_gf_pk_ext = GfPkCluge(Resolution * Fsub_table[i].fs_basemag); Fsub_table[i].fs_pxl_ext = PxlCluge (5.0 * Resolution * Fsub_table[i].fs_basemag); } #ifdef DEBUG for (i=0; i<=6; i++) fprintf (stderr, "%2d: %7.4lf %7.4lf %5d %5d\n", i, Fsub_table[i].fs_basemag, Fsub_table[i].fs_fontmag, Fsub_table[i].fs_gf_pk_ext, Fsub_table[i].fs_pxl_ext); #endif } /* * AdviseOnFontSubstitution * ************************ * Help finding a font to be used for font substitution. * * f_mag: font magnification of the font for which no font could * be found. * RET: largest index to be used in the Fsub_table[i] array for searching * for a proper replacement font. */ int AdviseOnFontSubstitution(f_mag) double f_mag; { int i; if (f_mag <= Fsub_table[0].fs_fontmag) return (0); if (f_mag >= Fsub_table[6].fs_fontmag) return (6); for (i=0; i<=5; i++) if (Fsub_table[i].fs_fontmag <= f_mag && f_mag < Fsub_table[i+1].fs_fontmag) return (i); Fatal ("AdviseOnFontSubstitution(): should never come here."); return(0); /* lint */ } /* * NewFontFromDviFile * ****************** * We have read in the basic information about a font from a dvi * file. We compute now the internal font number. We first look into * the hash table and see whether the font is there. If so we use the * old information. If not so we allocate a new driver internal font * * k: font number from dvi file * RET: TRUE, if this was a truely new font. * FALSE if the font was already known and was already in the font table. */ int NewFontFromDviFile (k) int k; { char buffer [256]; FH_P p; int check_sum; int s_factor; int design_size; int area_font_l; int length_font_name; char * font_name; if (DriverMag == 0) Fatal ("NewFontFromDviFile(): DriverMag not loaded."); check_sum = NoSignExtend(EX_FP(ExDvi), 4); s_factor = NoSignExtend(EX_FP(ExDvi), 4); design_size = NoSignExtend(EX_FP(ExDvi), 4); area_font_l = NoSignExtend(EX_FP(ExDvi), 1); length_font_name = NoSignExtend(EX_FP(ExDvi), 1); /* length font name */ font_name = GetBytes(EX_FP(ExDvi), area_font_l + length_font_name); /* Form key for hash table of fonts. Try to insert key. */ sprintf (buffer, "%s-%d-%d", font_name, s_factor, check_sum); if ((p=(FH_P)InsertKeyIntoHashTableDup(FontHashTable, buffer)) == NULL) { /* This font is already in the hash table. */ p = (FH_P)LookUpKeyInHashTableE (FontHashTable, buffer); CurFontNumber = p->fh_number; CurFontPointer = Fonts[CurFontNumber]; DviFileFontMap[k] = CurFontNumber; return (FALSE); } else { /* Insertion was successful, i.e. it is a truely new font. */ p->fh_number = NextFontIndex++; CurFontNumber = p->fh_number; DviFileFontMap[k] = CurFontNumber; /* Create room for this font. */ Fonts[CurFontNumber] = (FE_P) Malloc(sizeof(FE)); CurFontPointer = Fonts[CurFontNumber]; /* Enter some stuff we already read in. */ CurFontPointer->f_c = check_sum; CurFontPointer->f_s = s_factor; CurFontPointer->f_d = design_size; CurFontPointer->f_a = area_font_l; CurFontPointer->f_l = length_font_name; CurFontPointer->f_n = font_name; CurFontPointer->f_class = FOCLASS_UNDEFINED; /* More loading goes on in ReadFontDef(). */ return (TRUE); } } /* * ReadFontDef * *********** * Read font definition for font k from the postamble of the dvi file. * * k: font number as found in the dvi file. */ void ReadFontDef(k) int k; { char buffer[256]; FFS ffs_s; /* Result of FontFileSearchLoop(). */ #ifdef DEBUG char area[256]; char name[256]; #endif #ifdef DEBUG fprintf (stderr, "%% ReadFontDef() [%d]:, ", k); #endif if (k>= MAX_FONTS) Fatal ("ReadFontDef(): k>=MAX_FONTS"); /* If we found that this font is already known because it already * occured in a preceding dvi file then we don't have to continue. * If it's a new font, also the whole stuff is read in. */ if (! NewFontFromDviFile (k)) return; /* A truely new font: we have to load in some info. */ CurFontPointer->f_k = CurFontNumber; #ifdef DEBUG strncpy (area, CurFontPointer->f_n, CurFontPointer->f_a); area[CurFontPointer->f_a] = '\0'; strcpy (name, CurFontPointer->f_n+CurFontPointer->f_a); fprintf (stderr, "\"%s\", (area: \"%s\", name: \"%s\") ", CurFontPointer->f_n, area, name); #endif CurFontPointer->f_fnt_def_length = 4 + 4 + 4 + 1 + 1 + CurFontPointer->f_a + CurFontPointer->f_l; /* Compute the magnification of the font. This EXCLUDES the global magnification. */ CurFontPointer->f_mag = (double)CurFontPointer->f_s / (double)CurFontPointer->f_d; #ifdef DEBUG fprintf (stderr, "mag: %5.3lf, space: %d\n", CurFontPointer->f_mag, CurFontPointer->f_s); #endif /* Get the font type and try to find what type of font it is. * This also sets the PostScript name of the font * and the change font instruction for this font. */ CurFontPointer->f_ex_file.ef_fn = NULL; CurFontPointer->f_type = CF_NONE; CurFontPointer->f_new_font = FALSE; /* If the -F option is given some of the basic properties of this font will be printed. */ if (ListFontSearch) { fprintf (stderr, "Font search: \"%s\", %4.2lfpt font, used at %5.2lfpt\n", CurFontPointer->f_n, ConvertPosPoints(CurFontPointer->f_d), ConvertPosPoints(CurFontPointer->f_s)); if (CurFontPointer->f_d != CurFontPointer->f_s) { fprintf (stderr, "\tmagnification: "); PrintMag ((int)(CurFontPointer->f_mag*1000.0), stderr); fprintf (stderr, ")\n"); } } /* Here look for the font file now. */ CurFontPointer->f_class = FOCLASS_UNDEFINED; ffs_s = FontFileSearchLoop(CurFontPointer->f_n, CurFontPointer->f_a, CurFontPointer->f_mag); if (ffs_s.ffs_found) { CurFontPointer->f_ex_file.ef_fn = ffs_s.ffs_fn; CurFontPointer->f_type = ffs_s.ffs_type; CurFontPointer->f_class = FOCLASS_AS_REQUESTED; } else { /* No font file was found. Try substituting a different font. If SubstituteAFont() returns then a substitution occured. The procedure will generate a fatal error in case no substitution was possible. */ SubstituteAFont(); } #ifdef DEBUG fprintf (stderr, "%% ReadFontDef(): Font file name: \"%s\"\n", CurFontPointer->f_ex_file.ef_fn); #endif if (Verbose == V_A_LOT) fprintf (stderr, "%2d: [%s]\n", CurFontNumber, CurFontPointer->f_ex_file.ef_fn); /* Give the font name the name "@F" followed by the font number. */ sprintf (buffer, "@F%d", CurFontNumber); #ifdef DEBUG fprintf (stderr, "%% ReadFontDef(): Font[%d]: file name: \"%s\"\n", CurFontNumber, CurFontPointer->f_ex_file.ef_fn); #endif /* * Depending on where we get the font info from, load * some initial data for each font. */ switch (CurFontPointer->f_type) { case CF_GF: ReadGfFileInfo(); break; case CF_PK: ReadPkFileInfo(); break; case CF_PXL: ReadPxlFileInfo(); break; case CF_PDR: ReadPdrFileInfo(); break; default: Fatal ("ReadFontDef(): illegal font type."); } /* switch */ } /* * SendNewFontInstruction * ********************** * Send new font instruction to the PostScript output file, it this * is necessary. */ void SendNewFontInstruction() { char buffer[256]; if (CurFontPointer->f_new_font) return; /* Generate NewFont instructions. */ switch (CurFontPointer->f_type) { case CF_PXL: case CF_PK: case CF_GF: fprintf (EX_FP(Ex_PsOutput), "/@F%d @newfont\n", CurFontNumber); CurFontPointer->f_new_font = TRUE; sprintf (buffer, "@F%d @sf", CurFontNumber); CurFontPointer->f_sf = StrcpyAlloc(buffer); break; case CF_PDR: NewPsFont(); /* This sets f_new_font if not yet. */ sprintf (buffer, "@F%d-%d @sfps", CurFontNumber, CurFontPointer->f_pdr->p_ser); CurFontPointer->f_sf = StrcpyAlloc(buffer); break; default: Fatal ("SendNewFontInstruction(): default."); } /* switch */ } /* * SubstituteAFont * *************** * This is where the font substitution business is actually executed. */ void SubstituteAFont() { TFM_S_P tfm; /* tfm data structure if tfm file is loaded because no gf, pk, pxl or pdr file for the font can be found. */ FFS ffs_s; /* Result of FontFileSearchLoop(). */ int i; /* Loop variable. */ /* Generate elaborate error message because font was not found. */ FontsFindError = FALSE; fprintf (stderr, "Cannot locate a font file for the following font:\n"); fprintf (stderr, "=================================================\n"); fprintf (stderr, "\tName: \"%s\"\n", CurFontPointer->f_n); fprintf (stderr, "\tGlobal magnification: "); PrintMag (DriverMag, stderr); fprintf (stderr, "\n"); fprintf (stderr, "\tThis font's magnification: "); PrintMag ((int)(CurFontPointer->f_mag*1000.0), stderr); fprintf (stderr, "\n\tIt is a %5.2lfpt font used at %5.2lfpt.\n", ConvertPosPointsNoDriverMag(CurFontPointer->f_d), ConvertPosPoints(CurFontPointer->f_s)); /* Give an idea about what file extension (if it's a pixel based font) was used to locate the font. The computation is from "search2.c". */ fprintf (stderr, "\tGF/PK file extension used for searching font file: %4d.\n", GfPkCluge(CurFontPointer->f_mag * (DriverMag/1000.0) * Resolution)); fprintf (stderr, "\tPXL file extension used for searching font file: %4d.\n", PxlCluge(CurFontPointer->f_mag * (DriverMag/1000.0) * Resolution * 5)); /* Here is where we begin trying to fix things. Now a more or less intelligent font substitution will take place. */ /* Load the tfm file for this font; generates a fatal error if the tfm file can't be found. */ tfm = ReadTfmFileUsePath(CurFontPointer->f_n, getenv("TEXFONTS"), texfonts_default); /* Replacement font computation. The code which follows could be even more sophisticated. For instance, there could be a table which says that if the driver does not find font 'abc*' it should use 'def'. */ /* 1st attempt: use the same font, in a loop downwards, using standard magsteps. */ for (i=AdviseOnFontSubstitution(CurFontPointer->f_mag); i>=0; i--) { CurFontPointer->f_repl_mag = Fsub_table[i].fs_fontmag; CurFontPointer->f_repl_n = CurFontPointer->f_n; ffs_s = FontFileSearchLoop (CurFontPointer->f_repl_n, 0, CurFontPointer->f_repl_mag); /* Find it, if possible. */ if (ffs_s.ffs_found) goto replacement_font_found; } /* In all likelyhood the following attemps (2nd to 4th) are never executed, because the first one just attempted succeeded. */ /* 2nd attempt: use cmr10, at the magnification originally requested. */ CurFontPointer->f_repl_mag = CurFontPointer->f_mag; CurFontPointer->f_repl_n = "cmr10"; ffs_s = FontFileSearchLoop (CurFontPointer->f_repl_n, 0, CurFontPointer->f_repl_mag); if (ffs_s.ffs_found) goto replacement_font_found; /* 3rd attempt: use cmr10, compensate for some odd global magnification to arrive at a (hopefully) good pixel file extension. */ CurFontPointer->f_repl_mag = CurFontPointer->f_mag / (DriverMag / 1000.0); CurFontPointer->f_repl_n = "cmr10"; ffs_s = FontFileSearchLoop (CurFontPointer->f_repl_n, 0, CurFontPointer->f_repl_mag); if (ffs_s.ffs_found) goto replacement_font_found; /* 4th attempt: use cmr10, at magnification 1.0. This is the last attempt, and a fatal error will be generated in case this substitution also fails. Again compensation for any odd global magnification factor is executed. */ CurFontPointer->f_repl_mag = 1.0 / (DriverMag / 1000.0); CurFontPointer->f_repl_n = "cmr10"; ffs_s = FontFileSearchLoop (CurFontPointer->f_repl_n, 0, CurFontPointer->f_repl_mag); if (ffs_s.ffs_found) goto replacement_font_found; /* None of the substitutions worked, it's time to give up. */ fprintf (stderr, "Cannot locate a replacement font for this font.\n"); if (! ListFontSearch) fprintf (stderr, "Run driver again using -F option!\n"); Fatal ("SubstituteAFont(): that's it."); /* The replacement font was located. Perform the necessary substitutions so it will be loaded later. Report what substitution will be done. */ replacement_font_found: fprintf (stderr, "\n"); fprintf (stderr, "\tInformation about replacement font used:\n"); fprintf (stderr, "\t----------------------------------------\n"); fprintf (stderr, "\tFont file name, replacement font: \"%s\"\n", ffs_s.ffs_fn); fprintf (stderr, "\tMagnification of replacement font: %6.3lf\n", CurFontPointer->f_repl_mag); fprintf (stderr, "\tMagnification * global mag: %6.3lf\n", CurFontPointer->f_repl_mag * (DriverMag/1000.0)); fprintf (stderr, "\n"); CurFontPointer->f_n = CurFontPointer->f_repl_n; CurFontPointer->f_ex_file.ef_fn = ffs_s.ffs_fn; CurFontPointer->f_type = ffs_s.ffs_type; CurFontPointer->f_c = tfm->tfm_cs; CurFontPointer->f_class = FOCLASS_REPLACEMENT_FONT; /* Now copy the tfm metric information over to the character info array. */ for (i=0; i<128; i++) CurFontPointer->f_ch[i].c_w_tfm = tfm->tfm_c_width[i]; return; } /* * SkipFontDef * *********** * Skip a font definition (the assumption is that that * font has already been read in as part of the PostAmble * read procedure. Side effect is to reposition the dvi file * accordingly. * * command: dvi command which must be one of DVI_FONT_DEF1..4 * That was the last command read in and that command * caused a call to this function. */ void SkipFontDef(command) int command; { int k; /* Font number, first original from dvi file, then the normalized number. */ if (command < DVI_FNT_DEF1 || command > DVI_FNT_DEF4) Fatal2 ("SkipFontDef(): illegal dvi command %d", command); k = NoSignExtend(EX_FP(ExDvi), command - DVI_FNT_DEF1+1); k = DviFileFontMap[k]; FExSeek (&ExDvi, Fonts[k]->f_fnt_def_length, FSEEK_REL); } /* * SkipPotentialFontDefinitions * **************************** * Read from the dvi file until you find no more any font definitions. * The assumption is that if there are any font definitions actually * found, that those are known fonts (that is a valid assumption because * this driver reads in all font definitions from the postamble). */ void SkipPotentialFontDefinitions() { int command; /* A command code from the dvi file which is begin read in. */ for (;;) { switch(command = NoSignExtend (EX_FP(ExDvi), 1)) { case DVI_FNT_DEF1: case DVI_FNT_DEF2: case DVI_FNT_DEF3: case DVI_FNT_DEF4: SkipFontDef(command); break; default: /* Undo the effect of reading command, then return. */ FExSeek (&ExDvi, -1, FSEEK_REL); return; } } }