ref: 62cf866e11a041bad7607801f4f323dae8c23938
parent: c665634e1e8cc937426c71e98fcc9d2a13543d1c
author: Ali Gholami Rudi <ali@rudi.ir>
date: Sat Dec 17 15:42:25 EST 2016
otf: for each rule report its script
--- a/mkfn.c
+++ b/mkfn.c
@@ -24,7 +24,6 @@
static char *trfn_scripts; /* filtered scripts */
static char *trfn_langs; /* filtered languages */
-static char *trfn_order; /* feature ordering */
/* OpenType specifies a specific feature order for different scripts */
static char *scriptorder[][2] = {
@@ -63,11 +62,6 @@
/* return 1 if the given script is to be included */
int trfn_script(char *script, int nscripts)
{
- int i;
- trfn_order = NULL;
- for (i = 0; i < LEN(scriptorder); i++)
- if (script && !strcmp(script, scriptorder[i][0]))
- trfn_order = scriptorder[i][1];
/* fill trfn_scripts (if unspecified) in the first call */
if (!trfn_scripts) {
if (nscripts == 1 || !script)
@@ -99,10 +93,19 @@
}
/* return the rank of the given feature, for the current script */
-int trfn_featrank(char *feat)
+int trfn_featrank(char *scrp, char *feat)
{
- char *s = trfn_order ? strstr(trfn_order, feat) : NULL;
- return s ? s - trfn_order : 1000;
+ static char **order;
+ int i;
+ if (!order || strcmp(scrp, order[0])) {
+ order = NULL;
+ for (i = 0; i < LEN(scriptorder); i++)
+ if (!strcmp(scrp, scriptorder[i][0]))
+ order = scriptorder[i];
+ }
+ if (order && strstr(order[1], feat))
+ return strstr(order[1], feat) - order[1];
+ return 1000;
}
int otf_read(void);
--- a/otf.c
+++ b/otf.c
@@ -35,7 +35,7 @@
static int upm; /* units per em */
static int res; /* device resolution */
static int kmin; /* minimum kerning value */
-static int warn;
+static int warn; /* report unsupported tables */
static char *macset[];
@@ -50,6 +50,13 @@
return (w < 0 ? owid(w) - d / 2 : owid(w) + d / 2) / d;
}
+/* weather the script is right-to-left */
+static int otf_r2l(char *feat)
+{
+ char *scrp = strchr(feat, ':') + 1;
+ return !strcmp("arab", scrp) || !strcmp("hebr", scrp);
+}
+
/* report unsupported otf tables */
static void otf_unsupported(char *sub, int type, int fmt)
{
@@ -494,15 +501,23 @@
for (i = 0; i < mcnt; i++) {
void *mark = marks + U16(marks, 2 + 4 * i + 2); /* mark anchor */
int dx = -uwid(S16(mark, 2));
- int dy = uwid(S16(mark, 4));
- printf("gpos %s 2 @%d %s:%+d%+d%+d%+d\n",
+ int dy = -uwid(S16(mark, 4));
+ if (otf_r2l(feat)) {
+ dx += uwid(glyph_wid[mcov[i]]);
+ dy = -dy;
+ }
+ printf("gpos %s 2 @%d %s:%+d%+d%+d%+d\n",
feat, bgrp, glyph_name[mcov[i]], dx, dy, 0, 0);
}
for (i = 0; i < bcnt; i++) {
for (j = 0; j < ccnt; j++) {
void *base = bases + U16(bases, 2 + ccnt * 2 * i + 2 * j);
- int dx = uwid(S16(base, 2));
- int dy = -uwid(S16(base, 4));
+ int dx = uwid(S16(base, 2)) - uwid(glyph_wid[bcov[i]]);
+ int dy = uwid(S16(base, 4));
+ if (otf_r2l(feat)) {
+ dx += uwid(glyph_wid[bcov[i]]);
+ dy = -dy;
+ }
printf("gpos %s 2 %s @%d:%+d%+d%+d%+d\n",
feat, glyph_name[bcov[i]], cgrp[j], dx, dy, 0, 0);
}
@@ -685,12 +700,13 @@
/* an otf gsub/gpos lookup */
struct otflookup {
+ char scrp[8]; /* script name */
char feat[8]; /* feature name */
int lookup; /* index into the lookup table */
};
/* parse the given gsub/gpos feature table */
-static int otf_featrec(void *otf, void *gtab, void *featrec, struct otflookup *lookups)
+static int otf_featrec(void *otf, void *gtab, void *featrec, char *script, struct otflookup *lookups)
{
void *feats = gtab + U16(gtab, 6);
void *feat = feats + U16(featrec, 4);
@@ -699,6 +715,7 @@
for (i = 0; i < nlookups; i++) {
memcpy(lookups[i].feat, featrec, 4);
lookups[i].feat[4] = '\0';
+ strcpy(lookups[i].scrp, script);
lookups[i].lookup = U16(feat, 4 + 2 * i);
}
return nlookups;
@@ -705,7 +722,7 @@
}
/* parse the given language table and its feature tables */
-static int otf_lang(void *otf, void *gtab, void *lang, struct otflookup *lookups)
+static int otf_lang(void *otf, void *gtab, void *lang, char *script, struct otflookup *lookups)
{
void *feats = gtab + U16(gtab, 6);
int featidx = U16(lang, 2);
@@ -713,10 +730,10 @@
int n = 0;
int i;
if (featidx != 0xffff)
- n += otf_featrec(otf, gtab, feats + 2 + 6 * featidx, lookups + n);
+ n += otf_featrec(otf, gtab, feats + 2 + 6 * featidx, script, lookups + n);
for (i = 0; i < nfeat; i++)
n += otf_featrec(otf, gtab,
- feats + 2 + 6 * U16(lang, 6 + 2 * i), lookups + n);
+ feats + 2 + 6 * U16(lang, 6 + 2 * i), script, lookups + n);
return n;
}
@@ -724,8 +741,10 @@
{
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);
+ if (strcmp(l1->scrp, l2->scrp))
+ return strcmp(l1->scrp, l2->scrp);
+ if (trfn_featrank(l1->scrp, l1->feat) != trfn_featrank(l1->scrp, l2->feat))
+ return trfn_featrank(l1->scrp, l1->feat) - trfn_featrank(l1->scrp, l2->feat);
return l1->lookup - l2->lookup;
}
@@ -735,26 +754,28 @@
void *scripts = gpos + U16(gpos, 4);
int nscripts, nlangs;
void *script;
- char tag[8];
+ char stag[8], ltag[8]; /* script and language tags */
int i, j;
int n = 0;
nscripts = U16(scripts, 0);
for (i = 0; i < nscripts; i++) {
void *grec = scripts + 2 + 6 * i;
- memcpy(tag, grec, 4);
- tag[4] = '\0';
- if (!trfn_script(tag, nscripts))
+ memcpy(stag, grec, 4);
+ stag[4] = '\0';
+ if (!trfn_script(stag, nscripts))
continue;
script = scripts + U16(grec, 4);
nlangs = U16(script, 2);
if (U16(script, 0) && trfn_lang(NULL, nlangs + (U16(script, 0) != 0)))
- n += otf_lang(otf, gpos, script + U16(script, 0), lookups + n);
+ n += otf_lang(otf, gpos, script + U16(script, 0),
+ stag, lookups + n);
for (j = 0; j < nlangs; j++) {
void *lrec = script + 4 + 6 * j;
- memcpy(tag, lrec, 4);
- tag[4] = '\0';
- if (trfn_lang(tag, nlangs + (U16(script, 0) != 0)))
- n += otf_lang(otf, gpos, script + U16(lrec, 4), lookups + n);
+ memcpy(ltag, lrec, 4);
+ ltag[4] = '\0';
+ if (trfn_lang(ltag, nlangs + (U16(script, 0) != 0)))
+ n += otf_lang(otf, gpos, script + U16(lrec, 4),
+ stag, lookups + n);
}
}
qsort(lookups, n, sizeof(lookups[0]), (void *) lookupcmp);
@@ -766,12 +787,14 @@
struct otflookup lookups[NLOOKUPS];
void *lookuplist = gpos + U16(gpos, 8);
int nlookups = otf_gtab(otf, gpos, lookups);
+ char tag[16];
int i, j;
for (i = 0; i < nlookups; i++) {
void *lookup = lookuplist + U16(lookuplist, 2 + 2 * lookups[i].lookup);
- char *tag = lookups[i].feat;
int ltype = U16(lookup, 0);
int ntabs = U16(lookup, 4);
+ sprintf(tag, "%s:%s", lookups[i].feat,
+ lookups[i].scrp[0] ? lookups[i].scrp : "DFLT");
for (j = 0; j < ntabs; j++) {
void *tab = lookup + U16(lookup, 6 + 2 * j);
int type = ltype;
@@ -804,12 +827,14 @@
struct otflookup lookups[NLOOKUPS];
void *lookuplist = gsub + U16(gsub, 8);
int nlookups = otf_gtab(otf, gsub, lookups);
+ char tag[16];
int i, j;
for (i = 0; i < nlookups; i++) {
void *lookup = lookuplist + U16(lookuplist, 2 + 2 * lookups[i].lookup);
- char *tag = lookups[i].feat;
int ltype = U16(lookup, 0);
int ntabs = U16(lookup, 4);
+ sprintf(tag, "%s:%s", lookups[i].feat,
+ lookups[i].scrp[0] ? lookups[i].scrp : "DFLT");
for (j = 0; j < ntabs; j++) {
void *tab = lookup + U16(lookup, 6 + 2 * j);
int type = ltype;
--- a/trfn.h
+++ b/trfn.h
@@ -7,4 +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);
+int trfn_featrank(char *scrp, char *feat);