From: Ben Harris Date: Sat, 16 Nov 2024 23:33:30 +0000 (+0000) Subject: Some infrastructure towards edge hints X-Git-Tag: bedstead-3.246~26 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~bjharris/git?a=commitdiff_plain;h=1ad04e13fa255e46395c022fdc8697fbc4c91851;p=bedstead.git Some infrastructure towards edge hints There are places to record them now, but they're ignored by select_hints() and emit_hints(). --- diff --git a/bedstead.c b/bedstead.c index e120c75..6af8523 100644 --- a/bedstead.c +++ b/bedstead.c @@ -3808,51 +3808,79 @@ emit_path(void) printf(" endchar"); } +/* An "A" edge is top or left, a "Z" edge is bottom or right. */ +enum hint_type { + hint_none, hint_stem, hint_aedge, hint_zedge +}; + static void -select_hints(int nstems, int stems[nstems]) +select_hints(int nstems, int stems[nstems], + int aedges[nstems], int zedges[nstems], + enum hint_type hints[nstems]) { + int most = 0; + /* Find longest stems. */ for (int i = 0; i < nstems; i++) { - if (stems[i] > 0) { - stems[i] = 1; - if (i + 1 < nstems) stems[i + 1] = 0; + hints[i] = hint_none; + if (stems[i] > most) most = stems[i]; + } + for (;most > 0; most--) { + /* Prefer long stems. */ + for (int i = 0; i < nstems; i++) { + if (stems[i] == most) { + hints[i] = hint_stem; + stems[i] = 0; + /* Disallow overlapping stems. */ + if (i >= 1) stems[i-1] = 0; + if (i < nstems - 1) stems [i+1] = 0; + } } } } static void -emit_hints(int vstems[XSIZE], int hstems[YSIZE]) +emit_hints(int vstems[XSIZE], int ledges[XSIZE], int redges[XSIZE], + int hstems[YSIZE], int tedges[YSIZE], int bedges[YSIZE]) { int i, start, size, cur; + enum hint_type vhints[XSIZE], hhints[YSIZE]; bool printed; - select_hints(YSIZE, hstems); + select_hints(YSIZE, hstems, tedges, bedges, hhints); cur = DESCENT * YPIX; printed = false; - size = YPIX_S; for (i = YSIZE - 1; i >= 0; i--) { - if (hstems[i] > 0) { + switch (hhints[i]) { + case hint_stem: start = (YSIZE - i - 1) * YPIX_S; - printf(" %g %g", - (double)((start - cur) / YSCALE), - (double)(size / YSCALE)); - cur = start + size; - printed = true; + size = YPIX_S; + break; + default: continue; } + printf(" %g %g", + (double)((start - cur) / YSCALE), + (double)(size / YSCALE)); + cur = start + size; + printed = true; } if (printed) printf(" hstem"); - select_hints(XSIZE, vstems); + select_hints(XSIZE, vstems, ledges, redges, vhints); cur = 0; printed = false; size = XPIX_S + weight->weight; for (i = 0; i < XSIZE; i++) { - if (vstems[i] > 0) { + switch (vhints[i]) { + case hint_stem: start = i * XPIX_S - weight->weight; - printf(" %g %g", - (double)((start - cur) / XSCALE), - (double)(size / XSCALE)); - cur = start + size; - printed = true; + size = XPIX_S + weight->weight; + break; + default: continue; } + printf(" %g %g", + (double)((start - cur) / XSCALE), + (double)(size / XSCALE)); + cur = start + size; + printed = true; } if (printed) printf(" vstem"); } @@ -3994,7 +4022,8 @@ static void dochar(struct glyph *g) { int x, y; - int vstems[XSIZE], hstems[YSIZE]; + int vstems[XSIZE], ledges[XSIZE], redges[XSIZE]; + int hstems[YSIZE], tedges[YSIZE], bedges[YSIZE]; #define GETPIX(x,y) (getpix(g->data, (x), (y), g->flags)) #define L GETPIX(x-1, y) @@ -4029,11 +4058,15 @@ dochar(struct glyph *g) 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]++; + else if (!U && !D && (L || R)) hstems[y]++; + else if (UL + U + UR + L + R + DL + D + DR == 0) + vstems[x]++, hstems[y]++; + else { /* Not a stem. Maybe an edge? */ + if (UL + U + UR == 0) tedges[y]++; + if (DL + D + DR == 0) bedges[y]++; + if (UL + L + DL == 0) ledges[x]++; + if (UR + R + DR == 0) redges[x]++; } } else { bool tl, tr, bl, br; @@ -4052,7 +4085,7 @@ dochar(struct glyph *g) clean_path(); adjust_weight(); record_lsb(g); - emit_hints(vstems, hstems); + emit_hints(vstems, ledges, redges, hstems, tedges, bedges); emit_path(); }