home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / text / tex / pastex / source / dvips / finclude.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-08  |  9.0 KB  |  351 lines

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