Add a mechanism for making aliases of glyphs

This is done by making the new glyph contain only a reference to the
old one.  While it's possible to have multiple Unicode code points
reference the same glyph, that's rarely what you want because it's
useful to be able to map back from a glyph name to a code point, and
obviously that requires that the glyph have different names when
accessed through different code points.
This commit is contained in:
Ben Harris 2020-03-28 16:53:38 +00:00
parent c8c26e41a3
commit 1dc4e2da16

View File

@ -217,11 +217,13 @@ static void dochar(char const data[YSIZE], unsigned flags);
static void dochar_plotter(char const data[YSIZE], unsigned flags);
static void domosaic(unsigned code, bool sep);
static void domosaic4(unsigned code);
static void doalias(char const *alias_of);
static void dopanose(void);
static void glyph_complement(void);
/* U(N) sets the code point and name of a glyph not in AGLFN */
#define U(N) 0x ## N, "uni" #N
#define ALIAS(alias, canonical) {{},-1,alias,0,canonical}
static struct glyph {
char data[YSIZE];
@ -231,6 +233,7 @@ static struct glyph {
#define SC 0x01 /* Character has a small-caps variant. */
#define MOS 0x02 /* Mosaic graphics character */
#define MOS4 0x04 /* 4-cell mosaic graphics character */
char const *alias_of;
} const glyphs[] = {
/*
* The first batch of glyphs comes from the code tables at the end of
@ -1639,33 +1642,34 @@ static struct glyph {
{{004,012,021,021,025,033,021,000,000}, U(1FBCA) }, /* white chevron up */
/* Latin small caps */
{{000,000,016,021,037,021,021,000,000}, -1, "a.sc" },
{{000,000,036,021,036,021,036,000,000}, -1, "b.sc" },
{{000,000,016,021,020,021,016,000,000}, -1, "c.sc" },
{{000,000,036,021,021,021,036,000,000}, -1, "d.sc" },
{{000,000,037,020,036,020,037,000,000}, -1, "e.sc" },
{{000,000,037,020,036,020,020,000,000}, -1, "f.sc" },
{{000,000,017,020,023,021,017,000,000}, -1, "g.sc" },
{{000,000,021,021,037,021,021,000,000}, -1, "h.sc" },
{{000,000,016,004,004,004,016,000,000}, -1, "i.sc" },
{{000,000,001,001,001,021,016,000,000}, -1, "j.sc" },
{{000,000,021,022,034,022,021,000,000}, -1, "k.sc" },
{{000,000,020,020,020,020,037,000,000}, -1, "l.sc" },
{{000,000,021,033,025,021,021,000,000}, -1, "m.sc" },
{{000,000,021,031,025,023,021,000,000}, -1, "n.sc" },
{{000,000,016,021,021,021,016,000,000}, -1, "o.sc" },
{{000,000,036,021,036,020,020,000,000}, -1, "p.sc" },
{{000,000,016,021,025,022,015,000,000}, -1, "q.sc" },
{{000,000,036,021,036,022,021,000,000}, -1, "r.sc" },
{{000,000,017,020,016,001,036,000,000}, -1, "s.sc" },
{{000,000,037,004,004,004,004,000,000}, -1, "t.sc" },
{{000,000,021,021,021,021,016,000,000}, -1, "u.sc" },
{{000,000,021,021,012,012,004,000,000}, -1, "v.sc" },
{{000,000,021,021,025,025,012,000,000}, -1, "w.sc" },
{{000,000,021,012,004,012,021,000,000}, -1, "x.sc" },
{{000,000,021,012,004,004,004,000,000}, -1, "y.sc" },
{{000,000,037,001,016,020,037,000,000}, -1, "z.sc" },
{{000,000,016,021,037,021,021,000,000}, -1, "a.sc" }, ALIAS("A.c2sc", "a.sc"),
{{000,000,036,021,036,021,036,000,000}, -1, "b.sc" }, ALIAS("B.c2sc", "b.sc"),
{{000,000,016,021,020,021,016,000,000}, -1, "c.sc" }, ALIAS("C.c2sc", "c.sc"),
{{000,000,036,021,021,021,036,000,000}, -1, "d.sc" }, ALIAS("D.c2sc", "d.sc"),
{{000,000,037,020,036,020,037,000,000}, -1, "e.sc" }, ALIAS("E.c2sc", "e.sc"),
{{000,000,037,020,036,020,020,000,000}, -1, "f.sc" }, ALIAS("F.c2sc", "f.sc"),
{{000,000,017,020,023,021,017,000,000}, -1, "g.sc" }, ALIAS("G.c2sc", "g.sc"),
{{000,000,021,021,037,021,021,000,000}, -1, "h.sc" }, ALIAS("H.c2sc", "h.sc"),
{{000,000,016,004,004,004,016,000,000}, -1, "i.sc" }, ALIAS("I.c2sc", "i.sc"),
{{000,000,001,001,001,021,016,000,000}, -1, "j.sc" }, ALIAS("J.c2sc", "j.sc"),
{{000,000,021,022,034,022,021,000,000}, -1, "k.sc" }, ALIAS("K.c2sc", "k.sc"),
{{000,000,020,020,020,020,037,000,000}, -1, "l.sc" }, ALIAS("L.c2sc", "l.sc"),
{{000,000,021,033,025,021,021,000,000}, -1, "m.sc" }, ALIAS("M.c2sc", "m.sc"),
{{000,000,021,031,025,023,021,000,000}, -1, "n.sc" }, ALIAS("N.c2sc", "n.sc"),
{{000,000,016,021,021,021,016,000,000}, -1, "o.sc" }, ALIAS("O.c2sc", "o.sc"),
{{000,000,036,021,036,020,020,000,000}, -1, "p.sc" }, ALIAS("P.c2sc", "p.sc"),
{{000,000,016,021,025,022,015,000,000}, -1, "q.sc" }, ALIAS("Q.c2sc", "q.sc"),
{{000,000,036,021,036,022,021,000,000}, -1, "r.sc" }, ALIAS("R.c2sc", "r.sc"),
{{000,000,017,020,016,001,036,000,000}, -1, "s.sc" }, ALIAS("S.c2sc", "s.sc"),
{{000,000,037,004,004,004,004,000,000}, -1, "t.sc" }, ALIAS("T.c2sc", "t.sc"),
{{000,000,021,021,021,021,016,000,000}, -1, "u.sc" }, ALIAS("U.c2sc", "u.sc"),
{{000,000,021,021,012,012,004,000,000}, -1, "v.sc" }, ALIAS("V.c2sc", "v.sc"),
{{000,000,021,021,025,025,012,000,000}, -1, "w.sc" }, ALIAS("W.c2sc", "w.sc"),
{{000,000,021,012,004,012,021,000,000}, -1, "x.sc" }, ALIAS("X.c2sc", "x.sc"),
{{000,000,021,012,004,004,004,000,000}, -1, "y.sc" }, ALIAS("Y.c2sc", "y.sc"),
{{000,000,037,001,016,020,037,000,000}, -1, "z.sc" }, ALIAS("Z.c2sc", "z.sc"),
{{000,000,016,021,022,021,026,000,000}, -1, "germandbls.sc" },
ALIAS("uni1E9E.c2sc", "germandbls.sc"),
/* and finally */
{{037,021,021,021,021,021,037,000,000}, -1, ".notdef" },
@ -1733,6 +1737,25 @@ compare_glyphs_by_name(const void *va, const void *vb)
return strcmp(a->name, b->name);
}
static int compare_glyph_to_name(const void *vn, const void *vg)
{
struct glyph const * const *gp = vg;
struct glyph const *g = *gp;
char const *name = vn;
return strcmp(name, g->name);
}
static struct glyph const *get_glyph_by_name(char const *name)
{
struct glyph const * const *gp;
gp = bsearch(name, glyphs_by_name, nglyphs,
sizeof(glyphs_by_name[0]), &compare_glyph_to_name);
assert(gp != NULL);
return *gp;
}
int
main(int argc, char **argv)
{
@ -1880,7 +1903,8 @@ main(int argc, char **argv)
printf("Lookup: 1 0 0 \"smcp: lower-case to small caps\" "
"{\"smcp\" (\"sc\")} "
"['smcp' ('latn' <'dflt'>)]\n");
printf("Lookup: 1 0 0 \"c2sc: upper-case to small caps\" {\"c2sc\"} "
printf("Lookup: 1 0 0 \"c2sc: upper-case to small caps\" "
"{\"c2sc\" (\"c2sc\")} "
"['c2sc' ('latn' <'dflt'>)]\n");
printf("BeginChars: %d %d\n", 0x110000 + extraglyphs, nglyphs);
extraglyphs = 0;
@ -1900,7 +1924,9 @@ main(int argc, char **argv)
printf("Flags: HW\n");
printf("LayerCount: 2\n");
dolookups(&glyphs[i]);
if (glyphs[i].flags & MOS)
if (glyphs[i].alias_of != NULL)
doalias(glyphs[i].alias_of);
else if (glyphs[i].flags & MOS)
domosaic(glyphs[i].data[0],
(glyphs[i].data[0] & 0x20) != 0);
else if (glyphs[i].flags & MOS4)
@ -2036,6 +2062,8 @@ dopalt(struct glyph const *g)
unsigned char cols = 0;
int dx = 0, dh = 0;
while (g->alias_of != NULL)
g = get_glyph_by_name(g->alias_of);
if (g->flags & MOS) return;
/*
* For proportional layout, we'd like a left side-bearing of
@ -2628,6 +2656,15 @@ domosaic4(unsigned code)
emit_path();
}
static void
doalias(char const *alias_of)
{
struct glyph const *g;
g = get_glyph_by_name(alias_of);
printf("Refer: %td %d N 1 0 0 1 0 0 1\n", g - glyphs, g->unicode);
}
static int
byunicode(const void *va, const void *vb)
{