shithub: neatmkfn

Download patch

ref: eca57b68ca28c74aff5fceef687f38d77155b0c5
parent: 97655d31acf6b935b425803271b8a82a9e2aef07
author: Ali Gholami Rudi <ali@rudi.ir>
date: Tue Nov 19 19:05:37 EST 2013

mktrfn: use the new syntax for defining characters

Also added -k to specify the minimum amount of kerning to include.

--- a/gen.sh
+++ b/gen.sh
@@ -10,8 +10,11 @@
 # pattern of ligatures to ignore
 LIGIGN="\(ct\|st\|sp\|Rp\)"
 # pattern of allowed opentype features
-OTFFEATS="\(swsh\|tilt\|smcp\|case\)"
+OTFFEATS="\(swsh\|titl\|smcp\|case\)"
 
+# otherwise sort and grep would be too slow
+export LC_ALL="C"
+
 # creating DESC
 mkdir -p $TP
 echo "fonts 10 R I B BI CW H HI HB S1 S" >$TP/DESC
@@ -32,15 +35,16 @@
 function otfconv
 {
 	ODOUT="/tmp/.mktrfn.otfdump"
-	otfdump $3 >$ODOUT
-	FEATS="`grep "^feature " $ODOUT | cut -f2 -d ' ' | sort | uniq`"
+	FEATS="`otfdump -s $3 | cut -f2 -d ' ' | sort | uniq`"
 	echo "$1: `echo $FEATS | tr '\n' ' '`"
-	cat $ODOUT | grep -v "^feature " | ./mktrfn $4 -r$RES -p $2 | \
-		sed "/^ligatures /s/ $LIGIGN//g" >$TP/$1
+	otfdump -nc $3 >$ODOUT
+	otfdump -k $3 | sort | uniq >>$ODOUT
+	# without any substitutions
+	cat $ODOUT | ./mktrfn $4 -r$RES -p $2 | sed "/^ligatures /s/ $LIGIGN//g" >$TP/$1
 	for FEAT in `echo $FEATS | tr ' ' '\n' | sed "/$OTFFEATS/!d"`
 	do
 		echo "  $1.$FEAT"
-		(grep "^feature $FEAT" $ODOUT; grep -v "^feature " $ODOUT) | \
+		(otfdump -s $3 | grep "^feature $FEAT" | sort | uniq; cat $ODOUT) | \
 			./mktrfn $4 -r$RES -p $2 | \
 			sed "/^ligatures /s/ $LIGIGN//g" >$TP/$1.$FEAT
 	done
@@ -94,10 +98,10 @@
 
 for f in $FP/*.otf
 do
-	otfconv "`basename $f .otf`" "`basename $f .otf`" "$f"
+	otfconv "`basename $f .otf`" "`basename $f .otf`" "$f" -k50
 done
 
 for f in $FP/*.ttf
 do
-	otfconv "`basename $f .ttf`" "`basename $f .ttf`" "$f"
+	otfconv "`basename $f .ttf`" "`basename $f .ttf`" "$f" -k50
 done
--- a/mktrfn.c
+++ b/mktrfn.c
@@ -37,7 +37,7 @@
 		}
 		if (!strcmp("feature", cmd)) {
 			scanf("%s substitution %s %s", name, c1, c2);
-			trfn_subs(c2, c1);
+			trfn_sub(c1, c2);
 		}
 	}
 }
@@ -91,7 +91,8 @@
 	"  -s      \tspecial font\n"
 	"  -p name \toverride font postscript name\n"
 	"  -t name \tset font troff name\n"
-	"  -r res  \tset device resolution (720)\n";
+	"  -r res  \tset device resolution (720)\n"
+	"  -k kmin \tspecify the minimum amount of kerning (0)\n";
 
 int main(int argc, char *argv[])
 {
@@ -99,14 +100,21 @@
 	int i = 1;
 	int res = 720;
 	int spc = 0;
+	int kmin = 0;
 	for (i = 1; i < argc && argv[i][0] == '-'; i++) {
 		switch (argv[i][1]) {
 		case 'a':
 			afm = 1;
 			break;
+		case 'k':
+			kmin = atoi(argv[i][2] ? argv[i] + 2 : argv[++i]);
+			break;
 		case 'o':
 			afm = 0;
 			break;
+		case 'p':
+			trfn_psfont(argv[i][2] ? argv[i] + 2 : argv[++i]);
+			break;
 		case 'r':
 			res = atoi(argv[i][2] ? argv[i] + 2 : argv[++i]);
 			break;
@@ -116,15 +124,12 @@
 		case 't':
 			trfn_trfont(argv[i][2] ? argv[i] + 2 : argv[++i]);
 			break;
-		case 'p':
-			trfn_psfont(argv[i][2] ? argv[i] + 2 : argv[++i]);
-			break;
 		default:
 			printf("%s", usage);
 			return 0;
 		}
 	}
-	trfn_init(res, spc);
+	trfn_init(res, spc, kmin);
 	if (afm)
 		afm_read();
 	else
--- a/sbuf.h
+++ b/sbuf.h
@@ -9,3 +9,4 @@
 void sbuf_done(struct sbuf *sbuf);
 char *sbuf_buf(struct sbuf *sbuf);
 void sbuf_printf(struct sbuf *sbuf, char *s, ...);
+int sbuf_empty(struct sbuf *sbuf);
--- a/trfn.c
+++ b/trfn.c
@@ -10,19 +10,25 @@
 #define WX(w)		(((w) < 0 ? (w) - trfn_div / 2 : (w) + trfn_div / 2) / trfn_div)
 #define LEN(a)		((sizeof(a) / sizeof((a)[0])))
 #define HEXDIGS		"0123456789abcdef"
-#define NCHAR		8
-#define GNLEN		64
-#define AGLLEN		8192
-#define NSUBS		2048
+#define NCHAR		8	/* number of characters per glyph */
+#define GNLEN		64	/* glyph name length */
+#define AGLLEN		8192	/* adobe glyphlist length */
+#define NSUBS		2048	/* number of substitutions */
+#define NPSAL		32	/* number of substitutions per glyph */
 
-static struct sbuf sbuf_char;	/* charset section */
-static struct sbuf sbuf_kern;	/* kernpairs section */
+static struct sbuf sbuf_char;	/* characters */
+static struct sbuf sbuf_kern;	/* kerning pairs */
 static int trfn_div;		/* divisor of widths */
 static int trfn_swid;		/* space width */
 static int trfn_special;	/* special flag */
+static int trfn_kmin;		/* minimum kerning value */
 static char trfn_ligs[8192];	/* font ligatures */
 static char trfn_trname[256];	/* font troff name */
 static char trfn_psname[256];	/* font ps name */
+/* glyph substition */
+static char subs_src[NSUBS][GNLEN];
+static char subs_dst[NSUBS][GNLEN];
+static int subs_n;
 
 /* adobe glyphlist mapping */
 static char agl_key[AGLLEN][GNLEN];
@@ -196,13 +202,9 @@
 		utf8put(&str, s[i]);
 }
 
