Back to index

tetex-bin  3.0
virtualfont.c
Go to the documentation of this file.
00001 /*
00002  *   Here's the code to load a VF file into memory.
00003  *   Any resemblance between this file and loadfont.c is purely uncoincidental.
00004  */
00005 #include "dvips.h" /* The copyright notice in that file is included too! */
00006 #ifdef KPATHSEA
00007 #include <kpathsea/c-pathmx.h>
00008 #endif
00009 /*
00010  *   These are the external routines we use.
00011  */
00012 #include "protos.h"
00013 /*
00014  *   These are the external variables we use.
00015  */
00016 #ifdef DEBUG
00017 extern integer debug_flag;
00018 #endif  /* DEBUG */
00019 extern long bytesleft ;
00020 extern quarterword *raster ;
00021 #ifndef KPATHSEA
00022 extern char *vfpath ;
00023 #endif
00024 extern char errbuf[200] ;
00025 extern real conv ;
00026 extern real vconv ;
00027 extern real alpha ;
00028 extern int actualdpi ;
00029 extern int vactualdpi ;
00030 extern char *nextstring, *maxstring ;
00031 extern fontdesctype *fonthead ;
00032 extern real alpha ;
00033 extern Boolean noomega ;
00034 /*
00035  *   Now we have some routines to get stuff from the VF file.
00036  *   Subroutine vfbyte returns the next byte.
00037  */
00038 static FILE *vffile ;
00039 static char name[50] ;
00040 void
00041 badvf P1C(char *, s)
00042 {
00043    (void)sprintf(errbuf,"! Bad VF file %s: %s",name,s) ;
00044    error(errbuf);
00045 }
00046 
00047 shalfword
00048 vfbyte P1H(void)
00049 {
00050    register shalfword i ;
00051 
00052    if ((i=getc(vffile))==EOF)
00053       badvf("unexpected eof") ;
00054    return(i) ;
00055 }
00056 
00057 integer
00058 vfquad P1H(void)
00059 {
00060    register integer i ;
00061 
00062    i = vfbyte() ;
00063    if (i > 127)
00064       i -= 256 ;
00065    i = i * 256 + vfbyte() ;
00066    i = i * 256 + vfbyte() ;
00067    i = i * 256 + vfbyte() ;
00068    return(i) ;
00069 }
00070 
00071 integer
00072 vftrio P1H(void)
00073 {
00074    register integer i ;
00075 
00076    i = vfbyte() ;
00077    i = i * 256 + vfbyte() ;
00078    i = i * 256 + vfbyte() ;
00079    return(i) ;
00080 }
00081 
00082 int
00083 vfopen P1C(register fontdesctype *, fd)
00084 {
00085    register char *n ;
00086 #ifndef KPATHSEA
00087    register char *d ;
00088 #endif
00089 
00090    n = fd->name ;
00091 #ifndef KPATHSEA
00092    d = fd->area ;
00093    if (*d==0)
00094       d = vfpath ;
00095 #endif
00096 #ifdef MVSXA   /* IBM: MVS/XA */
00097    (void)sprintf(name, "vf(%s)", n) ;
00098 #else
00099    (void)sprintf(name, "%s.vf", n) ;
00100 #endif
00101 #ifdef KPATHSEA
00102    if (0 != (vffile=search(vfpath, name, READBIN)))
00103 #else
00104    if (0 != (vffile=search(d, name, READBIN)))
00105 #endif
00106       return(1) ;
00107    if (!noomega)
00108 #ifdef KPATHSEA
00109       if (0 != (vffile=search(ovfpath, n, READBIN)))
00110 #else
00111       if (0 != (vffile=search(d, n, READBIN)))
00112 #endif
00113          return(2) ;
00114    return(0) ;
00115 }
00116 
00117 /*
00118  * The following routine is like fontdef, but for local fontdefs in VF files.
00119  */
00120 fontmaptype *
00121 vfontdef P2C(integer, s, int, siz)
00122 {
00123    register integer i, j, fn ;
00124    register fontdesctype *fp ;
00125    register fontmaptype *cfnt ;
00126    char *nam, *area ;
00127    integer cksum, scsize, dssize ;
00128 
00129    fn = vfbyte() ;
00130    while (siz-- > 1)
00131       fn = (fn << 8) + vfbyte() ;
00132    cfnt = (fontmaptype *)mymalloc((integer)sizeof(fontmaptype)) ;
00133    cfnt->fontnum = fn ;
00134    cksum = vfquad() ;
00135    scsize = scalewidth(s, vfquad()) ;
00136    dssize = (integer)(alpha * (real)vfquad()) ;
00137    i = vfbyte() ; j = vfbyte() ;
00138    if (nextstring + i + j > maxstring)
00139       error("! out of string space") ;
00140    area = nextstring ;
00141    for (; i>0; i--)
00142       *nextstring++ = vfbyte() ;
00143    *nextstring++ = 0 ;
00144    nam = nextstring ;
00145    for (; j>0; j--)
00146       *nextstring++ = vfbyte() ;
00147    *nextstring++ = 0 ;
00148    fp = matchfont(nam, area, scsize, (char *)0) ;
00149    if (fp) {
00150       nextstring = nam ;
00151       fp->checksum = cksum ;
00152    } else {
00153       fp = newfontdesc(cksum, scsize, dssize, nam, area) ;
00154       fp->next = fonthead ;
00155       fonthead = fp ;
00156    }
00157    cfnt->desc = fp ;
00158    return (cfnt) ;
00159 }
00160 
00161 /*
00162  *   Now our virtualfont routine.
00163  */
00164 Boolean
00165 virtualfont P1C(register fontdesctype *, curfnt)
00166 {
00167    register integer i ;
00168    register shalfword cmd ;
00169    register integer k ;
00170    register integer length ;
00171    register integer cc ;
00172    register chardesctype *cd ;
00173    integer scaledsize = curfnt->scaledsize ;
00174    integer no_of_chars=256 ;
00175    integer maxcc=255 ;
00176    register quarterword *tempr ;
00177    fontmaptype *fm, *newf ;
00178    int kindfont ;
00179    kindfont = vfopen(curfnt) ;  /* 1 for TeX, 2 for Omega */
00180    if (!kindfont)
00181       return (0) ;
00182 #ifdef DEBUG
00183    if (dd(D_FONTS))
00184       (void)fprintf(stderr,"Loading virtual font %s at %.1fpt\n",
00185          name, (real)scaledsize/(alpha*0x100000)) ;
00186 #endif /* DEBUG */
00187 
00188 /*
00189  *   We clear out some pointers:
00190  */
00191    if (kindfont==2) {
00192      no_of_chars = 65536;
00193      curfnt->maxchars=65536;
00194      free(curfnt->chardesc);
00195      curfnt->chardesc = (chardesctype *)
00196                         mymalloc(65536 * (integer)sizeof(chardesctype));
00197    }
00198    for (i=0; i<no_of_chars; i++) {
00199       curfnt->chardesc[i].TFMwidth = 0 ;
00200       curfnt->chardesc[i].packptr = NULL ;
00201       curfnt->chardesc[i].pixelwidth = 0 ;
00202       curfnt->chardesc[i].flags = 0 ;
00203       curfnt->chardesc[i].flags2 = 0 ;
00204    }
00205    if (vfbyte()!=247)
00206       badvf("expected pre") ;
00207    if (vfbyte()!=202)
00208       badvf("wrong id byte") ;
00209    for(i=vfbyte(); i>0; i--)
00210       (void)vfbyte() ;
00211    k = vfquad() ;
00212    check_checksum (k, curfnt->checksum, curfnt->name);
00213    k = (integer)(alpha * (real)vfquad()) ;
00214    if (k > curfnt->designsize + 2 || k < curfnt->designsize - 2) {
00215       (void)sprintf(errbuf,"Design size mismatch in font %s", name) ;
00216       error(errbuf) ;
00217    }
00218 /*
00219  * Now we look for font definitions.
00220  */
00221    fm = NULL ;
00222    while ((cmd=vfbyte())>=243) {
00223       if (cmd>246)
00224          badvf("unexpected command in preamble") ;
00225       newf = vfontdef(scaledsize, cmd-242) ;
00226       if (fm)
00227          fm->next = newf ;
00228       else curfnt->localfonts = newf ;
00229       fm = newf ;
00230       fm->next = NULL ; /* FIFO */
00231    }
00232 /*
00233  *   Now we get down to the serious business of reading character definitions.
00234  */
00235    do {
00236       if (cmd==242) {
00237          length = vfquad() + 2 ;
00238          if (length<2) badvf("negative length packet") ;
00239          if (length>65535) badvf("packet too long") ;
00240          cc = vfquad() ;
00241          if (cc<0 || cc>=no_of_chars) badvf("character code out of range") ;
00242          cd = curfnt->chardesc + cc ;
00243          cd->TFMwidth = scalewidth(vfquad(), scaledsize) ;
00244       } else {
00245          length = cmd + 2;
00246          cc = vfbyte() ;
00247          cd = curfnt->chardesc + cc ;
00248          cd->TFMwidth = scalewidth(vftrio(), scaledsize) ;
00249       }
00250       maxcc = (maxcc<cc) ? cc : maxcc;
00251       if (cd->TFMwidth >= 0)
00252          cd->pixelwidth = ((integer)(conv*cd->TFMwidth+0.5)) ;
00253       else
00254          cd->pixelwidth = -((integer)(conv*-cd->TFMwidth+0.5)) ;
00255       cd->flags = EXISTS ;
00256       cd->flags2 = EXISTS ;
00257       if (bytesleft < length) {
00258 #ifdef DEBUG
00259           if (dd(D_MEM))
00260              (void)fprintf(stderr,
00261 #ifdef SHORTINT
00262                    "Allocating new raster memory (%ld req, %ld left)\n",
00263 #else
00264                    "Allocating new raster memory (%d req, %ld left)\n",
00265 #endif
00266                                 length, bytesleft) ;
00267 #endif /* DEBUG */
00268           if (length > MINCHUNK) {
00269              tempr = (quarterword *)mymalloc((integer)length) ;
00270              bytesleft = 0 ;
00271           } else {
00272              raster = (quarterword *)mymalloc((integer)RASTERCHUNK) ;
00273              tempr = raster ;
00274              bytesleft = RASTERCHUNK - length ;
00275              raster += length ;
00276          }
00277       } else {
00278          tempr = raster ;
00279          bytesleft -= length ;
00280          raster += length ;
00281       }
00282       cd->packptr = tempr ;
00283       length -= 2 ;
00284       *tempr++ = length / 256 ;
00285       *tempr++ = length % 256 ;
00286          for (; length>0; length--)
00287             *tempr++ = vfbyte() ;
00288       cmd = vfbyte() ;
00289    } while (cmd < 243) ;
00290    if (cmd != 248)
00291       badvf("missing postamble") ;
00292    (void)fclose(vffile) ;
00293    curfnt->loaded = 2 ;
00294    if (maxcc+1<no_of_chars) {
00295       curfnt->chardesc = (chardesctype *)
00296          xrealloc(curfnt->chardesc,
00297                   (maxcc+1) * (integer)sizeof(chardesctype));
00298       curfnt->maxchars=maxcc+1;
00299    }
00300    return (1) ;
00301 }