home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / dvipsk / virtualfont.c < prev   
C/C++ Source or Header  |  1996-09-28  |  7KB  |  266 lines

  1. /*
  2.  *   Here's the code to load a VF file into memory.
  3.  *   Any resemblance between this file and loadfont.c is purely uncoincidental.
  4.  */
  5. #include "dvips.h" /* The copyright notice in that file is included too! */
  6. #include <kpathsea/c-pathmx.h>
  7. /*
  8.  *   These are the external routines we use.
  9.  */
  10. extern void makefont() ;
  11. extern void error() ;
  12. extern integer scalewidth() ;
  13. extern FILE *search() ;
  14. extern fontdesctype *newfontdesc() ;
  15. extern fontdesctype *matchfont() ;
  16. /*
  17.  *   These are the external variables we use.
  18.  */
  19. #ifdef DEBUG
  20. extern integer debug_flag;
  21. #endif  /* DEBUG */
  22. extern long bytesleft ;
  23. extern quarterword *raster ;
  24. extern char errbuf[200] ;
  25. extern real conv ;
  26. extern real vconv ;
  27. extern real alpha ;
  28. extern integer mag ;
  29. extern int actualdpi ;
  30. extern int vactualdpi ;
  31. extern char *nextstring, *maxstring ;
  32. extern fontdesctype *fonthead ;
  33. extern real alpha ;
  34. /*
  35.  *   Now we have some routines to get stuff from the VF file.
  36.  *   Subroutine vfbyte returns the next byte.
  37.  */
  38. static FILE *vffile ;
  39. extern char name[];
  40. void
  41. badvf(s)
  42.    char *s ;
  43. {
  44.    (void)sprintf(errbuf,"! Bad VF file %s: %s",name,s) ;
  45.    error(errbuf);
  46. }
  47.  
  48. shalfword
  49. vfbyte()
  50. {
  51.    register shalfword i ;
  52.  
  53.    if ((i=getc(vffile))==EOF)
  54.       badvf("unexpected eof") ;
  55.    return(i) ;
  56. }
  57.  
  58. integer
  59. vfquad()
  60. {
  61.    register integer i ;
  62.  
  63.    i = vfbyte() ;
  64.    if (i > 127)
  65.       i -= 256 ;
  66.    i = i * 256 + vfbyte() ;
  67.    i = i * 256 + vfbyte() ;
  68.    i = i * 256 + vfbyte() ;
  69.    return(i) ;
  70. }
  71.  
  72. integer
  73. vftrio()
  74. {
  75.    register integer i ;
  76.  
  77.    i = vfbyte() ;
  78.    i = i * 256 + vfbyte() ;
  79.    i = i * 256 + vfbyte() ;
  80.    return(i) ;
  81. }
  82.  
  83. Boolean
  84. vfopen(fd)
  85.         register fontdesctype *fd ;
  86. {
  87.    vffile=search(vfpath, fd->name, READBIN);
  88.    if (vffile)
  89.       return(1) ;
  90.    return(0) ;
  91. }
  92.  
  93. /*
  94.  * The following routine is like fontdef, but for local fontdefs in VF files.
  95.  */
  96. fontmaptype *
  97. vfontdef(s, siz)
  98.       integer s ;
  99.     int siz ;
  100. {
  101.    register integer i, j, fn ;
  102.    register fontdesctype *fp ;
  103.    register fontmaptype *cfnt ;
  104.    char *name, *area ;
  105.    integer cksum, scsize, dssize ;
  106.  
  107.    fn = vfbyte() ;
  108.    while (siz-- > 1)
  109.       fn = (fn << 8) + vfbyte() ;
  110.    cfnt = (fontmaptype *)mymalloc((integer)sizeof(fontmaptype)) ;
  111.    cfnt->fontnum = fn ;
  112.    cksum = vfquad() ;
  113.    scsize = scalewidth(s, vfquad()) ;
  114.    dssize = (integer)(alpha * (real)vfquad()) ;
  115.    i = vfbyte() ; j = vfbyte() ;
  116.    if (nextstring + i + j > maxstring)
  117.       error("! out of string space") ;
  118.    area = nextstring ;
  119.    for (; i>0; i--)
  120.       *nextstring++ = vfbyte() ;
  121.    *nextstring++ = 0 ;
  122.    name = nextstring ;
  123.    for (; j>0; j--)
  124.       *nextstring++ = vfbyte() ;
  125.    *nextstring++ = 0 ;
  126.    fp = matchfont(name, area, scsize, (char *)0) ;
  127.    if (fp) {
  128.       nextstring = name ;
  129.       fp->checksum = cksum ;
  130.    } else {
  131.       fp = newfontdesc(cksum, scsize, dssize, name, area) ;
  132.       fp->next = fonthead ;
  133.       fonthead = fp ;
  134.    }
  135.    cfnt->desc = fp ;
  136.    return (cfnt) ;
  137. }
  138.  
  139. /*
  140.  *   Now our virtualfont routine.
  141.  */
  142. Boolean
  143. virtualfont(curfnt)
  144.         register fontdesctype *curfnt ;
  145. {
  146.    register shalfword i ;
  147.    register shalfword cmd ;
  148.    register integer k ;
  149.    register integer length ;
  150.    register shalfword cc ;
  151.    register chardesctype *cd ;
  152.    integer scaledsize = curfnt->scaledsize ;
  153.    register quarterword *tempr ;
  154.    fontmaptype *fm, *newf ;
  155.  
  156.    if (!vfopen(curfnt))
  157.       return (0) ;
  158. #ifdef DEBUG
  159.    if (dd(D_FONTS))
  160.       (void)fprintf(stderr,"Loading virtual font %s at %.1fpt\n",
  161.          name, (real)scaledsize/(alpha*0x100000)) ;
  162. #endif /* DEBUG */
  163.  
  164. /*
  165.  *   We clear out some pointers:
  166.  */
  167.    for (i=0; i<256; i++) {
  168.       curfnt->chardesc[i].TFMwidth = 0 ;
  169.       curfnt->chardesc[i].packptr = NULL ;
  170.       curfnt->chardesc[i].pixelwidth = 0 ;
  171.       curfnt->chardesc[i].flags = 0 ;
  172.    }
  173.    if (vfbyte()!=247)
  174.       badvf("expected pre") ;
  175.    if (vfbyte()!=202)
  176.       badvf("wrong id byte") ;
  177.    for(i=vfbyte(); i>0; i--)
  178.       (void)vfbyte() ;
  179.    k = vfquad() ;
  180.    if (k && curfnt->checksum)
  181.       if (k!=curfnt->checksum) {
  182.          (void)sprintf(errbuf,"Checksum mismatch in font %s", name) ;
  183.          error(errbuf) ;
  184.        }
  185.    k = (integer)(alpha * (real)vfquad()) ;
  186.    if (k > curfnt->designsize + 2 || k < curfnt->designsize - 2) {
  187.       (void)sprintf(errbuf,"Design size mismatch in font %s", name) ;
  188.       error(errbuf) ;
  189.    }
  190. /*
  191.  * Now we look for font definitions.
  192.  */
  193.    fm = NULL ;
  194.    while ((cmd=vfbyte())>=243) {
  195.       if (cmd>246)
  196.          badvf("unexpected command in preamble") ;
  197.       newf = vfontdef(scaledsize, cmd-242) ;
  198.       if (fm)
  199.          fm->next = newf ;
  200.       else curfnt->localfonts = newf ;
  201.       fm = newf ;
  202.       fm->next = NULL ; /* FIFO */
  203.    }
  204. /*
  205.  *   Now we get down to the serious business of reading character definitions.
  206.  */
  207.    do {
  208.       if (cmd==242) {
  209.          length = vfquad() + 2 ;
  210.          if (length<2) badvf("negative length packet") ;
  211.          if (length>65535) badvf("packet too long") ;
  212.          cc = vfquad() ;
  213.          if (cc<0 || cc>255) badvf("character code out of range") ;
  214.          cd = curfnt->chardesc + cc ;
  215.          cd->TFMwidth = scalewidth(vfquad(), scaledsize) ;
  216.       } else {
  217.          length = cmd + 2;
  218.          cc = vfbyte() ;
  219.          cd = curfnt->chardesc + cc ;
  220.          cd->TFMwidth = scalewidth(vftrio(), scaledsize) ;
  221.       }
  222.       if (cd->TFMwidth >= 0)
  223.          cd->pixelwidth = ((integer)(conv*cd->TFMwidth+0.5)) ;
  224.       else
  225.          cd->pixelwidth = -((integer)(conv*-cd->TFMwidth+0.5)) ;
  226.       cd->flags = EXISTS ;
  227.       if (bytesleft < length) {
  228. #ifdef DEBUG
  229.           if (dd(D_MEM))
  230.              (void)fprintf(stderr,
  231. #ifdef SHORTINT
  232.                    "Allocating new raster memory (%ld req, %ld left)\n",
  233. #else
  234.                    "Allocating new raster memory (%d req, %ld left)\n",
  235. #endif
  236.                                 length, bytesleft) ;
  237. #endif /* DEBUG */
  238.           if (length > MINCHUNK) {
  239.              tempr = (quarterword *)mymalloc((integer)length) ;
  240.              bytesleft = 0 ;
  241.           } else {
  242.              raster = (quarterword *)mymalloc((integer)RASTERCHUNK) ;
  243.              tempr = raster ;
  244.              bytesleft = RASTERCHUNK - length ;
  245.              raster += length ;
  246.          }
  247.       } else {
  248.          tempr = raster ;
  249.          bytesleft -= length ;
  250.          raster += length ;
  251.       }
  252.       cd->packptr = tempr ;
  253.       length -= 2 ;
  254.       *tempr++ = length / 256 ;
  255.       *tempr++ = length % 256 ;
  256.          for (; length>0; length--)
  257.             *tempr++ = vfbyte() ;
  258.       cmd = vfbyte() ;
  259.    } while (cmd < 243) ;
  260.    if (cmd != 248)
  261.       badvf("missing postamble") ;
  262.    (void)fclose(vffile) ;
  263.    curfnt->loaded = 2 ;
  264.    return (1) ;
  265. }
  266.