/** Program: aftopl -- convert Adobe AFM files into TeX PL files Author: Clayton M. Elwell, Ohio State University Disclaimer: This program seems to work, but it was cobbled up in an afternoon. Its operation should be readily apparent to any C programmer. **/ static char RCSid[] = "$Header: aftopl.c,v 2.1 87/11/24 12:34:38 cudcv Exp $"; /* * $Log: aftopl.c,v $ * Revision 2.1 87/11/24 12:34:38 cudcv * Finished (?) - Release. * * Revision 1.3 87/10/30 09:41:26 cudcv * Don't want ligatures for typewriter fonts, even if they are in the * Postscript fonts. * * Revision 1.2 87/10/30 09:19:26 cudcv * Remap for TeX fonts, add LIGTABLE. Fixed bug in slant. * * Revision 1.1 87/07/09 12:57:27 cudcv * Initial revision * */ #include #include #include #ifndef M_PI /* not in all math.h files */ #define M_PI 3.14159265358979323846 #endif #define max(a,b) ((a) > (b) ? (a) : (b)) char line[BUFSIZ]; char *strupr(s) register char *s; { register char *s1; s1 = s; while (*s) { if (islower(*s)) *s = toupper(*s); s++; } return s1; } starts(s1, s2) register char *s1; register char *s2; { return !strncmp(s1, s2, strlen(s2)); } float hscale; float scale(i) int i; { return (hscale * (((float) i) / 1000.0)); } struct { int number; char *name; int forfw; } map [] = { { 0000, "Gamma", 1 }, { 0001, "Delta", 1 }, { 0002, "Theta", 1 }, { 0003, "Lambda", 1 }, { 0004, "Xi", 1 }, { 0005, "Pi", 1 }, { 0006, "Sigma", 1 }, { 0007, "Upsilon", 1 }, { 0010, "Phi", 1 }, { 0011, "Psi", 1 }, { 0012, "Omega", 1 }, { 0013, "ff", 0 }, { 0014, "fi", 0 }, { 0015, "fl", 0 }, { 0016, "ffi", 0 }, { 0017, "ffl", 0 }, { 0020, "dotlessi", 1 }, { 0021, "dotlessj", 1 }, { 0022, "grave", 1 }, { 0023, "acute", 1 }, { 0024, "caron", 1 }, { 0025, "breve", 1 }, { 0026, "macron", 1 }, { 0027, "ring", 1 }, { 0030, "cedilla", 1 }, { 0031, "germandbls", 1 }, { 0032, "ae", 1 }, { 0033, "oe", 1 }, { 0034, "oslash", 1 }, { 0035, "AE", 1 }, { 0036, "OE", 1 }, { 0037, "Oslash", 1 }, { 0136, "circumflex", 0 }, { 0137, "dotaccent", 0 }, { 0175, "hungarumlaut", 0 }, { 0176, "tilde", 0 }, { 0177, "dieresis", 1 }, }; int number, width, left, bottom, right, top; char name[64]; main(argc, argv) int argc; char *argv[]; { double atof(); int fixedwidth = 0, filigs = 0; if (argc == 2) hscale = atof(argv[1]); else hscale = 1.0; puts("(COMMENT THIS PL FILE WAS GENERATED FROM AN AFM FILE BY AFTOPL)"); puts("(COMMENT AFTOPL WAS WRITTEN BY CLAYTON M. ELWELL, OHIO STATE UNIVERSITY)"); puts("(DESIGNSIZE R 10.0)"); puts("(SEVENBITSAFEFLAG FALSE)"); while (gets(line)) { if (starts(line, "Comment")) printf("(COMMENT %s)\n", strupr(line+8)); else if (starts(line, "EncodingScheme")) printf("(CODINGSCHEME %s)\n", strupr(line+15)); else if (starts(line, "ItalicAngle")) { double d = -tan(atof(line+12) * M_PI / 180.0); printf("(FONTDIMEN\n (SLANT R %.6f)\n", d); puts(" (STRETCH R 0.300)\n (SHRINK R 0.100)\n )"); } else if (starts(line, "IsFixedPitch")) { if (line[13] == 't') fixedwidth++; } else if (starts(line, "CapHeight")) printf("(FONTDIMEN\n (QUAD R %f)\n )\n", scale(atoi(line+10))); else if (starts(line, "XHeight")) printf("(FONTDIMEN\n (XHEIGHT R %f)\n )\n", scale(atoi(line+8))); else if (starts(line, "C ")) { sscanf(line, "C %d ; WX %d ; N %s ; B %d %d %d %d ;", &number, &width, name, &left, &bottom, &right, &top); if (number < 32) { /* do nothing */ } else if (number == 32) { printf("(FONTDIMEN\n"); printf(" (SPACE R %f)\n (EXTRASPACE R %f)\n", scale(width), fixedwidth ? scale(width) : scale(width)/2); printf(" )\n"); } else { int found = 0, i; for (i = 0; i < sizeof(map)/sizeof(map[0]); i++) { if (fixedwidth && !map[i].forfw) continue; if (!(strcmp(map[i].name, name))) OutChar(map[i].number, width, name, left, bottom, right, top); if (map[i].number == number) found++; } if (!found) OutChar(number, width, name, left, bottom, right, top); if (!strcmp(name, "fi")) filigs++; } } else if (starts(line, "StartKernPairs")) puts("(LIGTABLE"); else if (starts(line, "EndKernPairs")) puts(" )"); else if (starts(line, "KPX ")) { if ((line[5] != ' ') || (line[7] != ' ')) { } else { printf(" (LABEL C %c)\n", line[4]); while (starts(line, "KPX ")) { if ((line[5] == ' ') && (line[7] == ' ')) { sscanf(line, "KPX %c %c %d", name, name+1, &width); printf(" (KRN C %c R %f)\n", name[1], scale(width)); } gets(line); } puts(" (STOP)"); } } } printf( "(LIGTABLE\n\ (LABEL O 40)\n\ (LIG C l O 370)\n\ (LIG C L O 350)\n\ (STOP)\n\ (LABEL O 41)\n\ (LIG O 140 O 241)\n\ (STOP)\n\ (LABEL O 77)\n\ (LIG O 140 O 277)\n\ (STOP)\n"); if (!fixedwidth) { printf( " (LABEL O 140)\n\ (LIG O 140 O 252)\n\ (STOP)\n\ (LABEL O 47)\n\ (LIG O 47 O 272)\n\ (STOP)\n\ (LABEL O 55)\n\ (LIG O 55 O 261)\n\ (STOP)\n\ (LABEL O 261)\n\ (LIG O 55 O 320)\n\ (STOP)\n"); if (filigs) printf( " (LABEL C f)\n\ (LIG C i O 256)\n\ (LIG C l O 257)\n\ (STOP)\n"); } printf(" )"); } OutChar(number, width, name, left, bottom, right, top) int number, width, left, bottom, right, top; char *name; { printf("(COMMENT %s)\n(CHARACTER D %d\n", name, number); printf(" (CHARWD R %f)\n (CHARHT R %f)\n", scale(width), scale(top)); if (max(0, -bottom)) printf(" (CHARDP R %f)\n", scale(-bottom)); if (right > width) printf(" (CHARIC R %f)\n", scale(right - width)); puts(" )"); }