home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1888 < prev    next >
Encoding:
Text File  |  1990-12-28  |  6.6 KB  |  266 lines

  1. Newsgroups: alt.sources
  2. From: shiva@well.sf.ca.us (Kenneth Porter)
  3. Subject: [postscript] Re: PostScript downloadable font formats
  4. Message-ID: <1990Sep30.201844.29357@math.lsa.umich.edu>
  5. Date: Sun, 30 Sep 90 20:18:44 GMT
  6.  
  7. Archive-name: pfb2pfa/28-Sep-90
  8. Original-posting-by: shiva@well.sf.ca.us (Kenneth Porter)
  9. Original-subject: Re: PostScript downloadable font formats
  10. Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)
  11.  
  12. [Reposted from comp.lang.postscript.
  13. Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]
  14.  
  15.  
  16.  
  17. Sorry Woody, my PC fonts arrived in binary form, and I had to
  18. use Adobe's downloader to decrypt them.  I used my Sun 386i DOS
  19. window to capture the ASCII output to a file.  Once I had more
  20. time, I wrote a program to decrypt the Adobe binary format.
  21.  
  22. /* Decompress .pfb file into .pfa file */
  23.  
  24. /*
  25.  
  26. Copyright 1990 Kenneth Porter (shiva@well.sf.ca.us)
  27. This is freely re-distributable, NOT public domain.
  28.  
  29. Adobe PostScript font files are distributed in a compressed binary
  30. format to be decompressed and downloaded to the printer by Adobe's
  31. download utilities.  Since we want to download the fonts ourselves, this
  32. utility is necessary to convert the binary file into an ASCII file
  33. readable by the printer.
  34.  
  35. */
  36.  
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40.  
  41. /* pfb record types */
  42.  
  43. #define PFBTXT 0x180    /* followed by long byte count */
  44. #define PFBBIN 0x280    /* followed by long byte count */
  45. #define PFBEOF 0x380
  46.  
  47. char *ExitServerString =
  48. "%!PS-Adobe-2.0 ExitServer\n"
  49. "%%BeginExitServer: 0\n"
  50. "serverdict begin 0 exitserver\n"
  51. "%%EndExitServer\n";
  52.  
  53. int Mac2IBM(FILE *mac, FILE *ibm, unsigned long count);
  54. int Bin2Txt(FILE *bin, FILE *txt, unsigned long count);
  55. FILE *srcopen(char *name);
  56. FILE *dstopen(char *name);
  57. FILE *fileopen(char *name, char *mode, char *humanmode);
  58. unsigned long fgetl(FILE *f);
  59. void ExitServer(char *tempfile,char *dstfile);
  60. void CheckFontName(char *linebuf);
  61.  
  62. void main(int argc, char *argv[])
  63. {
  64.     FILE *pfb, *pfa;
  65.     unsigned long count;
  66.     int eof = 0;
  67.     unsigned rtype; /* pfb record type */
  68.     char temp[L_tmpnam];
  69.  
  70.     banner();
  71.     if (argc < 3 || argc > 4) {
  72.         fprintf(stderr,"syntax: %s <PFB file> <PFA file>
  73. [persistent]\n",argv[0]);
  74.         exit(1);
  75.     }
  76.     pfb = srcopen(argv[1]);
  77.     pfa = dstopen(tmpnam(temp));
  78.     while (!eof) {
  79.         rtype = getw(pfb);
  80.     if (feof(pfb)) {
  81.         fprintf(stderr,"Unexpected end of file\n");
  82.         break;
  83.     }
  84.         switch (rtype) {
  85.             case PFBEOF:
  86.                 eof = 1;
  87.                 break;
  88.             case PFBTXT:
  89.                 count = fgetl(pfb);
  90.                 printf("Text count = %ld\n",count);
  91.                 if (feof(pfb)) {
  92.                     fprintf(stderr,"Unexpected end of file\n");
  93.                     eof = 1;
  94.                     break;
  95.                 }
  96.                 if (Mac2IBM(pfb,pfa,count)) {
  97.                     fprintf(stderr,"Unexpected end of file\n");
  98.                     eof = 1;
  99.                     break;
  100.                 }
  101.                 break;
  102.             case PFBBIN:
  103.                 count = fgetl(pfb);
  104.                 printf("Bin  count = %ld\n",count);
  105.                 if (feof(pfb)) {
  106.                     fprintf(stderr,"Unexpected end of file\n");
  107.                     eof = 1;
  108.                     break;
  109.                 }
  110.                 if (Bin2Txt(pfb,pfa,count)) {
  111.                     fprintf(stderr,"Unexpected end of file\n");
  112.                     eof = 1;
  113.                     break;
  114.                 }
  115.                 break;
  116.             default:
  117.                 fprintf(stderr,"Record type %X not recognized\n",rtype);
  118.                 eof = 1;
  119.                 break;
  120.         }
  121.     }
  122.     fclose(pfa);
  123.     fclose(pfb);
  124.     if (argc == 4) ExitServer(temp,argv[2]);
  125.     else rename(temp,argv[2]);
  126.     exit(0);
  127. }
  128.  
  129. #define CR 13   /* Mac ends line with carriage return, IBM with CRLF */
  130.  
  131. int Mac2IBM(FILE *mac, FILE *ibm, unsigned long count)
  132. {
  133.     int c;
  134.     char *lp;
  135.     static char linebuf[128];
  136.  
  137.     linebuf[0] = 0;
  138.     lp = linebuf;
  139.     while (count--) {
  140.         c = fgetc(mac);
  141.         if (feof(mac)) return(EOF);
  142.         if (c == CR) {
  143.             fputc('\n',ibm);
  144.             *lp = 0;
  145.             CheckFontName(linebuf);
  146.             linebuf[0] = 0;
  147.             lp = linebuf;
  148.         }
  149.         else {
  150.             fputc(c,ibm);
  151.             *lp++ = c;
  152.         }
  153.     }
  154.     *lp = 0;
  155.     CheckFontName(linebuf);
  156.     return(0);
  157. }
  158.  
  159. int Bin2Txt(FILE *bin, FILE *txt, unsigned long count)
  160. {
  161.     int c;
  162.     unsigned long i;
  163.  
  164.     for (i=0; i<count; i++) {
  165.         c = fgetc(bin);
  166.         if (feof(bin)) return(EOF);
  167.         fprintf(txt,"%02X",c);
  168.         if ((i & 0x1F) == 0x1F) fputc('\n',txt);
  169.     }
  170.     if ((i & 0x1F) != 0x1F) fputc('\n',txt);
  171.     return(0);
  172. }
  173.  
  174. FILE *srcopen(char *name)
  175. {
  176.     return(fileopen(name,"rb","read"));
  177. }
  178.  
  179. FILE *dstopen(char *name)
  180. {
  181.     return(fileopen(name,"wt","write"));
  182. }
  183.  
  184. FILE *fileopen(char *name, char *mode, char *humanmode)
  185. {
  186.     FILE *file;
  187.  
  188.     file = fopen(name,mode);
  189.     if (!file) {
  190.         fprintf(stderr,"Failed to open %s for %s: %s\n",
  191.             name,humanmode,strerror(errno));
  192.         exit(1);
  193.     }
  194.     return(file);
  195. }
  196.  
  197. unsigned long fgetl(FILE *f)
  198. {
  199.     unsigned long low, high;
  200.  
  201.     low = (unsigned) getw(f);
  202.     high = (unsigned) getw(f);
  203.     return(low+(high<<16));
  204. }
  205.  
  206. char FontTest1[] =
  207. "% Test for existence of font, abort if present.\n"
  208. "% This won't work on a printer with a hard disk!\n"
  209. "/str 32 string def\n";
  210.  
  211. char FontName[128];
  212.  
  213. char FontTest2[] =
  214. " dup FontDirectory exch known\n"
  215. "{ str cvs print ( is already loaded!\\n) print flush quit }\n"
  216. "{ (loading font ) print str cvs print (\\n) print flush }\n"
  217. "ifelse\n";
  218.  
  219. void ExitServer(char *tempfile,char *dstfile)
  220. {
  221.     FILE *tmp, *pfa;
  222.     static char linebuf[128];
  223.  
  224.     pfa = dstopen(dstfile);
  225.     fputs(ExitServerString,pfa);
  226.     if (FontName[0]) {
  227.         fputs(FontTest1,pfa);
  228.         fputs(FontName,pfa);
  229.         fputs(FontTest2,pfa);
  230.     }
  231.     tmp = srcopen(tempfile);
  232.     fgets(linebuf,sizeof linebuf,tmp);
  233.     while (!feof(tmp)) {
  234.         fputs(linebuf,pfa);
  235.         fgets(linebuf,sizeof linebuf,tmp);
  236.     }
  237.     fclose(tmp);
  238.     unlink(tempfile);
  239.     fclose(pfa);
  240. }
  241.  
  242. char FontNameKey[] = "/FontName";
  243. #define FNKL (sizeof FontNameKey - 1)   /* strlen(FontNameKey) */
  244.  
  245. void CheckFontName(char *linebuf)
  246. {
  247.     char *lp, *dp;
  248.  
  249.     if (!strncmp(FontNameKey,linebuf,FNKL)) {
  250.         lp = &linebuf[FNKL];
  251.         while (*lp == ' ') lp++;
  252.         dp = FontName;
  253.         while (*lp != ' ' && *lp != 0) *dp++ = *lp++;
  254.         *dp = 0;
  255.     }
  256. }
  257.  
  258. void banner(void)
  259. {
  260.     printf("ABF Decompressor\n");
  261.     printf("(c)1990 Kenneth Porter, all rights reserved\n");
  262. }
  263.  
  264. P.S. I think the usage line got truncated in upload; the end should
  265. read "...,argv[0]);".
  266.