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);