home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fonts 1 / freshfonts1.bin / bbs / programs / amiga / pastex13.lha / DVIPS / dvips5519.lha / dvips / download.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  8KB  |  330 lines

  1. /*
  2.  *   Code to download a font definition at the beginning of a section.
  3.  */
  4. #include "dvips.h" /* The copyright notice in that file is included too! */
  5. /*
  6.  *   These are the external routines we call.
  7.  */
  8. extern void numout() ;
  9. extern void mhexout() ;
  10. extern void cmdout() ;
  11. extern long unpack() ;
  12. extern void flip() ;
  13. extern void specialout() ;
  14. extern long getlong() ;
  15. extern void error() ;
  16. extern char *nextstring ;
  17. /*
  18.  *   These are the external variables we access.
  19.  */
  20. extern FILE *bitfile ;
  21. extern fontdesctype *curfnt ;
  22. extern long bytesleft ;
  23. extern long mbytesleft ;
  24. extern quarterword *raster ;
  25. extern quarterword *mraster ;
  26. extern Boolean compressed ;
  27. extern integer mag ;
  28. extern int actualdpi ;
  29. static unsigned char dummyend[8] = { 252 } ;
  30. /*
  31.  *   We have a routine that downloads an individual character.
  32.  */
  33. static int lastccout ;
  34. void downchar(c, cc)
  35. chardesctype *c ;
  36. shalfword cc ;
  37. {
  38.    register long i, j ;
  39.    register halfword cheight, cwidth ;
  40.    register long k ;
  41.    register quarterword *p ;
  42.    register halfword cmd ;
  43.    register shalfword xoff, yoff ;
  44.    halfword wwidth = 0 ;
  45.    register long len ;
  46.    int smallchar ;
  47.  
  48.    p = c->packptr ;
  49.    cmd = *p++ ;
  50.    if (cmd & 4) {
  51.       if ((cmd & 7) == 7) {
  52.          cwidth = getlong(p) ;
  53.          cheight = getlong(p + 4) ;
  54.          xoff = getlong(p + 8) ;
  55.          yoff = getlong(p + 12) ;
  56.          p += 16 ;
  57.       } else {
  58.          cwidth = p[0] * 256 + p[1] ;
  59.          cheight = p[2] * 256 + p[3] ;
  60.          xoff = p[4] * 256 + p[5] ; /* N.B.: xoff, yoff are signed halfwords */
  61.          yoff = p[6] * 256 + p[7] ;
  62.          p += 8 ;
  63.       }
  64.    } else {
  65.       cwidth = *p++ ;
  66.       cheight = *p++ ;
  67.       xoff = *p++ ;
  68.       yoff = *p++ ;
  69.       if (xoff > 127)
  70.          xoff -= 256 ;
  71.       if (yoff > 127)
  72.          yoff -= 256 ;
  73.    }
  74.    if (c->flags & BIGCHAR)
  75.       smallchar = 0 ;
  76.    else
  77.       smallchar = 5 ;
  78.    if (compressed) {
  79.       len = getlong(p) ;
  80.       p += 4 ;
  81.    } else {
  82.       wwidth = (cwidth + 15) / 16 ;
  83.       i = 2 * cheight * (long)wwidth ;
  84.       if (i <= 0)
  85.          i = 2 ;
  86.       i += smallchar ;
  87.       if (mbytesleft < i) {
  88.          if (mbytesleft >= RASTERCHUNK)
  89.             (void) free((char *) mraster) ;
  90.          if (RASTERCHUNK > i) {
  91.             mraster = (quarterword *)mymalloc((integer)RASTERCHUNK) ;
  92.             mbytesleft = RASTERCHUNK ;
  93.          } else {
  94.             k = i + i / 4 ;
  95.             mraster = (quarterword *)mymalloc((integer)k) ;
  96.             mbytesleft = k ;
  97.          }
  98.       }
  99.       k = i;
  100.       while (k > 0)
  101.          mraster[--k] = 0 ;
  102.       unpack(p, (halfword *)mraster, cwidth, cheight, cmd) ;
  103.       p = mraster ;
  104.       len = i - smallchar ;
  105.    }
  106.    if (cheight == 0 || cwidth == 0 || len == 0) {
  107.       cwidth = 1 ;
  108.       cheight = 1 ;
  109.       wwidth = 1 ;
  110.       len = 2 ;
  111.       if (compressed)
  112.          p = dummyend ;  /* CMD(END); see repack.c */
  113.       else
  114.          mraster[0] = 0 ;
  115.    }
  116.    if (smallchar) {
  117.       p[len] = cwidth ;
  118.       p[len + 1] = cheight ;
  119.       p[len + 2] = xoff + 128 ;
  120.       p[len + 3] = yoff + 128 ;
  121.       p[len + 4] = c->pixelwidth ;
  122.    } else
  123. /*
  124.  *   Now we actually send out the data.
  125.  */
  126.       specialout('[') ;
  127.    if (compressed) {
  128.       specialout('<') ;
  129.       mhexout(p, len + smallchar) ;
  130.       specialout('>') ;
  131.    } else {
  132.       i = (cwidth + 7) / 8 ;
  133.       if (i * cheight > 65520) {
  134.          long bc = 0 ;
  135.          specialout('<') ;
  136.          for (j=0; j<cheight; j++) {
  137.             if (bc + i > 65520) {
  138.                specialout('>') ;
  139.                specialout('<') ;
  140.                bc = 0 ;
  141.             }
  142.             mhexout(p, i) ;
  143.             bc += i ;
  144.             p += 2*wwidth ;
  145.          }
  146.          specialout('>') ;
  147.       } else {
  148.          specialout('<') ;
  149.          if (2 * wwidth == i)
  150.             mhexout(p, ((long)cheight) * i + smallchar) ;
  151.          else {
  152.             for (j=0; j<cheight; j++) {
  153.                mhexout(p, i) ;
  154.                p += 2*wwidth ;
  155.             }
  156.             if (smallchar)
  157.                mhexout(p, (long)smallchar) ;
  158.          }
  159.          specialout('>') ;
  160.       }
  161.    }
  162.    if (smallchar == 0) {
  163.       numout((integer)cwidth) ;
  164.       numout((integer)cheight) ;
  165.       numout((integer)xoff + 128) ; /* not all these casts needed. */
  166.       numout((integer)yoff + 128) ;
  167.       numout((integer)(c->pixelwidth)) ;
  168.    }
  169.    if (lastccout + 1 == cc) {
  170.       cmdout("I") ;
  171.    } else {
  172.       numout((integer)cc) ;
  173.       cmdout("D") ;
  174.    }
  175.    lastccout = cc ;
  176. }
  177. /*
  178.  * Output the literal name of the font change command with PostScript index n
  179.  */
  180. static char goodnames[] =
  181.    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ;
  182. void
  183. makepsname(s, n)
  184. register char *s ;
  185. register int n ;
  186. {
  187.    n-- ;
  188.    *s++ = 'F' + n / sizeof(goodnames) ;
  189.    *s++ = goodnames[n % sizeof(goodnames)] ;
  190.    *s++ = 0 ;
  191. }
  192. void
  193. lfontout(n)
  194. int n ;
  195. {
  196.     char buf[10];
  197.         char *b = buf ;
  198.         *b++ = '/' ;
  199.         makepsname(b, n) ;
  200.     cmdout(buf);
  201. }
  202. /*
  203.  *   And the download procedure.
  204.  */
  205. void download(p, psfont)
  206. charusetype *p ;
  207. int psfont ;
  208. {
  209.    register int b, i ;
  210.    register halfword bit ;
  211.    register chardesctype *c ;
  212.    int cc, maxcc = -1, numcc ;
  213.    float fontscale ;
  214.    char name[10] ;
  215.  
  216.    lastccout = -5 ;
  217.    name[0] = '/' ;
  218.    makepsname(name + 1, psfont) ;
  219.    curfnt = p->fd ;
  220.    curfnt->psname = psfont ;
  221.    if (curfnt->resfont) {
  222.       struct resfont *rf = curfnt->resfont ;
  223.  
  224.       cmdout(name) ;
  225. /* following code re-arranged - Rob Hutchings 1992Apr02 */
  226.       c = curfnt->chardesc ;
  227.  
  228.       c = curfnt->chardesc + 255 ;
  229.       cc = 255 ;
  230.       numcc = 0 ;
  231.       i = 0 ;
  232.       for (b=15; b>=0; b--) {
  233.          for (bit=1; bit; bit<<=1) {
  234.             if (p->bitmap[b] & bit) {
  235.                if (i > 0) {
  236.                   numout((integer)i) ;
  237.                   specialout('[') ;
  238.                   i = 0 ;
  239.                }
  240.                numout((integer)c->pixelwidth) ;
  241.                c->flags |= EXISTS ;
  242.                numcc++ ;
  243.             } else {
  244.                i++ ;
  245.                c->flags &= ~EXISTS ;
  246.             }
  247.             c-- ;
  248.             cc-- ;
  249.          }
  250.       }
  251.       if (i > 0) {
  252.          numout((integer)i) ;
  253.          specialout('[') ;
  254.       }
  255.       specialout ('{') ;
  256.       if (rf->specialinstructions)
  257.          cmdout(rf->specialinstructions) ;
  258.       specialout ('}') ;
  259. /* 
  260.  * Perhaps there is a good reason to avoid float in this code; but in general
  261.  * arithmetic should be done in the driver rather than the interpreter - Rob 
  262.  */
  263.       numout((integer)numcc) ;
  264.       fontscale = ((float)(curfnt->scaledsize)) / 655360.0 ;
  265.       fontscale *= (((float)mag)/7200.0) ;
  266.       fontscale *= actualdpi ;
  267.       (void)sprintf(nextstring, "%f", fontscale) ;
  268.       cmdout(nextstring) ;
  269.       (void)strcpy(nextstring, "/") ;
  270.       (void)strcat(nextstring, rf->PSname) ;
  271.       cmdout(nextstring) ;
  272. /* end of changed section - Rob */
  273.       cmdout("rf") ;
  274.       rf->sent = 1 ;
  275.       return ;
  276.    }
  277. /*
  278.  *   Here we calculate the largest character actually used, and
  279.  *   send it as a parameter to df.
  280.  */
  281.    cc = 0 ;
  282.    numcc = 0 ;
  283.    for (b=0; b<16; b++) {
  284.       for (bit=32768; bit!=0; bit>>=1) {
  285.          if (p->bitmap[b] & bit) {
  286.             maxcc = cc ;
  287.             numcc++ ;
  288.          }
  289.          cc++ ;
  290.       }
  291.    }
  292.    if (numcc <= 0)
  293.       return ;
  294.    cmdout(name) ;
  295.    numout((integer)numcc) ;
  296.    numout((integer)maxcc + 1) ;
  297. /*
  298.  *   If we need to scale the font, we say so by using dfs
  299.  *   instead of df, and we give it a scale factor.  We also
  300.  *   scale the character widths; this is ugly, but scaling
  301.  *   fonts is ugly, and this is the best we can probably do.
  302.  */
  303.    if (curfnt->dpi != curfnt->loadeddpi) {
  304.       numout((integer)curfnt->dpi) ;
  305.       numout((integer)curfnt->loadeddpi) ;
  306.       if (curfnt->alreadyscaled == 0) {
  307.          for (b=0, c=curfnt->chardesc; b<256; b++, c++)
  308.             c->pixelwidth = (c->pixelwidth * 
  309.       (long)curfnt->dpi * 2 + curfnt->loadeddpi) / (2 * curfnt->loadeddpi) ;
  310.          curfnt->alreadyscaled = 1 ;
  311.       }
  312.       cmdout("dfs") ;
  313.    } else
  314.       cmdout("df") ;
  315.    c = curfnt->chardesc ;
  316.    cc = 0 ;
  317.    for (b=0; b<16; b++) {
  318.       for (bit=32768; bit; bit>>=1) {
  319.          if (p->bitmap[b] & bit) {
  320.             downchar(c, cc) ;