home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / PRINTING / DVIPS386.ZIP / LOADFONT.C < prev    next >
C/C++ Source or Header  |  1991-11-03  |  11KB  |  365 lines

  1. /*
  2.  *   Here's the code to load a PK file into memory.
  3.  *   Individual bitmaps won't be unpacked until they prove to be needed.
  4.  */
  5. #include "structures.h" /* The copyright notice in that file is included too! */
  6. /*
  7.  *   These are the external routines we use.
  8.  */
  9. extern void makefont() ;
  10. extern void error() ;
  11. extern integer scalewidth() ;
  12. extern void tfmload() ;
  13. extern FILE *pksearch() ;
  14. /*
  15.  *   These are the external variables we use.
  16.  */
  17. #ifdef DEBUG
  18. extern integer debug_flag;
  19. #endif  /* DEBUG */
  20. extern long bytesleft ;
  21. extern quarterword *raster ;
  22. extern int actualdpi ;
  23. extern real alpha ;
  24. extern char *pkpath ;
  25. char errbuf[200] ;
  26. int lastresortsizes[40] ;
  27. extern integer fsizetol ;
  28. extern Boolean nosmallchars ;
  29. #ifdef FONTLIB
  30. extern Boolean flib ;
  31. extern FILE *flisearch() ;
  32. #endif
  33. /*
  34.  *   We use malloc here.
  35.  */
  36. /* char *malloc() ; */
  37. void* malloc(unsigned) ;
  38.  
  39. /*
  40.  *   Now we have some routines to get stuff from the PK file.
  41.  *   Subroutine pkbyte returns the next byte.
  42.  */
  43.  
  44. FILE *pkfile ;
  45. char name[50] ;
  46. void
  47. badpk(s)
  48.    char *s ;
  49. {
  50.    (void)sprintf(errbuf,"! Bad PK file %s: %s",name,s) ;
  51.    error(errbuf);
  52. }
  53.  
  54. shalfword
  55. pkbyte()
  56. {
  57.    register shalfword i ;
  58.  
  59.    if ((i=getc(pkfile))==EOF)
  60.       badpk("unexpected eof") ;
  61.    return(i) ;
  62. }
  63.  
  64. integer
  65. pkquad()
  66. {
  67.    register integer i ;
  68.  
  69.    i = pkbyte() ;
  70.    if (i > 127)
  71.       i -= 256 ;
  72.    i = i * 256 + pkbyte() ;
  73.    i = i * 256 + pkbyte() ;
  74.    i = i * 256 + pkbyte() ;
  75.    return(i) ;
  76. }
  77.  
  78. integer
  79. pktrio()
  80. {
  81.    register integer i ;
  82.  
  83.    i = pkbyte() ;
  84.    i = i * 256 + pkbyte() ;
  85.    i = i * 256 + pkbyte() ;
  86.    return(i) ;
  87. }
  88.  
  89.  
  90. /*
  91.  *   pkopen opens the pk file.  This is system dependent.  We work really
  92.  *   hard to open some sort of PK file.
  93.  */
  94. static int dontmakefont = 0 ; /* if makefont fails once we won't try again */
  95.  
  96. void
  97. lectureuser() {
  98.    static int userwarned = 0 ;
  99.  
  100.    if (! userwarned) {
  101.       error("Such scaling will generate extremely poor output.") ;
  102.       userwarned = 1 ;
  103.    }
  104. }
  105. Boolean
  106. pkopen(fd)
  107.         register fontdesctype *fd ;
  108. {
  109.    register char *d, *n ;
  110.  
  111.    d = fd->area ;
  112.    n = fd->name ;
  113.    if (*d==0)
  114.       d = pkpath ;
  115. #ifdef FONTLIB
  116.    if (*(fd->area) == 0) { 
  117.       int del ;
  118.       for (del=0; del<=RES_TOLERANCE(fd->dpi); del=del>0?-del:-del+1) {
  119.         if ((pkfile=flisearch(n, fd->dpi + del)) != (FILE *)NULL )
  120.           return(1);
  121.       }
  122.    }
  123. #endif
  124.    {  
  125.       int del ;
  126.       for (del=0; del<=RES_TOLERANCE(fd->dpi); del=del>0?-del:-del+1) {
  127.          (void)sprintf(name, "%s.%dpk", n, fd->dpi + del) ;
  128.          if (pkfile=pksearch(d, name, READBIN, n, fd->dpi + del))
  129.             return(1) ;
  130.       }
  131.    }
  132.    if (d == pkpath && dontmakefont == 0) {
  133.       (void)sprintf(name, "%s.%dpk", n, fd->dpi) ;
  134.       makefont(n, (int)fd->dpi, DPI) ;
  135.       if (pkfile = pksearch(d, name, READBIN, n, fd->dpi))
  136.          return(1) ;
  137. #ifndef MSDOS
  138.       dontmakefont = 1 ;
  139. #endif
  140.    }
  141. /*
  142.  *   If nothing above worked, then we get desparate.  We attempt to
  143.  *   open the stupid font at one of a small set of predefined sizes,
  144.  *   and then use PostScript scaling to generate the correct size.
  145.  *
  146.  *   We much prefer scaling up to scaling down, since scaling down
  147.  *   can omit character features, so we try the larger sizes first,
  148.  *   and then work down.
  149.  */
  150.    {
  151.       int i, j ;
  152.  
  153.       if (lastresortsizes[0] && fd->dpi < 30000) {
  154.          for (i=0; lastresortsizes[i] < fd->dpi; i++) ;
  155.          for (j = i-1; j >= 0; j--) {
  156.             (void)sprintf(name, "%s.%dpk", n, lastresortsizes[j]) ;
  157. #ifdef FONTLIB
  158.             if ((pkfile=flisearch(n,(halfword)lastresortsizes[j]))
  159.              || (pkfile=pksearch(d, name, READBIN, n,
  160.                          (halfword)lastresortsizes[j]))) {
  161. #else
  162.             if (pkfile=pksearch(d, name, READBIN, n,
  163.                                            (halfword)lastresortsizes[j])) {
  164. #endif
  165.                fd->loadeddpi = lastresortsizes[j] ;
  166.                fd->alreadyscaled = 0 ;
  167.                (void)sprintf(errbuf,
  168.                        "Font %s at %d not found; scaling %d instead.",
  169.                                          name, fd->dpi, lastresortsizes[j]) ;
  170.                error(errbuf) ;
  171.                lectureuser() ;
  172.                return 1 ;
  173.             }
  174.          }
  175.          for (j = i; lastresortsizes[j] < 30000; j++) {
  176.             (void)sprintf(name, "%s.%dpk", n, lastresortsizes[j]) ;
  177. #ifdef FONTLIB
  178.             if ((pkfile=flisearch(n, (halfword)lastresortsizes[j]))
  179.                 || (pkfile=pksearch(d, name, READBIN, n,
  180.                       (halfword)lastresortsizes[j]))) {
  181. #else
  182.             if (pkfile=pksearch(d, name, READBIN, n, 
  183.                                        (halfword)lastresortsizes[j])) {
  184. #endif
  185.                fd->loadeddpi = lastresortsizes[j] ;
  186.                fd->alreadyscaled = 0 ;
  187.                (void)sprintf(errbuf,
  188.                        "Font %s at %d not found; scaling %d instead.",
  189.                                          name, fd->dpi, lastresortsizes[j]) ;
  190.                error(errbuf) ;
  191.                lectureuser() ;
  192.                return 1 ;
  193.             }
  194.          }
  195.       }
  196.    }
  197.    (void)sprintf(name, "%s.%dpk", n, fd->dpi) ;
  198.    (void)sprintf(errbuf,
  199.       "Font %s%s not found, characters will be left blank.",
  200.       fd->area, name) ;
  201.    error(errbuf) ;
  202.    return(0) ;
  203. }
  204.  
  205. /*
  206.  *   Now our loadfont routine.  We return an integer indicating the
  207.  *   highest character code in the font, so we know how much space
  208.  *   to reserve for the character.  (It's returned in the font
  209.  *   structure, along with everything else.)
  210.  */
  211. void
  212. loadfont(curfnt)
  213.         register fontdesctype *curfnt ;
  214. {
  215.    register shalfword i ;
  216.    register shalfword cmd ;
  217.    register integer k ;
  218.    register integer length = 0 ;
  219.    register shalfword cc = 0 ;
  220.    register integer scaledsize = curfnt->scaledsize ;
  221.    register quarterword *tempr ;
  222.    register chardesctype *cd = 0 ;
  223.    int maxcc = 0 ;
  224.  
  225. /*
  226.  *   We clear out some pointers:
  227.  */
  228.    for (i=0; i<256; i++) {
  229.       curfnt->chardesc[i].TFMwidth = 0 ;
  230.       curfnt->chardesc[i].packptr = NULL ;
  231.       curfnt->chardesc[i].pixelwidth = 0 ;
  232.       curfnt->chardesc[i].flags = 0 ;
  233.    }
  234.    curfnt->maxchars = 256 ; /* just in case we return before the end */
  235.    if (!pkopen(curfnt)) {
  236.       tfmload(curfnt) ;
  237.       return ;
  238.    }
  239. #ifdef DEBUG
  240.    if (dd(D_FONTS))
  241.       (void)fprintf(stderr,"Loading pk font %s at %.1fpt\n",
  242.          name, (real)scaledsize/(alpha*0x100000)) ;
  243. #endif /* DEBUG */
  244.    if (pkbyte()!=247)
  245.       badpk("expected pre") ;
  246.    if (pkbyte()!=89)
  247.       badpk("wrong id byte") ;
  248.    for(i=pkbyte(); i>0; i--)
  249.       (void)pkbyte() ;
  250.    k = (integer)(alpha * (real)pkquad()) ;
  251.    if (k > curfnt->designsize + fsizetol ||
  252.        k < curfnt->designsize - fsizetol) {
  253.       (void)sprintf(errbuf,"Design size mismatch in font %s", name) ;
  254.       error(errbuf) ;
  255.    }
  256.    k = pkquad() ;
  257.    if (k && curfnt->checksum)
  258.       if (k!=curfnt->checksum) {
  259.          (void)sprintf(errbuf,"Checksum mismatch in font %s", name) ;
  260.          error(errbuf) ;
  261.        }
  262.    k = pkquad() ; /* assume that hppp is correct in the PK file */
  263.    k = pkquad() ; /* assume that vppp is correct in the PK file */
  264. /*
  265.  *   Now we get down to the serious business of reading character definitions.
  266.  */
  267.    while ((cmd=pkbyte())!=245) {
  268.       if (cmd < 240) {
  269.          switch (cmd & 7) {
  270. case 0: case 1: case 2: case 3:
  271.             length = (cmd & 7) * 256 + pkbyte() - 3 ;
  272.             cc = pkbyte() ;
  273.             cd = curfnt->chardesc+cc ;
  274.             if (nosmallchars || curfnt->dpi != curfnt->loadeddpi)
  275.                cd->flags |= BIGCHAR ;
  276.             cd->TFMwidth = scalewidth(pktrio(), scaledsize) ;
  277.             cd->pixelwidth = pkbyte() ;
  278.             break ;
  279. case 4: case 5: case 6:
  280.             length = (cmd & 3) * 65536 + pkbyte() * 256 ;
  281.             length = length + pkbyte() - 4 ;
  282.             cc = pkbyte() ;
  283.             cd = curfnt->chardesc+cc ;
  284.             cd->TFMwidth = scalewidth(pktrio(), scaledsize) ;
  285.             cd->flags |= BIGCHAR ;
  286.             i = pkbyte() ;
  287.             cd->pixelwidth = i * 256 + pkbyte() ;
  288.             break ;
  289. case 7:
  290.             length = pkquad() - 11 ;
  291.             cc = pkquad() ;
  292.             if (cc<0 || cc>255) badpk("character code out of range") ;
  293.             cd = curfnt->chardesc + cc ;
  294.             cd->flags |= BIGCHAR ;
  295.             cd->TFMwidth = scalewidth(pkquad(), scaledsize) ;
  296.             cd->pixelwidth = (pkquad() + 32768) >> 16 ;
  297.             k = pkquad() ;
  298.          }
  299.          if (cc > maxcc)
  300.             maxcc = cc ;
  301.          if (length <= 0)
  302.             badpk("packet length too small") ;
  303.          if (bytesleft < length) {
  304. #ifdef DEBUG
  305.              if (dd(D_FONTS))
  306.                 (void)fprintf(stderr,
  307.                    "Allocating new raster memory (%d req, %d left)\n",
  308.                                 length, bytesleft) ;
  309. #endif /* DEBUG */
  310.              if (length > MINCHUNK) {
  311.                 tempr = (quarterword *)malloc((unsigned int)length) ;
  312.                 bytesleft = 0 ;
  313.              } else {
  314.                 raster = (quarterword *)malloc(RASTERCHUNK) ;
  315.                 tempr = raster ;
  316.                 bytesleft = RASTERCHUNK - length ;
  317.                 raster += length ;
  318.             }
  319.             if (tempr == NULL)
  320.                error("! out of memory while allocating raster") ;
  321.          } else {
  322.             tempr = raster ;
  323.             bytesleft -= length ;
  324.             raster += length ;
  325.          }
  326.          cd->packptr = tempr ;
  327.          *tempr++ = cmd ;
  328.          for (length--; length>0; length--)
  329.             *tempr++ = pkbyte() ;
  330.       } else {
  331.          k = 0 ;
  332.          switch (cmd) {
  333. case 243:
  334.             k = pkbyte() ;
  335.             if (k > 127)
  336.                k -= 256 ;
  337. case 242:
  338.             k = k * 256 + pkbyte() ;
  339. case 241:
  340.             k = k * 256 + pkbyte() ;
  341. case 240:
  342.             k = k * 256 + pkbyte() ;
  343.             while (k-- > 0)
  344.                i = pkbyte() ;
  345.             break ;
  346. case 244:
  347.             k = pkquad() ;
  348.             break ;
  349. case 246:
  350.             break ;
  351. default:
  352.             badpk("! unexpected command") ;
  353.          }
  354.       }
  355.    }
  356. #ifdef FONTLIB
  357.    if (flib)
  358.       flib = 0 ;
  359.    else
  360. #endif
  361.    (void)fclose(pkfile) ;
  362.    curfnt->loaded = 1 ;
  363.    curfnt->maxchars = maxcc + 1 ;
  364. }
  365.