~ubuntu-branches/ubuntu/precise/vflib3/precise

« back to all changes in this revision

Viewing changes to src/vflmkt1.c

  • Committer: Bazaar Package Importer
  • Author(s): Masayuki Hatta
  • Date: 2002-04-15 12:10:24 UTC
  • Revision ID: james.westby@ubuntu.com-20020415121024-cann32wucyfbq22f
Tags: upstream-3.6.12
ImportĀ upstreamĀ versionĀ 3.6.12

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * vflmkt1.c 
 
3
 * - a vflibcap entry generator for PostScript Type 1 fonts
 
4
 *
 
5
 * - This program read "font map" file (e.g. psfonts.map) of dvips,
 
6
 *   and prints vflibcap entries to standard output.
 
7
 *
 
8
 * - Useful for generating vflibcap for TeX DVI drivers
 
9
 *
 
10
 *
 
11
 * by Hirotsugu Kakugawa
 
12
 *
 
13
 *   2 May 2001   
 
14
 *   3 May 2001  Support for kpathsea. 
 
15
 *   9 May 2001  Support for font file substitution by Ghostscript fonts
 
16
 *  10 May 2001  Support for font class geneeration, afm and encoding
 
17
 *               vector directories.
 
18
 */
 
19
/*
 
20
 * Copyright (C) 2001  Hirotsugu Kakugawa. 
 
21
 * All rights reserved.
 
22
 *
 
23
 * This program is free software; you can redistribute it and/or modify
 
24
 * it under the terms of the GNU General Public License as published by
 
25
 * the Free Software Foundation; either version 2, or (at your option)
 
26
 * any later version.
 
27
 * 
 
28
 * This program is distributed in the hope that it will be useful,
 
29
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
30
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
31
 * GNU General Public License for more details.
 
32
 * 
 
33
 * You should have received a copy of the GNU General Public License
 
34
 * along with this program; if not, write to the Free Software
 
35
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 
36
 */
 
37
 
 
38
 
 
39
#include "config.h"
 
40
#include "with.h"
 
41
#include <stdio.h>
 
42
#include <stdlib.h>
 
43
#include <ctype.h>
 
44
#include <unistd.h>
 
45
#ifdef HAVE_STRING_H
 
46
#include <string.h>
 
47
#endif
 
48
#include <sys/param.h>
 
49
#include <sys/time.h>
 
50
 
 
51
#ifdef WITH_KPATHSEA
 
52
# include  "kpathsea/kpathsea.h"
 
53
#endif
 
54
 
 
55
#include  "VFlib-3_6.h"
 
56
#include  "VFsys.h"
 
57
#include  "vflibcap.h"
 
58
#include  "texfonts.h"
 
59
#include  "t1.h"
 
60
#include  "fsearch.h"
 
61
#include  "vflmklib.h"
 
62
 
 
63
 
 
64
 
 
65
void    gen_class_deafult(void);
 
66
void    translate(FILE*,FILE*,char*);
 
67
int     get_token(char *s, char *b, int *x);
 
68
void    emit(void);
 
69
 
 
70
int     parse_pscmd(char *cmds, double *val);
 
71
 
 
72
void    read_gs_fontmap(void);
 
73
char   *find_gs_font(char *f);
 
74
int     query_gs_db(char *s);
 
75
 
 
76
double  tfm_read_ds(char *name);
 
77
 
 
78
 
 
79
 
 
80
 
 
81
#define MAXPSCODE   4
 
82
char  texfont[BUFSIZ];
 
83
char  psfont[BUFSIZ];
 
84
char  t1font[BUFSIZ];
 
85
char  encfile[BUFSIZ];
 
86
char  pscode[MAXPSCODE][BUFSIZ];
 
87
 
 
88
char  *mode  = DEFAULT_KPS_MODE;
 
89
char  *dpi   = NULL;
 
90
int    dpi_i = DEFAULT_KPS_DPI;
 
91
 
 
92
#define NDIRS    64
 
93
int   n_t1f; 
 
94
char  *t1_fontdirs[NDIRS];
 
95
int   n_t1e; 
 
96
char  *t1_encdirs[NDIRS];
 