-static char subs_src[NSUBS][GNLEN];
-static char subs_dst[NSUBS][GNLEN];
-static int subs_n;
-
-void trfn_subs(char *c1, char *c2)
+void trfn_sub(char *c1, char *c2)
 {
-	if (subs_n < NSUBS) {
+	if (subs_n < NSUBS && !strchr(c1, '.')) {
 		strcpy(subs_src[subs_n], c1);
 		strcpy(subs_dst[subs_n], c2);
 		subs_n++;
@@ -209,20 +211,24 @@
 	}
 }
 
-static char *trfn_substitude(char *c)
+/* return the list of postscript glyph aliases of character c */
+static void trfn_subs(char *c, char **a)
 {
 	char *dot;
-	int i;
+	int i, subs = 0;
+	/* adding c itself to the list of aliases only if not substituded */
 	for (i = 0; i < subs_n; i++)
 		if (!strcmp(c, subs_src[i]))
-			return subs_dst[i];
+			subs = 1;
+	dot = strrchr(c, '.');
+	if (!subs && (!dot || !strcmp(".init", dot) || !strcmp(".fina", dot) ||
+							!strcmp(".medi", dot)))
+			*a++ = c;
+	/* adding aliases added via trfn_subs() */
 	for (i = 0; i < subs_n; i++)
 		if (!strcmp(c, subs_dst[i]))
-			return NULL;
-	dot = strrchr(c, '.');
-	if (dot && strcmp(".init", dot) && strcmp(".fina", dot) && strcmp(".medi", dot))
-		return NULL;
-	return c;
+			*a++ = subs_src[i];
+	*a++ = NULL;
 }
 
 static int trfn_name(char *dst, char *src)
@@ -231,7 +237,6 @@
 	char *d = dst;
 	char *s;
 	int i;
-	src = trfn_substitude(src);
 	if (!src || src[0] == '.')
 		return 1;
 	while (*src && *src != '.') {
@@ -280,39 +285,46 @@
 	return t ? t->type : 3;
 }
 
-void trfn_char(char *c, char *n, int wid, int typ)
+void trfn_char(char *psname, char *n, int wid, int typ)
 {
-	char uc[GNLEN];
-	char pos[GNLEN];
-	char **a;
-	if (trfn_name(uc, c))
+	char uc[GNLEN];			/* mapping unicode character */
+	char *a_ps[NPSAL] = {NULL};	/* postscript glyph substitutions */
+	char **a_tr;			/* troff character names */
+	char pos[GNLEN] = "";		/* postscript character position/name */
+	int i_ps = 0;			/* current name in a_ps */
+	/* initializing character attributes */
+	if (trfn_name(uc, psname))
 		strcpy(uc, "---");
-	if (strchr(uc, ' ')) {		/* space not allowed in char names */
-		if (!trfn_swid && !strcmp(" ", uc))
-			trfn_swid = WX(wid);
-		return;
-	}
-	if (strcmp("---", uc))
-		trfn_lig(uc);
-	if (typ < 0)
-		typ = trfn_type(uc);
-	strcpy(pos, c);
 	if (n && atoi(n) >= 0 && atoi(n) < 256)
 		strcpy(pos, n);
-	if (!n && !strchr(c, '.') && !uc[1] && uc[0] >= 32 && uc[0] <= 125)
+	if (!n && !strchr(psname, '.') && !uc[1] && uc[0] >= 32 && uc[0] <= 125)
 		sprintf(pos, "%d", uc[0]);
-	sbuf_printf(&sbuf_char, "%s\t%d\t%d\t%s\n", uc, WX(wid), typ, pos);
-	a = tab_get(tab_alts, uc);
-	while (a && *a)
-		sbuf_printf(&sbuf_char, "%s\t\"\n", *a++);
+	if (typ < 0)
+		typ = trfn_type(!strchr(psname, '.') ? uc : "");
+	/* printing troff charset */
+	trfn_subs(psname, a_ps);
+	for (i_ps = 0; !i_ps || a_ps[i_ps]; i_ps++) {
+		if (trfn_name(uc, a_ps[i_ps]))
+			strcpy(uc, "---");
+		if (strchr(uc, ' ')) {		/* space not allowed in char names */
+			if (!trfn_swid && !strcmp(" ", uc))
+				trfn_swid = WX(wid);
+			continue;
+		}
+		if (strcmp("---", uc))
+			trfn_lig(uc);
+		sbuf_printf(&sbuf_char, "char %s\t%d\t%d\t%s\t%s\n",
+				uc, WX(wid), typ, psname, pos);
+		a_tr = tab_get(tab_alts, uc);
+		while (a_tr && *a_tr)
+			sbuf_printf(&sbuf_char, "char %s\t\"\n", *a_tr++);
+	}
 }
 
 void trfn_kern(char *c1, char *c2, int x)
 {
-	char g1[GNLEN], g2[GNLEN];
-	if (!trfn_name(g1, c1) && !trfn_name(g2, c2) && abs(WX(x)) > WX(20))
-		if (!strchr(g1, ' ') && !strchr(g2, ' '))
-			sbuf_printf(&sbuf_kern, "%s\t%s\t%d\n", g1, g2, WX(x));
+	if (abs(WX(x)) >= WX(trfn_kmin))
+		sbuf_printf(&sbuf_kern, "kern %s\t%s\t%d\n", c1, c2, WX(x));
 }
 
 void trfn_trfont(char *name)
@@ -337,17 +349,16 @@
 	printf("ligatures %s0\n", trfn_ligs);
 	if (trfn_special)
 		printf("special\n");
-	printf("charset\n");
 	printf("%s", sbuf_buf(&sbuf_char));
-	printf("kernpairs\n");
 	printf("%s", sbuf_buf(&sbuf_kern));
 }
 
-void trfn_init(int res, int spc)
+void trfn_init(int res, int spc, int kmin)
 {
 	int i;
 	trfn_div = 7200 / res;
 	trfn_special = spc;
+	trfn_kmin = kmin;
 	if (agl_read("glyphlist.txt"))
 		fprintf(stderr, "mktrfn: could not open glyphlist.txt\n");
 	sbuf_init(&sbuf_char);
--- a/trfn.h
+++ b/trfn.h
@@ -1,4 +1,4 @@
-void trfn_init(int res, int special);
+void trfn_init(int res, int special, int kmin);
 void trfn_done(void);
 void trfn_trfont(char *name);
 void trfn_psfont(char *fontname);
@@ -5,4 +5,4 @@
 void trfn_print(void);
 void trfn_char(char *c, char *n, int wid, int typ);
 void trfn_kern(char *c1, char *c2, int x);
-void trfn_subs(char *c1, char *c2);
+void trfn_sub(char *c1, char *c2);