ftp.nice.ch/pub/next/text/tex/apps/TeXview-kp0.25.s.tar.gz#/TeXview-grey/loadfont.c

This is loadfont.c in view mode; [Download] [Up]

/*
 *   loadfont.c of dvisw software package
 *   loads a pk file into memory.
 */
#include "structures.h"
#include <kpathsea/tex-file.h>
#include <kpathsea/tex-glyph.h>
#include <strings.h>
/*
 *   These are the external routines we use.
 */
extern void error() ;
extern integer scalewidth() ;
extern void tfmload() ;
extern FILE *pksearch() ;
extern void makefont() ;
extern shalfword dvibyte() ;
extern halfword twobytes() ;
extern integer threebytes() ;
extern integer signedquad() ;
extern shalfword signedbyte() ;
extern shalfword signedpair() ;
extern integer signedtrio() ;
extern void movmem(), cmpmem() ;
extern void free() ;
extern void unpack() ;
extern void setstatus(), qstatus() ;
extern void TPSinit(), TPSdf(), TPSdc(), TPSbop(), TPSeop() ;
extern void texflush() ;
extern void TPSdfe(), TPSrfe(), TPSdfes() ;
extern void pswrite() ;
extern int residentfont(), virtualfont() ;
extern void add_header() ;
/*
 *   These are the external variables we use.
 */
static quarterword *svirpos ;
extern quarterword *virpos ;
extern char temperrorbuf[] ;
extern fontdesctype *fontlist, *curfnt ;
extern integer dvimag ;
extern FILE *pkfile ;
extern FILE *dvifile ;
extern integer curpos ;
extern real pxlconv ;
extern real screendpi ;
#ifdef DEBUG
extern int debugon ;
#endif
extern int *existsize ;
FILE *readingpk ;
integer scurpos ;
integer curid ;
int lastresortsizes[40] ;
/*
 *   We use mymalloc here.
 */
void *mymalloc() ;
void *tempbuf() ;
char lastfile[400] ;
extern TeXfontdesctype *TeXfontlist ;
Boolean pkopen(tft, dpi)
register TeXfontdesctype *tft ;
int dpi ;
{
   register char *d, *n ;
   char *name_ret ;
   int dpi_ret ;

   n = tft->name ;
   if (*n==0) {
      n++ ;
      d = pkpath ;
   } else {
      d = n ;
      while (*n) n++ ;
      n++ ;
   }
   sprintf(lastfile, "%s.%dpk", n, dpi) ;
   sprintf(temperrorbuf, "Loading %s", lastfile) ;
   qstatus(temperrorbuf) ;
#if 0
   {  
      int del ;
      for (del=0; del<=1+dpi/500; del=del>0?-del:-del+1) {
         (void)sprintf(lastfile, "%s.%dpk", n, dpi + del) ;
         if (pkfile=pksearch(d, lastfile, n, dpi + del))
            goto fontfound ;
      }
   }
#else
   {
//     char *this_name = concat (d, n);
     char *this_name = xstrdup(n);

     pkfile=pksearch(pkpath, this_name, &name_ret, dpi, &dpi_ret);

     if (!pkfile || !(strcmp(this_name, name_ret) == 0))
       {
         (void)sprintf(temperrorbuf,
            "Font %s%s not found, characters will be left blank.",
            tft->name, n) ;
//         dontmakefont = 1;
         setstatus(temperrorbuf) ;
   strcat(temperrorbuf, " [blocks]") ;
   qstatus(temperrorbuf) ;
   return 0 ;
       }
     else if (!kpse_bitmap_tolerance ((double) dpi_ret, (double) dpi))
       {
           (void)sprintf(temperrorbuf,
                   "Font %s at %d not found; scaling %d instead.",
                                     n, dpi, dpi_ret) ;
           dpi = dpi_ret ;
           tft->loaded->alreadyscaled = 0 ;
           setstatus(temperrorbuf) ;
       }

     if (this_name != name_ret)
       free (this_name);
       
     if (pkfile != NULL) goto fontfound;
	 goto fontfound;
   }
#endif
/* Nothing below this gets executed.  */
#if 0
   if (d == pkpath) {
      (void)sprintf(lastfile, "%s.%dpk", n, dpi) ;
      makefont(n, (int)dpi) ;
      if (pkfile = pksearch(d, lastfile, n, dpi))
         goto fontfound ;
   }
/*
 *   If nothing above worked, then we get desparate.  We attempt to
 *   open the stupid font at one of a small set of predefined sizes,
 *   and then use PostScript scaling to generate the correct size.
 *
 *   We much prefer scaling up to scaling down, since scaling down
 *   can omit character features, so we try the larger sizes first,
 *   and then work down.
 */
   {
      int i, j ;

      if (lastresortsizes[0] && dpi < 30000) {
         for (i=0; lastresortsizes[i] < dpi; i++) ;
         for (j = i-1; j >= 0; j--) {
            (void)sprintf(lastfile, "%s.%dpk", n, lastresortsizes[j]) ;
            if (pkfile=pksearch(d, lastfile, n, lastresortsizes[j])) {
               dpi = lastresortsizes[j] ;
               tft->loaded->alreadyscaled = 0 ;
               goto sfontfound ;
            }
         }
         for (j = i; lastresortsizes[j] < 30000; j++) {
            (void)sprintf(lastfile, "%s.%dpk", n, lastresortsizes[j]) ;
            if (pkfile=pksearch(d, lastfile, n, lastresortsizes[j])) {
               dpi = lastresortsizes[j] ;
               tft->loaded->alreadyscaled = 0 ;
               goto sfontfound ;
            }
         }
      }
   }
   strcat(temperrorbuf, " [blocks]") ;
   qstatus(temperrorbuf) ;
   return 0 ;
#endif /* 0 */
sfontfound: ;
#ifdef DEBUG
   strcat(temperrorbuf, " [scaled]") ;
   qstatus(temperrorbuf) ;
   if (debugon > 1)
      printf("Had to scale %d to %d\n", dpi, tft->loaded->dpi) ;
#endif
fontfound:
   readingpk = dvifile ;
   scurpos = curpos ;
   svirpos = virpos ;
   virpos = 0 ;
   dvifile = pkfile ;
   tft->loaded->loadeddpi = dpi ;
   return(1) ;
}
/*
 *   This routine compares two strings in sucession, for font names.
 */