97
int   n_t1a; 
 
98
char  *t1_afmdirs[NDIRS];
 
99
int   n_gsf; 
 
100
char  *gs_fontdirs[NDIRS];
 
101
char  *gs_fontmap;
 
102
 
 
103
#define NGSFONTS   1024
 
104
char *gs_db_f[NGSFONTS];
 
105
char *gs_db_d[NGSFONTS];
 
106
int   i_db; 
 
107
 
 
108
char *cmdline = NULL; 
 
109
char *font_suffix = "";
 
110
int   gen_font = 0;
 
111
int   with_tfm = 0;
 
112
int   exist_only = 0; 
 
113
 
 
114
 
 
115
 
 
116
 
 
117
int 
 
118
main(int argc, char **argv)
 
119
{
 
120
  int     nmaps, i;
 
121
  FILE   *fp;
 
122
  int    xargc;
 
123
  char **xargv;
 
124
#ifdef WITH_KPATHSEA
 
125
  int    f;
 
126
  char   *progname, *s;
 
127
#endif
 
128
 
 
129
  dpi = malloc(256);
 
130
  sprintf(dpi, "%d", dpi_i);
 
131
 
 
132
  cmdline = copy_cmdline(argc, argv);
 
133
 
 
134
  n_t1f = n_t1a = n_t1e = 0;
 
135
  for (i = 0; i < NDIRS; i++){
 
136
    t1_fontdirs[i] = NULL;
 
137
    t1_afmdirs[i]  = NULL;
 
138
    t1_encdirs[i]  = NULL;
 
139
    gs_fontdirs[i] = NULL;
 
140
  }
 
141
  gs_fontmap = NULL;
 
142
 
 
143
  i_db = 0;
 
144
  for (i = 0; i < NGSFONTS; i++){
 
145
    gs_db_f[i] = NULL;
 
146
    gs_db_d[i] = NULL;
 
147
  }
 
148
 
 
149
  xargc = argc; 
 
150
  xargv = argv;
 
151
 
 
152
  nmaps = 0;
 
153
  for (xargc--,xargv++; xargc > 0; xargc--,xargv++){
 
154
    if ((strcmp(*xargv, "--help") == 0)
 
155
        || (strcmp(*xargv, "-help") == 0)){
 
156
      printf("vflmkt1: generates vflibcap entries for Type1 fonts from\n");
 
157
      printf("         a 'font map' file of dvips\n");
 
158
      printf("Usage: vflmkt1 [options] [map-file ...]\n");
 
159
      printf("Options\n");
 
160
      printf("  -d DIR   : Type 1 font file directory\n");
 
161
      printf("  -a DIR   : AFM file directory\n");
 
162
      printf("  -e DIR   : T1Lib encoding vector directory\n");
 
163
      printf("  -gf DIR  : Ghostscript font file directory\n");
 
164
      printf("  -gm FILE : Ghostscript font map file 'Fontmap' path\n");
 
165
      printf("  -r DPI   : Default device resolution\n");
 
166
      printf("  -n MODE  : Device mode name for kpathsea\n");
 
167
      printf("  -f       : Generate font entries\n");
 
168
      printf("  -z       : Generate font entries whose font file exists\n");
 
169
      printf("  -t       : Generate font entries with TeX TFM file\n");
 
170
      printf("  -x STR   : String added to the end of font name\n");
 
171
 
 
172
#ifdef WITH_KPATHSEA
 
173
      printf("Example: vflmkt1 -d TEXMF -f psfonts.map\n");
 
174
#else
 
175
      printf("Example: vflmkt1 -d TEXMF -f /usr/local/share/texmf/dvips/psfonts.map\n");
 
176
#endif
 
177
      exit(0);
 
178
 
 
179
    } else if (strcmp(*xargv, "-r") == 0){
 
180
      xargv++; xargc--;
 
181
      check_argc(xargc);
 
182
      dpi = strdup(*xargv);
 
183
 
 
184
    } else if (strcmp(*xargv, "-n") == 0){
 
185
      /* mode */
 
186
      xargv++; xargc--;
 
187
      check_argc(xargc);
 
188
      mode = x_strdup(*xargv);
 
189
 
 
190
    } else if (strcmp(*xargv, "-d") == 0){
 
191
      /* type 1 font dir */
 
192
      if (n_t1f == NDIRS){
 
193
        fprintf(stderr, "Too many Type 1 font directories\n");
 
194
        exit(1);
 
195
      }
 
196
      xargv++; xargc--;
 
197
      check_argc(xargc);
 
198
      t1_fontdirs[n_t1f++] = x_strdup(*xargv);
 
199
 
 
200
    } else if (strcmp(*xargv, "-a") == 0){
 
201
      /* afm dir */
 
202
      if (n_t1a == NDIRS){
 
203
        fprintf(stderr, "Too many AFM directories\n");
 
204
        exit(1);
 
205
      }
 
206
      xargv++; xargc--;
 
207
      check_argc(xargc);
 
208
      t1_afmdirs[n_t1a++] = x_strdup(*xargv);
 
209
 
 
210
    } else if (strcmp(*xargv, "-e") == 0){
 
211
      /* encoding vector dir */
 
212
      if (n_t1e == NDIRS){
 
213
        fprintf(stderr, "Too many T1Lib Encoding Vector directories\n");
 
214
        exit(1);
 
215
      }
 
216
      xargv++; xargc--;
 
217
      check_argc(xargc);
 
218
      t1_encdirs[n_t1e++] = x_strdup(*xargv);
 
219
 
 
220
    } else if (strcmp(*xargv, "-gf") == 0){
 
221
      /* gs font dir */
 
222
      if (n_gsf == NDIRS){
 
223
        fprintf(stderr, "Too many Ghostscript font directories\n");
 
224
        exit(1);
 
225
      }
 
226
      xargv++; xargc--;
 
227
      check_argc(xargc);
 
228
      gs_fontdirs[n_gsf++] = x_strdup(*xargv);
 
229
 
 
230
    } else if (strcmp(*xargv, "-gm") == 0){
 
231
      /* gs font map */
 
232
      xargv++; xargc--;
 
233
      check_argc(xargc);
 
234
      gs_fontmap = x_strdup(*xargv);
 
235
 
 
236
    } else if (strcmp(*xargv, "-f") == 0){
 
237
      gen_font = 1;
 
238
 
 
239
    } else if (strcmp(*xargv, "-z") == 0){
 
240
      exist_only = 1;
 
241
 
 
242
    } else if (strcmp(*xargv, "-t") == 0){
 
243
      with_tfm = 1;
 
244
 
 
245
    } else if (strcmp(*xargv, "-x") == 0){
 
246
      xargv++; xargc--;
 
247
      check_argc(xargc);
 
248
      font_suffix = strdup(*xargv);
 
249
 
 
250
    } else {
 
251
      if (*xargv[0] == '-'){
 
252
        fprintf(stderr, "vflmkt1: unknown option %s\n", *xargv);
 
253
        exit(1);
 
254
      }
 
255
      break;
 
256
 
 
257
    }
 
258
  }
 
259
 
 
260
#ifdef WITH_KPATHSEA
 
261
  progname = NULL;
 
262
  kpse_set_program_name (argv[0], progname);
 
263
  kpse_init_prog (uppercasify(kpse_program_name), atoi(dpi), mode, NULL);
 
264
  for (f = 0; f < kpse_last_format; f++) {
 
265
    kpse_init_format(f);
 
266
  }
 
267
#endif
 
268
 
 
269
  banner("Type 1", "vflmkt1", cmdline);
 
270
 
 
271
  read_gs_fontmap();
 
272
 
 
273
  gen_class_deafult();    
 
274
 
 
275
  for ( ; xargc > 0; xargc--,xargv++){
 
276
    nmaps++;
 
277
    
 
278
    s = *xargv;
 
279
    if ((fp = fopen(s, "r")) == NULL){
 
280
#ifdef WITH_KPATHSEA
 
281
      s = kpse_find_file(*xargv, kpse_dvips_config_format, 0);
 
282
      if (s == NULL){ 
 
283
        fprintf(stderr, "Cannot find: %s\n", *xargv);
 
284
        exit(1);
 
285
      }
 
286
      if (s != NULL){ 
 
287
        if ((fp = fopen(s, "r")) == NULL){
 
288
#endif
 
289
          fprintf(stderr, "Cannot open: %s\n", *xargv);
 
290
          exit(1);
 
291
#ifdef WITH_KPATHSEA
 
292
        }
 
293
      }
 
294
#endif
 
295
    }
 
296
    translate(fp, stdout, s);
 
297
    fclose(fp);
 
298
  }
 
299
  
 
300
  if (nmaps == 0){
 
301
    translate(stdin, stdout, "<stdard input>");
 
302
  }
 
303
 
 
304
  printf("\n");
 
305
 
 
306
  return 0;
 
307
}
 
