From: Ben Harris Date: Tue, 5 Nov 2024 23:57:51 +0000 (+0000) Subject: 'aalt' feature implemented via TTX X-Git-Tag: bedstead-3.246~49 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~bjharris/git?a=commitdiff_plain;h=774c06ba3bf41d6dd68c559ca6d1d5a3231c6a63;p=bedstead-debian.git 'aalt' feature implemented via TTX --- diff --git a/bedstead.c b/bedstead.c index 324490b..b82753b 100644 --- a/bedstead.c +++ b/bedstead.c @@ -2620,27 +2620,38 @@ static int const nglyphs = NGLYPHS; static struct glyph const *glyphs_by_name[NGLYPHS]; -static struct gsub_lookup { +static struct gsub_feature { char const *tag; - char const *suffix; + char const *suffix; /* NULL for all alternative glyphs. */ #define SCRIPT_DFLT 0x01 #define SCRIPT_LATN 0x02 -#define SCRIPT_ALL 0x03 +#define SCRIPT_ALL 0x03 unsigned int scripts; char const *name; -} const gsub_lookups[] = { - { "aalt", NULL, SCRIPT_ALL }, - { "smcp", "sc", SCRIPT_LATN }, - { "c2sc", "c2sc", SCRIPT_LATN }, - { "rtlm", "rtlm", SCRIPT_ALL }, - { "ss01", "saa5051", SCRIPT_ALL, "SAA5051" }, - { "ss02", "saa5052", SCRIPT_ALL, "SAA5052" }, - { "ss04", "saa5054", SCRIPT_ALL, "SAA5054" }, - { "ss14", "sep4", SCRIPT_ALL, "4-cell separated graphics" }, - { "ss16", "sep6", SCRIPT_ALL, "6-cell separated graphics" }, +} const gsub_features[] = { + { "aalt", NULL, SCRIPT_ALL }, + { "smcp", ".sc", SCRIPT_LATN }, + { "c2sc", ".c2sc", SCRIPT_LATN }, + { "rtlm", ".rtlm", SCRIPT_ALL }, + { "ss01", ".saa5051", SCRIPT_ALL, "SAA5051" }, + { "ss02", ".saa5052", SCRIPT_ALL, "SAA5052" }, + { "ss04", ".saa5054", SCRIPT_ALL, "SAA5054" }, + { "ss14", ".sep4", SCRIPT_ALL, "4-cell separated graphics" }, + { "ss16", ".sep6", SCRIPT_ALL, "6-cell separated graphics" }, +}; + +static int const ngsub_features = + sizeof(gsub_features) / sizeof(gsub_features[0]); + +struct gsub_script { + char const *tag; + unsigned int flag; +} const gsub_scripts[] = { + { "DFLT", SCRIPT_DFLT }, + { "latn", SCRIPT_LATN }, }; -#define NGSUB_LOOKUPS (sizeof(gsub_lookups) / sizeof(gsub_lookups[0])) +static int const ngsub_scripts = sizeof(gsub_scripts) / sizeof(gsub_scripts[0]); static void dochar(struct glyph *g); static void dochar_plotter(struct glyph *g); @@ -2648,6 +2659,8 @@ static void domosaic(struct glyph *g); static void domosaic4(struct glyph *g); static void dopanose(void); static void docmap(int pid, int eid, int format); +static void dogsub(void); +static void doaltsubs(void); static void glyph_complement(void); static void bdf_gen(int size); static void dolookups(struct glyph *); @@ -3017,9 +3030,9 @@ main(int argc, char **argv) NAME(6, fullname_to_fontname(get_fullname())); /* Stylistic set names. */ #define NAMEBASE_GSUB 0x100 - for (i = 0; i < NGSUB_LOOKUPS; i++) - if (gsub_lookups[i].name != NULL) - NAME(NAMEBASE_GSUB + i, gsub_lookups[i].name); + for (i = 0; i < ngsub_features; i++) + if (gsub_features[i].name != NULL) + NAME(NAMEBASE_GSUB + i, gsub_features[i].name); printf(" \n"); printf(" \n"); @@ -3071,8 +3084,6 @@ main(int argc, char **argv) /* printf("StrokedFont: 1\n"); */ /* printf("StrokeWidth: 50\n"); */ /* } */ - /* printf("Lookup: 3 0 0 \"aalt: all alternates\" {\"aalt\"} " */ - /* "['aalt' ('DFLT' <'dflt'> 'latn' <'dflt'>)]\n"); */ /* printf("Lookup: 1 0 0 \"smcp: lower-case to small caps\" " */ /* "{\"smcp\" (\"sc\")} " */ /* "['smcp' ('latn' <'dflt'>)]\n"); */ @@ -3141,6 +3152,7 @@ main(int argc, char **argv) glyphs[i].name, (int)(XSIZE * XPIX), (int)realglyph(&glyphs[i])->left_sidebearing); printf(" \n"); + dogsub(); printf("\n"); return EXIT_SUCCESS; } @@ -3317,6 +3329,93 @@ docmap(int pid, int eid, int format) printf(" \n", format); } +static void +dogsub(void) +{ + int i, j; + + printf(" \n"); + TTXS(Version, "0x00010000"); + printf(" \n"); + for (i = 0; i < ngsub_scripts; i++) { + printf(" \n"); + TTXS(ScriptTag, gsub_scripts[i].tag); + printf(" \n"); + printf(" \n"); + } + printf(" \n"); + printf(" \n"); + for (i = 0; i < ngsub_features; i++) { + printf(" \n"); + TTXS(FeatureTag, gsub_features[i].tag); + printf(" \n"); + if (gsub_features[i].name != NULL) { + printf(" \n"); + TTXI(Version, 0); + TTXI(UINameID, NAMEBASE_GSUB + i); + printf(" \n"); + } + /* We only have one GSUB lookup per feature, thankfully. */ + TTXI(LookupListIndex, i); + printf(" \n"); + printf(" \n"); + } + printf(" \n"); + printf(" \n"); + for (i = 0; i < ngsub_features; i++) { + printf(" \n"); + if (gsub_features[i].suffix == NULL) { + /* This is 'aalt' */ + TTXI(LookupType, 3); + TTXI(LookupFlag, 0); + printf(" \n"); + doaltsubs(); + printf(" \n"); + } else { + TTXI(LookupType, 1); + TTXI(LookupFlag, 0); + printf(" \n"); + printf(" \n"); + } + printf(" \n"); + } + printf(" \n"); + printf(" \n"); + +} + +/* Find all the mappings from normal to alternative glyphs. */ +static void +doaltsubs(void) +{ + int i; + + for (i = 1; i < nglyphs; i++) { +#define HASDOT(x) (strchr(glyphs_by_name[x]->name, '.') != NULL) + /* + * We want to map each glyph with a name that doesn't + * contain a '.' to all the glyphs whose names start + * with that name followed by a '.'. By sorting them + * by name, we guarantee that each qualified glyph + * name comes immediately after the unqualified one. + * [Does that depend on ASCII ordering?] + */ + if (HASDOT(i)) { + printf(" ", + glyphs_by_name[i-1]->name); + for (; i < nglyphs && HASDOT(i); i++) + printf("", + glyphs_by_name[i]->name); + printf("\n"); + } + } +} + /* Emit a charstring for a glyph. */ static void doglyph(struct glyph *g) @@ -3405,14 +3504,6 @@ dolookups(struct glyph *g) if (strcmp((*gp)->name + plen, "rtlm") == 0) printf("Substitution2: \"rtlm\" %s\n", (*gp)->name); } - if (any_alt) { - printf("AlternateSubs2: \"aalt\""); - for (gp = found + 1; gp < glyphs_by_name + nglyphs; gp++) { - if (strncmp(prefix, (*gp)->name, plen) != 0) break; - printf(" %s", (*gp)->name); - } - printf("\n"); - } dopalt(g); }