summaryrefslogtreecommitdiff
path: root/fonts/utilities/afmtopl
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /fonts/utilities/afmtopl
Initial commit
Diffstat (limited to 'fonts/utilities/afmtopl')
-rw-r--r--fonts/utilities/afmtopl/clark/aftopl.177
-rw-r--r--fonts/utilities/afmtopl/clark/aftopl.c510
-rw-r--r--fonts/utilities/afmtopl/clark/util.h91
-rw-r--r--fonts/utilities/afmtopl/elwell/aftopl.c236
-rw-r--r--fonts/utilities/afmtopl/wolczko/aftopl203
-rw-r--r--fonts/utilities/afmtopl/wolczko/edsymbols4
-rw-r--r--fonts/utilities/afmtopl/wolczko/fontdimens24
-rw-r--r--fonts/utilities/afmtopl/wolczko/mk-con91
-rw-r--r--fonts/utilities/afmtopl/wolczko/mk-obl100
-rw-r--r--fonts/utilities/afmtopl/wolczko/mk-red43
-rw-r--r--fonts/utilities/afmtopl/wolczko/mk-sc99
-rw-r--r--fonts/utilities/afmtopl/wolczko/readme14
12 files changed, 1492 insertions, 0 deletions
diff --git a/fonts/utilities/afmtopl/clark/aftopl.1 b/fonts/utilities/afmtopl/clark/aftopl.1
new file mode 100644
index 0000000000..3162a230b3
--- /dev/null
+++ b/fonts/utilities/afmtopl/clark/aftopl.1
@@ -0,0 +1,77 @@
+.\" $Header: /u/jjc/dvitops/RCS/aftopl.1,v 1.1 89/02/01 09:06:36 jjc Rel $
+.TH AFTOPL L "10 December 1988"
+.SH NAME
+aftopl \- convert an AFM file to a TeX PL file
+.SH SYNOPSIS
+.B aftopl
+[
+.BI \-e encoding
+]
+.I afmfile
+[
+.I plfile
+]
+.SH DESCRIPTION
+.B aftopl
+converts an AFM (Adobe Font Metric) file to a TeX PL (Property List) file.
+An extension of
+.B .afm
+can be omitted from
+.IR afmfile .
+An extension of
+.B .pl
+can be omitted from
+.IR plfile .
+If
+.I plfile
+is omitted, it will be derived from
+.I afmfile
+by replacing the extension of
+.I afmfile
+by
+.BR .pl .
+The PL file can be converted to the TFM file needed by TeX by the pltotf
+utility.
+.SH OPTIONS
+.TP
+.BI \-e encoding
+Produce a PL file suitable for the font when reencoded using
+.IR encoding .
+There should be a file called
+.IB encoding .enc
+in the same place that TFM files are kept.
+This should give the PostScript name of each element of the encoding vector
+(without a leading
+.BR / ).
+Names should be separated by white space.
+Use the name
+.B .notdef
+for empty elements of the vector.
+.SH FILES
+.B /usr/local/tex/fonts/*.enc
+.SH "SEE ALSO"
+.BR tex (L),
+.BR pltotf (L),
+.BR dvitops (L),
+.IR "PostScript Language Reference Manual" .
+.SH BUGS
+.LP
+The same character must not occur more than once in the encoding vector.
+.LP
+There is no single `right' way to generate a PL file from an AFM file.
+.B aftopl
+tries to do something reasonable.
+If you don't like the results, you should feel free to edit the PL file.
+.LP
+If a composite character is included in the encoding vector, then all
+of its components must also be included; for example, if
+.B aacute
+occurs
+then so must
+.B a
+and
+.BR acute .
+.B aftopl
+does not check this.
+.SH AUTHOR
+James Clark <jjc@jclark.uucp>
diff --git a/fonts/utilities/afmtopl/clark/aftopl.c b/fonts/utilities/afmtopl/clark/aftopl.c
new file mode 100644
index 0000000000..6e9aa5cd66
--- /dev/null
+++ b/fonts/utilities/afmtopl/clark/aftopl.c
@@ -0,0 +1,510 @@
+static char rcsid[] = "$Header: /u/jjc/dvitops/RCS/aftopl.c,v 1.3 89/02/22 11:40:31 jjc Rel $";
+
+#include "util.h"
+
+#define MAXNAMES 500
+#define NOT_DEFINED 100000.0
+#ifndef PI
+#define PI 3.14159265358979324
+#endif
+
+struct ligatures {
+ char *ch;
+ char *succ;
+ char *lig;
+};
+
+char *program_name = "aftopl";
+
+static int lineno = 0;
+
+FILE *infp;
+FILE *outfp;
+#ifdef PROTO
+int lookup(const char *);
+char *getkeyvalue(char *, int);
+void scan_char_metric(char *);
+void compute_font_dimens(void);
+void do_kern_pairs(int);
+void do_char_metrics(int);
+void do_afms(void);
+void print_font_dimens(void);
+void do_encoding(char *);
+void print_char_metrics(void);
+void print_lig_kerns(void);
+void do_ligatures(struct ligatures *);
+#endif
+
+#define bad_afm_file() message(FATAL_ERROR, "bad afm file, line %d", lineno)
+
+struct lig_kern_list {
+ struct lig_kern_list *next;
+ int succ;
+ int lig; /* -1 if its a kern */
+ double x;
+};
+
+
+struct {
+ struct lig_kern_list *p;
+ char *name;
+ int code;
+ double llx;
+ double lly;
+ double urx;
+ double ury;
+ double wx;
+} table[MAXNAMES];
+
+struct {
+ int is_fixed_pitch;
+ double italic_angle;
+ double x_height;
+ /* we use max(urx - wx + italic_correction_space, 0)
+ as the italic correction for each character */
+ double italic_correction_space;
+ double normal_space;
+ double normal_stretch;
+ double normal_shrink;
+ double extra_space;
+ double quad;
+ double slant;
+} font = { 0, 0.0, NOT_DEFINED, NOT_DEFINED, NOT_DEFINED, NOT_DEFINED,
+NOT_DEFINED, NOT_DEFINED, NOT_DEFINED, NOT_DEFINED};
+
+
+
+int lookup(s)
+const char *s;
+{
+ int i;
+ for (i = 0; i < MAXNAMES; i++)
+ if (table[i].name == NULL)
+ break;
+ else if (strcmp(table[i].name, s) == 0)
+ return i;
+ if (i == MAXNAMES)
+ message(FATAL_ERROR, "too many names");
+ if ((table[i].name = malloc(strlen(s) + 1)) == NULL)
+ message(FATAL_ERROR, "out of memory");
+ strcpy(table[i].name, s);
+ table[i].code = -2;
+ table[i].llx = table[i].lly = 0.0;
+ table[i].urx = table[i].ury = 0.0;
+ table[i].wx = 0.0;
+ table[i].p = NULL;
+ return i;
+}
+
+
+char *getkeyvalue(s, c)
+char *s;
+char c;
+{
+ while (*s != '\0') {
+ while (isspace(*s))
+ s++;
+ if (*s == c)
+ return s + 1;
+ while (*s != '\0')
+ if (*s++ == ';')
+ break;
+ }
+ return NULL;
+}
+
+void scan_char_metric(s)
+char *s;
+{
+ char name[128];
+ int code, n;
+ double llx, lly, urx, ury;
+ double wx, wy;
+ char *p;
+ while (isspace(*s))
+ s++;
+ if (*s == '\0') /* ignore blank line */
+ return;
+ p = getkeyvalue(s, 'N');
+ if (p == NULL)
+ bad_afm_file();
+ /* sscanf(p, " %[A-Za-z0-9]", name); */
+ /* Microsoft C scanf doesn't understand %[ */
+ sscanf(p, "%s", name);
+ if ((p = strchr(name, ';')) != NULL)
+ *p = '\0';
+ if ((p = getkeyvalue(s, 'C')) == NULL)
+ bad_afm_file();
+ if (sscanf(p, "%d", &code) != 1)
+ bad_afm_file();
+ p = getkeyvalue(s, 'B');
+ if (p == NULL)
+ bad_afm_file();
+ if (sscanf(p, "%lg %lg %lg %lg", &llx, &lly, &urx, &ury) != 4)
+ bad_afm_file();
+ p = getkeyvalue(s, 'W');
+ if (p == NULL)
+ bad_afm_file();
+ if (*p == 'X') {
+ if (sscanf(p+1, "%lg", &wx) != 1)
+ bad_afm_file();
+ wy = 0.0;
+ }
+ else if (sscanf(p, "%lg %lg", &wx, &wy) != 2)
+ bad_afm_file();
+ n = lookup(name);
+ table[n].code = code;
+ table[n].wx = wx;
+ table[n].llx = llx;
+ table[n].lly = lly;
+ table[n].urx = urx;
+ table[n].ury = ury;
+ while ((p = getkeyvalue(s, 'L')) != NULL) {
+ char successor[128];
+ char ligature[128];
+ struct lig_kern_list *ptr;
+ if (sscanf(p, " %s %s", successor, ligature) != 2)
+ bad_afm_file();
+ else if ((s = strchr(ligature, ';')) != NULL)
+ *s = '\0';
+ if ((s = strchr(p, ';')) == NULL)
+ bad_afm_file();
+ s++;
+ if ((ptr = (struct lig_kern_list *)malloc(sizeof(struct lig_kern_list))) == NULL)
+ message(FATAL_ERROR, "out of memory");
+ ptr->succ = lookup(successor);
+ ptr->lig = lookup(ligature);
+ ptr->next = table[n].p;
+ table[n].p = ptr;
+ }
+}
+
+
+void compute_font_dimens()
+{
+ if (font.normal_space == NOT_DEFINED) {
+ int n = lookup("space");
+ if (table[n].code == -2)
+ message(FATAL_ERROR, "no char metric for space character");
+ else
+ font.normal_space = table[n].wx;
+ }
+ if (font.quad == NOT_DEFINED)
+ font.quad = (font.is_fixed_pitch?2.0:3.0)*font.normal_space;
+ if (font.italic_correction_space == NOT_DEFINED)
+ font.italic_correction_space = font.normal_space/12.0;
+ if (font.normal_shrink == NOT_DEFINED)
+ font.normal_shrink = font.is_fixed_pitch ? 0.0 :
+ font.normal_space/3.0;
+ if (font.normal_stretch == NOT_DEFINED)
+ font.normal_stretch = font.is_fixed_pitch ? 0.0 :
+ font.normal_space/2.0;
+ if (font.extra_space == NOT_DEFINED)
+ font.extra_space = (font.is_fixed_pitch ? 1.0 :0.5)
+ *font.normal_space;
+ if (font.slant == NOT_DEFINED)
+ if (font.italic_angle == 0.0)
+ font.slant = 0.0;
+ else
+ font.slant = sin(-font.italic_angle*PI/180.0);
+ if (font.x_height == NOT_DEFINED)
+ font.x_height = table[lookup("x")].ury;
+}
+
+void do_kern_pairs(n)
+int n;
+{
+ char buf[512];
+ char name1[128];
+ char name2[128];
+ double x, y;
+ for (;;) {
+ int i;
+ struct lig_kern_list *ptr;
+ lineno++;
+ if (fgets(buf, 512, infp) == NULL)
+ bad_afm_file();
+ if (buf[0] == '\n')
+ continue;
+ if (strcmp(buf, "EndKernPairs\n") == 0)
+ break;
+ if (sscanf(buf, "KPX %s %s %lg", name1, name2, &x) != 3) {
+ if (sscanf(buf, "KP %s %s %lg %lg", name1, name2,
+ &x, &y) != 4)
+ bad_afm_file();
+ }
+ else
+ y = 0.0;
+ i = lookup(name1);
+ if ((ptr = (struct lig_kern_list *)malloc(sizeof(struct lig_kern_list))) == NULL)
+ message(FATAL_ERROR, "out of memory");
+ ptr->succ = lookup(name2);
+ ptr->lig = -1;
+ ptr->x = x;
+ ptr->next = table[i].p;
+ table[i].p = ptr;
+ n--;
+ }
+ if (n != 0)
+ message(WARNING, "wrong number of kern pairs");
+}
+
+
+void do_char_metrics(n)
+int n;
+{
+ char buf[512];
+ for (;;) {
+ char *ptr = buf;
+ lineno++;
+ if (fgets(buf, 512, infp) == NULL)
+ bad_afm_file();
+ if (strcmp(buf, "EndCharMetrics\n") == 0)
+ break;
+ while (isspace(*ptr))
+ ptr++;
+ if (*ptr == '\0')
+ continue;
+ scan_char_metric(buf);
+ n--;
+ }
+ if (n != 0)
+ message(WARNING, "wrong number of char metrics");
+}
+
+void do_afms()
+{
+ char buf[512];
+ lineno = 0;
+
+ while (fgets(buf, 512, infp) != NULL) {
+ char *key, *value;
+ key = buf;
+ lineno++;
+ while (isspace(*key))
+ key++;
+ value = key;
+ while (*value != '\0' && !isspace(*value))
+ value++;
+ if (*value != '\0') {
+ /* strip trailing white space */
+ char *p;
+ *value++ = '\0';
+ while (isspace(*value))
+ value++;
+ p = value;
+ while (*p != '\0')
+ p++;
+ while (p > value && isspace(*(p-1)))
+ p--;
+ *p = '\0';
+ }
+ if (strcmp(key, "IsFixedPitch") == 0)
+ font.is_fixed_pitch = (strcmp(value, "true") == 0);
+ else if (strcmp(key, "XHeight") == 0)
+ font.x_height = atof(value);
+ else if (strcmp(key, "StartCharMetrics") == 0)
+ do_char_metrics(atoi(value));
+ else if (strcmp(key, "ItalicAngle") == 0)
+ font.italic_angle = atof(value);
+ else if (strcmp(key, "StartKernPairs") == 0)
+ do_kern_pairs(atoi(value));
+ else if (strcmp(key, "italicCorrectionSpace") == 0)
+ font.italic_correction_space = atof(value);
+ }
+
+}
+
+
+void print_font_dimens()
+{
+ fprintf(outfp, "(FONTDIMEN\n");
+ fprintf(outfp, " (SLANT R %f)\n", font.slant);
+ fprintf(outfp, " (SPACE R %f)\n", font.normal_space/1000.0);
+ fprintf(outfp, " (SHRINK R %f)\n", font.normal_shrink/1000.0);
+ fprintf(outfp, " (STRETCH R %f)\n", font.normal_stretch/1000.0);
+ fprintf(outfp, " (EXTRASPACE R %f)\n", font.extra_space/1000.0);
+ fprintf(outfp, " (QUAD R %f)\n", font.quad/1000.0);
+ fprintf(outfp, " (XHEIGHT R %f)\n", font.x_height/1000.0);
+ fprintf(outfp, " )\n");
+}
+
+
+void do_encoding(encoding)
+char *encoding;
+{
+ int i;
+ char name[256];
+ FILE *fp;
+ char *texfonts;
+ fprintf(outfp, "(CODINGSCHEME %s)\n", encoding);
+ texfonts = getenv("TEXFONTS");
+ if (texfonts == NULL)
+ texfonts = TEXFONTS;
+ if ((fp = xfopen(encoding, FALSE, texfonts, ".enc")) == NULL)
+ message(FATAL_ERROR, "can't find %s", encoding);
+ for (i = 0; i < MAXNAMES; i++)
+ if (table[i].code >= -1)
+ table[i].code = -1;
+ for (i = 0; i < 256 && fscanf(fp, " %s ", name) == 1; i++) {
+ int n;
+ if (strcmp(".notdef", name) == 0)
+ continue;
+ n = lookup(name);
+ if (table[n].code == -2)
+ message(WARNING, "%s in encoding but not in font", name);
+ else if (table[n].code == -1)
+ table[n].code = i;
+ else
+ message(ERROR, "%s appears more than once in encoding", name);
+ }
+}
+
+
+
+void print_char_metrics()
+{
+ int i;
+ for (i = 0; i < MAXNAMES; i++)
+ if (table[i].name != NULL && table[i].code > 0) {
+ double charic;
+ fprintf(outfp, "(CHARACTER O %03o\n", table[i].code);
+ fprintf(outfp, " (COMMENT %s)\n", table[i].name);
+ fprintf(outfp, " (CHARWD R %f)\n",
+ table[i].wx/1000.0);
+ /* negative heights and depths mess up \mathaccent */
+ if (table[i].ury > 0.0)
+ fprintf(outfp, " (CHARHT R %f)\n",
+ table[i].ury/1000.0);
+ if (table[i].lly < 0.0)
+ fprintf(outfp, " (CHARDP R %f)\n",
+ -table[i].lly/1000.0);
+ charic = table[i].urx - table[i].wx + font.italic_correction_space;
+ if (charic > 0.0)
+ fprintf(outfp, " (CHARIC R %f)\n",
+ charic/1000.0);
+ fputs(" )\n", outfp);
+ }
+}
+
+
+
+void print_lig_kerns()
+{
+ int i;
+ fputs("(LIGTABLE\n", outfp);
+ for (i = 0; i < MAXNAMES; i++) {
+ struct lig_kern_list *p;
+ char label_line[128];
+ if (table[i].name == NULL || table[i].code < 0)
+ continue;
+ sprintf(label_line, " (LABEL O %03o)\n", table[i].code);
+ /* print the ligatures */
+ for (p = table[i].p; p != NULL; p = p->next)
+ if (p->lig != -1 && table[p->lig].code > 0
+ && table[p->succ].code > 0) {
+ fputs(label_line, outfp);
+ label_line[0]= '\0';
+ fprintf(outfp," (LIG O %03o O %03o)\n",
+ table[p->succ].code,
+ table[p->lig].code);
+ }
+ for (p = table[i].p; p != NULL; p = p->next)
+ if (p->lig == -1 && table[p->succ].code > 0) {
+ fputs(label_line, outfp);
+ label_line[0] = '\0';
+ fprintf(outfp, " (KRN O %03o R %f)\n",
+ table[p->succ].code,
+ p->x/1000.0);
+ }
+ if (label_line[0] == '\0')
+ fputs(" (STOP)\n", outfp);
+ }
+ fputs(" )\n", outfp);
+}
+
+
+struct ligatures standard_ligatures[] = {
+ "hyphen", "hyphen", "endash",
+ "endash", "hyphen", "emdash",
+ "quoteleft", "quoteleft", "quotedblleft",
+ "quoteright", "quoteright", "quotedblright",
+ "exclam", "quoteleft", "exclamdown",
+ "question", "quoteleft", "questiondown",
+ NULL, NULL, NULL
+ };
+
+struct ligatures tt_ligatures[] = {
+ "exclam", "quoteleft", "exclamdown",
+ "question", "quoteleft", "questiondown",
+ NULL, NULL, NULL
+ };
+
+
+void do_ligatures(lig)
+struct ligatures *lig;
+{
+ int i;
+ for (i = 0; lig[i].lig != NULL; i++) {
+ int n;
+ struct lig_kern_list *p;
+ n = lookup(lig[i].ch);
+ if ((p = (struct lig_kern_list *)malloc(sizeof(struct lig_kern_list))) == NULL)
+ message(FATAL_ERROR, "out_of_memory");
+ p->succ = lookup(lig[i].succ);
+ p->lig = lookup(lig[i].lig);
+ p->next = table[n].p;
+ table[n].p = p;
+ }
+}
+
+
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ char filename[128];
+ int c;
+ char *efile = NULL;
+ while ((c = getopt(argc, argv, "e:")) != EOF)
+ switch(c) {
+ case 'e':
+ efile = optarg;
+ break;
+ case '?':
+ goto usage;
+ }
+ if (argc - optind < 1)
+ goto usage;
+ strcpy(filename, argv[optind]);
+ if (strchr(filename, '.') == NULL)
+ strcat(filename, ".afm");
+ if ((infp = fopen(filename, "r")) == NULL)
+ message(FATAL_ERROR, "can't open %s", filename);
+ if (argc - optind == 1)
+ strcpy(strchr(filename, '.'), ".pl");
+ else if (argc - optind == 2) {
+ strcpy(filename, argv[optind+1]);
+ if (strchr(filename, '.') == NULL)
+ strcat(filename, ".pl");
+ }
+ else
+ goto usage;
+ if ((outfp = fopen(filename, "w")) == NULL)
+ message(FATAL_ERROR, "can't open %s", filename);
+ do_afms();
+ if (efile != NULL)
+ do_encoding(efile);
+ if (font.is_fixed_pitch)
+ do_ligatures(tt_ligatures);
+ else
+ do_ligatures(standard_ligatures);
+ compute_font_dimens();
+ print_font_dimens();
+ print_char_metrics();
+ print_lig_kerns();
+ exit(history);
+usage:
+ message(FATAL_ERROR, "usage: aftopl [-e encoding] afmfile [plfile]");
+}
diff --git a/fonts/utilities/afmtopl/clark/util.h b/fonts/utilities/afmtopl/clark/util.h
new file mode 100644
index 0000000000..c96a8672f7
--- /dev/null
+++ b/fonts/utilities/afmtopl/clark/util.h
@@ -0,0 +1,91 @@
+/* $Header: /u/jjc/dvitops/RCS/util.h,v 1.2 89/02/01 12:18:22 jjc Rel $ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+#include <time.h>
+#include <errno.h>
+
+#include "config.h"
+
+#ifdef STDARG
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+#ifdef PROTO
+int abs(int);
+char *getenv(char *);
+int atoi(const char *);
+long atol(const char *);
+char *calloc(size_t, size_t);
+void exit(int);
+void free(char *);
+char *getenv(char *);
+char *malloc(size_t);
+void qsort(char *, size_t, size_t, int (*)());
+char *realloc(char *, size_t);
+double atof(const char *);
+int getopt(int argc, char **argv, char *opts);
+FILE *xfopen(char *filename, int is_binary, char *area_list,
+char *extension);
+#else
+int abs();
+char *getenv();
+double atof();
+int atoi();
+long atol();
+char *calloc();
+void exit();
+void free();
+char *getenv();
+char *malloc();
+void qsort();
+char *realloc();
+double atof();
+long atol();
+int getopt();
+FILE *xfopen();
+#endif
+
+extern int errno;
+
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern char *optarg;
+
+#define TRUE 1
+#define FALSE 0
+
+#ifdef BINARY
+#define RB "rb"
+#else
+#define RB "r"
+#endif
+
+#define cant_happen() message(FATAL_ERROR, "can't happen: %s, line %d",\
+__FILE__, __LINE__);
+#define out_of_memory() message(FATAL_ERROR, "out of memory");
+
+
+enum message_type {INFORMATION = 0, WARNING = 1, ERROR = 2, FATAL_ERROR = 3 };
+
+extern enum message_type history;
+extern char *program_name;
+
+#ifdef STDARG
+void message(enum message_type, char *,...);
+#else
+void message();
+#endif
diff --git a/fonts/utilities/afmtopl/elwell/aftopl.c b/fonts/utilities/afmtopl/elwell/aftopl.c
new file mode 100644
index 0000000000..8ff16630c0
--- /dev/null
+++ b/fonts/utilities/afmtopl/elwell/aftopl.c
@@ -0,0 +1,236 @@
+/**
+ 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 <stdio.h>
+#include <ctype.h>
+#include <math.h>
+
+#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(" )");
+}
diff --git a/fonts/utilities/afmtopl/wolczko/aftopl b/fonts/utilities/afmtopl/wolczko/aftopl
new file mode 100644
index 0000000000..4c628c6b1e
--- /dev/null
+++ b/fonts/utilities/afmtopl/wolczko/aftopl
@@ -0,0 +1,203 @@
+#! /bin/awk -f
+# Translate Adobe afm file to TeX pl file.
+# usage: aftopl afm-file-name >pl-file-name
+# Greg Lee, lee@uhccux.uhcc.hawaii.edu, 12/87
+# extensively modified by Mario Wolczko, mario@uk.ac.man.cs.ux, 4/88
+BEGIN {
+ tan[ 0]=0; tan[ 1]=.017454; tan[ 2]=.034919; tan[ 3]=.052406;
+ tan[ 4]=.069926; tan[ 5]=.087487; tan[ 6]=.105102; tan[ 7]=.122783;
+ tan[ 8]=.140539; tan[ 9]=.158383; tan[10]=.176325; tan[11]=.194379;
+ tan[12]=.212555; tan[13]=.230867; tan[14]=.249325; tan[15]=.267948;
+ tan[16]=.286744; tan[17]=.305728; tan[18]=.324918; tan[19]=.344326;
+ tan[20]=.363969; tan[21]=.383863; tan[22]=.404025; tan[23]=.424473;
+ tan[24]=.445227; tan[25]=.466306; tan[26]=.487731; tan[27]=.509524;
+ tan[28]=.531707; tan[29]=.554308; tan[30]=.577349; tan[31]=.600859;
+ tan[32]=.624867; tan[33]=.649406; tan[34]=.674507; tan[35]=.700205;
+ tan[36]=.726540; tan[37]=.753552; tan[38]=.781283; tan[39]=.809782;
+ tan[40]=.839099; tan[41]=.869284; tan[42]=.900401; tan[43]=.932512;
+ tan[44]=.965686; tan[45]=.999998; tan[46]=1.035526; tan[47]=1.072368;
+ tan[48]=1.110610; tan[49]=1.150364; tan[50]=1.191750; tan[51]=1.234894;
+ tan[52]=1.279939; tan[53]=1.327040; tan[54]=1.376380; tan[55]=1.428144;
+ tan[56]=1.482555; tan[57]=1.539859; tan[58]=1.600330; tan[59]=1.664273;
+ tan[60]=1.732044; tan[61]=1.804039; tan[62]=1.880723; tan[63]=1.962604;
+ tan[64]=2.050297; tan[65]=2.144501; tan[66]=2.246033; tan[67]=2.355844;
+ tan[68]=2.475075; tan[69]=2.605080; tan[70]=2.747468; tan[71]=2.904201;
+ tan[72]=3.077671; tan[73]=3.270835; tan[74]=3.487391; tan[75]=3.732019;
+ tan[76]=4.010759; tan[77]=4.331452; tan[78]=4.704597; tan[79]=5.144493;
+ tan[80]=5.671250; tan[81]=6.313687; tan[82]=7.115264; tan[83]=8.144301;
+ tan[84]=9.514216; tan[85]=11.42988; tan[86]=14.30034; tan[87]=19.08075;
+ tan[88]=28.63500; tan[89]=57.28469;
+
+ # extra kerning and ligature info is added to these chars
+ extra= " exclam question hyphen endash quoteleft quoteright f ";
+ # same, except for \tt fonts
+ extraf= " exclam question ";
+
+ LIG = " (LIG O %o O %o)\n"
+
+ print "(DESIGNSIZE R 10.0)"
+ print "(COMMENT DESIGNSIZE IS IN POINTS)"
+ print "(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)"
+ }
+
+/^FontName/ {
+ smallcaps = index($2, "SmallCaps");
+}
+
+/^FamilyName/ {
+ family = substr($0, length("FamilyName "));
+# if (family ~ /Symbol/) {
+# print "Can't deal with Symbol fonts" >"/dev/tty";
+# exit 1;
+# }
+ if (family ~ /Dingbats/ || family ~ /Symbol/)
+ nonchar = 1;
+ print "(FAMILY " family ")";
+}
+
+/^EncodingScheme/ { print "(CODINGSCHEME " $2 ")"; }
+
+/^ItalicAngle/ {
+ angle = int($2 + .5); slant = 0;
+ if (angle < 0)
+ slant = tan[-angle];
+ else
+ slant = -tan[angle];
+}
+
+/^IsFixedPitch/ { fixed = $2; }
+
+/^XHeight/ { xheight = $2/1000; }
+
+/^C 32/ { if (fixed == "true")
+ space = $5/1000
+ else
+ space = ($5 * 1.1)/1000 # this is a frig...
+ print "(FONTDIMEN"
+ printf(" (SLANT R %1.6f)\n", slant)
+ printf(" (SPACE R %1.6f)\n", space)
+ if (fixed == "false") {
+ # ...and this...
+ printf(" (STRETCH R %1.6f)\n", space/2)
+ # ...and this...
+ printf(" (SHRINK R %1.6f)\n", space/3)
+ }
+ printf(" (XHEIGHT R %1.6f)\n", xheight)
+ # ... and this ...
+ print " (QUAD R 1.0)"
+ # ...and this
+ if (fixed == "true")
+ printf(" (EXTRASPACE R %1.6f)\n", space)
+ else
+ printf(" (EXTRASPACE R %1.6f)\n", space/3)
+ print " )"
+ }
+
+/WX/ && $2 >= 0 {
+
+ ch = $2;
+ w = $5;
+ h = $14;
+ d = -$12;
+ rp = $13 - w;
+ name[$8] = ch;
+ c = ch;
+
+ if (c < 48) printf("(CHARACTER O %o\n", c);
+ if (c >= 48 && c <= 57) printf("(CHARACTER C %c\n", c);
+ if (c > 57 && c < 65) printf("(CHARACTER O %o\n", c);
+ if (c >= 65 && c <= 90) printf("(CHARACTER C %c\n", c);
+ if (c > 90 && c < 97) printf("(CHARACTER O %o\n", c);
+ if (c >= 97 && c <= 122) printf("(CHARACTER C %c\n", c);
+ if (c > 122) printf("(CHARACTER O %o\n", c);
+
+ printf(" (CHARWD R %1.6f)\n", w/1000);
+
+ if (h > 0) printf(" (CHARHT R %1.6f)\n", h/1000);
+ if (d > 0) printf(" (CHARDP R %1.6f)\n", d/1000);
+ if (rp > 0) printf(" (CHARIC R %1.6f)\n", rp/1000);
+
+ print " )";
+}
+
+/^EndCharMetrics/ {
+ # all TeX fonts (except DingBats)
+ # map !` to upside-down! and ?` to upside-down?
+ if (nonchar) next;
+ printf("(LIGTABLE\n");
+}
+
+/^KPX/ {
+ if ($2=="quoteleft" && $3=="quoteleft") next; # these are ligatured,
+ if ($2=="quoteright" && $3=="quoteright") next;# not kerned.
+ if (ck != $2) {
+ if (ck != "") printf(" (STOP)\n");
+ c = name[$2];
+ printf(" (LABEL O %o)\n", c);
+ ck = $2;
+ if ((fixed == "false" && index(extra," "ck" ")) || (fixed == "true" && index(extraf," "ck" "))) {
+ if (ck == "exclam")
+ printf(LIG,name["quoteleft"], name["exclamdown"]);
+ else if (ck == "question")
+ printf(LIG,name["quoteleft"], name["questiondown"]);
+ else if (ck == "hyphen")
+ printf(LIG,name["hyphen"], name["endash"]);
+ else if (ck == "endash")
+ printf(LIG,name["hyphen"], name["emdash"]);
+ else if (ck == "quoteleft")
+ printf(LIG,name["quoteleft"], name["quotedblleft"]);
+ else if (ck == "quoteright")
+ printf(LIG,name["quoteright"], name["quotedblright"]);
+ else if (ck == "f") {
+ printf(" (LIG C i O %o)\n",name["fi"]);
+ printf(" (LIG C l O %o)\n",name["fl"]);
+ }
+ done[ck]=1;
+ }
+
+ }
+ cm = name[$3];
+ printf(" (KRN O %o R %1.6f)\n", cm, $4/1000)
+ }
+
+/^EndKernPairs/ {
+ printf(" (STOP)\n");
+}
+
+/^EndFontMetrics/ {
+ if (nonchar) next;
+
+ if (fixed=="true")
+ todo= substr(extraf, 2);
+ else
+ todo= substr(extra, 2);
+ while (todo) {
+ n = index(todo, " ");
+ ck = substr(todo, 1, n-1);
+ todo = substr(todo, n+1);
+ if (!done[ck]) {
+ printf(" (LABEL O %o)\n", name[ck]);
+ # this is replica of the code in KPX
+ if (ck == "exclam")
+ printf(LIG,name["quoteleft"], name["exclamdown"]);
+ else if (ck == "question")
+ printf(LIG,name["quoteleft"], name["questiondown"]);
+ else if (ck == "f") {
+ printf(" (LIG C i O %o)\n",name["fi"]);
+ printf(" (LIG C l O %o)\n",name["fl"]);
+ } else if (fixed == "false") {
+ if (ck == "hyphen")
+ printf(LIG,name["hyphen"], name["endash"]);
+ else if (ck == "endash")
+ printf(LIG,name["hyphen"], name["emdash"]);
+ else if (ck == "quoteleft")
+ printf(LIG,name["quoteleft"], name["quotedblleft"]);
+ else if (ck == "quoteright")
+ printf(LIG,name["quoteright"], name["quotedblright"]);
+ }
+ printf(" (STOP)\n");
+ }
+ }
+ printf(" )\n");
+}
+
diff --git a/fonts/utilities/afmtopl/wolczko/edsymbols b/fonts/utilities/afmtopl/wolczko/edsymbols
new file mode 100644
index 0000000000..96bb6efdb9
--- /dev/null
+++ b/fonts/utilities/afmtopl/wolczko/edsymbols
@@ -0,0 +1,4 @@
+/^(FONTDIMEN/,/^ )/d
+.-1r fontdimens
+w
+q
diff --git a/fonts/utilities/afmtopl/wolczko/fontdimens b/fonts/utilities/afmtopl/wolczko/fontdimens
new file mode 100644
index 0000000000..92d4a6f024
--- /dev/null
+++ b/fonts/utilities/afmtopl/wolczko/fontdimens
@@ -0,0 +1,24 @@
+(FONTDIMEN
+ (SLANT R 0.0)
+ (SPACE R 0.0)
+ (STRETCH R 0.0)
+ (SHRINK R 0.0)
+ (XHEIGHT R 0.500)
+ (QUAD R 1.0)
+ (EXTRASPACE R 0.0)
+ (PARAMETER D 8 R 0.677)
+ (PARAMETER D 9 R 0.394)
+ (PARAMETER D 10 R 0.444)
+ (PARAMETER D 11 R 0.686)
+ (PARAMETER D 12 R 0.345)
+ (PARAMETER D 13 R 0.413)
+ (PARAMETER D 14 R 0.363)
+ (PARAMETER D 15 R 0.289)
+ (PARAMETER D 16 R 0.150)
+ (PARAMETER D 17 R 0.247)
+ (PARAMETER D 18 R 0.386)
+ (PARAMETER D 19 R 0.050)
+ (PARAMETER D 20 R 2.390)
+ (PARAMETER D 21 R 1.010)
+ (PARAMETER D 22 R 0.250)
+ )
diff --git a/fonts/utilities/afmtopl/wolczko/mk-con b/fonts/utilities/afmtopl/wolczko/mk-con
new file mode 100644
index 0000000000..ffd92c5844
--- /dev/null
+++ b/fonts/utilities/afmtopl/wolczko/mk-con
@@ -0,0 +1,91 @@
+#! /bin/sh
+# Make a condensed version of an AFM file
+# usage: mk-con x-scaling afm-file-name >new-afm-file-name
+#
+# rounding is done with int(x+0.5) --- this is wrong for -ve values
+awk 'BEGIN {'scale=$1';
+ tan[ 0]=0; tan[ 1]=.017454; tan[ 2]=.034919; tan[ 3]=.052406;
+ tan[ 4]=.069926; tan[ 5]=.087487; tan[ 6]=.105102; tan[ 7]=.122783;
+ tan[ 8]=.140539; tan[ 9]=.158383; tan[10]=.176325; tan[11]=.194379;
+ tan[12]=.212555; tan[13]=.230867; tan[14]=.249325; tan[15]=.267948;
+ tan[16]=.286744; tan[17]=.305728; tan[18]=.324918; tan[19]=.344326;
+ tan[20]=.363969; tan[21]=.383863; tan[22]=.404025; tan[23]=.424473;
+ tan[24]=.445227; tan[25]=.466306; tan[26]=.487731; tan[27]=.509524;
+ tan[28]=.531707; tan[29]=.554308; tan[30]=.577349; tan[31]=.600859;
+ tan[32]=.624867; tan[33]=.649406; tan[34]=.674507; tan[35]=.700205;
+ tan[36]=.726540; tan[37]=.753552; tan[38]=.781283; tan[39]=.809782;
+ tan[40]=.839099; tan[41]=.869284; tan[42]=.900401; tan[43]=.932512;
+ tan[44]=.965686; tan[45]=.999998; tan[46]=1.035526; tan[47]=1.072368;
+ tan[48]=1.110610; tan[49]=1.150364; tan[50]=1.191750; tan[51]=1.234894;
+ tan[52]=1.279939; tan[53]=1.327040; tan[54]=1.376380; tan[55]=1.428144;
+ tan[56]=1.482555; tan[57]=1.539859; tan[58]=1.600330; tan[59]=1.664273;
+ tan[60]=1.732044; tan[61]=1.804039; tan[62]=1.880723; tan[63]=1.962604;
+ tan[64]=2.050297; tan[65]=2.144501; tan[66]=2.246033; tan[67]=2.355844;
+ tan[68]=2.475075; tan[69]=2.605080; tan[70]=2.747468; tan[71]=2.904201;
+ tan[72]=3.077671; tan[73]=3.270835; tan[74]=3.487391; tan[75]=3.732019;
+ tan[76]=4.010759; tan[77]=4.331452; tan[78]=4.704597; tan[79]=5.144493;
+ tan[80]=5.671250; tan[81]=6.313687; tan[82]=7.115264; tan[83]=8.144301;
+ tan[84]=9.514216; tan[85]=11.42988; tan[86]=14.30034; tan[87]=19.08075;
+ tan[88]=28.63500; tan[89]=57.28469; tan[90]=1e6;
+
+
+}
+
+/^FontName/ {
+ print $0 "-Condensed";
+ next;
+ }
+
+/^FullName/ {
+ print $0, "Condensed";
+ next;
+ }
+
+/^ItalicAngle/ {
+ if ($2 < 0) {
+ origangle = int($2 - 0.5);
+ abstanorig = tan[-origangle];
+ } else if ($2 > 0) {
+ origangle = int($2 + 0.5);
+ abstanorig = tan[origangle];
+ } else {
+ origangle = 0;
+ abstanorig = 0;
+ }
+ abstannew = scale * abstanorig;
+ newangle= 0;
+ while (tan[newangle] < abstannew)
+ ++newangle;
+ if (origangle < 0)
+ newangle = -newangle;
+ print "ItalicAngle " newangle ; next ;
+}
+
+/^UnderlinePosition/ {
+ $2 = int(scale*$2 + 0.5);
+ print $0; next;
+}
+
+/^FontBBox/ {
+ $2 = int(scale*$2 + 0.5);
+ $4 = int(scale*$4 + 0.5);
+ print $0; next;
+}
+
+
+/^C / {
+ llx = $11;
+ urx = $13;
+ w = $5;
+ $11 = int(scale*llx + 0.5);
+ $13 = int(scale*urx + 0.5);
+ $5 = int(scale*w + 0.5);
+ print $0; next;
+}
+
+/^KPX/ {
+ $4 = int($4*scale - 0.5)
+ print $0; next;
+}
+
+{print}' $2
diff --git a/fonts/utilities/afmtopl/wolczko/mk-obl b/fonts/utilities/afmtopl/wolczko/mk-obl
new file mode 100644
index 0000000000..56d7354223
--- /dev/null
+++ b/fonts/utilities/afmtopl/wolczko/mk-obl
@@ -0,0 +1,100 @@
+#! /bin/sh
+# Make an oblique version of an AFM file
+# usage: mk-obl newangle afm-file-name >new-afm-file-name
+#
+# newangle should be an integer, in degrees of anti-clockwise skew
+#
+# bugs: doesn't set these fields properly:
+# FontBBox
+# UnderlinePosition
+# KPX
+# the llx field of Character Metrics is unchanged.
+# the urx field is guesstimated
+#
+# rounding is done with int(x+0.5) --- this is wrong for -ve values
+awk 'BEGIN {'newangle=$1';
+ tan[ 0]=0; tan[ 1]=.017454; tan[ 2]=.034919; tan[ 3]=.052406;
+ tan[ 4]=.069926; tan[ 5]=.087487; tan[ 6]=.105102; tan[ 7]=.122783;
+ tan[ 8]=.140539; tan[ 9]=.158383; tan[10]=.176325; tan[11]=.194379;
+ tan[12]=.212555; tan[13]=.230867; tan[14]=.249325; tan[15]=.267948;
+ tan[16]=.286744; tan[17]=.305728; tan[18]=.324918; tan[19]=.344326;
+ tan[20]=.363969; tan[21]=.383863; tan[22]=.404025; tan[23]=.424473;
+ tan[24]=.445227; tan[25]=.466306; tan[26]=.487731; tan[27]=.509524;
+ tan[28]=.531707; tan[29]=.554308; tan[30]=.577349; tan[31]=.600859;
+ tan[32]=.624867; tan[33]=.649406; tan[34]=.674507; tan[35]=.700205;
+ tan[36]=.726540; tan[37]=.753552; tan[38]=.781283; tan[39]=.809782;
+ tan[40]=.839099; tan[41]=.869284; tan[42]=.900401; tan[43]=.932512;
+ tan[44]=.965686; tan[45]=.999998; tan[46]=1.035526; tan[47]=1.072368;
+ tan[48]=1.110610; tan[49]=1.150364; tan[50]=1.191750; tan[51]=1.234894;
+ tan[52]=1.279939; tan[53]=1.327040; tan[54]=1.376380; tan[55]=1.428144;
+ tan[56]=1.482555; tan[57]=1.539859; tan[58]=1.600330; tan[59]=1.664273;
+ tan[60]=1.732044; tan[61]=1.804039; tan[62]=1.880723; tan[63]=1.962604;
+ tan[64]=2.050297; tan[65]=2.144501; tan[66]=2.246033; tan[67]=2.355844;
+ tan[68]=2.475075; tan[69]=2.605080; tan[70]=2.747468; tan[71]=2.904201;
+ tan[72]=3.077671; tan[73]=3.270835; tan[74]=3.487391; tan[75]=3.732019;
+ tan[76]=4.010759; tan[77]=4.331452; tan[78]=4.704597; tan[79]=5.144493;
+ tan[80]=5.671250; tan[81]=6.313687; tan[82]=7.115264; tan[83]=8.144301;
+ tan[84]=9.514216; tan[85]=11.42988; tan[86]=14.30034; tan[87]=19.08075;
+ tan[88]=28.63500; tan[89]=57.28469;
+
+ if (newangle != int(newangle)) {
+ print "Angle must be an integer" >"/dev/tty";
+ exit 1;
+ }
+ if (newangle < 0) {
+ tannew = -tan[-newangle];
+ } else if (newangle > 0) {
+ tannew = tan[newangle];
+ } else {
+ tannew = 0;
+ }
+}
+
+/^FontName/ {
+ print $0 "-Oblique";
+ next;
+ }
+
+/^FullName/ {
+ print $0, "Oblique";
+ next;
+ }
+
+/^ItalicAngle/ {
+ if ($2 < 0) {
+ origangle = int($2 - 0.5);
+ tanorig = -tan[-origangle];
+ } else if ($2 > 0) {
+ origangle = int($2 + 0.5);
+ tanorig = tan[origangle];
+ } else {
+ origangle = 0;
+ tanorig = 0;
+ }
+ print "ItalicAngle " newangle ; next ;
+}
+
+/^C / {
+ llx = $11;
+ lly = $12;
+ urx = $13;
+ ury = $14;
+ h = ury - lly;
+ if (origangle < 0)
+ urx = urx + h * tanorig;
+ else if (origangle > 0)
+ llx = llx + h * tanorig;
+
+ # now llx and urx are correct for an upright font
+ # so apply the desired slope
+ if (newangle < 0)
+ urx = urx - h * tannew;
+ else if (newangle > 0)
+ llx = llx - h * tannew;
+
+ $11 = int(llx + 0.5);
+ $13 = int(urx + 0.5);
+ print $0; next;
+}
+
+{print}' $2
diff --git a/fonts/utilities/afmtopl/wolczko/mk-red b/fonts/utilities/afmtopl/wolczko/mk-red
new file mode 100644
index 0000000000..f6bfeb045f
--- /dev/null
+++ b/fonts/utilities/afmtopl/wolczko/mk-red
@@ -0,0 +1,43 @@
+#! /bin/sh
+# Make a reduced version of an AFM file
+# usage: mk-red scale afm-file-name >new-afm-file-name
+#
+# rounding is done with int(x+0.5) --- this is wrong for -ve values
+# doesn't deal with composites
+awk 'BEGIN {'scale=$1'; }
+
+/^FontName/ {
+ print $0 "-Reduced";
+ next;
+ }
+
+/^FullName/ {
+ print $0, "Reduced";
+ next;
+ }
+
+/^Underline/ || /^CapHeight/ || /^XHeight/ || /^Descender/ || /^Ascender/ {
+ print $1, int($2*scale + 0.5); next;
+}
+
+/^FontBBox/ {
+ print "FontBBox", int($2*scale+0.5), int($3*scale+0.5), int($4*scale+0.5), int($5*scale+0.5);
+ next;
+}
+
+
+/^C / {
+ $5 = int($5 * scale + 0.5);
+ $11 = int($11 * scale + 0.5);
+ $12 = int($12 * scale + 0.5);
+ $13 = int($13 * scale + 0.5);
+ $14 = int($14 * scale + 0.5);
+ print $0; next;
+}
+
+/^KPX/ {
+ $4 = int($4*scale - 0.5)
+ print $0; next;
+}
+
+{print}' $2
diff --git a/fonts/utilities/afmtopl/wolczko/mk-sc b/fonts/utilities/afmtopl/wolczko/mk-sc
new file mode 100644
index 0000000000..8b74dac630
--- /dev/null
+++ b/fonts/utilities/afmtopl/wolczko/mk-sc
@@ -0,0 +1,99 @@
+#! /bin/sh
+# Make a small-caps version of an AFM file
+# usage: mk-sc scale afm-file-name >new-afm-file-name
+#
+# scale is the ratio between the small and the large caps (e.g, 0.8)
+#
+# bugs: doesn't set these fields properly:
+# FontBBox
+# KPX data for lowercase is discarded
+#
+# rounding is done with int(x+0.5) --- this is wrong for -ve values
+
+trap "rm -f /tmp/afm$$0[012] /tmp/kern$$" 0
+
+csplit -f /tmp/afm$$ -s $2 /StartKernPairs/+1 /EndKernPairs/
+
+# chardata now in /tmp/afm$$00, kern in /tmp/afm$$01,
+# composites in /tmp/afm$$02
+
+# first do the kern data
+
+awk 'BEGIN {
+ lower= "abcdefghijklmnopqrstuvwxyz";
+ upper= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ }
+
+ /^$/ { next; }
+
+ /^KPX/ && $2 ~ /^[A-Z]$/ && $3 ~ /^[A-Z]$/ {
+ # insert extra kerning data for lower case, based on upper case
+ lwr2=substr(lower, index(upper, $2), 1);
+ lwr3=substr(lower, index(upper, $3), 1);
+ print "KPX", lwr2, $3, $4
+ print "KPX", $2, lwr3, $4
+ print "KPX", lwr2, lwr3, $4
+ print $0
+ next;
+ }
+
+ /^KPX/ && ($2 ~ /^[a-z]$/ || $3 ~ /^[a-z]$/) {
+ # filter out kerning applied to lower-case
+ next;
+ }
+ { print ; }' /tmp/afm$$01 |
+sort +1 -3 |
+awk '
+ $2 != last { printf "\n" ; last= $2 }
+ { print }
+' >/tmp/kern$$
+
+# now process the chardata, and put the bits together
+awk 'BEGIN {'scale=$1';}
+
+ /^FontName/ {
+ print $0 "-SmallCaps";
+ next;
+ }
+
+ /^FullName/ {
+ print $0, "SmallCaps";
+ next;
+ }
+
+ /^CapHeight/ {
+ print "XHeight", int($2*scale + 0.5)
+ }
+
+ /^XHeight/ { next;}
+
+ /^Descender/ {
+ print "Descender 0";
+ next;
+ }
+
+ /^C / {
+ ch = $2;
+ if (ch >= 65 && ch <= 90) {
+ # it is an upper case letter, so save the (scaled) metric info
+ ch += 32;
+ w[ch] = int($5 * scale + 0.5);
+ llx[ch] = int($11 * scale + 0.5);
+ lly[ch] = int($12 * scale + 0.5);
+ urx[ch] = int($13 * scale + 0.5);
+ ury[ch] = int($14 * scale + 0.5);
+ print;
+ } else if (ch >= 97 && ch <= 122) {
+ # it is a lower case letter -- substitute the saved info
+ printf "C %d ; WX %d ; N %s ; B %d %d %d %d\n", \
+ ch, w[ch], $8, llx[ch], lly[ch], urx[ch], ury[ch], ";";
+ # do not want any ligature info
+ } else
+ print;
+
+ next;
+ }
+
+ {print}' /tmp/afm$$00 |
+cat - /tmp/kern$$ /tmp/afm$$02
+
diff --git a/fonts/utilities/afmtopl/wolczko/readme b/fonts/utilities/afmtopl/wolczko/readme
new file mode 100644
index 0000000000..9d2bc101ef
--- /dev/null
+++ b/fonts/utilities/afmtopl/wolczko/readme
@@ -0,0 +1,14 @@
+This directory contains several UNIX utilities for converting AFM to
+PL files.
+
+aftopl - an awk script that does basic AFM to PL conversion
+
+edsymbols & fontdimens - used by the Makefile in the TFM directory to
+ make a Symbol font
+
+mk-con - makes a condensed AFM font (ie, squeezed horizontally)
+mk-obl - makes an oblique AFM font
+mk-red - makes a reduced (in both x and y) AFM font
+mk-sc - makes a smallcaps AFM fonts
+
+getmetrics - alternative way of getting AFM data...asks the printer for it!