308
 
 
309
 
 
310
 
 
311
void
 
312
gen_class_deafult(void)
 
313
{
 
314
  int   i;
 
315
 
 
316
  printf("(%s %s", 
 
317
         VF_CAPE_VFLIBCAP_CLASS_DEFAULT_DEFINITION, FONTCLASS_NAME);
 
318
  printf("\n  (%s", VF_CAPE_FONT_DIRECTORIES);
 
319
  for (i = 0; i < n_t1f; i++)
 
320
    printf("\n       \"%s\"", t1_fontdirs[i]);
 
321
  for (i = 0; i < n_gsf; i++)
 
322
    printf("\n       \"%s\"", gs_fontdirs[i]);
 
323
  printf(")");
 
324
  printf("\n  (%s", VF_CAPE_TYPE1_AFM_DIRECTORIES);
 
325
  for (i = 0; i < n_t1a; i++)
 
326
    printf("\n       \"%s\"", t1_afmdirs[i]);
 
327
  printf(")");
 
328
  printf("\n  (%s", VF_CAPE_TYPE1_ENC_DIRECTORIES);
 
329
  for (i = 0; i < n_t1e; i++)
 
330
    printf("\n       \"%s\"", t1_encdirs[i]);
 
331
  printf(")");
 
332
  printf("\n  (%s \"none\")", VF_CAPE_TYPE1_LOG_LEVEL);
 
333
  printf("\n  (%s %s)", VF_CAPE_DPI, dpi);
 
334
  printf(")\n");
 
335
  printf("\n");
 
336
}
 
