shithub: neatmkfn

Download patch

ref: df10da43ee913de20674851c35a0440e2c78e3f4
parent: 25138e475ff9e5cef62dd0e8a455bf9812f84d6e
author: Ali Gholami Rudi <ali@rudi.ir>
date: Tue Aug 12 19:46:52 EDT 2014

mkfn: add -O parameter to order otf lookups

In some languages like Arabic, some features should be applied first.
The -O argument of mkfn allows specifying the features to output
before any other feature.  For instance for Arabic, one should pass
"-O ccmp,rlig,calt,liga,dlig,cswh,mset" to mkfn.  Thanks to Behdad
Esfahbod <behdad@behdad.org> for the explanation.

--- a/README
+++ b/README
@@ -2,11 +2,16 @@
 ======
 
 The mktrfn program creates troff font description files for neatroff
-from AFM (Adobe Font Metrics) files.  TrueType and OpenType fonts can
-be first converted to AFM using programs like fontforge or
-lcdf-typetools (see ./gen.sh, for instance).  See the output of
-"mktrfn -h" for the available options.
+from AFM (Adobe Font Metrics) and TTF (TrueType Font) files.  OpenType
+fonts can be first converted to TTF (see ./gen.sh, for instance).  See
+the output of "mktrfn -h" for the available options.
 
 The included ./gen.sh script invokes mktrfn to create a complete
 output device for neatroff.  Change the variables in that file before
 running it.
+
+By default, font features are ordered as specified in the font.
+However, in some languages like Arabic, some features should be
+applied first.  The -O argument of mkfn allows specifying the features
+to output before any other feature.  For instance for Arabic, one
+should pass "-O ccmp,rlig,calt,liga,dlig,cswh,mset" to mkfn.
--- a/mkfn.c
+++ b/mkfn.c
@@ -17,6 +17,7 @@
 
 static char *trfn_scripts;	/* filtered scripts */
 static char *trfn_langs;	/* filtered languages */
+static char *trfn_featranks;	/* manual feature ordering */
 
 static char *afm_charfield(char *s, char *d)
 {
@@ -130,6 +131,12 @@
 	return !!strstr(trfn_langs, lang);
 }
 
+int trfn_featrank(char *feat)
+{
+	char *s = trfn_featranks ? strstr(trfn_featranks, feat) : NULL;
+	return s ? s - trfn_featranks : 1000;
+}
+
 int otf_read(void);
 void otf_feat(int res, int kmin, int warn);
 
@@ -146,6 +153,7 @@
 	"  -b      \tinclude glyph bounding boxes\n"
 	"  -S scrs \tcomma-separated list of scripts to include (help to list)\n"
 	"  -L langs\tcomma-separated list of languages to include (help to list)\n"
+	"  -O order\tfeatures to apply first (required only for some languages)\n"
 	"  -w      \twarn about unsupported font features\n";
 
 int main(int argc, char *argv[])
@@ -173,6 +181,9 @@
 			break;
 		case 'o':
 			afm = 0;
+			break;
+		case 'O':
+			trfn_featranks = argv[i][2] ? argv[i] + 2 : argv[++i];
 			break;
 		case 'p':
 			trfn_psfont(argv[i][2] ? argv[i] + 2 : argv[++i]);
--- a/otf.c
+++ b/otf.c
@@ -689,7 +689,11 @@
 
 static int lookupcmp(void *v1, void *v2)
 {
-	return ((struct otflookup *) v1)->lookup - ((struct otflookup *) v2)->lookup;
+	struct otflookup *l1 = v1;
+	struct otflookup *l2 = v2;
+	if (trfn_featrank(l1->feat) != trfn_featrank(l2->feat))
+		return trfn_featrank(l1->feat) - trfn_featrank(l2->feat);
+	return l1->lookup - l2->lookup;
 }
 
 /* extract lookup tables for all features of the given gsub/gpos table */
--- a/trfn.h
+++ b/trfn.h
@@ -7,3 +7,4 @@
 void trfn_kern(char *c1, char *c2, int x);
 int trfn_script(char *script, int nscripts);
 int trfn_lang(char *lang, int nlangs);
+int trfn_featrank(char *feat);