1 /* mktexpk.c (Web2C-7.5.5 --ak 2006)
2  * %%----------------------------------------
3  * % Special variables for mktexpk ( W32TeX )
4  * % ----------------------------------------
5  * % MAKETEXPK_STYLE = dosnames
6  * % -----------------------------------------
7  * % MAKETEXPK_TOP_DIR = $VARTEXFONTS
8  * % -----------------------------------------
9  * % MAKETEXPK_MODE = canonex
10  * % -----------------------------------------
11  * % MAKETEXPK_MODE_300 = cx
12  * % MAKETEXPK_MODE_400 = nexthi
13  * % MAKETEXPK_MODE_600 = canonex
14  * % etc.
15  * %%-----------------------------------------
16  *
17  * Usage: mktexpk [OPTIONS] name,
18  *   Create a PK font.
19  *
20  * --dpi DPI           use resolution DPI.
21  * --bdpi BDPI         use base resolution BDPI.
22  * --mag MAG           use magnificiation MAG.
23  * --mfmode MODE       use MODE as the METAFONT mode.
24  * --destdir DESTDIR   write fonts in DESTDIR (absolute path).
25  *
26  * The following old form is also supported:
27  * Usage: mktexmk name dpi bdpi mag [mode]
28  */
29 
30 #include <kpathsea/kpathsea.h>
31 
32 #include "dirutil.h"
33 #include "getdestdir.h"
34 #include "mktexupd.h"
35 
36 #define LLBUF 1024
37 #define LBUF  512
38 #define SBUF  256
39 #define TBUF  256
40 
41 /*
42 Global variables
43 */
44 
45 char *progname;
46 int UseAspectRatio = 0;
47 int FileName = 0;
48 double AspectRatio = 1.0;
49 
50 #define BBUFF_FUL     253
51 #define FFILE_END     254
52 #define LLINE_END     255
53 
54 static int
ffgets(char * buf,int size,FILE * fi)55 ffgets(char *buf, int size, FILE *fi)
56 {
57   char *p;
58   int  c;
59   int  n;
60 
61   n = 0;
62   p = buf;
63   *p = '\0';
64 
65   while(1) {
66     c = getc(fi);
67     if(c == 26)
68       continue;
69     n++;
70     if(c == EOF) {
71       n++;
72       *p++ = '\n';
73       *p = '\0';
74       return FFILE_END;
75     }
76     else if(c == 0x0d || c == 0x0a) {
77       n++;
78       *p++ = '\n';
79       *p = '\0';
80       if(c == 0x0d) {
81         c = getc(fi);
82         if(c != 0x0a)
83           ungetc(c, fi);
84       }
85       return LLINE_END;
86     }
87     else if(n == (size - 3)) {
88       *p++ = c; *p = '\0';
89       return BBUFF_FUL;
90     }
91     else *p++ = c;
92   }
93 }
94 
95 static int
isskip(char c)96 isskip(char c)
97 {
98   if((c == ' ') || (c == '\t'))
99     return 1;
100   else if((c == '<') || (c == '[')) {
101     FileName = 1;
102     return 1;
103   }
104   else
105     return 0;
106 }
107 
108 static void
skipchar(char ** p)109 skipchar(char **p)
110 {
111   while(isskip(**p))
112     (*p)++;
113 }
114 
115 static void
version(void)116 version (void)
117 {
118   fprintf (stderr, "%s, (C version 1.5 --ak 2006-2012)\n", progname);
119   fprintf (stderr, WEB2C_KPSE_VERSION "\n");
120 }
121 
122 static void
usage(void)123 usage (void)
124 {
125   fprintf (stderr, "Usage: %s [OPTIONS] NAME,\n\
126   Create a PK font.\n\n\
127 --dpi DPI           use resolution DPI.\n\
128 --bdpi BDPI         use base resolution BDPI.\n\
129 --mag MAG           use magnificiation MAG.\n\
130 --mfmode MODE       use MODE as the METAFONT mode.\n\
131 --destdir DESTDIR   write fonts in DESTDIR.\n", progname);
132 }
133 
134 static void
help(void)135 help (void)
136 {
137   fprintf (stderr, "Usage: %s [OPTIONS] NAME,\n\
138   Create a PK font.\n\n\
139 --dpi DPI           use resolution DPI.\n\
140 --bdpi BDPI         use base resolution BDPI.\n\
141 --mag MAG           use magnificiation MAG.\n\
142 --mfmode MODE       use MODE as the METAFONT mode.\n\
143 --destdir DESTDIR   write fonts in DESTDIR.\n\n\
144 Try to create a PK file for NAME at resolution DPI, with an assumed\n\
145 device base resolution of BDPI, and a Metafont `mag' of MAG. Use MODE\n\
146 for the METAFONT mode.  Use DESTDIR for the root of where to install\n\
147 into. DESTDIR must be an absolute directory name. If DESTDIR is not given,\n\
148 suitable directory is determined according to the TDS.\n\n\
149 Old form:\n\
150 Usage: %s name dpi bdpi mag [mode]\n\
151 is also supported.", progname, progname);
152 }
153 
154 
155 static void
tpkerr(const char * s)156 tpkerr (const char *s)
157 {
158   fprintf (stderr, "%s\n", s);
159 }
160 
161 
162 static void
relmem(char ** v)163 relmem (char **v)
164 {
165   int j;
166   for (j = 0; j < 4; j++)
167     free (v[j]);
168   return;
169 }
170 
171 
172 int
main(int ac,char ** av)173 main (int ac, char **av)
174 {
175   static char execfile[SBUF];
176   char rbuff[LBUF];
177   char buff[LBUF];
178   char cmd[LBUF];
179   char mfname[TBUF];
180   char tfname[TBUF];
181   char pkname[TBUF];
182 
183   char name[TBUF];
184   char dpi[TBUF];
185   char ydpi[TBUF];
186   char bdpi[TBUF];
187   char mag[TBUF];
188   char mode[TBUF];
189   char destdir[SBUF];
190 
191   char *arg[4];
192 
193   char currdir[SBUF];
194   char kpsedot[SBUF];
195   char *tmp;
196   int cdrive, tdrive;
197 
198   FILE *fr, *fw, *fnul, *tfmfileptr;
199 
200   int i, savo, savi, ret;
201   int style;
202   int issetdest;
203   int app;
204   int oldform;
205   int ps2pkok;
206   char *env;
207   char *p, *fpp;
208 
209   double Xdpi, Ydpi;
210 
211   char texname[TBUF], pfbname[TBUF], slant[TBUF], extend[TBUF], encname[TBUF];
212 
213   char texbindir[256];
214   char fullbin[512];
215 
216 /*
217  * style =  0 : MAKETEXPK_STYLE undefined or other than dosnames
218  * style =  1 : MAKETEXPK_STYLE = dosnames
219  */
220 
221 /*
222  * issetdest = 0 : no destdir
223  * issetdest = 1 : destdir
224  * issetdest = 2 : current working dir
225  */
226 
227 /*
228  * app = 0 : mf
229  * app = 1 : ps2pk
230  * app = 2 : gsftopk
231  * app = 3 : ttf2pk
232  * app = 4 : hbf2gf
233  */
234 
235 /*
236  * oldform = 0 : newform of the command line
237  * oldform = 1 : oldform of the command line
238  */
239 
240 /*
241  * TEMP | TMP | TMPDIR (necessary)
242  *
243  */
244 
245   tmp = getenv ("TEMP");
246   if (!tmp)
247     getenv ("TMP");
248   if (!tmp)
249     getenv ("TMPDIR");
250   if (!tmp) {
251     tpkerr ("Please define TEMP | TMP | TMPDIR.");
252     return (100);
253   }
254   tmp = xstrdup(tmp);
255 /*
256  * normalize directory separators
257  */
258 
259   for (fpp = tmp; *fpp; fpp++) {
260     if (*fpp == '\\')
261       *fpp = '/';
262     else if (IS_KANJI(fpp))
263       fpp++;
264   }
265 
266   for (i = 0; i < 4; i++)
267     arg[i] = (char *) malloc (SBUF);
268 
269   progname = av[0];
270   kpse_set_program_name (progname, NULL);
271 
272 /*
273  * get tex binary dir
274  *
275  */
276   p = kpse_var_value("SELFAUTOLOC");
277   if(p == 0) {
278      fprintf(stderr, "I cannot get SELFAUTOLOC\n");
279      exit(100);
280   }
281   strcpy(texbindir, p);
282   free(p);
283   for(p=texbindir; *p; p++) {
284      if(*p == '/') *p = '\\';
285   }
286   *p = '\\';
287   *(p+1) = '\0';
288 
289   if (ac < 2) {
290     usage ();
291     relmem (arg);
292     return (100);
293   }
294 
295   issetdest = 0;
296   ps2pkok = 0;
297 
298 /*
299  * oldform or newform ?
300  *
301  */
302 
303   if (av[1][0] == '-')
304     oldform = 0;
305   else
306     oldform = 1;
307 
308 
309 /*
310  * Old form of the command line
311  */
312 
313   if (oldform == 1) {
314     if (ac < 5) {
315       usage ();
316       relmem (arg);
317       return (100);
318     }
319     if((strlen(av[1]) > TBUF -1 ) ||
320        (strlen(av[2]) > TBUF -1 ) ||
321        (strlen(av[3]) > TBUF -1 ) ||
322        (strlen(av[4]) > TBUF -1 )) {
323       fprintf(stderr, "\nToo long a string.\n");
324       return 100;
325     }
326 
327     strcpy (name, av[1]);
328     strcpy (dpi, av[2]);
329     strcpy (bdpi, av[3]);
330     strcpy (mag, av[4]);
331     if (ac > 5) {
332       if(strlen(av[5]) > TBUF -1) {
333         fprintf(stderr, "\nToo long a string.\n");
334         return 100;
335       }
336       strcpy (mode, av[5]);
337     }
338     else
339       mode[0] = '\0';
340   } else {
341 /*
342  * New form of the command line
343  */
344     name[0] = dpi[0] = bdpi[0] = mag[0] = mode[0] = destdir[0] = '\0';
345     i = 1;
346     while (i < ac) {
347       if(strlen(av[i]) > TBUF - 1) {
348         fprintf(stderr, "\nToo long a string.\n");
349         return 100;
350       }
351       if (av[i][0] != '-') {
352         strcpy (name, av[i]);
353         break;
354       }
355       if (!strcmp (av[i], "--dpi") || !strcmp (av[i], "-dpi")) {
356         i++;
357         if (i >= ac) {
358           tpkerr ("Invarid arguments.");
359           relmem (arg);
360           return (100);
361         }
362         strcpy (dpi, av[i]);
363         i++;
364       } else if (!strcmp (av[i], "--bdpi") || !strcmp (av[i], "-bdpi")) {
365         i++;
366         if (i >= ac) {
367           tpkerr ("Invarid arguments.");
368           relmem (arg);
369           return (100);
370         }
371         strcpy (bdpi, av[i]);
372         i++;
373       } else if (!strcmp (av[i], "--mag") || !strcmp (av[i], "-mag")) {
374         i++;
375         if (i >= ac) {
376           tpkerr ("Invarid arguments.");
377           relmem (arg);
378           return (100);
379         }
380         strcpy (mag, av[i]);
381         i++;
382       } else if (!strcmp (av[i], "--mfmode") || !strcmp (av[i], "-mfmode")) {
383         i++;
384         if (i >= ac) {
385           tpkerr ("Invarid arguments.");
386           relmem (arg);
387           return (100);
388         }
389         strcpy (mode, av[i]);
390         i++;
391       } else if (!strcmp (av[i], "--destdir") || !strcmp (av[i], "-destdir")) {
392         i++;
393         if (i >= ac) {
394           tpkerr ("Invarid arguments.");
395           relmem (arg);
396           return (100);
397         }
398         strcpy (destdir, av[i]);
399         issetdest = 1;
400         i++;
401       } else if (!strcmp (av[i], "--version") || !strcmp (av[i], "-version")) {
402         version ();
403         relmem (arg);
404         return (0);
405       } else if (!strcmp (av[i], "--help") || !strcmp (av[i], "-help")) {
406         help ();
407         relmem (arg);
408         return (0);
409       } else {
410         tpkerr ("Argument error.");
411         relmem (arg);
412         return (100);
413       }
414     }
415   }                             /* End of command line analysis */
416 
417   env = kpse_var_value ("MAKETEXPK_STYLE");
418 
419   if ((env == NULL) || !(*env) || (env && strcmp (env, "dosnames"))) {
420     style = 0;
421   } else
422     style = 1;
423 
424 /*
425  * Default program is mf
426  */
427 
428   app = 0;
429 
430 /*
431  * check if mfmode and bdpi are consistent or not
432  */
433 
434   if (bdpi[0] && mode[0] && mode[0] != '/') {
435     FILE *frd;
436     char buff[128];
437     int len;
438 
439     strcpy (fullbin, texbindir);
440     strcat (fullbin, "mf-nowin.exe \"\\mode:=");
441     strcat (fullbin, mode);
442     strcat (fullbin, ";mode_setup;message");
443     strcat (fullbin, "(decimal round pixels_per_inch);");
444     strcat (fullbin, "end. <nul\"");
445 
446     frd = popen (fullbin, "r");
447     if (!frd) {
448       tpkerr ("I cannot find METAFONT.\n");
449       relmem (arg);
450       return (100);
451     }
452     (void) fgets (buff, 126, frd);
453     (void) fgets (buff, 126, frd);
454     pclose (frd);
455     remove ("mfput.log");
456     remove ("mfput.tfm");
457 
458     len = strlen (buff);
459     if (buff[len - 1] == '\n')
460       buff[len - 1] = '\0';
461     if (strcmp (bdpi, buff)) {
462       fprintf(stderr, "mode_dpi %s and bdpi %s are inconsistent.\n", buff, bdpi);
463       fprintf(stderr, "therefore I reset mfmode.\n");
464       mode[0] = '\0';
465     }
466   }
467 
468 /*
469  * determine mfmode if not given
470  */
471 
472   if (mode[0] == 0 || mode[0] == '/') {
473     if (bdpi[0] == 0) {
474       tpkerr ("Cannot determine the mode.");
475       tpkerr ("I will try other possibilities.");
476       app = 1;
477     } else {
478       strcpy (rbuff, "MAKETEXPK_MODE_");
479       strcat (rbuff, bdpi);
480       if ((env = kpse_var_value ("MAKETEXPK_MODE")) && *env)
481         strcpy (mode, env);
482       else if ((env = kpse_var_value (rbuff)))
483         strcpy (mode, env);
484       else if (!strcmp (bdpi, "85"))
485         strcpy (mode, "sun");
486       else if (!strcmp (bdpi, "100"))
487         strcpy (mode, "nextscrn");
488       else if (!strcmp (bdpi, "118"))
489         strcpy (mode, "pcprevw");
490       else if (!strcmp (bdpi, "160"))
491         strcpy (mode, "nectzo");
492       else if (!strcmp (bdpi, "180"))
493         strcpy (mode, "toshiba");
494       else if (!strcmp (bdpi, "200"))
495         strcpy (mode, "highfax");
496       else if (!strcmp (bdpi, "240"))
497         strcpy (mode, "canonlbp");
498       else if (!strcmp (bdpi, "300"))
499         strcpy (mode, "cx");
500       else if (!strcmp (bdpi, "320"))
501         strcpy (mode, "neclm");
502       else if (!strcmp (bdpi, "360"))
503         strcpy (mode, "epstylus");
504       else if (!strcmp (bdpi, "400"))
505         strcpy (mode, "nexthi");
506       else if (!strcmp (bdpi, "600"))
507         strcpy (mode, "ljfour");
508       else if (!strcmp (bdpi, "720"))
509         strcpy (mode, "epscszz");
510       else if (!strcmp (bdpi, "800"))
511         strcpy (mode, "lwpro");
512       else if (!strcmp (bdpi, "1000"))
513         strcpy (mode, "lmaster");
514       else if (!strcmp (bdpi, "1200"))
515         strcpy (mode, "ultre");
516       else if (!strcmp (bdpi, "1270"))
517         strcpy (mode, "linoone");
518       else if (!strcmp (bdpi, "1800"))
519         strcpy (mode, "vtftzz");
520       else if (!strcmp (bdpi, "2400"))
521         strcpy (mode, "supre");
522       else if (!strcmp (bdpi, "2540"))
523         strcpy (mode, "linotzzh");
524       else if (!strcmp (bdpi, "3386"))
525         strcpy (mode, "linolttz");
526       else if (!strcmp (bdpi, "8000"))
527         strcpy (mode, "dpdfezzz");
528       else if (!strcmp (bdpi, "9600"))
529         strcpy (mode, "ibx");
530       else {
531         tpkerr ("Cannot determine the mode.");
532         tpkerr ("I will try other possibilities.");
533         app = 1;
534       }
535     }
536   }
537 
538   if (env) free (env);
539 
540   if (name[0] == 0) {
541     tpkerr ("Font name is not given.");
542     relmem (arg);
543     return (100);
544   }
545 
546   if ((p = strrchr (name, '.')))
547     *p = '\0';
548 
549   strcpy (mfname, name);
550   strcat (mfname, ".mf");
551 
552   if (app == 0) {
553     if (!(p = kpse_var_value ("MFINPUTS"))) {
554       tpkerr ("Cannot get value of MFINPUTS.");
555       relmem (arg);
556       return (100);
557     }
558     free (p);
559     xputenv("MKTEXMF", "1");
560     if (!(p = kpse_find_file (mfname, kpse_mf_format, 1))) {
561       fprintf (stderr, "Cannot find %s .\n", mfname);
562       tpkerr ("I try ps2pk --> gsftopk --> ttf2pk --> hbf2gf.");
563       app = 1;
564     }
565   }
566 
567   if (app != 0) {
568     strcpy (mode, "modeless");
569     strcpy (tfname, name);
570     strcat (tfname, ".tfm");
571     if (!(p = kpse_var_value ("TFMFONTS"))) {
572       tpkerr ("Cannot get value of TFMFONTS.");
573       relmem (arg);
574       return (100);
575     }
576     free (p);
577 /*
578  I don't try to create nonexisting tfm here.
579 */
580     if (!(p = kpse_find_file (tfname, kpse_tfm_format, 0))) {
581       fprintf (stderr, "Cannot find %s .\n", tfname);
582       relmem (arg);
583       return 100;
584     }
585     tfmfileptr = fopen (p, "rb");
586     if (!tfmfileptr) {
587       fprintf (stderr, "I cannot open %s.\n", p);
588       relmem (arg);
589       return 100;
590     }
591     i = 256 * getc (tfmfileptr);
592     i += getc (tfmfileptr);
593     fclose (tfmfileptr);
594     if ((i == 9) || (i == 11)) {
595       fprintf (stderr, "Current font seems to be a Japanese one.\n");
596       fprintf (stderr, "I give up to create a PK font.\n");
597       relmem (arg);
598       return 100;
599     }
600   }
601 
602   if ((p[0] == '.') && (p[1] == '/') && (issetdest != 1))
603     issetdest = 2;
604 
605   fpp = _getcwd (currdir, SBUF);
606   if (!fpp) {
607     fprintf (stderr, "Failed to get current working directory.\n");
608     relmem (arg);
609     return (100);
610   }
611   for (fpp = currdir; *fpp; fpp++) {
612     if (*fpp == '\\')
613       *fpp = '/';
614     else if (IS_KANJI(fpp))
615       fpp++;
616   }
617 
618   i = strlen (currdir);
619   if (currdir[i - 1] == '/')
620     currdir[i - 1] = '\0';
621 
622   strcpy (kpsedot, "KPSE_DOT=.;");
623   strcat (kpsedot, currdir);
624   _putenv (kpsedot);
625 
626   if (issetdest == 2) {
627     strcpy (destdir, currdir);
628   }
629 
630   if (issetdest == 0) {
631     strcpy (arg[0], "Dummy");
632     strcpy (arg[1], "pk");
633     strcpy (arg[2], p);
634     strcpy (arg[3], mode);
635 
636     if (!(p = getdestdir (4, arg))) {
637       tpkerr ("Cannot get destination directory name.");
638       relmem (arg);
639       return (100);
640     }
641     strcpy (rbuff, p);
642   } else
643     strcpy (rbuff, destdir);
644 
645 /*
646  * Change backslash into slash
647  */
648 
649   for (p = rbuff; *p; p++) {
650     if (*p == '\\')
651       *p = '/';
652     else if (IS_KANJI(p))
653       p++;
654   }
655 
656   p = rbuff;
657   i = strlen (p);
658   if (p[i - 1] == '/')
659     p[i - 1] = '\0';
660 
661   if (issetdest) {
662     if (!is_dir (p)) {
663       fprintf (stderr, "Destination %s is not found.\n", p);
664       relmem (arg);
665       return (100);
666     }
667   } else if (!is_dir (p)) {
668     if (make_dir (p)) {
669       tpkerr ("Error in make_dir.");
670       relmem (arg);
671       return (100);
672     }
673   }
674 
675   strcpy (buff, p);
676   p = buff;
677 
678   i = strlen (p);
679 
680   if (p[i - 1] != '/')
681     strcat (p, "/");
682 
683   if (dpi[0] == 0) {
684     tpkerr ("Cannot determine DPI.");
685     relmem (arg);
686     return (100);
687   }
688 
689   if (style == 1 && issetdest != 2) {   /* dosnames */
690     strcat (p, "dpi");
691     strcat (p, dpi);
692     if (!is_dir (p)) {
693       if (make_dir (p)) {
694         tpkerr ("Error in make_dir.");
695         relmem (arg);
696         return (100);
697       }
698     }
699     strcat (p, "/");
700   }
701 
702   strcat (p, name);
703   strcat (p, ".");
704 
705   if (style != 1 || issetdest == 2)
706     strcat (p, dpi);            /* long suffix */
707   strcat (p, "pk");
708 
709 /* Now buff and p is the full path name of pk file */
710 /* check the existence of pk file */
711 
712   if (_access (p, 0) == 0) {
713     fprintf (stderr, "%s exists.\n", p);
714     relmem (arg);
715     printf ("%s\n", p);
716     return (0);
717   }
718 
719 /*
720  * Go to the temporary directory
721  */
722 
723   cdrive = _getdrive ();
724   if (tmp[1] == ':') {
725     tdrive = tolower (*tmp) - 'a' + 1;
726     _chdrive (tdrive);
727   }
728   _chdir (tmp);
729 
730 /*
731  * save stdout and stdin
732  */
733   savo = _dup (fileno (stdout));
734   savi = _dup (fileno (stdin));
735 
736 /*
737  * connect stdout to stderr
738 */
739   _dup2 (fileno (stderr), fileno (stdout));
740 
741 /*
742  * connect stdin to nul
743  */
744   if (!(fnul = fopen ("nul", "rb"))) {
745     fprintf (stderr, "Cannot open nul device to read.\n");
746     _chdrive (cdrive);
747     _chdir (currdir);
748     relmem (arg);
749     return (100);
750   }
751   _dup2 (fileno (fnul), fileno (stdin));
752 
753 /*
754  * pkname is the filename of PK font
755  */
756   sprintf (pkname, "%s.%spk", name, dpi);
757 
758   if (app == 0) {
759 /*
760  * METAFONT command line
761  */
762     if (mag[0] == 0) {
763       tpkerr ("Cannot determine MAG.");
764       _chdrive (cdrive);
765       _chdir (currdir);
766       relmem (arg);
767       return (100);
768     }
769     sprintf (cmd,
770        "--progname=mf --base=mf \\mode:=%s; \\mag:=%s; nonstopmode; input %s;",
771         mode, mag, name);
772 
773     strcpy (execfile, "mf-nowin.exe");
774     fprintf (stderr, "%s %s\n", execfile, cmd);
775     strcpy(fullbin, texbindir);
776     strcat(fullbin, execfile);
777     (void) _spawnlp (_P_WAIT, fullbin, execfile, cmd, NULL);
778 
779     sprintf (cmd, "%s.%sgf", name, dpi);
780 
781 /*
782  * check the consistency
783  */
784     if (_access (cmd, 0) != 0) {
785       tpkerr ("Failed to make gf font by METAFONT.");
786       _chdrive (cdrive);
787       _chdir (currdir);
788       relmem (arg);
789       return (100);
790     }
791 
792 /*
793  * Change gf into pk
794  */
795     strcpy (execfile, "gftopk.exe");
796     fprintf (stderr, "%s %s %s\n", execfile, cmd, pkname);
797     strcpy(fullbin, texbindir);
798     strcat(fullbin, execfile);
799     (void) _spawnlp (_P_WAIT, fullbin, execfile, cmd, pkname, NULL);
800 
801     if (_access (pkname, 0) != 0) {
802       tpkerr ("Failed to make pk from gf.");
803       _chdrive (cdrive);
804       _chdir (currdir);
805       relmem (arg);
806       return (100);
807     }
808 
809 /*
810  * erase gf file
811  */
812     remove (cmd);
813 
814 /*
815  * erase log file
816  */
817     sprintf (cmd, "%s.log", name);
818     remove (cmd);
819 /*
820  * erase tfm file
821  */
822     sprintf (cmd, "%s.tfm", name);
823     remove (cmd);
824 
825     goto finale;
826   }
827 
828 /*
829  * app = 1 : ps2pk --> gsftopk --> ttf2pk --> hbf2gf
830  */
831 
832   p = kpse_find_file ("pspksupp.map", kpse_fontmap_format, 0);
833   if(p) {
834     fr = fopen (p, "r");        /* Read pspksupp.map */
835     free (p);
836 
837     if (!fr) {
838       tpkerr ("Cannot open pspksupp.map to read.");
839       ps2pkok = 0;
840       goto do_ps2pk;
841     }
842 
843     while (fgets (rbuff, SBUF, fr)) {
844       if (rbuff[0] == '%' || rbuff[0] == '#' || rbuff[0] == '\n')
845         continue;
846       texname[0] = pfbname[0] = slant[0] = extend[0] = encname[0] = '\0';
847       i = sscanf (rbuff, "%s %s %s %s %s", texname, pfbname, slant, extend,
848                   encname);
849       if (i == 2 && !strncmp (texname, "AspectRatio", 11)) {
850         if (!sscanf (pfbname, "%lf", &AspectRatio)) {
851           tpkerr ("File format of pspksupp.map is wrong.");
852           fclose (fr);
853           ps2pkok = 0;
854           goto do_ps2pk;
855         }
856         UseAspectRatio = 1;
857         continue;
858       } else if (i > 0 && !stricmp (texname, name)) {
859         p = kpse_var_value ("T1FONTS");
860         if (!p) {
861           tpkerr ("T1FONTS is not defined.");
862           ps2pkok = 0;
863           break;
864         }
865         free (p);
866         p = kpse_find_file (pfbname, kpse_type1_format, 0);
867         if (!p) {
868           fprintf (stderr, "%s is not found.\n", pfbname);
869           ps2pkok = 0;
870           break;
871         }
872         free (p);
873         ps2pkok = 1;
874         if(bdpi[0] == 0)
875           i--;
876         break;
877       }
878     }
879     fclose (fr);
880     goto do_ps2pk;
881   } else {
882     char *q;
883     char a[SBUF];
884     char b[SBUF];
885     char psname[SBUF];
886     char pscommand[SBUF];
887     double slantval, extendval;
888 
889     texname[0] = pfbname[0] = encname[0] = '\0';
890     a[0] = b[0] = psname[0] = pscommand[0] = '\0';
891     FileName = 0;
892     strcpy(slant, "0");
893     strcpy(extend, "1");
894 
895     ps2pkok = 0;
896 
897     p = kpse_find_file ("ps2pk.map", kpse_fontmap_format, 0);
898     if(!p) {
899       tpkerr("Necessary map file for ps2pk is not found.");
900       goto do_ps2pk;
901     }
902     fr = fopen(p,"rb");
903     free(p);
904     if (!fr) {
905       tpkerr ("Cannot open ps2pk.map to read.");
906       goto do_ps2pk;
907     }
908     while ((ret=ffgets (rbuff, LBUF, fr)) != FFILE_END) {
909       if(ret == BBUFF_FUL) {
910         fprintf(stderr, "A line in ps2pk.map seems to be too long.\n");
911         fprintf(stderr, "I try to continue. But something may be wrong.\n");
912       }
913       p = rbuff;
914       skipchar(&p);
915       if((*p == '%') || (*p == '#') || (*p == '\n'))
916         continue;
917       q = texname;
918       while(!isskip(*p) && (*p != '\n'))
919         *q++ = *p++;
920       *q = '\0';
921       if(stricmp(texname, name))
922         continue;
923       skipchar(&p);
924       if((*p == '%') || (*p == '#') || (*p == '\n')) {
925         fprintf(stderr, "Incorrect line in \"ps2pk.map\".\n");
926         break;
927       }
928       if(FileName)
929         q = a;
930       else
931         q = psname;
932       while(!isskip(*p) && (*p != '\n'))
933         *q++ = *p++;
934       *q = '\0';
935       skipchar(&p);
936 /*
937 skip flag
938 */
939       if(!FileName) {
940         while(isdigit(*p))
941           p++;
942         skipchar(&p);
943       }
944       if((*p == '%') || (*p == '#') || (*p == '\n')) {
945         tpkerr("I cannot use ps2pk due to lack of data.");
946         break;
947       }
948       if(*p == '\"') {
949         q = pscommand;
950         *q++ = *p++;
951         while(*p != '\"')
952           *q++ = *p++;
953         *q++ = *p++;
954         *q = '\0';
955         skipchar(&p);
956         if((*p == '%') || (*p == '#') || (*p == '\n'))
957           break;
958       }
959       if(FileName && a[0] == '\0')
960         q = a;
961       else if(FileName && b[0] == '\0')
962         q = b;
963       else {
964         tpkerr("Incorrect line in ps2pk.map.");
965         break;
966       }
967       while(!isskip(*p) && (*p != '\n'))
968         *q++ = *p++;
969       *q = '\0';
970       skipchar(&p);
971       if((*p == '%') || (*p == '#') || (*p == '\n'))
972         break;
973       if(*p == '\"') {
974         q = pscommand;
975         *q++ = *p++;
976         while(*p != '\"')
977           *q++ = *p++;
978         *q++ = *p++;
979         *q = '\0';
980         skipchar(&p);
981         if((*p == '%') || (*p == '#') || (*p == '\n'))
982           break;
983       }
984       if (FileName && a[0] == '\0')
985         q = a;
986       else if (FileName && b[0] == '\0')
987         q = b;
988       else {
989         fprintf(stderr, "Incorrect line in \"ps2pk.map\".\n");
990         break;
991       }
992       while(!isskip(*p) && (*p != '\n'))
993         *q++ = *p++;
994       *q = '\0';
995       skipchar(&p);
996       if((*p == '%') || (*p == '#') || (*p == '\n'))
997         break;
998       if(*p == '\"') {
999         q = pscommand;
1000         *q++ = *p++;
1001         while(*p != '\"')
1002           *q++ = *p++;
1003         *q++ = *p++;
1004         *q = '\0';
1005         skipchar(&p);
1006         if((*p == '%') || (*p == '#') || (*p == '\n'))
1007           break;
1008       }
1009       skipchar(&p);
1010       if((*p == '%') || (*p == '#') || (*p == '\n'))
1011         break;
1012       else {
1013         fprintf(stderr, "Incorrect line in \"ps2pk.map\".\n");
1014         break;
1015       }
1016     }
1017     fclose(fr);
1018 
1019     if(pscommand[0]) {
1020       p = strstr(pscommand, "SlantFont");
1021       if(p) {
1022         p--;
1023         while(*p == ' ' || *p == '\t') p--;
1024         while(*p != ' ' && *p != '\t' && *p != '\"') p--;
1025         p++;
1026         sscanf(p, "%lf SlantFont", &slantval);
1027         sprintf(slant, "%lf", slantval);
1028         p = slant + strlen(slant) - 1;
1029         while(*p == '0') {
1030           *p = '\0';
1031           p--;
1032         }
1033       }
1034       p = strstr(pscommand, "ExtendFont");
1035       if(p) {
1036         p--;
1037         while(*p == ' ' || *p == '\t') p--;
1038         while(*p != ' ' && *p != '\t' && *p != '\"') p--;
1039         p++;
1040         sscanf(p, "%lf ExtendFont", &extendval);
1041         sprintf(extend, "%lf", extendval);
1042         p = extend + strlen(extend) - 1;
1043         while(*p == '0') {
1044           *p = '\0';
1045           p--;
1046         }
1047       }
1048     }
1049     if(a[0]) {
1050       p = strrchr(a, '.');
1051       if(p && !stricmp(p, ".enc")) {
1052         *p = '\0';
1053         strcpy(encname, a);
1054       }
1055       else if(p && !stricmp(p, ".pfb")) {
1056         *p = '\0';
1057         strcpy(pfbname, a);
1058       }
1059     }
1060     if(b[0]) {
1061       p = strrchr(b, '.');
1062       if(p && !stricmp(p, ".enc")) {
1063         *p = '\0';
1064         strcpy(encname, b);
1065       }
1066       else if(p && !stricmp(p, ".pfb")) {
1067         *p = '\0';
1068         strcpy(pfbname, b);
1069       }
1070     }
1071     if(pfbname[0] == '\0')
1072       goto do_ps2pk;
1073     p = kpse_find_file (pfbname, kpse_type1_format, 0);
1074     if(!p)
1075       goto do_ps2pk;
1076     free(p);
1077     ps2pkok = 1;
1078     if(encname[0] && bdpi[0]) {
1079       i = 5;
1080     } else if(!encname[0] && !bdpi[0]) {
1081       i = 3;
1082     } else {
1083       i = 4;
1084     }
1085   }
1086 
1087  do_ps2pk:
1088 
1089   if (ps2pkok) {
1090     if (UseAspectRatio) {
1091       sscanf (dpi, "%lf", &Xdpi);
1092       Ydpi = Xdpi * AspectRatio;
1093       sprintf (ydpi, "%d", (int) Ydpi);
1094     } else
1095       strcpy (ydpi, dpi);
1096 
1097     if (i == 3) {
1098       sprintf (cmd, "-X%s -Y%s -S%s -E%s %s %s",
1099                dpi, ydpi, slant, extend, pfbname, pkname);
1100     } else if (i == 4 && bdpi[0]) {
1101       sprintf (cmd, "-X%s -Y%s -R%s -S%s -E%s %s %s",
1102                dpi, ydpi, bdpi, slant, extend, pfbname, pkname);
1103     } else if (i == 4 && encname[0]) {
1104       sprintf (cmd, "-e%s -X%s -Y%s -S%s -E%s %s %s",
1105                encname, dpi, ydpi, slant, extend, pfbname, pkname);
1106     } else if (i == 5) {
1107       sprintf (cmd, "-e%s -X%s -Y%s -R%s -S%s -E%s %s %s",
1108                encname, dpi, ydpi, bdpi, slant, extend, pfbname, pkname);
1109     } else {
1110       tpkerr ("File format of pspksupp.map is wrong.");
1111       goto do_gsftopk;
1112     }
1113 
1114     strcpy (execfile, "ps2pk.exe");
1115     fprintf (stderr, "%s %s\n", execfile, cmd);
1116     strcpy(fullbin, texbindir);
1117     strcat(fullbin, execfile);
1118     (void) _spawnlp (_P_WAIT, fullbin, execfile, cmd, NULL);
1119 
1120     if (_access (pkname, 0) != 0) {
1121       tpkerr ("ps2pk failed to make pk font.");
1122       goto do_gsftopk;
1123     }
1124     goto finale;
1125   }
1126 
1127 /*
1128  * ps2pk is impossible to use
1129  */
1130 
1131  do_gsftopk:
1132 
1133   tpkerr ("ps2pk cannot be used.");
1134   tpkerr ("I try gsftopk.");
1135   app = 2;
1136 
1137   strcpy (execfile, "gsftopk.exe");
1138   fprintf (stderr, "%s %s %s\n", execfile, name, dpi);
1139   strcpy(fullbin, texbindir);
1140   strcat(fullbin, execfile);
1141   (void) _spawnlp (_P_WAIT, fullbin, execfile, name, dpi, NULL);
1142 
1143   if (_access (pkname, 0) != 0) {
1144     tpkerr ("gsftopk cannot be used.");
1145     tpkerr ("Next I try ttf2pk.");
1146     app = 3;
1147     strcpy (execfile, "ttf2pk.exe");
1148     fprintf (stderr, "%s -q %s %s\n", execfile, name, dpi);
1149     strcpy(fullbin, texbindir);
1150     strcat(fullbin, execfile);
1151     (void) _spawnlp (_P_WAIT, fullbin, execfile, "-q", name, dpi, NULL);
1152 
1153     if (_access (pkname, 0) != 0) {
1154       tpkerr ("ttf2pk failed.");
1155       tpkerr ("Finally I try hbf2gf.");
1156       app = 4;
1157       strcpy (execfile, "hbf2gf.exe");
1158       fprintf (stderr, "%s -q -p %s %s\n", execfile, name, dpi);
1159       strcpy(fullbin, texbindir);
1160       strcat(fullbin, execfile);
1161       (void) _spawnlp (_P_WAIT, fullbin, execfile, "-q -p", name, dpi, NULL);
1162 
1163       sprintf (cmd, "%s.%sgf", name, dpi);
1164       if (_access (cmd, 0) != 0) {
1165         tpkerr ("All trials failed.");
1166         _chdrive (cdrive);
1167         _chdir (currdir);
1168         relmem (arg);
1169         return (100);
1170       }
1171       strcpy (execfile, "gftopk.exe");
1172       fprintf (stderr, "%s %s %s\n", execfile, cmd, pkname);
1173       strcpy(fullbin, texbindir);
1174       strcat(fullbin, execfile);
1175       (void) _spawnlp (_P_WAIT, fullbin, execfile, cmd, pkname, NULL);
1176 
1177       if (_access (pkname, 0) != 0) {
1178         tpkerr ("All trials failed.");
1179         _chdrive (cdrive);
1180         _chdir (currdir);
1181         relmem (arg);
1182         return (100);
1183       }
1184       remove (cmd);
1185     }
1186   }
1187 
1188  finale:
1189 
1190 /*
1191  * return to original stdout and stdin
1192  */
1193   _dup2 (savo, fileno (stdout));
1194   close (savo);
1195   _dup2 (savi, fileno (stdin));
1196   close (savi);
1197 
1198 /*
1199  * close nul device
1200  */
1201   fclose (fnul);
1202 
1203 /*
1204  * copy the pk file
1205  */
1206   if (!(fr = fopen (pkname, "rb"))) {
1207     fprintf (stderr, "Cannot open %s to read.\n", pkname);
1208     _chdrive (cdrive);
1209     _chdir (currdir);
1210     relmem (arg);
1211     return (100);
1212   }
1213 
1214   if (!(fw = fopen (buff, "wb"))) {
1215     fprintf (stderr, "Cannot open %s to write.\n", buff);
1216     _chdrive (cdrive);
1217     _chdir (currdir);
1218     relmem (arg);
1219     return (100);
1220   }
1221 
1222   while ((i = fread (rbuff, 1, LBUF, fr)))
1223     fwrite (rbuff, 1, i, fw);
1224 
1225   fclose (fr);
1226   fclose (fw);
1227   remove (pkname);
1228 
1229   relmem (arg);
1230 
1231 /*
1232  * update ls-R if it exists
1233  */
1234   mktexupd (buff);
1235 
1236 /*
1237  * tell kpathsea
1238  */
1239 
1240   printf ("%s\n", buff);
1241   _chdrive (cdrive);
1242   _chdir (currdir);
1243 
1244   return (0);
1245 }
1246