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");
}
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)
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;
clean_path();
adjust_weight();
record_lsb(g);
- emit_hints(vstems, hstems);
+ emit_hints(vstems, ledges, redges, hstems, tedges, bedges);
emit_path();
}