337
 
 
338
 
 
339
void
 
340
translate(FILE *in, FILE *out, char *map)
 
341
{
 
342
  int   lno, x, v, i;
 
343
  char  buff[BUFSIZ];
 
344
  char  opt[BUFSIZ];
 
345
  int   npscode;
 
346
 
 
347
  if (gen_font == 0)
 
348
    return;
 
349
 
 
350
  printf(";; dvips mapfile: %s\n", map);
 
351
 
 
352
  lno = 0;
 
353
  while (fgets(buff, sizeof(buff), in) != NULL){
 
354
    lno++;
 
355
    if (isspace(buff[0]))
 
356
      continue;
 
357
    switch (buff[0]){
 
358
    case '\0':
 
359
    case ' ':
 
360
    case '\t':
 
361
    case '%':
 
362
    case '*':
 
363
    case ';':
 
364
    case '#':
 
365
      continue;
 
366
    default:
 
367
      break;
 
368
    }
 
369
    x = 0;
 
370
    npscode = 0;
 
371
    *t1font = *encfile = *opt = '\0';
 
372
    for (i = 0; i < MAXPSCODE; i++)
 
373
      *pscode[i] = '\0';
 
374
    v = get_token(texfont, buff, &x); 
 
375
    v = get_token(psfont,  buff, &x); 
 
376
    while (v >= 0){
 
377
      v = get_token(opt, buff, &x);
 
378
      if (strncmp(opt, "<<", 2) == 0){
 
379
        if (*t1font != '\0') 
 
380
          fprintf(stderr, "Error: line %d: %s\n", lno, buff);
 
381
        strcpy(t1font, &opt[1]);
 
382
      } else if (strncmp(opt, "<[", 2) == 0){
 
383
        if (*encfile != '\0') 
 
384
          fprintf(stderr, "Error: line %d: %s\n", lno, buff);
 
385
        strcpy(encfile, &opt[1]);
 
386
      } else if (strncmp(opt, "<", 1) == 0){
 
387
        if ((strlen(opt) >= 4) && (strcmp(".enc", &opt[strlen(opt)-4]) == 0)){
 
388
          if (*encfile != '\0') 
 
389
            fprintf(stderr, "Error: line %d: %s\n", lno, buff);
 
390
          strcpy(encfile, &opt[1]);
 
391
        } else {
 
392
          if (*t1font != '\0') 
 
393
            fprintf(stderr, "Error: line %d: %s\n", lno, buff);
 
394
          strcpy(t1font, &opt[1]);
 
395
        }
 
396
      } else if (strncmp(opt, "\"", 1) == 0){
 
397
        strcpy(pscode[npscode], &opt[1]);
 
398
        pscode[npscode][strlen(pscode[npscode])-1] = '\0';
 
399
        npscode++;
 
400
        if (npscode == MAXPSCODE){
 
401
          fprintf(stderr, "Error (Too many PS code): line %d: %s\n",
 
402
                  lno, buff);
 
403
          exit(0);
 
404
        }
 
405
      }
 
406
    }
 
407
 
 
408
    emit(); 
 
409
  }
 
410
 
 
411
  printf(";; end of %s\n", map);
 
412
}
 
