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

  1. /*
  2.  *  Code for allowing fonts to be used in PostScript files given via
  3.  *  `psfile=...'.
  4.  */
  5. #include "structures.h" /* The copyright notice in that file is included too! */
  6. #include <ctype.h>
  7. #ifndef SYSV
  8. extern char *strtok() ; /* some systems don't have this in strings.h */
  9. #endif
  10. #ifdef VMS
  11. #define getname vms_getname
  12. #endif
  13.  
  14. /*
  15.  *   These are the external routines we call.
  16.  */
  17. extern fontdesctype *newfontdesc() ;
  18. extern fontdesctype *matchfont() ;
  19. extern Boolean prescanchar() ;
  20. extern Boolean preselectfont() ;
  21. extern void scout() ;
  22. extern void stringend() ;
  23. extern void cmdout() ;
  24. extern void numout() ;
  25. extern void lfontout() ;
  26. extern char *newstring() ;
  27. extern FILE *search() ;
  28. /*
  29.  *   These are the external variables we access.
  30.  */
  31. extern fontdesctype *curfnt ;
  32. extern fontdesctype *fonthead ;
  33. extern integer fontmem ;
  34. extern fontdesctype *fonthd[MAXFONTHD] ;
  35. extern int nextfonthd ;
  36. extern char *nextstring ;
  37. extern char xdig[256] ;
  38. extern real conv ;
  39. extern integer pagecost ;
  40. extern int actualdpi ;
  41. extern Boolean includesfonts ;
  42. extern char *figpath ;
  43. /*
  44.  * Create a font descriptor for a font included in a psfile.  There will be
  45.  * no fontmaptype node for the resulting font descriptor until this font is
  46.  * encountered by fontdef() (if that ever happens).
  47.  */
  48. fontdesctype *
  49. ifontdef(name, area, scsize, dssize, scname)
  50. char *name, *scname, *area ;
  51. integer scsize, dssize ;
  52. {
  53.    fontdesctype *fp;
  54.  
  55.    fp = newfontdesc((integer)0, scsize, dssize, name, area);
  56.    fp->scalename = scname;
  57.    fp->next = fonthead ;
  58.    fonthead = fp ;
  59.    return fp;
  60. }
  61. /*
  62.  * When a font appears in an included psfile for the first time, this routine
  63.  * links it into the fonthd[] array.
  64.  */
  65. void
  66. setfamily(f)
  67. fontdesctype *f ;
  68. {
  69.    int i ;
  70.  
  71.    fontmem -= DICTITEMCOST;
  72.    for (i=0; i<nextfonthd; i++)
  73.       if (strcmp(f->name, fonthd[i]->name)==0
  74.             && strcmp(f->area, fonthd[i]->area)==0) {
  75.          f->nextsize = fonthd[i];
  76.          fonthd[i] = f;
  77.          return;
  78.       }
  79.    if (nextfonthd==MAXFONTHD)
  80.       error("! Too many fonts in included psfiles") ;
  81.    fontmem -= NAMECOST + strlen(f->name) + strlen(f->area) ;
  82.    fonthd[nextfonthd++] = f ;
  83.    f->nextsize = NULL ;
  84. }
  85. /*
  86.  * Convert file name s to a pair of new strings in the string pool.
  87.  * The first string is the original value of nextstring; the second
  88.  * string is the return value.
  89.  */
  90. char*
  91. getname(s)
  92. char *s ;
  93. {
  94.    char *a, *p, sav;
  95.  
  96.    a = NULL;
  97.    for (p=s; *p!=0; p++)
  98.       if (*p=='/')
  99.          a = p+1 ;
  100.    if (a==NULL) *nextstring++ = 0 ;
  101.    else {   sav = *a ;
  102.       *a = 0 ;
  103.       (void) newstring(s) ;
  104.       *a = sav ;
  105.       s = a ;
  106.    }
  107.    return newstring(s);
  108. }
  109. /*
  110.  * Mark character usage in *f based on the hexadicimal bitmap found in
  111.  * string s.  A two-digit offset separated by a colon gives the initial
  112.  * character code.  We have no way of knowing how many times each character
  113.  * is used or how many strings get created when showing the characters so
  114.  * we just estimate two usages per character and one string per pair of
  115.  * usages.
  116.  */
  117. void
  118. includechars(f, s)
  119. fontdesctype *f ;
  120. char *s ;
  121. {
  122.    int b, c, d ;
  123.    int l = strlen(s) ;
  124.  
  125.    if (l>0 && s[l-1]=='\n')
  126.       s[--l] = 0 ;
  127.    if (!isxdigit(s[0]) || !isxdigit(s[1]) || s[2]!=':'
  128.          || strspn(s+3,"0123456789ABCDEFabcdef") < l-3) {
  129.       fprintf(stderr, "%s\n", s) ;
  130.       error("Bad syntax in included font usage table") ;
  131.       return ;
  132.    }
  133.    c = (xdig[s[0]] << 4) + xdig[s[1]] ;
  134.    s += 2 ;
  135.    while (*++s) {
  136.       d = xdig[*s] ;
  137.       for (b=8; b!=0; b>>=1) {
  138.          if ((d&b)!=0) {
  139.             pagecost ++ ;
  140.             (void) prescanchar(&f->chardesc[c]) ;
  141.          }
  142.          if (++c==256) return ;
  143.       }
  144.    }
  145. }
  146. /*
  147.  * String p should be start after the ":" in a font declaration of the form
  148. %*FONT: <tfm-name> <scaled-size> <design-size> <2-hex-digits>:<hex-string>
  149.  * where the sizes are floating-point numbers in units of PostScript points
  150.  * (TeX's "bp").  We update the data structures for the included font,
  151.  * charge fontmem for the VM used, and add to delchar if necessary.
  152.  */
  153. void
  154. scan1fontcomment(p)
  155. char *p ;
  156. {
  157.    char *q, *name, *area;
  158.    char *scname;      /* location in buffer where we got scsize */
  159.    integer scsize, dssize;
  160.    fontdesctype *fptr;
  161.    real DVIperBP;
  162.  
  163.    DVIperBP = actualdpi/(72.0*conv);
  164.    p = strtok(p, " ");
  165.    if (p==NULL) return;
  166.    area = nextstring ;   /* tentatively in the string pool */
  167.    name = getname(p);
  168.    q = strtok((char *)0, " ");
  169.    if (p==NULL || (scsize=(int)(atof(q)*DVIperBP))==0) {
  170.       fprintf(stderr, "%s\n",p);
  171.       error("No scaled size for included font");
  172.       nextstring = area ;   /* remove from string pool */
  173.       return;
  174.    }
  175.    scname = q;
  176.    q = strtok((char *)0, " ");
  177.    if (p==NULL || (dssize=(int)(atof(q)*DVIperBP))==0) {
  178.       fprintf(stderr, "%s\n",p);
  179.       error("No design size for included font");
  180.       nextstring = area ;
  181.       return;
  182.    }
  183.    q = strtok((char *)0, " ");
  184.    fptr = matchfont(name, area, scsize, scname);
  185.    if (!fptr) {
  186.       fptr = ifontdef(name, area, scsize, dssize, newstring(scname));
  187.       (void) preselectfont(fptr);
  188.       setfamily(fptr);
  189.    } else {
  190.       nextstring = area;   /* remove from string pool */
  191.       (void) preselectfont(fptr);
  192.       if (fptr->scalename==NULL) {
  193.          fptr->scalename=newstring(scname);
  194.          setfamily(fptr);
  195.       }
  196.    }
  197.    includesfonts = 1;
  198.    fptr->psflag |= THISPAGE;
  199.    includechars(fptr, q);
  200. }
  201. /*
  202.  * Parse the arguments to a "%%VMusage" comment.  The Adobe Type 1 Font Format
  203.  * book specifies two arguments. This routine will accept one or two arguments;
  204.  * if there are two arguments we take the maximum.
  205.  */
  206. integer
  207. scanvm(p)
  208. char *p ;
  209. {
  210.    char* q;
  211.    integer vm, vmmax;
  212.  
  213.    q = strtok(p, " ");
  214.    if (q==NULL) {
  215.       error("Missing data in VMusage comment");
  216.       return 0;
  217.    }
  218.    vmmax = atol(q);
  219.    q = strtok((char *)0, " ");
  220.    if (q!=NULL && (vm=atol(q))>vmmax)
  221.       vmmax = vm;
  222.    return vmmax;
  223. }
  224. /*
  225.  * Scan an initial sequence of comment lines looking for font and memory
  226.  * usage specifications.  This does not handle the "atend" construction.
  227.  */
  228. void
  229. scanfontcomments(filename)
  230. char* filename ;
  231. {
  232.    char p[500];
  233.    FILE *f;
  234.    integer truecost = pagecost ;
  235.    Boolean trueknown = 0 ;
  236.    fontdesctype *oldcf = curfnt;
  237.  
  238.    f = search(figpath, filename, READ) ;
  239.    if (f) {
  240.       while (fgets(p,500,f) && p[0]=='%' &&
  241.             (p[1]=='!' || p[1]=='%' || p[1]=='*'))
  242.          if (strncmp(p, "%*Font:", 7) == 0)
  243.             scan1fontcomment(p+7);
  244.          else if (strncmp(p, "%%VMusage:", 9) == 0) {
  245.             truecost += scanvm(p+10) ;
  246.             trueknown = 1 ;
  247.          }
  248.       if (trueknown)
  249.          pagecost = truecost ;
  250.       fclose(f) ;
  251.    }
  252.    curfnt = oldcf;
  253. }
  254. /*
  255.  * Is string s less than 30 characters long with no special characters
  256.  * that are not allowed in PostScript commands.
  257.  */
  258. Boolean
  259. okascmd(ss)
  260. char *ss ;
  261. {
  262.    register c = 0 ;
  263.    register char *s = ss ;
  264.  
  265.    while (*s)
  266.       if (*s<' ' || *s>126 || ++c==30)
  267.          return(0) ;
  268.    return(strcspn(ss,"()<>[]{}%/") == c) ;
  269. }
  270. /*
  271.  * Output font area and font name strings as a literal string
  272.  */
  273. void
  274. nameout(area, name)
  275. char *area, *name ;
  276. {
  277.    char buf[30] ;
  278.    char *s ;
  279.  
  280.    if (*area==0 && okascmd(name)) {
  281.       (void)sprintf(buf, "/%s", name) ;
  282.       cmdout(name);
  283.    } else {
  284.       for (s=area; *s; s++)
  285.          scout(*s) ;
  286.       for (s=name; *s; s++)
  287.          scout(*s) ;
  288.       stringend();
  289.       cmdout("cvn") ;
  290.    }
  291. }
  292. /*
  293.  * Output commands for defining a table of PostScript font identifiers for
  294.  * fonts used in included psfiles in the current section.
  295.  */
  296. void
  297. fonttableout()
  298. {
  299.    int i, k;
  300.    fontdesctype *f;
  301.  
  302.    for (i=0; i<nextfonthd; i++) {
  303.       for (f=fonthd[i]; f!=NULL; f=f->nextsize)
  304.          if (f->psflag==EXISTS) break;
  305.       if (f!=NULL) {
  306.          nameout(f->area, f->name);
  307.          k = 0;
  308.          do {   if (f->psflag==EXISTS) {
  309.                cmdout(f->scalename);
  310.                lfontout((int)f->psname);
  311.             }
  312.             f = f->nextsize;
  313.             k++;
  314.          } while (f!=NULL);
  315.          numout((integer)k);
  316.          cmdout("fstore");
  317.       }
  318.    }
  319. }
  320.