chiark / gitweb /
Redesign how stylistic sets for particular chips work
authorBen Harris <bjh21@bjh21.me.uk>
Fri, 20 Dec 2024 16:42:23 +0000 (16:42 +0000)
committerBen Harris <bjh21@bjh21.me.uk>
Sun, 29 Dec 2024 18:50:11 +0000 (18:50 +0000)
The old approach was that each stylistic set had a distinct glyph-name
suffix, the same way that small caps or right-to-left mirrored glyphs
did. This meant that when several chips used the same alternative
glyph, there needed to be a separate alias for each chip.  This was
slightly awkward for just the SAA5051 and SAA5052, but I'd like to add
coverage for the SN74S262 and SN74S263, and those share some of the
same glyphs as well.

So now those stylistic sets have an explicit list of which variant
glyphs they include, and my plan is that each variant glyph will have
a single canonical name.  They'll still have to keep the existing
names for compatibility.  Indeed, for now that's what they're using
because that makes checking the output easier.

No change to the resulting font, though the lookups do end up in a
different order in the TTX file.

bedstead.c

index bbb002a95d80a48c87c7713621b248b929783387..c2d2f8107e1af4080025f43868a37f4a19dfd754 100644 (file)
@@ -2677,6 +2677,7 @@ static int const nglyphs = NGLYPHS;
 
 static struct glyph const *glyphs_by_name[NGLYPHS];
 
+#define MAXSUBS 10
 static struct gsub_feature {
        char const *tag;
 #define SCRIPT_DFLT 0x01
@@ -2684,17 +2685,28 @@ static struct gsub_feature {
 #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 =
@@ -3565,19 +3577,35 @@ dogsub(void)
        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");
        }