413
 
 
414
int 
 
415
get_token(char *s, char *b, int *x)
 
416
{
 
417
  int  d;
 
418
 
 
419
  if (b[*x] == '\0')
 
420
    return -1;
 
421
  while (isspace(b[*x])){
 
422
    (*x)++;
 
423
    if (b[*x] == '\0')
 
424
      return -1;
 
425
  }
 
426
 
 
427
  d = 0;
 
428
  if (b[*x] == '"')
 
429
    d = 1;
 
430
  for (;;){
 
431
    *s = b[*x];
 
432
    if (b[*x] == '\0')
 
433
      return 0;
 
434
    s++;
 
435
    (*x)++;
 
436
    if ((d == 0) && isspace(b[*x])){
 
437
      *s = '\0';
 
438
      break;
 
439
    }
 
440
    if ((d == 1) && (b[*x] == '"'))
 
441
      d = 0;
 
442
  }
 
443
 
 
444
  while (isspace(b[*x])){
 
445
    (*x)++;
 
446
    if (b[*x] == '\0')
 
447
      return -1;
 
448
  }
 
449
 
 
450
  return 0;
 
451
}
 
452
 
 
453
void 
 
454
emit(void)
 
455
{
 
456
  char   *f, *ff;
 
457
  int     i, n, type, l;
 
458
  double  val, ds;
 
459
 
 
460
  if (*t1font != '\0'){
 
461
    ff = t1font;
 
462
  } else {
 
463
    ff = psfont;
 
464
  }
 
465
 
 
466
  if (exist_only == 1){
 
467
    f = check_font_exist(ff, t1_fontdirs, n_t1f, kpse_type1_format, NULL);
 
468
    ds = tfm_read_ds(texfont);
 
469
    if (ds < 0){
 
470
      free(f);
 
471
      f = NULL;
 
472
    }      
 
473
    if (f == NULL){
 
474
      /* search substitute font in Ghostscript font directory */
 
475
      f = find_gs_font(ff);    /* f is NULL if not found in gs Fontmap */
 
476
      if (f == NULL){
 
477
        return;
 
478
      } else {                 /* ignore .gsf font files */
 
479
        l = strlen(ff);
 
480
        if ((l >= strlen(".gsf")) && (strcmp(&f[l-4], ".gsf") == 0)){
 
481
          free(f); 
 
482
          f = NULL;
 
483
          return;
 
484
        }
 
485
      }
 
486
    }
 
487
    printf("(%s %s%s", VF_CAPE_VFLIBCAP_FONT_ENTRY_DEFINITION, 
 
488
           texfont, font_suffix); 
 
489
    printf("\t(%s %s)", VF_CAPE_FONT_CLASS, FONTCLASS_NAME); 
 
490
    if ((with_tfm == 1) && (ds > 0)){
 
491
      printf("\n  (%s %.2f)", VF_CAPE_POINT_SIZE, ds);
 
492
      printf(" (%s \"%s\")", VF_CAPE_TYPE1_TFM, texfont);
 
493
    }
 
494
    printf(" (%s \"%s\")", VF_CAPE_FONT_FILE, f);
 
495
 
 
496
  } else {
 
497
 
 
498
    /* search substitute font in Ghostscript font directory */
 
499
    f = find_gs_font(ff);    /* f is NULL if not found in gs Fontmap */
 
500
    ds = tfm_read_ds(texfont);
 
501
    if (f != NULL){
 
502
      /* ignore .gsf font files */
 
503
      l = strlen(ff);
 
504
      if ((l >= strlen(".gsf")) && (strcmp(&f[l-4], ".gsf") == 0)){
 
505
        free(f); f = NULL;
 
506
      }
 
507
    }
 
508
    printf("(%s %s%s", VF_CAPE_VFLIBCAP_FONT_ENTRY_DEFINITION, 
 
509
           texfont, font_suffix); 
 
510
    printf("\t(%s %s)", VF_CAPE_FONT_CLASS, FONTCLASS_NAME); 
 
511
    if ((with_tfm == 1) && (ds > 0)){
 
512
      printf("\n  (%s %.2f)", VF_CAPE_POINT_SIZE, ds);
 
513
      printf(" (%s \"%s\")", VF_CAPE_TYPE1_TFM, texfont);
 
514
    }
 
515
    if (f != NULL){
 
516
      printf("\n  (%s \"%s\" \"%s\")", VF_CAPE_FONT_FILE, ff, f);
 
517
    } else {
 
518
      printf("\n  (%s \"%s\")", VF_CAPE_FONT_FILE, ff);
 
519
    }
 
520
  }
 
521
 
 
522
  n = 0;
 
523
  for (i = 0; i < MAXPSCODE; i++){
 
524
    if (pscode[i][0] == '\0')
 
525
      continue;
 
526
    if ((type = parse_pscmd(pscode[i], &val)) < 0)
 
527
      continue;
 
528
    if (n == 0){
 
529
      printf("\n  "); 
 
530
    } else {
 
531
      printf(" ");
 
532
    }
 
533
    switch (type){
 
534
    case 1:
 
535
      if (*encfile != '\0')
 
536
        printf("(%s \"%s\")", VF_CAPE_TYPE1_ENC_VECT, encfile);
 
537
      break;
 
538
    case 2:
 
539
      printf("(%s %.3f)", VF_CAPE_SLANT_FACTOR, val);
 
540
      break;
 
541
    case 3:
 
542
      printf("(%s %.3f)", VF_CAPE_ASPECT_RATIO, val);
 
543
      break;
 
544
    }
 
545
    n++;
 
546
  }
 
547
  printf(")\n");
 
548
 
 
549
  if (f != NULL)
 
550
    free(f);
 
551
}
 
