chiark / gitweb /
Some infrastructure towards edge hints
authorBen Harris <bjh21@bjh21.me.uk>
Sat, 16 Nov 2024 23:33:30 +0000 (23:33 +0000)
committerBen Harris <bjh21@bjh21.me.uk>
Sat, 16 Nov 2024 23:33:30 +0000 (23:33 +0000)
There are places to record them now, but they're ignored by
select_hints() and emit_hints().

bedstead.c

index e120c756197066e9af72eebb73e957021318efb9..6af85239c1518a80b7dfb38d2958c9c3b506f28b 100644 (file)
@@ -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();
 }