home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / text / tex / pastex / source / dvips / makefont.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-29  |  13.6 KB  |  551 lines

  1. /*
  2.  *   This software is Copyright 1988 by Radical Eye Software.
  3.  */
  4. #include "dvips.h"
  5. #ifdef AMIGA
  6.  
  7. #include <stdlib.h>
  8. #include "makefont_protos.h"
  9. #include "dvips_protos.h"
  10. #include "search_protos.h"
  11. #include "rexx_protos.h"
  12.  
  13. extern char *pkpath;
  14. extern int actualdpi;
  15. extern int vactualdpi;
  16.  
  17. enum {PKEXPAND_FULL, PKEXPAND_ONE, PKEXPAND_TWO, PKEXPAND_PKPART};
  18.  
  19. struct amipk_info {
  20.     char *path;    /* font path */
  21.     char *name;    /* font name */
  22.     char *mode;    /* METAFONT mode */
  23.     int dpi;
  24.     int xdpi;    /* horizontal base resolution */
  25.     int ydpi;    /* vertical base resolution */
  26. };
  27.  
  28. static char *last_pkpath = NULL;
  29. static char *expand_pkpath(struct amipk_info *, int);
  30. static int magstep(register int, register int);
  31.  
  32. #endif /* AMIGA */
  33. extern int quiet ;
  34. extern int filter ;
  35. extern int dontmakefont ;
  36. #ifndef AMIGA
  37. extern int system() ;
  38. extern char *getenv(), *newstring() ;
  39. #endif
  40. extern Boolean secure ;
  41. extern char *mfmode ;
  42. #ifdef OS2
  43. #include <stdlib.h>
  44. #endif
  45. #if defined MSDOS || defined OS2
  46. extern char *mfjobname ;
  47. extern FILE *mfjobfile ;
  48. extern char *pkpath ;
  49. extern int actualdpi ;
  50. extern int vactualdpi ;
  51. /*
  52.  *  Write mfjob file
  53.  */
  54. void
  55. mfjobout(font,mag)
  56. char *font;
  57. double mag;
  58. {
  59.    if (mfjobfile == (FILE *)NULL) {
  60.       char pkout[128];
  61.       char *p;
  62.       int i;
  63.       for (p=pkpath, i=0; *p && *p!=PATHSEP && i<127; p++) {
  64.          if (*p=='%') {
  65.             p++;
  66.             switch(*p) { /* convert %x codes to mfjob @y codes */
  67.                case 'b':
  68.                   sprintf(pkout+i,"%d",actualdpi);
  69.                   break;
  70.                case 'd':
  71.                   strcpy(pkout+i,"@Rr");
  72.                   break;
  73.                case 'f':
  74.                   strcpy(pkout+i,"@f");
  75.                   break;
  76.                case 'p':
  77.                   strcpy(pkout+i,"pk");
  78.                   break;
  79.                case 'm':
  80.                   strcpy(pkout+i, mfmode ? mfmode : "default");
  81.                   break;
  82.                case '%':
  83.                   strcpy(pkout+i,"%");
  84.                   break;
  85.                default:
  86.                   sprintf(pkout+i, "%%%c", *p) ;
  87.                   fprintf(stderr,"Unknown option %%%c in pk path\n",*p);
  88.             }
  89.             i += strlen(pkout+i);
  90.          }
  91.          else
  92.            pkout[i++] = *p;
  93.       }
  94.       /* *p='\0'; Could some DOS person explain to me what this does? */
  95.       pkout[i] = 0 ;
  96.       mfjobfile =  fopen(mfjobname,"w");
  97.       if (mfjobfile == (FILE *)NULL)
  98.          return;
  99.       fprintf(mfjobfile,"input[dvidrv];\n{\ndriver=dvips;\n");
  100.       if (actualdpi == vactualdpi)
  101.          fprintf(mfjobfile,"mode=%s[%d];\n",mfmode,actualdpi);
  102.       else
  103.          fprintf(mfjobfile,"mode=%s[%d %d];\n",mfmode,actualdpi,vactualdpi);
  104.       fprintf(mfjobfile,"output=pk[%s];\n",pkout);
  105.    }
  106.    fprintf(mfjobfile,"{font=%s; mag=%f;}\n",font,mag);
  107.    (void)fprintf(stderr,
  108.         "Appending {font=%s; mag=%f;} to %s\n",font,mag,mfjobname) ;
  109. }
  110. #endif
  111. /*
  112.  *   Calculate magstep values.
  113.  */
  114. static int
  115. magstep(n, bdpi)
  116. register int n, bdpi ;
  117. {
  118.    register float t ;
  119.    int neg = 0 ;
  120.  
  121.    if (n < 0) {
  122.       neg = 1 ;
  123.       n = -n ;
  124.    }
  125.    if (n & 1) {
  126.       n &= ~1 ;
  127.       t = 1.095445115 ;
  128.    } else
  129.       t = 1.0 ;
  130.    while (n > 8) {
  131.       n -= 8 ;
  132.       t = t * 2.0736 ;
  133.    }
  134.    while (n > 0) {
  135.       n -= 2 ;
  136.       t = t * 1.2 ;
  137.    }
  138.    if (neg)
  139.       return((int)(0.5 + bdpi / t)) ;
  140.    else
  141.       return((int)(0.5 + bdpi * t)) ;
  142. }
  143. #ifdef MAKEPKCMD
  144. static char *defcommand = MAKEPKCMD " %n %d %b %m" ;
  145. #else
  146. #ifdef OS2
  147. static char *doscommand = "command /c MakeTeXP %n %d %b %m" ;
  148. static char *os2command = "MakeTeXP %n %d %b %m" ;
  149. #define defcommand ( _osmode==OS2_MODE ? os2command : doscommand )
  150. #else
  151. #ifdef MSDOS
  152. static char *defcommand = "command /c MakeTeXP %n %d %b %m" ;
  153. #else
  154. #ifdef VMCMS
  155. static char *defcommand = "EXEC MakeTeXPK %n %d %b %m" ;
  156. #else
  157. #ifdef ATARIST
  158. static char *defcommand = "maketexp %n %d %b %m" ;
  159. #else
  160. static char *defcommand = "MakeTeXPK %n %d %b %m" ;
  161. #endif
  162. #endif
  163. #endif
  164. #endif
  165. #endif
  166. char *command = 0 ;
  167. /*
  168.  *   This routine tries to create a font by executing a command, and
  169.  *   then opening the font again if possible.
  170.  */
  171. #ifdef AMIGA
  172. static char buf[256], amibuf[256] ;
  173. #else
  174. static char buf[125] ;
  175. #endif
  176. void
  177. makefont(name, dpi, bdpi)
  178.    char *name ;
  179.    int dpi, bdpi ;
  180. {
  181.    register char *p, *q ;
  182.    register int m, n ;
  183.    int modegiven = 0 ;
  184. #if defined MSDOS || defined OS2 || defined(ATARIST)
  185.    double t;
  186. #endif
  187.  
  188. #ifdef AMIGA
  189. #define CALLMFNAME "CALLMF"
  190.    Boolean amigamaketexpk = 0; /* use of Amiga MakeTeXPK features ? */
  191.    Boolean arexx_callmf = 0;   /* call the arexx script specified by the env var CALLMF ? */
  192.    struct amipk_info amipk;
  193.  
  194.    amipk.path = pkpath;
  195.    amipk.name = name;
  196.    amipk.mode = mfmode;
  197.    amipk.dpi  = dpi;
  198.    amipk.xdpi = bdpi;
  199.    amipk.ydpi = vactualdpi;
  200.  
  201.    command = 0;
  202.    if (secure == 0 && (command=getenv("MAKETEXPK")))
  203.       command = newstring(command);
  204.    else
  205.    {
  206.       if (command = getenv(CALLMFNAME)) /* try to get the env var CALLMF */
  207.          arexx_callmf = 1;
  208.       else
  209.          command = defcommand; /* default command */
  210.    }
  211.  
  212.    if (!stricmp(command,CALLMFNAME))
  213.    {
  214.       if (command = getenv(CALLMFNAME))
  215.          arexx_callmf = 1;
  216.       else
  217.          command = defcommand;
  218.    }         
  219.  
  220. #else
  221.    if (command == 0)
  222.       if (secure == 0 && (command=getenv("MAKETEXPK")))
  223.          command = newstring(command) ;
  224.       else 
  225.          command = defcommand ;
  226. #endif
  227. #ifdef AMIGA
  228.    if (!arexx_callmf) {
  229. #endif /* AMIGA */
  230.    for (p=command, q=buf; *p; p++)
  231.       if (*p != '%')
  232.          *q++ = *p ;
  233.       else {
  234.          switch (*++p) {
  235. case 'n' : case 'N' :
  236.             (void)strcpy(q, name) ;
  237.             break ;
  238. case 'd' : case 'D' :
  239.             (void)sprintf(q, "%d", dpi) ;
  240.             break ;
  241. case 'b' : case 'B' :
  242.             (void)sprintf(q, "%d", bdpi) ;
  243.             break ;
  244. case 'o' : case 'O' :
  245.             (void)sprintf(q, "%s", mfmode ? mfmode : "default") ;
  246.             modegiven = 1 ;
  247.             break ;
  248. case 'm' : case 'M' :
  249. /*
  250.  *   Here we want to return a string.  If we can find some integer
  251.  *   m such that floor(0.5 + bdpi * 1.2 ^ (m/2)) = dpi, we write out
  252.  *      magstep(m/2)
  253.  *   where m/2 is a decimal number; else we write out
  254.  *      dpi/bdpi
  255.  *   We do this for the very slight improvement in accuracy that
  256.  *   magstep() gives us over the rounded dpi/bdpi.
  257.  */
  258.             m = 0 ;
  259.             if (dpi < bdpi) {
  260.                while (1) {
  261.                   m-- ;
  262.                   n = magstep(m, bdpi) ;
  263.                   if (n == dpi)
  264.                      break ;
  265.                   if (n < dpi || m < -40) {
  266.                      m = 9999 ;
  267.                      break ;
  268.                   }
  269.                }
  270.             } else if (dpi > bdpi) {
  271.                while (1) {
  272.                   m++ ;
  273.                   n = magstep(m, bdpi) ;
  274.                   if (n == dpi)
  275.                      break ;
  276.                   if (n > dpi || m > 40) {
  277.                      m = 9999 ;
  278.                      break ;
  279.                   }
  280.                }
  281.             }
  282. #if defined MSDOS || defined OS2
  283. /* write out magnification as decimal number */
  284.             if (m == 9999) {
  285.                t = (double)dpi/bdpi;
  286.             } else {
  287.                if (m < 0)
  288.                     n = -m;
  289.                else
  290.                     n = m;
  291.                if (n & 1) {
  292.                     n &= ~1 ;
  293.                     t = 1.095445115 ;
  294.                } else
  295.                     t = 1.0 ;
  296.                while (n > 0) {
  297.                     n -= 2 ;
  298.                     t = t * 1.2 ;
  299.                }
  300.                if (m < 0)
  301.                     t = 1 / t ;
  302.             }
  303.             (void)sprintf(q, "%12.9f", t) ;
  304. #else
  305. #ifndef ATARIST
  306.             if (m == 9999) {
  307. #else
  308.             {
  309. #endif
  310.                (void)sprintf(q, "%d+%d/%d", dpi/bdpi, dpi%bdpi, bdpi) ;
  311.             } else if (m >= 0) {
  312. #ifdef AMIGA
  313.                (void)sprintf(q, "magstep(%d.%d)", m/2, (m&1)*5) ;
  314.             } else {
  315.                (void)sprintf(q, "magstep(-%d.%d)", (-m)/2, (m&1)*5) ;
  316. #else
  317.                (void)sprintf(q, "magstep\\(%d.%d\\)", m/2, (m&1)*5) ;
  318.             } else {
  319.                (void)sprintf(q, "magstep\\(-%d.%d\\)", (-m)/2, (m&1)*5) ;
  320. #endif /* AMIGA */
  321.             }
  322. #endif
  323.             break ;
  324. #ifdef AMIGA
  325. case 'p':
  326.             amigamaketexpk = 1;
  327.             (void) expand_pkpath(&amipk, PKEXPAND_ONE);
  328.             (void) strcpy(q, amibuf);
  329.             break;
  330.  
  331. case 'P':
  332.             amigamaketexpk = 1;
  333.             (void) expand_pkpath(&amipk, PKEXPAND_TWO);
  334.             (void) strcpy(q, amibuf);
  335.             break;
  336.  
  337. case 'x' : case 'X' :
  338.         amigamaketexpk = 1;
  339.             (void)sprintf(q, "%d", actualdpi) ;
  340.             break ;
  341.  
  342. case 'y' : case 'Y' :
  343.         amigamaketexpk = 1;
  344.             (void)sprintf(q, "%d", vactualdpi) ;
  345.             break ;
  346.  
  347. #endif /* AMIGA */
  348. case 0 :    *q = 0 ;
  349.             break ;
  350. default:    *q++ = *p ;
  351.             *q = 0 ;
  352.             break ;
  353.          }
  354.          q += strlen(q) ;
  355.       }
  356. #ifdef AMIGA
  357.       *q = 0;
  358.       if (mfmode && !modegiven && !amigamaketexpk)
  359.       {
  360.           strcpy(q, " ");
  361.           strcat(q, mfmode);
  362.       }
  363.    }
  364.    else
  365.    {
  366.       long result = 20;
  367.  
  368.       sprintf(buf, "'%s %s %d %d %d dvips %d/%s.%dpk %s'", command,
  369.          name, dpi, bdpi, vactualdpi, dpi, name, dpi,
  370.          expand_pkpath(&amipk, PKEXPAND_PKPART));
  371.  
  372.       if (!quiet)
  373.          (void)fprintf(stderr, "- %s\n", buf);
  374.  
  375.       (void)call_rexx(buf, &result);
  376.       return;
  377.    }
  378.  
  379. #else
  380.    *q = 0 ;
  381.    if (mfmode && !modegiven) {
  382.       strcpy(q, " ") ;
  383.       strcat(q, mfmode) ;
  384.    }
  385. #endif /* AMIGA */
  386. #ifdef OS2
  387.    if ((_osmode == OS2_MODE) && filter)
  388.       (void)strcat(buf, quiet ? " >nul" : " 1>&2") ;
  389. #else
  390. #ifndef VMCMS   /* no filters and no need to print to stderr */
  391. #ifndef MVSXA
  392. #ifndef MSDOS
  393. #ifndef ATARIST
  394.    if (filter)
  395. #ifdef AMIGA
  396.       (void)strcat(buf, quiet ? " >NIL:" : "") ;
  397. #else
  398.       (void)strcat(buf, quiet ? " >/dev/null" : " 1>&2") ;
  399. #endif /* AMIGA */
  400. #endif
  401. #endif
  402. #endif
  403. #endif
  404. #endif
  405.  
  406. #if defined MSDOS || defined OS2
  407.    if (! quiet && mfjobname == (char *)NULL)
  408.       (void)fprintf(stderr, "- %s\n", buf) ;
  409.    if (dontmakefont == 0) {
  410.       if (mfjobname != (char *)NULL)
  411.          mfjobout(name,t);
  412.       else
  413.          (void)system(buf) ;
  414.    }
  415. #else
  416.    if (! quiet)
  417.       (void)fprintf(stderr, "- %s\n", buf) ;
  418.    if (dontmakefont == 0)
  419.       (void)system(buf) ;
  420. #endif
  421.    else {
  422.       static FILE *fontlog = 0 ;
  423.  
  424.       if (fontlog == 0) {
  425.          fontlog = fopen("missfont.log", "a") ;
  426.          if (fontlog != 0) {
  427.             (void)fprintf(stderr,
  428. #ifndef VMCMS
  429.                   "Appending font creation commands to missfont.log\n") ;
  430. #else
  431.   "\nMissing font data will be passed to DVIPS EXEC via MISSFONT LOG\n");
  432. #endif
  433.          }
  434.       }
  435.       if (fontlog != 0) {
  436.          (void)fprintf(fontlog, "%s\n", buf) ;
  437.          (void)fflush(fontlog) ;
  438.       }
  439.    }
  440. }
  441.  
  442. #ifdef AMIGA
  443. static char *expand_pkpath(struct amipk_info *amipk, int action)
  444. {
  445.    char *p = amipk->path; /* index into path */
  446.    char *s = amibuf;      /* index into amibuf */
  447.    char *t = NULL;        /* last path position before font name */
  448.    char *k = s + 256;     /* bottom of buffer */
  449.    Boolean subs = 0;      /* true if a substitution was performed */
  450.  
  451.    while (*p != PATHSEP && *p && s < k)
  452.    {
  453.       if (*p == '%')
  454.       {
  455.          subs = 1;
  456.          switch (*++p)
  457.          {
  458.             case 'b': case 'x':
  459.                (void)sprintf(s, "%d", amipk->xdpi);
  460.                break;
  461.  
  462.             case 'y':
  463.                (void)sprintf(s, "%d", amipk->ydpi);
  464.                break;
  465.  
  466.             case 'd':
  467.                (void)sprintf(s, "%d", amipk->dpi);
  468.                break;
  469.  
  470.             case 'f': case 's':
  471.                (void)strcpy(s, amipk->name);
  472.                t = s; /* save name position */
  473.                break;
  474.  
  475.             case 'm':
  476.                if (amipk->mode == 0)
  477.                {
  478.                   if (actualdpi == 180)
  479.                      amipk->mode = "nec";
  480.                   else if (actualdpi == 300)
  481.                      amipk->mode = "cx";
  482.                   else if (actualdpi == 360)
  483.                      amipk->mode = "nechi";
  484.                   else if (actualdpi == 400)
  485.                      amipk->mode = "nexthi";
  486.                   else if (actualdpi == 600)
  487.                      amipk->mode = "ljfour";
  488.                   else if (actualdpi == 635)
  489.                      amipk->mode = "linoone";
  490.                   else if (actualdpi == 1270)
  491.                      amipk->mode = "linohi";
  492.                   else if (actualdpi == 2540)
  493.                      amipk->mode = "linotzzh";
  494.                }
  495.                (void)strcpy(s, amipk->mode);
  496.                break ;
  497.  
  498.             case 'p':
  499.                (void)strcpy(s, "pk");
  500.                break ;
  501.  
  502.             case '%':
  503.                (void)strcpy(s, "%");
  504.                break;
  505.  
  506.             default:
  507.                error("! bad format character in pk path");
  508.          }
  509.          s = amibuf + strlen(amibuf);
  510.          if (*p) p++;
  511.       }
  512.       else *s++ = *p++; /* copy the path string */
  513.    }
  514.    *s = '\0'; /* terminate the string */
  515.  
  516.    if (subs)
  517.    {
  518.       int l;
  519.  
  520.       if (action == PKEXPAND_PKPART)
  521.       {
  522.          static char filepart[80];
  523.          l = strlen(amibuf);
  524.  
  525.          sprintf(filepart,"%d/%.32s.%dpk", amipk->dpi, amipk->name, amipk->dpi);
  526.          if ((s = strstr(amibuf,filepart)) != NULL)
  527.             *s = '\0';
  528.       }
  529.       else
  530.       {
  531.          if (action == PKEXPAND_ONE || action == PKEXPAND_TWO)
  532.          {
  533.             *t = '\0'; /* remove font name from pk path */
  534.             l = strlen(amibuf);
  535.  
  536.             if (l > 0 && amibuf[l-1] == DIRSEP)
  537.                amibuf[l-1] = '\0'; /* remove trailing DIRSEP */
  538.  
  539.             if (action == PKEXPAND_TWO)
  540.             {
  541.                if ((s = strrchr(amibuf, DIRSEP)) != NULL)
  542.                   *s = '\0';
  543.             }
  544.          }
  545.       }
  546.    }
  547.  
  548.    return(amibuf);
  549. }
  550. #endif
  551.