552
 
 
553
 
 
554
int
 
555
parse_pscmd(char *cmds, double *val)
 
556
{
 
557
  char  psc[2][256];
 
558
 
 
559
  if (sscanf(cmds, "%s %s", psc[0], psc[1]) == 2){
 
560
    if (strcmp(psc[1], "ReEncodeFont") == 0){
 
561
      return 1; 
 
562
    }
 
563
    if (strcmp(psc[1], "SlantFont") == 0){
 
564
      *val = atof(psc[0]);
 
565
      return 2; 
 
566
    }
 
567
    if (strcmp(psc[1], "ExtendFont") == 0){
 
568
      *val = atof(psc[0]);
 
569
      return 3; 
 
570
    }
 
571
    return -1;
 
572
  }
 
573
 
 
574
  return -1;
 
575
}
 
576
 
 
577
 
 
578
 
 
579
 
 
580
 
 
581
void
 
582
read_gs_fontmap(void)
 
583
{
 
584
  int   lno, i, j;
 
585
  char  f[BUFSIZ], d[BUFSIZ];
 
586
  char  buff[BUFSIZ];
 
587
  char  *p;
 
588
  FILE *fp; 
 
589
 
 
590
  if (n_gsf == 0)
 
591
    return;
 
592
 
 
593
  if ((fp = fopen(gs_fontmap, "r")) == NULL){
 
594
    fprintf(stderr, "Cannot open Ghostscript Fontmap file\n");
 
595
    exit(1);
 
596
  }
 
597
 
 
598
  lno = 0;
 
599
  while (fgets(buff, sizeof(buff), fp) != NULL){
 
600
    lno++;
 
601
    /* skip empty line */
 
602
    if ((p = strchr(buff, '%')) != NULL)
 
603
      *p = '\0';
 
604
    for (i = 0; buff[i] != '\0'; i++){
 
605
      if (!isspace(buff[i]))
 
606
        break;
 
607
    }
 
608
    if (buff[i] == '\0')
 
609
      continue;
 
610
    /* font name */
 
611
    for (j = 0; (buff[i] != '\0') && !isspace(buff[i]); i++, j++)
 
612
      f[j] = buff[i];
 
613
    f[j] = '\0';
 
614
    if (buff[i] == '\0'){
 
615
      fprintf(stderr, "Unexpected file format: gs_fontmap\n");
 
616
      continue;
 
617
    }
 
618
 
 
619
    /* skip space */
 
620
    for ( ; buff[i] != '\0'; i++){
 
621
      if (!isspace(buff[i]))
 
622
        break;
 
623
    }
 
624
    if (buff[i] == '\0'){
 
625
      fprintf(stderr, "Unexpected file format: Ghostscript Fontmap\n");
 
626
      continue;
 
627
    }
 
628
    /* font file or alias */
 
629
    for (j = 0; (buff[i] != '\0') && !isspace(buff[i]); i++, j++)
 
630
      d[j] = buff[i];
 
631
    d[j] = '\0';
 
632
    
 
633
    /* add to DB */
 
634
    if (i_db == NGSFONTS){
 
635
      fprintf(stderr, "Too many fonts in Ghostscript Fontmap\n");
 
636
      exit(1);
 
637
    }
 
638
#if 0
 
639
    printf("*** GS Fontmap db %d: %s\t%s\n", i_db, f, d);
 
640
#endif
 
641
    gs_db_f[i_db] = x_strdup(f);
 
642
    gs_db_d[i_db] = x_strdup(d);
 
643
    i_db++;
 
644
  }
 
645
 
 
646
  fclose(fp);
 
647
  fp = NULL;
 
648
}
 
