#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
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)
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
}
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++) {
argv[i]);
return EXIT_FAILURE;
}
- data[y++] = u;
+ g.data[y++] = u;
}
- dochar(data, 0);
+ dochar(&g);
return EXIT_SUCCESS;
}
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(" <CharString> <!-- %s -->", g->name);
doglyph(g);
printf(" <hmtx>\n");
for (i = 0; i < nglyphs; i++)
printf(" <mtx name='%s' width='%d' lsb='%d'/>\n",
- glyphs[i].name, (int)(XSIZE * XPIX), 0 /* XXX */);
+ glyphs[i].name, (int)(XSIZE * XPIX),
+ (int)realglyph(&glyphs[i])->left_sidebearing);
printf(" </hmtx>\n");
printf("</ttFont>\n");
return EXIT_SUCCESS;
/* 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
static void
-dolookups(struct glyph const *g)
+dolookups(struct glyph *g)
{
char prefix[32];
struct glyph const **found, **gp;
}
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)
}
clean_path();
adjust_weight();
+ record_lsb(g);
emit_path();
}
}
static void
-dochar_plotter(char const data[YSIZE], unsigned flags)
+dochar_plotter(struct glyph *g)
{
int x, y;
}
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);
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);
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();
}