From f6a4441d41c4813ba3a10aec7be5fdb391239206 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Sat, 1 Jun 2024 23:18:25 +0100 Subject: [PATCH] Output glyphs in an order that FontForge won't change FontForge has opinions about what order glyphs in an OpenType font should appear in, at least some of them being mandated by the OpenType spec (for instance that .notdef must by glyph 0). When outputting an OpenType font, FontForge re-orders it in accordance with these opinions. I expect that this will be a problem if I want to emit a table that FontForge doesn't understand, since it won't be able to correct the glyph indexes in that table. Thus I've added code to re-order the glyphs in Bedstead such that FontForge won't re-order them. This should mean that bedstead.c can safely use the glyph indexes that it generates without worrying that FontForge might change them. I don't think FontForge minds what order unencoded glyphs appear in, but I've defined them to be in strcmp() order of glyph name so that they're at least somewhat stable. Before this, they were in the same order as in the source file. --- bedstead.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/bedstead.c b/bedstead.c index ab4291d..1031a32 100644 --- a/bedstead.c +++ b/bedstead.c @@ -207,7 +207,7 @@ static struct glyph { #define SEP6 (SEP | MOS6) #define SEP4 (SEP | MOS4) char const *alias_of; -} const glyphs[] = { +} glyphs[] = { /* * The first batch of glyphs comes from the code tables at the end of * the Mullard SAA5050 series datasheet, dated July 1982. @@ -2646,6 +2646,27 @@ get_glyph_by_name(char const *name) return *gp; } +/* + * Compare glyphs in a way that will put them in an order that + * FontForge won't change. This should mean that our glyph IDs match + * FontForge's, so that we can use them in tables that FontForge + * doesn't understand. + */ +static int +compare_glyphs_by_ffid(const void *va, const void *vb) +{ + struct glyph const *a = va, *b = vb; + + /* .notdef comes first. */ + if (strcmp(a->name, ".notdef") == 0) return -1; + if (strcmp(b->name, ".notdef") == 0) return +1; + /* Then characters with Unicode code-points in order. */ + if ((unsigned)a->unicode < (unsigned)b->unicode) return -1; + if ((unsigned)a->unicode > (unsigned)b->unicode) return +1; + /* Finally sort by glyph name for an arbitrary stable order. */ + return strcmp(a->name, b->name); +} + int main(int argc, char **argv) { @@ -2711,6 +2732,8 @@ main(int argc, char **argv) return 0; } + /* Put glyphs into FontForge-compatible order. */ + qsort(glyphs, nglyphs, sizeof(glyphs[0]), &compare_glyphs_by_ffid); for (i = 0; i < nglyphs; i++) if (glyphs[i].unicode == -1) extraglyphs++; -- 2.30.2