649
 
 
650
 
 
651
char*
 
652
find_gs_font(char *f)
 
653
{
 
654
  int   j;
 
655
  char  *s;
 
656
 
 
657
  if ((j = query_gs_db(f)) < 0)
 
658
    return NULL;
 
659
 
 
660
  while (gs_db_d[j][0] == '/'){    /* resolve alias */
 
661
    if ((j = query_gs_db(&gs_db_d[j][1])) < 0)
 
662
      return NULL;
 
663
  } 
 
664
 
 
665
  s = x_strdup(&gs_db_d[j][1]);
 
666
  s[strlen(s)-1] = '\0';
 
667
 
 
668
  return s;
 
669
}
 
670
 
 
671
int
 
672
query_gs_db(char *s)
 
673
{
 
674
  int  i;
 
675
 
 
676
  for (i = 0; i < i_db; i++){
 
677
    if (strcmp(&gs_db_f[i][1], s) == 0)
 
678
      return i;
 
679
  }
 
680
  return -1;  /* font not in db. */
 
681
}
 
682
 
 
683
 
 
684
 
 
685
 
 
686
double
 
687
tfm_read_ds(char *name)
 
688
{
 
689
  FILE  *fp;
 
690
  char  tfm[1024];
 
691
  UINT4  lf, cs, ds, offset_header;
 
692
  UINT2  aux;
 
693
  int    type;
 
694
  char  *s;
 
695
 
 
696
  sprintf(tfm, "%s.%s", name, DEFAULT_EXTENSIONS_TFM);
 
697
#ifdef WITH_KPATHSEA
 
698
  s = kpse_find_file(tfm, kpse_tfm_format, 0);
 
699
#else
 
700
  s = name;
 
701
#endif
 
702
  if (s == NULL)
 
703
    return -1;
 
704
  if ((fp = fopen(s, "r")) == NULL)
 
705
    return -1;
 
706
 
 
707
  lf = (UINT4)READ_UINT2(fp);
 
708
  if ((lf == 11) || (lf == 9)){
 
709
    /* JFM file of Japanese TeX by ASCII Coop. */
 
710
    type = METRIC_TYPE_JFM;
 
711
    (UINT4)READ_UINT2(fp);
 
712
    (UINT4)READ_UINT2(fp);
 
713
    (UINT4)READ_UINT2(fp);    
 
714
    offset_header = 4*7;
 
715
  } else if (lf == 0){
 
716
    /* Omega Metric File */
 
717
    type = METRIC_TYPE_OFM;
 
718
    aux = READ_INT2(fp);    /* ofm_level */
 
719
    READ_UINT4(fp);
 
720
    READ_UINT4(fp);
 
721
    if (aux == 0){   /* level 0 OFM */
 
722
      offset_header = 4*14;
 
723
    } else {                   /* level 1 OFM: *** NOT SUPPORTED YET *** */
 
724
      offset_header = 4*29;
 
725
    }
 
726
  } else {
 
727
    /* Traditional TeX Metric File */
 
728
    type = METRIC_TYPE_TFM;
 
729
    aux = 0;
 
730
    (int)READ_UINT2(fp);    
 
731
    offset_header    = 4*6;
 
732
  }
 
733
 
 
734
  if (type == METRIC_TYPE_OFM){
 
735
    READ_UINT4(fp);
 
736
    READ_UINT4(fp);
 
737
    READ_UINT4(fp);
 
738
    READ_UINT4(fp);
 
739
    READ_UINT4(fp);
 
740
    READ_UINT4(fp);
 
741
    READ_UINT4(fp);
 
742
    READ_UINT4(fp);
 
743
    READ_UINT4(fp);
 
744
    READ_UINT4(fp);
 
745
    READ_UINT4(fp); 
 
746
  } else {
 
747
    (int)READ_UINT2(fp); 
 
748
    (int)READ_UINT2(fp);
 
749
    (UINT4)READ_UINT2(fp);
 
750
    (UINT4)READ_UINT2(fp);
 
751
    (UINT4)READ_UINT2(fp);
 
752
    (UINT4)READ_UINT2(fp);
 
753
    (UINT4)READ_UINT2(fp);
 
754
    (UINT4)READ_UINT2(fp);
 
755
    (UINT4)READ_UINT2(fp);
 
756
    (UINT4)READ_UINT2(fp);
 
757
  }
 
758
 
 
759
  fseek(fp, offset_header, SEEK_SET);
 
760
  cs = READ_UINT4(fp); 
 
761
  ds = READ_UINT4(fp); 
 
762
 
 
763
  fclose(fp);
 
764
 
 
765
  return (double)(ds)/(double)(1<<20);
 
766
}
 
767
 
 
768
unsigned long
 
769
vf_tex_read_uintn(FILE* fp, int size)
 
770
{
 
771
  unsigned long  v;
 
772
 
 
773
  v = 0L;
 
774
  while (size >= 1){
 
775
    v = v*256L + (unsigned long)getc(fp);
 
776
    --size;
 
777
  }
 
778
  return v;
 
779
}
 
780
 
 
781
long
 
782
vf_tex_read_intn(FILE* fp, int size)
 
783
{
 
784
  long           v;
 
785
 
 
786
  v = (long)getc(fp) & 0xffL;
 
787
  if (v & 0x80L)
 
788
    v = v - 256L;
 
789
  --size;
 
790
  while (size >= 1){
 
791
    v = v*256L + (unsigned long)getc(fp);
 
792
    --size;
 
793
  }
 
794
 
 
795
  return v;
 
796
}
 
797
 
 
798
void
 
799
vf_tex_skip_n(FILE* fp, int size)
 
800
{
 
801
  while (size > 0){
 
802
    (void)getc(fp);
 
803
    --size;
 
804
  }
 
805
}