short str2cmp(a, b)
register char *a, *b ;
{
   while (*a!=0 && *a==*b) {
      a++ ; b++ ;
   }
   if (*a!=0 || *b!=0)
      return(0) ;
   a++ ; b++ ;
   while (*a!=0 && *a==*b) {
      a++ ; b++ ;
   }
   return (*a==0 && *b==0) ;
}
void bytepack(p, w, h)
register char *p ;
register int w, h ;
{
   register char *q ;
   register int i ;

   w = (w + 7) / 8 ;
   if ((w & 1) == 0)
      return ;
   q = p + w ;
   p = q + 1 ;
   while (h > 1) {
      for (i=w; i>0; i--)
         *q++ = *p++ ;
      p++ ;
      h-- ;
   }
}
/*
 *   Now our loadfont routine.
 */
void loadfont(tft)
register TeXfontdesctype *tft ;
{
   register fontdesctype *cf ;
   register chardesctype *cd ;
   register integer k ;
   register integer length ;
   register integer cmd ;
   register integer i, j ;
   register integer cc ;
   register integer scaledsize = tft->scaledsize ;
   register integer cheight, cwidth ;
   register integer xoffset, yoffset ;
   register integer dpi ;
   register shalfword *p, *q ;
   int fontwidths[256] ;
/*
 *   First, we scan through the linked list of fonts in memory, looking
 *   for one that matches ours.
 */
   dpi = pxlconv * (float)scaledsize / tft->designsize + 0.5 ;
/*
 *   Now we check to see if that value is close to some other value.
 *   Close is within one.  If so, we load that size.  There should
 *   never be an error of more than one; the only errors are due to
 *   floating point and magnifications being only valid to about three
 *   sig digits.
 */
   for (i=0; existsize[i] < dpi; i++) ;
   if (existsize[i] == dpi + 1)
      dpi = existsize[i] ;
   else if (existsize[i-1] == dpi - 1)
      dpi = existsize[i-1] ;
   if (debugon > 5)
      printf("Looking for %s %ld %ld\n", tft->name+1, tft->scaledsize, dpi) ;
   for (cf=fontlist; cf!=NULL; cf=cf->next) {
      if (cf->dpi==dpi && str2cmp(cf->name, tft->name))
         break ;
   }
   if (cf!=NULL) {
      if (debugon > 5)
         printf("Found: %s\n", cf->name+1) ;
      tft->loaded = cf ;
      for (i=0; i<cf->maxchars; i++)
         tft->scaledwidth[i] = scalewidth(cf->chardesc[i].TFMwidth,
                 tft->scaledsize) ;
      if (cf->virtual) {
         fontmaptype *fm ;
         for (fm = cf->localfonts; fm; fm = fm->next) {
            tft = fm->tdesc ;
            tft->scaledsize = scalewidth(scaledsize, tft->origssize) ;
         }
      }
      return ;
   }
   if (debugon > 5) printf("Not found.\n") ;
/*
 *   Didn't find any, we allocate a new fontdesc.
 */
   i = 0 ;
   while (tft->name[i++]!=0) ;
   while (tft->name[i++]!=0) ;
   cf = mymalloc(sizeof(fontdesctype)+i, MEMF_CLEAR) ;
   curfnt = cf ;
   cf->chardesc = mymalloc(sizeof(chardesctype) * 256, MEMF_CLEAR) ;
   cf->maxchars = 256 ;
   while (i >= 0) {
      cf->name[i] = tft->name[i] ;
      i-- ;
   }
   tft->loaded = cf ;
   cf->next = fontlist ;
   fontlist = cf ;
   cf->dpi = dpi ;
   cf->id = curid++ ;
   cf->resfont = NULL ;
   if (residentfont(tft)) {
      float fontscale ;
      struct resfont *rf = cf->resfont ;
      static int firstPSfont = 1 ;
      char num[50] ;
      char nfn[10] ;

#ifdef POPRESTORE
      TPSeop() ;
#endif
      if (firstPSfont) {
         add_header("texps.pro") ;
         firstPSfont = 0 ;
      }
      for (i=0; i<256; i++)
         fontwidths[i] = 0 ;
      for (i=0; i<cf->maxchars; i++)
         fontwidths[i] = cf->chardesc[i].pixelwidth ;
      sprintf(nfn, "Q%ld", curid-1) ;
      if (rf->downloadheader) {
         char *cp = rf->downloadheader ;
         char *q ;

         while (1) {
            q = cp ;
            while (*cp && *cp != ' ')
               cp++ ;
            if (*cp) {
               *cp = 0 ;
               add_header(q) ;
               *cp++ = ' ' ;
            } else {
               add_header(q) ;
               break ;
            }
         }
      }
      pswrite(" /") ;
      pswrite(nfn) ;
      pswrite(" /") ;
      pswrite(nfn) ;
      for (i=255; i>=0; i--) {
         sprintf(num, " %d", fontwidths[i]) ;
         pswrite(num) ;
      }
      pswrite(" {") ;
      if (rf->specialinstructions)
         pswrite(rf->specialinstructions) ;
      pswrite("} 256 ") ;
      fontscale = tft->scaledsize / 655360.0 ;
      fontscale *= dvimag / 7200.0 ;
      fontscale *= screendpi ;
      sprintf(num, "%f ", fontscale) ;
      pswrite(num) ;
      pswrite("/") ;
      pswrite(rf->PSname) ;
      pswrite(" rf ") ;
      TPSrfe(curid-1) ;
#ifdef POPRESTORE
      TPSbop() ;
#else
      texflush() ;
#endif
      if (debugon > 5) printf("Font was resident.\n") ;
      goto scalethem ;
   } else if (virtualfont(tft)) {
      if (debugon > 5) printf("Font was virtual.\n") ;
      goto scalethem ;
   }
   if (!(i=pkopen(tft, dpi))) { 
      tfmload(tft, 1) ;
scalethem:
      for (i=0; i<cf->maxchars; i++)
         tft->scaledwidth[i] = scalewidth(cf->chardesc[i].TFMwidth, tft->scaledsize) ;
      return ;
   }
#ifdef POPRESTORE
   TPSeop() ;
#endif
   TPSdf(cf->id) ;
   if (dvibyte()!=247)
      error("! bad pk file, expected pre") ;
   if (dvibyte()!=89)
      error("! bad version of pk file") ;
   for(i=dvibyte(); i>0; i--)
      j=dvibyte() ;
   k = signedquad() >> 4 ;
   if (k > tft->designsize + 2 || k < tft->designsize - 2)
      error("design size mismatch") ;
   signedquad() ;
   signedquad() ;
   signedquad() ;
/*
 *   Now we get down to the serious business of reading character definitions.
 */
   while ((cmd=dvibyte())!=245) {
      if (cmd < 240) {
         switch (cmd & 7) {
case 0: case 1: case 2: case 3:
            length = (cmd & 7) * 256 + dvibyte() - 8 ;
            cc = dvibyte() ;
            cd = cf->chardesc+cc ;
            cd->TFMwidth = threebytes() ;
            cd->pixelwidth = dvibyte() ;
            cwidth = dvibyte() ;
            cheight = dvibyte() ;
            xoffset = signedbyte() ;
            yoffset = signedbyte() ;
            break ;
case 4:
            length = dvibyte() * 256 ;
            length = length + dvibyte() - 13 ;
            cc = dvibyte() ;
            cd = cf->chardesc+cc ;
            cd->TFMwidth = threebytes() ;
            cd->pixelwidth = twobytes() ;
            cwidth = twobytes() ;
            cheight = twobytes() ;
            xoffset = signedpair() ;
            yoffset = signedpair() ;
            break ;
case 7:
            length = signedquad() - 28 ;
            cc = signedquad() ;
            cd = cf->chardesc+cc ;
            cd->TFMwidth = signedquad() ;
            cd->pixelwidth = (signedquad() + 32768) >> 16 ;
            signedquad() ;
            cwidth = signedquad() ;
            cheight = signedquad() ;
            xoffset = signedquad() ;
            yoffset = signedquad() ;
            break ;
case 5: case 6: default:
            error("! lost sync in pk file (character too big)") ;
            return ;
         }
         i = cheight * ((cwidth + 15) / 16) ;
         p = tempbuf(length + 2 * i + 10) ;
         if (i > 0) {
            fread(p, 1, length, dvifile) ;
            q = p + (length + 3) / 2 ;
            unpack(p, q, cwidth, cheight, cmd) ;
	  } else {
             cwidth = 1 ;
             cheight = 1 ;
             q = p ;
             *q = ~0 ;
          }
/*
 *   It's an ugly, ugly story, but now we need to byte-pack the word-packed
 *   data.  Of course, we do this only if the data isn't already byte packed.
 */
         bytepack(q, cwidth, cheight) ;
         i = cheight * ((cwidth + 7) / 8) ;
         TPSdc(q, i, cwidth, cheight, xoffset, cheight - yoffset - 1, cd->pixelwidth, cc) ;
      } else {
         k = 0 ;
         switch (cmd) {
case 243:
            k = dvibyte() ;
            if (k > 127)
               k -= 256 ;
case 242:
            k = k * 256 + dvibyte() ;
case 241:
            k = k * 256 + dvibyte() ;
case 240:
            k = k * 256 + dvibyte() ;
            while (k-- > 0)
               i = dvibyte() ;
            break ;
case 244:
            k = signedquad() ;
            break ;
case 246:
            break ;
default:
            error("! lost sync in pk file") ;
         }
      }
   }
   fclose(dvifile) ;
   dvifile = readingpk ;
   curpos = scurpos ;
   virpos = svirpos ;
   readingpk = NULL ;
   for (i=0; i<cf->maxchars; i++)
      tft->scaledwidth[i] = scalewidth(cf->chardesc[i].TFMwidth,
              tft->scaledsize) ;
   if (cf->dpi == cf->loadeddpi)
      TPSdfe() ;
   else
      TPSdfes(cf->dpi, cf->loadeddpi) ;
#ifdef POPRESTORE
   TPSbop() ;
#else
   texflush() ;
#endif
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.