Back to index

tetex-bin  3.0
tfmload.c
Go to the documentation of this file.
00001 /*
00002  *   Loads a tfm file.  It marks the characters as undefined.
00003  */
00004 #include "dvips.h" /* The copyright notice in that file is included too! */
00005 #ifdef KPATHSEA
00006 #include <kpathsea/c-pathmx.h>
00007 #endif
00008 /*
00009  *   These are the external routines it calls:
00010  */
00011 #include "protos.h"
00012 /*
00013  *   Here are the external variables we use:
00014  */
00015 extern real conv ;
00016 extern real vconv ;
00017 extern real alpha ;
00018 #ifndef KPATHSEA
00019 extern char *tfmpath ;
00020 #endif
00021 extern char errbuf[] ;
00022 extern integer fsizetol ;
00023 extern Boolean noomega ;
00024 /*
00025  *   Our static variables:
00026  */
00027 FILE *tfmfile ; 
00028 static char name[50] ;
00029 
00030 void
00031 badtfm P1C(char *, s)
00032 {
00033    (void)sprintf(errbuf,"! Bad TFM file %s: %s",name,s) ;
00034    error(errbuf);
00035 }
00036 
00037 /*
00038  *   Tries to open a tfm file.  Uses cmr10.tfm if unsuccessful,
00039  *   and complains loudly about it.
00040  */
00041 void
00042 tfmopen P1C(register fontdesctype *, fd)
00043 {
00044   register char *n;
00045 #ifdef KPATHSEA
00046   kpse_file_format_type d ;
00047 #else
00048    register char *d;
00049 #endif
00050    n = fd->name ;
00051    if (!noomega) {
00052 #ifdef KPATHSEA
00053       d = ofmpath;
00054 #else
00055       d = fd->area ;
00056       if (*d==0)
00057         d = ofmpath ;
00058 #endif
00059 #ifdef MVSXA   /* IBM: MVS/XA */
00060       (void)sprintf(name, "ofm(%s)", n) ;
00061 #else
00062       (void)sprintf(name, "%s.ofm", n) ;
00063 #endif
00064       if ((tfmfile=search(d, name, READBIN))!=NULL)
00065          return ;
00066    }
00067 #ifdef KPATHSEA
00068    d = tfmpath;
00069 #else
00070    d = fd->area ;
00071    if (*d==0)
00072      d = tfmpath ;
00073 #endif
00074 #ifdef MVSXA   /* IBM: MVS/XA */
00075    (void)sprintf(name, "tfm(%s)", n) ;
00076 #else
00077    (void)sprintf(name, "%s.tfm", n) ;
00078 #endif
00079    if ((tfmfile=search(d, name, READBIN))!=NULL)
00080       return ;
00081    (void)sprintf(errbuf, "Can't open font metric file %s%s",
00082           fd->area, name) ;
00083    error(errbuf) ;
00084    error("I will use cmr10.tfm instead, so expect bad output.") ;
00085 #ifdef MVSXA   /* IBM: MVS/XA */
00086    if ((tfmfile=search(d, "tfm(cmr10)", READBIN))!=NULL)
00087 #else
00088    if ((tfmfile=search(d, "cmr10.tfm", READBIN))!=NULL)
00089 #endif
00090       return ;
00091    error("! I can't find cmr10.tfm; please reinstall me with proper paths") ;
00092 }
00093 
00094 shalfword
00095 tfmbyte P1H(void)
00096 {
00097   return(getc(tfmfile)) ;
00098 }
00099 
00100 halfword
00101 tfm16 P1H(void)
00102 {
00103   register halfword a ; 
00104   a = tfmbyte () ; 
00105   return ( a * 256 + tfmbyte () ) ; 
00106 } 
00107 
00108 integer
00109 tfm32 P1H(void)
00110 {
00111   register integer a ; 
00112   a = tfm16 () ; 
00113   if (a > 32767) a -= 65536 ;
00114   return ( a * 65536 + tfm16 () ) ; 
00115 } 
00116 
00117 int
00118 tfmload P1C(register fontdesctype *, curfnt)
00119 {
00120    register integer i, j ;
00121    register integer li, cd=0 ;
00122    integer scaledsize ;
00123    integer nw, hd ;
00124    integer bc, ec ;
00125    integer nco=0, ncw=0, npc=0, no_repeats = 0 ;
00126    integer *scaled ;
00127    integer *chardat ;
00128    int font_level ;
00129    integer pretend_no_chars ;
00130    int charcount = 0 ;
00131 
00132    tfmopen(curfnt) ;
00133 /*
00134  *   Next, we read the font data from the tfm file, and store it in
00135  *   our own arrays.
00136  */
00137    li = tfm16() ;
00138    if (li!=0) {
00139       font_level = -1 ;
00140       hd = tfm16() ;
00141       bc = tfm16() ; ec = tfm16() ;
00142       nw = tfm16() ;
00143       li = tfm32() ; li = tfm32() ; li = tfm32() ; li = tfm16() ;
00144       if (hd<2 || bc>ec+1 || ec>255 || nw>256)
00145          badtfm("header") ;
00146    } else {  /* In an .ofm file */
00147       if (noomega) badtfm("length") ;
00148       font_level = tfm16();
00149       li = tfm32() ; hd = tfm32() ;
00150       bc = tfm32() ; ec = tfm32() ;
00151       nw = tfm32() ;
00152       for (i=0; i<8; i++) li=tfm32();
00153       if (font_level>1 || hd<2 || bc<0 || ec<0 || nw<0
00154                        || bc>ec+1 || ec>65535 || nw>65536)
00155          badtfm("header") ;
00156       if (font_level==1) {
00157          nco = tfm32() ;
00158          ncw = tfm32() ;
00159          npc = tfm32() ;
00160          for (i=0; i<12; i++) li=tfm32();
00161       }
00162    }
00163    li = tfm32() ;
00164    check_checksum (li, curfnt->checksum, curfnt->name);
00165    li = (integer)(alpha * (real)tfm32()) ;
00166    if (li > curfnt->designsize + fsizetol ||
00167        li < curfnt->designsize - fsizetol) {
00168       (void)sprintf(errbuf,"Design size mismatch in %s", name) ;
00169       error(errbuf) ;
00170    }
00171    pretend_no_chars=ec+1 ;
00172    if (pretend_no_chars<256) pretend_no_chars=256 ;
00173    else {
00174       curfnt->chardesc = (chardesctype *)
00175          xrealloc(curfnt->chardesc, sizeof(chardesctype)*pretend_no_chars) ;
00176       curfnt->maxchars = pretend_no_chars ;
00177    }
00178    for (i=2; i<((font_level==1)?nco-29:hd); i++)
00179       li = tfm32() ;
00180    chardat = (integer *) xmalloc(pretend_no_chars*sizeof(integer)) ;
00181    for (i=0; i<pretend_no_chars; i++)
00182       chardat[i] = -1 ;
00183    for (i=bc; i<=ec; i++) {
00184       if (no_repeats>0) {
00185          no_repeats-- ;
00186       } else if (font_level>=0) {
00187          cd = tfm16() ;
00188          li = tfm32() ;
00189          li = tfm16() ;
00190          if (font_level==1) {
00191             no_repeats = tfm16() ;
00192             for (j=0; j<(npc|1); j++) tfm16() ;
00193             ncw -= 3 + npc/2 ;
00194          }
00195       } else {
00196          cd = tfmbyte() ;
00197          li = tfm16() ;
00198          li = tfmbyte() ;
00199       }
00200       if (cd>=nw) badtfm("char info") ;
00201       if (cd) {
00202          chardat[i] = cd ;
00203          charcount++ ;
00204       }
00205    }
00206    if (font_level==1&&ncw!=0) {
00207       sprintf(errbuf, "Table size mismatch in %s", curfnt->name) ;
00208       error(errbuf) ;
00209    }
00210    scaledsize = curfnt->scaledsize ;
00211    scaled = (integer *) xmalloc(nw*sizeof(integer)) ;
00212    for (i=0; i<nw; i++)
00213       scaled[i] = scalewidth(tfm32(), scaledsize) ;
00214    (void)fclose(tfmfile) ;
00215    for (i=0; i<pretend_no_chars; i++)
00216       if (chardat[i]!= -1) {
00217          li = scaled[chardat[i]] ;
00218          curfnt->chardesc[i].TFMwidth = li ;
00219          if (li >= 0)
00220             curfnt->chardesc[i].pixelwidth = ((integer)(conv*li+0.5)) ;
00221          else
00222             curfnt->chardesc[i].pixelwidth = -((integer)(conv*-li+0.5)) ;
00223          curfnt->chardesc[i].flags = (curfnt->resfont ? EXISTS : 0) ;
00224          curfnt->chardesc[i].flags2 = EXISTS ;
00225       } else curfnt->chardesc[i].flags = curfnt->chardesc[i].flags2 = 0 ;
00226    free(chardat) ;
00227    free(scaled) ;
00228    if (ec>=256) curfnt->codewidth = 2 ; /* XXX: 2byte-code can have ec<256 */
00229    curfnt->loaded = 1 ;
00230    return charcount ;
00231 }