From: Ben Harris Date: Sat, 9 Nov 2024 23:51:36 +0000 (+0000) Subject: Generate stem hints X-Git-Tag: bedstead-3.246~41 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~bjharris/git?a=commitdiff_plain;h=4254bff53ae9367bf09302ebecded363617af322;p=bedstead.git Generate stem hints These are generated from the glyph bitmap by a similar pattern-matching arrangement that generates the outline. Then, like emit_path(), there's an emit_hints() that turns them into valid charstrings. The handling of overlapping hints could be cleverer: at the moment we emit the leftmost-possible set of hints, but we collect a histogram of where hints are needed so could instead emit the most useful. Or even try to do hint substitution. This makes the Bedstead Web page at 90% zoom much prettier than before, but it's not as good as the FontForge auto-hinter managed. Edge hints and counter hints will probably help. --- diff --git a/bedstead.c b/bedstead.c index 0de87ff..7522b6e 100644 --- a/bedstead.c +++ b/bedstead.c @@ -3746,6 +3746,43 @@ emit_path(void) printf(" endchar"); } +static void +emit_hints(int vstems[XSIZE], int hstems[YSIZE]) +{ + int i, start, size, cur; + bool printed; + + cur = 0; printed = false; + size = XPIX_S + weight->weight; + for (i = 0; i < XSIZE; i++) { + if (vstems[i] > 0) { + start = i * XPIX_S - weight->weight; + printf(" %g %g", + (double)((start - cur) / XSCALE), + (double)(size / XSCALE)); + cur = start + size; + i++; /* Avoid overlapping stems. */ + printed = true; + } + } + if (printed) printf(" vstem"); + + cur = DESCENT * YPIX; printed = false; + size = YPIX_S; + for (i = YSIZE - 1; i >= 0; i--) { + if (hstems[i] > 0) { + start = (YSIZE - i - 1) * YPIX_S; + printf(" %g %g", + (double)((start - cur) / YSCALE), + (double)(size / YSCALE)); + cur = start + size; + i--; /* Avoid overlapping stems. */ + printed = true; + } + } + if (printed) printf(" hstem"); +} + /* * To vary the weight of Bedstead, we just vary the thickness of * vertical strokes. More precisely, we pretend that the weight @@ -3883,6 +3920,7 @@ static void dochar(struct glyph *g) { int x, y; + int vstems[XSIZE], hstems[YSIZE]; #define GETPIX(x,y) (getpix(g->data, (x), (y), g->flags)) #define L GETPIX(x-1, y) @@ -3894,6 +3932,8 @@ dochar(struct glyph *g) #define DL GETPIX(x-1, y+1) #define DR GETPIX(x+1, y+1) + for (x = 0; x < XSIZE; x++) vstems[x] = 0; + for (y = 0; y < YSIZE; y++) hstems[y] = 0; clearpath(); for (x = 0; x < XSIZE; x++) { for (y = 0; y < YSIZE; y++) { @@ -3913,6 +3953,14 @@ dochar(struct glyph *g) if (L || DL || D) bl = true; if (R || DR || D) br = true; blackpixel(x, YSIZE - y - 1, bl, br, tr, tl); + if (!L && !R && (U || D)) + vstems[x]++; + if (!U && !D && (L || R)) + hstems[y]++; + if (UL + U + UR + L + R + DL + D + DR == 0) { + vstems[x]++; + hstems[y]++; + } } else { bool tl, tr, bl, br; @@ -3930,6 +3978,7 @@ dochar(struct glyph *g) clean_path(); adjust_weight(); record_lsb(g); + emit_hints(vstems, hstems); emit_path(); }