home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
-
- /*
- ** Get character widths out of tfm files. See man page.
- */
-
- /* where the TeX tfm files live */
- #ifndef TEXFONT
- #define TEXFONT "/usr/lib/tex/fonts/"
- #endif
-
- #define FIX (1<<20)
- #define UNKNOWN (-1)
- #define PPI 72
-
- #ifndef RESOLUTION
- #define RESOLUTION (PPI*8)
- #endif
-
- #define HEADERSIZE 24
-
- int designsize = 0;
- int spacewidth = -1;
-
- usage()
- {
- (void)fprintf(stderr, "Usage: tfm2desc [-d<ds>] [-s<sw>] fontmap [m|s]\n");
- exit(1);
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- register int c;
- register char type = ' ';
- char tfmname[256];
- char extname[10];
- FILE *tfmfile;
- extern int optind;
- extern char *optarg;
- int getopt(), atoi();
-
- while ((c = getopt(argc, argv, "d:s:")) != EOF)
- {
- switch (c)
- {
- case 'd':
- designsize = atoi(optarg);
- if (designsize <= 0)
- (void)fprintf(stderr, "Bad designsize: %d, will use designsize in tfm file\n", designsize);
- break;
- case 's':
- spacewidth = atoi(optarg);
- break;
- default:
- exit(1);
- break;
- }
- }
-
- argc -= optind;
- argv += optind;
-
- if (argc < 1)
- usage();
- if (freopen(argv[0], "r", stdin) == NULL)
- {
- perror(argv[0]);
- exit(1);
- }
- (void)sprintf(tfmname, "%s%s.tfm", TEXFONT, argv[0]);
- if ((tfmfile = fopen(tfmname, "r")) == NULL)
- {
- perror(argv[0]);
- exit(1);
- }
- (void)fgets(extname, sizeof(extname), stdin);
- if (extname[1] == '\n')
- extname[1] = '\0';
- if (extname[2] == '\n')
- extname[2] = '\0';
- if (argc >= 2)
- type = argv[1][0];
- convert(extname, argv[0], tfmfile, type);
- exit(0);
- }
-
- #define get1(buffer, offset) (buffer[offset])
-
- int get2(buffer, offset)
- unsigned char *buffer;
- int offset;
- {
- return ((buffer[offset] << 8) | buffer[offset + 1]);
- }
-
- int get4(buffer, offset)
- unsigned char *buffer;
- int offset;
- {
- register int i, n;
-
- n = 0;
- for (i = 0; i < 4; ++i)
- n = (n << 8) | buffer[offset + i];
- return (n);
- }
-
- /*
- ** Convert from FIXES to pixels. The roundoff error of this
- ** routine is a max of (72*designsize)/2^20, which is negligible
- ** for ordinary pointsizes.
- */
- fixestopixels(fix, designsize)
- int fix;
- int designsize;
- {
- register unsigned long l;
-
- l = fix * RESOLUTION / PPI;
- l = (l * designsize + FIX / 2) / FIX;
- return (l);
- }
-
- /*
- ** The main routine which converts a tfm file to a troff width table file
- */
- convert(extname, intname, tfmfile, type)
- char *extname, *intname;
- FILE *tfmfile;
- char type;
- {
- register int i, j, ch;
- register unsigned char *tfmbuf;
- register int aheight;
- int lh, bc, ec, nw, nh;
- char line[256];
- char name[3];
- char *malloc();
-
- /*
- ** Read the whole tfm file in one gulp
- */
- i = getc(tfmfile) & 0xff;
- i = (i << 8) | (getc(tfmfile) & 0xff);
- i *= 4;
- if ((tfmbuf = (unsigned char *)malloc(i)) == NULL)
- {
- (void)fprintf(stderr, "Out of memory\n");
- exit(1);
- }
- i -= 2;
- if ((j = fread(tfmbuf + 2, sizeof(char), i, tfmfile)) != i)
- {
- (void)fprintf(stderr, "Short read on %s, want %d, got %d\n",
- intname, i, j);
- exit(1);
- }
-
- (void)printf("name %s\ninternalname %s\n", extname, intname);
- if (type == 's')
- (void)printf("special\n");
- else if (type != 's' && type != 'm') /* not special or mono-spaced */
- (void)printf("ligatures ff fi fl ffi ffl 0\n");
- if (type != 's')
- {
- if ((aheight = getaheight(tfmbuf)) == UNKNOWN)
- {
- (void)fprintf(stderr, "No letter 'a' in %s.tfm\n", intname);
- (void)fprintf(stderr, "\tSetting height to zero\n");
- aheight = 0;
- }
- }
-
- if (spacewidth >= 0)
- (void)printf("spacewidth %d\n", spacewidth);
-
- lh = get2(tfmbuf, 2) * 4;
- bc = get2(tfmbuf, 4);
- ec = get2(tfmbuf, 6);
- nw = get2(tfmbuf, 8) * 4;
- nh = get2(tfmbuf, 10) * 4;
- if (designsize <= 0)
- designsize = get4(tfmbuf, HEADERSIZE + 4) / FIX;
-
- (void)printf("charset\n");
- ch = -1;
- while (fgets(line, sizeof(line), stdin) != NULL)
- {
- register int widthindex, heightanddepth, width;
- int height, depth, kerning;
- int temp;
-
- if (sscanf(line, "%o\t%2s\n", &temp, name) != 2)
- {
- (void)fprintf(stderr, "Bad spec file: %s", line);
- exit(1);
- }
- /* space is a terminator */
- if (name[0] == '\0')
- {
- name[0] = ' ';
- name[1] = '\0';
- }
- if (temp >= 128)
- {
- specials(name, temp, spacewidth);
- continue;
- }
- if (temp == ch)
- {
- (void)printf("%s\t\"\n", name);
- continue;
- }
- ch = temp;
- widthindex = get1(tfmbuf, HEADERSIZE + lh + (ch-bc)*4);
- heightanddepth = get1(tfmbuf, HEADERSIZE + lh + (ch-bc)*4 + 1);
- if (widthindex == 0)
- continue;
- width = get4(tfmbuf, HEADERSIZE + lh + (ec-bc+1)*4 + widthindex*4);
- width = fixestopixels(width, designsize);
- height = get4(tfmbuf, HEADERSIZE + lh + (ec-bc+1)*4 + nw +
- (heightanddepth>>4)*4);
- height = fixestopixels(height, designsize);
- depth = get4(tfmbuf, HEADERSIZE + lh + (ec-bc+1)*4 + nw + nh +
- (heightanddepth & 0xf)*4);
- depth = fixestopixels(depth, designsize);
- kerning = 0;
- if (height > aheight)
- kerning |= 2;
- if (depth > 0)
- kerning |= 1;
- if (width >= 256)
- (void)fprintf(stderr, "Warning: width of %d for %s is too wide for ditroff to handle\n",
- width, name);
- (void)printf("%s\t%d\t%d\t0%o\n", name, width, kerning, ch);
- }
- }
-
- /* Returns the height of the letter 'a' in the font passed as a parameter.
- * The height is returned in pixels since troff likes to use pixels as its
- * unit. If the letter 'a' is not found, UNKNOWN is returned.
- */
- int getaheight(buffer)
- unsigned char *buffer;
- {
- register int lh, bc, ec, nw, designsize;
- register int widthindex, heightanddepth, height;
-
- lh = get2(buffer, 2) * 4;
- bc = get2(buffer, 4);
- ec = get2(buffer, 6);
- nw = get2(buffer, 8) * 4;
- if (bc > 'a' || ec < 'a')
- return (UNKNOWN);
- designsize = get4(buffer, HEADERSIZE + 4) / FIX; /* Convert from FIXes */
- widthindex = get1(buffer, HEADERSIZE + lh + ('a'-bc)*4);
- heightanddepth = get1(buffer, HEADERSIZE + lh + ('a'-bc)*4 + 1);
- if (widthindex == 0)
- return (UNKNOWN);
- height = get4(buffer, HEADERSIZE + lh + (ec-bc+1)*4 + nw +
- (heightanddepth >> 4)*4);
- return (fixestopixels(height, designsize));
- }
-
- specials(name, ch, width)
- char *name;
- int ch, width;
- {
- if (strcmp(name, "\\&") == 0)
- width = 0;
- /* assume em space is twice space width */
- else if (strcmp(name, "\\^") == 0)
- width = (width + 3) / 6; /* 1/12 em space */
- else if (strcmp(name, "\\|") == 0)
- width = (width + 1) / 3; /* 1/6 em space */
- /* make ru same as spacewidth */
- (void)printf("%s\t%d\t0\t0%o\n", name, width, ch);
- }
-