From 7b9dc784ee920c907df6d2f909ec132e99c924c7 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Sun, 3 Nov 2024 17:37:44 +0000 Subject: [PATCH] Record proper left sidebearings in 'hmtx' table That change was more invasive than I was expecting. --- bedstead.c | 88 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 30 deletions(-) diff --git a/bedstead.c b/bedstead.c index 706adf1..f70f601 100644 --- a/bedstead.c +++ b/bedstead.c @@ -213,6 +213,7 @@ static struct glyph { #define SEP4 (SEP | MOS4) #define IS_ALIAS 0x08 #define IS_SUBR 0x10 + uint_least16_t left_sidebearing; /* Set when outline generated. */ } glyphs[] = { /* * The first batch of glyphs comes from the code tables at the end of @@ -2619,16 +2620,16 @@ static int const nglyphs = NGLYPHS; static struct glyph const *glyphs_by_name[NGLYPHS]; -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, bool sep); +static void dochar(struct glyph *g); +static void dochar_plotter(struct glyph *g); +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 glyph_complement(void); static void bdf_gen(int size); -static void dolookups(struct glyph const *); -static void doglyph(struct glyph const *); +static void dolookups(struct glyph *); +static void doglyph(struct glyph *); static bool getpix(char const data[YSIZE - 1], int x, int y, unsigned flags) @@ -2739,6 +2740,13 @@ get_glyph_by_name(char const *name) return *gp; } +static struct glyph * +realglyph(struct glyph *g) +{ + while (g->flags & IS_ALIAS) g = get_glyph_by_name(g->alias_of); + return g; +} + /* * Compare glyphs in a way that will put them in an order that * FontForge wouldn't change. We don't actually use FontForge any @@ -2819,12 +2827,12 @@ main(int argc, char **argv) } if (argc > 1) { - char data[YSIZE]; + struct glyph g = { .flags = 0 }; int i, y; unsigned long u; - for (y = 0; y < YSIZE; y++) - data[y] = 0; + for (y = 0; y < YSIZE - 1; y++) + g.data[y] = 0; y = 0; for (i = 1; i < argc; i++) { @@ -2838,9 +2846,9 @@ main(int argc, char **argv) argv[i]); return EXIT_FAILURE; } - data[y++] = u; + g.data[y++] = u; } - dochar(data, 0); + dochar(&g); return EXIT_SUCCESS; } @@ -3082,8 +3090,7 @@ main(int argc, char **argv) for (i = 0; i < nglyphs; i++) { struct glyph *g = &glyphs[i]; if (g->flags & IS_ALIAS) { - while (g->flags & IS_ALIAS) - g = get_glyph_by_name(g->alias_of); + g = realglyph(g); if (g->flags & IS_SUBR) continue; printf(" ", g->name); doglyph(g); @@ -3110,7 +3117,8 @@ main(int argc, char **argv) printf(" \n"); for (i = 0; i < nglyphs; i++) printf(" \n", - glyphs[i].name, (int)(XSIZE * XPIX), 0 /* XXX */); + glyphs[i].name, (int)(XSIZE * XPIX), + (int)realglyph(&glyphs[i])->left_sidebearing); printf(" \n"); printf("\n"); return EXIT_SUCCESS; @@ -3290,33 +3298,31 @@ docmap(int pid, int eid, int format) /* Emit a charstring for a glyph. */ static void -doglyph(struct glyph const *g) +doglyph(struct glyph *g) { - while (g->flags & IS_ALIAS) - g = get_glyph_by_name(g->alias_of); + g = realglyph(g); if (g->flags & IS_SUBR) printf(" %d callsubr", g->subr_idx - (nsubrs < 1240 ? 107 : 1131)); else if (g->flags & MOS6) - domosaic(g->data[0], (g->flags & SEP) != 0); + domosaic(g); else if (g->flags & MOS4) - domosaic4(g->data[0], (g->flags & SEP) != 0); + domosaic4(g); else if (plottermode) - dochar_plotter(g->data, g->flags); + dochar_plotter(g); else - dochar(g->data, g->flags); + dochar(g); } static void -dopalt(struct glyph const *g) +dopalt(struct glyph *g) { int i; unsigned char cols = 0; int dx = 0, dh = 0; - while (g->flags & IS_ALIAS) - g = get_glyph_by_name(g->alias_of); + g = realglyph(g); if (g->flags & (MOS6|MOS4)) return; /* * For proportional layout, we'd like a left side-bearing of @@ -3344,7 +3350,7 @@ dopalt(struct glyph const *g) static void -dolookups(struct glyph const *g) +dolookups(struct glyph *g) { char prefix[32]; struct glyph const **found, **gp; @@ -3742,11 +3748,26 @@ whitepixel(int x, int y, bool bl, bool br, bool tr, bool tl) } static void -dochar(char const data[YSIZE], unsigned flags) +record_lsb(struct glyph *g) +{ + int i; + int lsb = XPIX_S * XSIZE; + + for (i = 0; i < nextpoint; i++) { + if (points[i].next == NULL) continue; + if (points[i].v.x < lsb) lsb = points[i].v.x; + } + /* A glyph with no contours has an lsb of zero. */ + if (lsb < XPIX_S * XSIZE) + g->left_sidebearing = lsb / XSCALE; +} + +static void +dochar(struct glyph *g) { int x, y; -#define GETPIX(x,y) (getpix(data, (x), (y), flags)) +#define GETPIX(x,y) (getpix(g->data, (x), (y), g->flags)) #define L GETPIX(x-1, y) #define R GETPIX(x+1, y) #define U GETPIX(x, y-1) @@ -3791,6 +3812,7 @@ dochar(char const data[YSIZE], unsigned flags) } clean_path(); adjust_weight(); + record_lsb(g); emit_path(); } @@ -3883,7 +3905,7 @@ clean_skeleton() } static void -dochar_plotter(char const data[YSIZE], unsigned flags) +dochar_plotter(struct glyph *g) { int x, y; @@ -3922,8 +3944,10 @@ tile(int x0, int y0, int x1, int y1) } static void -domosaic(unsigned code, bool sep) +domosaic(struct glyph *g) { + unsigned code = g->data[0]; + bool sep = (g->flags & SEP) != 0; clearpath(); if (code & 1) tile(0 + sep, 7 + sep, 3, 10); @@ -3933,12 +3957,15 @@ domosaic(unsigned code, bool sep) if (code & 16) tile(0 + sep, 0 + sep, 3, 3); if (code & 32) tile(3 + sep, 0 + sep, 6, 3); clean_path(); + record_lsb(g); emit_path(); } static void -domosaic4(unsigned code, bool sep) +domosaic4(struct glyph *g) { + unsigned code = g->data[0]; + bool sep = (g->flags & SEP) != 0; clearpath(); if (code & 1) tile(0 + sep, 5 + sep, 3, 10); @@ -3946,6 +3973,7 @@ domosaic4(unsigned code, bool sep) if (code & 4) tile(0 + sep, 0 + sep, 3, 5); if (code & 8) tile(3 + sep, 0 + sep, 6, 5); clean_path(); + record_lsb(g); emit_path(); } -- 2.30.2