From 62cf866e11a041bad7607801f4f323dae8c23938 Mon Sep 17 00:00:00 2001 From: Ali Gholami Rudi Date: Sat, 17 Dec 2016 20:42:25 +0330 Subject: [PATCH] otf: for each rule report its script --- mkfn.c | 21 ++++++++++++--------- otf.c | 67 +++++++++++++++++++++++++++++++++++++++++++++--------------------- trfn.h | 2 +- 3 files changed, 59 insertions(+), 31 deletions(-) diff --git a/mkfn.c b/mkfn.c index cde2b7e..395b0c3 100644 --- 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 @@ static char *scriptorder[][2] = { /* 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 @@ int trfn_lang(char *lang, int nlangs) } /* 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); diff --git a/otf.c b/otf.c index 629c531..666c9ee 100644 --- a/otf.c +++ b/otf.c @@ -35,7 +35,7 @@ static int glyph_n; 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 @@ static int uwid(int w) 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 @@ static void otf_gpostype4(void *otf, void *sub, char *feat) 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)); + 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 @@ static void otf_gsubtype6(void *otf, void *sub, char *feat, void *gsub) /* 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,13 +715,14 @@ static int otf_featrec(void *otf, void *gtab, void *featrec, struct otflookup *l 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; } /* 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 @@ static int otf_lang(void *otf, void *gtab, void *lang, struct otflookup *lookups 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 @@ static int lookupcmp(void *v1, void *v2) { 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 @@ static int otf_gtab(void *otf, void *gpos, struct otflookup *lookups) 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 @@ static void otf_gpos(void *otf, void *gpos) 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 @@ static void otf_gsub(void *otf, void *gsub) 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; diff --git a/trfn.h b/trfn.h index fcb0533..d4d93a4 100644 --- a/trfn.h +++ b/trfn.h @@ -7,4 +7,4 @@ void trfn_char(char *c, int n, int u, int wid, int llx, int lly, int urx, int ur 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); -- 2.11.4.GIT