home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d7xx / d795 / pstools.lha / PSTools / PSTools1.lha / source / download.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-14  |  7.4 KB  |  301 lines

  1. /*
  2.  *   Code to download a font definition at the beginning of a section.
  3.  */
  4. #include "structures.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 quarterword *raster ;
  24. extern Boolean compressed ;
  25. extern integer mag ;
  26. /*
  27.  *   We might use malloc here.
  28.  */
  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 (bytesleft < i) {
  88.          if (bytesleft >= RASTERCHUNK)
  89.             (void) free((char *) raster) ;
  90.          if (RASTERCHUNK > i) {
  91.             raster = (quarterword *)malloc(RASTERCHUNK) ;
  92.             bytesleft = RASTERCHUNK ;
  93.          } else {
  94.             raster = (quarterword *)malloc((unsigned)i) ;
  95.             bytesleft = i ;
  96.          }
  97.          if (raster == NULL) {
  98.             error("! out of memory during allocation") ;
  99.          }
  100.       }
  101.       k = i;
  102.       while (k > 0)
  103.          raster[--k] = 0 ;
  104.       unpack(p, (halfword *)raster, cwidth, cheight, cmd) ;
  105.       p = raster ;
  106.       len = i - smallchar ;
  107.    }
  108.    if (cheight == 0 || cwidth == 0 || len == 0) {
  109.       cwidth = 1 ;
  110.       cheight = 1 ;
  111.       wwidth = 1 ;
  112.       len = 2 ;
  113.       if (compressed)
  114.          p = dummyend ;  /* CMD(END); see repack.c */
  115.       else
  116.          raster[0] = 0 ;
  117.    }
  118.    if (smallchar) {
  119.       p[len] = cwidth ;
  120.       p[len + 1] = cheight ;
  121.       p[len + 2] = xoff + 128 ;
  122.       p[len + 3] = yoff + 128 ;
  123.       p[len + 4] = c->pixelwidth ;
  124.    } else
  125. /*
  126.  *   Now we actually send out the data.
  127.  */
  128.       specialout('[') ;
  129.    if (compressed) {
  130.       specialout('<') ;
  131.       mhexout(p, len + smallchar) ;
  132.       specialout('>') ;
  133.    } else {
  134.       i = (cwidth + 7) / 8 ;
  135.       if (i * cheight > 65520) {
  136.          long bc = 0 ;
  137.          specialout('<') ;
  138.          for (j=0; j<cheight; j++) {
  139.             if (bc + i > 65520) {
  140.                specialout('>') ;
  141.                specialout('<') ;
  142.                bc = 0 ;
  143.             }
  144.             mhexout(p, i) ;
  145.             bc += i ;
  146.             p += 2*wwidth ;
  147.          }
  148.          specialout('>') ;
  149.       } else {
  150.          specialout('<') ;
  151.          if (2 * wwidth == i)
  152.             mhexout(p, ((long)cheight) * i + smallchar) ;
  153.          else {
  154.             for (j=0; j<cheight; j++) {
  155.                mhexout(p, i) ;
  156.                p += 2*wwidth ;
  157.             }
  158.             if (smallchar)
  159.                mhexout(p, (long)smallchar) ;
  160.          }
  161.          specialout('>') ;
  162.       }
  163.    }
  164.    if (smallchar == 0) {
  165.       numout((integer)cwidth) ;
  166.       numout((integer)cheight) ;
  167.       numout((integer)xoff + 128) ; /* not all these casts needed. */
  168.       numout((integer)yoff + 128) ;
  169.       numout((integer)(c->pixelwidth)) ;
  170.    }
  171.    if (lastccout + 1 == cc) {
  172.       cmdout("I") ;
  173.    } else {
  174.       numout((integer)cc) ;
  175.       cmdout("D") ;
  176.    }
  177.    lastccout = cc ;
  178. }
  179. /*
  180.  * Output the literal name of the font change command with PostScript index n
  181.  */
  182. void
  183. lfontout(n)
  184. int n ;
  185. {
  186.     char buf[10];
  187.     if (n < 27)
  188.         (void)sprintf(buf, "/f%c", 'a'+n-1) ;
  189.     else
  190.         (void)sprintf(buf, "/f%d", n-27) ;
  191.     cmdout(buf);
  192. }
  193. static char goodnames[] =
  194.    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ;
  195. void makepsname(s, n)
  196. register char *s ;
  197. register int n ;
  198. {
  199.    n-- ;
  200.    *s++ = 'F' + n / sizeof(goodnames) ;
  201.    *s++ = goodnames[n % sizeof(goodnames)] ;
  202.    *s++ = 0 ;
  203. }
  204. /*
  205.  *   And the download procedure.
  206.  */
  207. void download(p, psfont)
  208. charusetype *p ;
  209. int psfont ;
  210. {
  211.    register halfword b, bit ;
  212.    register chardesctype *c ;
  213.    int cc, maxcc = -1, numcc ;
  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.  *   I'm not sure why we tried to download each font only
  225.  *   once here---we definitely need it each time . . .
  226.  */
  227. /*    if (rf->sent == 0) { */
  228.          cmdout(name) ;
  229.          cmdout("[") ;
  230.          c = curfnt->chardesc ;
  231.          for (cc=0; cc<256; cc++, c++)
  232.             numout((integer)c->pixelwidth) ;
  233.          cmdout("]") ;
  234.          (void)strcpy(nextstring, "/") ;
  235.          (void)strcat(nextstring, rf->PSname) ;
  236.          cmdout(nextstring) ;
  237.          if (rf->specialinstructions)
  238.                cmdout(rf->specialinstructions) ;
  239.          (void)sprintf(nextstring, "%ld", mag) ;
  240.          cmdout(nextstring) ;
  241.          (void)sprintf(nextstring, "%ld", curfnt->scaledsize) ;
  242.          cmdout(nextstring) ;
  243.          cmdout("rf") ;
  244.          rf->sent = 1 ;
  245. /*    } */
  246.       return ;
  247.    }
  248. /*
  249.  *   Here we calculate the largest character actually used, and
  250.  *   send it as a parameter to df.
  251.  */
  252.    cc = 0 ;
  253.    numcc = 0 ;
  254.    for (b=0; b<16; b++) {
  255.       for (bit=32768; bit!=0; bit>>=1) {
  256.          if (p->bitmap[b] & bit) {
  257.             maxcc = cc ;
  258.             numcc++ ;
  259.          }
  260.          cc++ ;
  261.       }
  262.    }
  263.    if (numcc <= 0)
  264.       return ;
  265.    cmdout(name) ;
  266.    numout((integer)numcc) ;
  267.    numout((integer)maxcc + 1) ;
  268. /*
  269.  *   If we need to scale the font, we say so by using dfs
  270.  *   instead of df, and we give it a scale factor.  We also
  271.  *   scale the character widths; this is ugly, but scaling
  272.  *   fonts is ugly, and this is the best we can probably do.
  273.  */
  274.    if (curfnt->dpi != curfnt->loadeddpi) {
  275.       numout((integer)curfnt->dpi) ;
  276.       numout((integer)curfnt->loadeddpi) ;
  277.       if (curfnt->alreadyscaled == 0) {
  278.          for (b=0, c=curfnt->chardesc; b<256; b++, c++)
  279.             c->pixelwidth = (c->pixelwidth * 
  280.       (long)curfnt->dpi * 2 + curfnt->loadeddpi) / (2 * curfnt->loadeddpi) ;
  281.          curfnt->alreadyscaled = 1 ;
  282.       }
  283.       cmdout("dfs") ;
  284.    } else
  285.       cmdout("df") ;
  286.    c = curfnt->chardesc ;
  287.    cc = 0 ;
  288.    for (b=0; b<16; b++) {
  289.       for (bit=32768; bit; bit>>=1) {
  290.          if (p->bitmap[b] & bit) {
  291.             downchar(c, cc) ;
  292.             c->flags |= EXISTS ;
  293.          } else
  294.             c->flags &= ~EXISTS ;
  295.          c++ ;
  296.          cc++ ;
  297.       }
  298.    }
  299.    cmdout("E") ;
  300. }
  301.