static struct glyph const *glyphs_by_name[NGLYPHS];
+#define MAXSUBS 10
static struct gsub_feature {
char const *tag;
#define SCRIPT_DFLT 0x01
#define SCRIPT_ALL 0x03
unsigned int scripts;
char const *suffix; /* NULL for all alternative glyphs. */
+ char const *subs[MAXSUBS]; /* Individual character substitutions. */
char const *name;
} const gsub_features[] = {
{ "aalt", SCRIPT_ALL },
- { "smcp", SCRIPT_LATN, ".sc" },
- { "c2sc", SCRIPT_LATN, ".c2sc" },
- { "rtlm", SCRIPT_ALL, ".rtlm" },
- { "ss01", SCRIPT_ALL, ".saa5051", "SAA5051" },
- { "ss02", SCRIPT_ALL, ".saa5052", "SAA5052" },
- { "ss04", SCRIPT_ALL, ".saa5054", "SAA5054" },
- { "ss14", SCRIPT_ALL, ".sep4", "4-cell separated graphics" },
- { "ss16", SCRIPT_ALL, ".sep6", "6-cell separated graphics" },
+ { "smcp", SCRIPT_LATN, .suffix = ".sc" },
+ { "c2sc", SCRIPT_LATN, .suffix = ".c2sc" },
+ { "rtlm", SCRIPT_ALL, .suffix = ".rtlm" },
+ { "ss01", SCRIPT_ALL, .name = "SAA5051",
+ .subs = { "comma.saa5051", "period.saa5051", "colon.saa5051",
+ "semicolon.saa5051", "question.saa5051",
+ "D.saa5051", "J.saa5051", "L.saa5051",
+ "j.saa5051", "t.saa5051" } },
+ { "ss02", SCRIPT_ALL, .name = "SAA5052",
+ .subs = { "comma.saa5052", "period.saa5052", "colon.saa5052",
+ "semicolon.saa5052", "question.saa5052",
+ "D.saa5052", "J.saa5052", "L.saa5052",
+ "j.saa5052", "t.saa5052" } },
+ { "ss04", SCRIPT_ALL, .name = "SAA5054",
+ .subs = { "ugrave.saa5054", "ocircumflex.saa5054",
+ "ccedilla.saa5054" } },
+ { "ss14", SCRIPT_ALL, ".sep4", .name = "4-cell separated graphics" },
+ { "ss16", SCRIPT_ALL, ".sep6", .name = "6-cell separated graphics" },
};
static int const ngsub_features =
printf(" <LookupList>\n");
for (i = 0; i < ngsub_features; i++) {
printf(" <Lookup>\n");
- if (gsub_features[i].suffix == NULL) {
- /* This is 'aalt' */
- TTXI("LookupType", 3);
- TTXI("LookupFlag", 0);
- printf(" <AlternateSubst>\n");
- doaltsubs();
- printf(" </AlternateSubst>\n");
- } else {
+ if (gsub_features[i].suffix != NULL) {
+ /* Single lookup for all glyphs with a suffix. */
TTXI("LookupType", 1);
TTXI("LookupFlag", 0);
printf(" <SingleSubst>\n");
dosinglesubs(gsub_features[i].suffix);
printf(" </SingleSubst>\n");
+ } else if (gsub_features[i].subs[0] != NULL) {
+ /* Stylistic set of pick and mix glyphs. */
+ TTXI("LookupType", 1);
+ TTXI("LookupFlag", 0);
+ printf(" <SingleSubst>\n");
+ for (int j = 0; j < MAXSUBS; j++) {
+ char const *sub = gsub_features[i].subs[j];
+ if (sub == NULL) break;
+ char *dot = strchr(sub, '.');
+ assert(dot != NULL);
+ printf(" "
+ "<Substitution in='%.*s' out='%s'/>\n",
+ (int)(dot - sub), sub, sub);
+ }
+ printf(" </SingleSubst>\n");
+ } else {
+ /* All possible alternative glyphs. */
+ TTXI("LookupType", 3);
+ TTXI("LookupFlag", 0);
+ printf(" <AlternateSubst>\n");
+ doaltsubs();
+ printf(" </AlternateSubst>\n");
}
printf(" </Lookup>\n");
}