ref: acfc4e9fc9fd7cf704960d9d3182bea09e0ea681
parent: 9b80100cf16bf8bfa27209442d84544e209edacf
author: Ali Gholami Rudi <[email protected]>
date: Wed Feb 19 16:37:48 EST 2014
ren: italic correction escapes This patch also allows troff font description files to include the bounding box of the glyphs; the third column in the charset section, which contains glyph widths, may include four more numbers just like groff. However, in neatroff these numbers specify glyph bounding box.
--- a/font.c
+++ b/font.c
@@ -36,7 +36,7 @@
return i >= 0 ? &fn->glyphs[i] : NULL;
}
-static struct glyph *font_glyphput(struct font *fn, char *id, char *name, int wid, int type)
+static struct glyph *font_glyphput(struct font *fn, char *id, char *name, int type)
{
int i = fn->nglyphs++;
struct glyph *g;
@@ -43,7 +43,6 @@
g = &fn->glyphs[i];
strcpy(g->id, id);
strcpy(g->name, name);
- g->wid = wid;
g->type = type;
g->font = fn;
fn->gnext[i] = fn->ghead[(unsigned char) id[0]];
@@ -144,7 +143,8 @@
char name[ILNLEN];
char id[ILNLEN];
struct glyph *glyph = NULL;
- int wid, type;
+ int llx = 0, lly = 0, urx = 0, ury = 0;
+ int type;
if (fn->n >= NGLYPHS)
return 1;
if (fscanf(fin, "%s %s", name, tok) != 2)
@@ -154,12 +154,16 @@
if (!strcmp("\"", tok)) {
glyph = fn->g[fn->n - 1];
} else {
- wid = atoi(tok);
if (fscanf(fin, "%d %s", &type, id) != 2)
return 1;
glyph = font_glyph(fn, id);
- if (!glyph)
- glyph = font_glyphput(fn, id, name, wid, type);
+ if (!glyph) {
+ glyph = font_glyphput(fn, id, name, type);
+ sscanf(tok, "%d,%d,%d,%d,%d", &glyph->wid,
+ &llx, &lly, &urx, &ury);
+ glyph->ic = MAX(0, urx - glyph->wid);
+ glyph->icleft = MAX(0, -llx);
+ }
}
strcpy(fn->c[fn->n], name);
fn->g[fn->n] = glyph;
--- a/ren.c
+++ b/ren.c
@@ -671,6 +671,12 @@
case '^':
wb_hmov(wb, SC_EM / 12);
break;
+ case '/':
+ wb_italiccorrection(wb);
+ break;
+ case ',':
+ wb_italiccorrectionleft(wb);
+ break;
case '{':
case '}':
break;
@@ -719,7 +725,7 @@
}
return;
}
- if (strchr(" bCcDdfHhkLlmNoprSsuvXxz0^|{}&", c[1])) {
+ if (strchr(" bCcDdfHhkLlmNoprSsuvXxz0^|{}&/,", c[1])) {
argnext(arg, c[1], next, back);
if (c[1] == 'S' || c[1] == 'H')
return; /* not implemented */
--- a/roff.h
+++ b/roff.h
@@ -121,6 +121,7 @@
struct font *font; /* glyph font */
int wid; /* character width */
int type; /* character type; ascender/descender */
+ int ic, icleft; /* italic and left italic correction */
};
struct font {
@@ -234,6 +235,7 @@
int els_neg, els_pos; /* extra line spacing */
int h, v; /* buffer vertical and horizontal positions */
int ct, sb, st; /* \w registers */
+ int icleft_ll; /* len after the pending left italic correction */
/* saving previous characters added via wb_put() */
char prev_c[LIGLEN][GNLEN];
int prev_l[LIGLEN]; /* sbuf_len(&wb->sbuf) before wb_put() calls */
@@ -259,6 +261,8 @@
void wb_drawxbeg(struct wb *wb, int c);
void wb_drawxdot(struct wb *wb, int h, int v);
void wb_drawxend(struct wb *wb);
+void wb_italiccorrection(struct wb *wb);
+void wb_italiccorrectionleft(struct wb *wb);
void wb_cat(struct wb *wb, struct wb *src);
int wb_hyph(struct wb *wb, int w, struct wb *w1, struct wb *w2, int flg);
int wb_wid(struct wb *wb);
--- a/wb.c
+++ b/wb.c
@@ -18,6 +18,7 @@
wb->r_f = -1;
wb->r_s = -1;
wb->r_m = -1;
+ wb->icleft_ll = -1;
}
void wb_done(struct wb *wb)
@@ -125,6 +126,11 @@
return i < wb->prev_n ? wb->prev_c[i] : NULL;
}
+static struct glyph *wb_prevglyph(struct wb *wb)
+{
+ return wb_prev(wb, 0) ? dev_glyph(wb_prev(wb, 0), R_F(wb)) : NULL;
+}
+
void wb_put(struct wb *wb, char *c)
{
struct glyph *g;
@@ -149,6 +155,9 @@
g = dev_glyph(c, R_F(wb));
}
wb_font(wb);
+ if (g && !zerowidth && g->icleft && wb->icleft_ll == sbuf_len(&wb->sbuf))
+ wb_hmov(wb, charwid_base(R_F(wb), R_S(wb), g->icleft));
+ wb->icleft_ll = -1;
wb_prevcheck(wb); /* make sure wb->prev_c[] is valid */
ll = sbuf_len(&wb->sbuf); /* sbuf length before inserting c */
if (!c[1] || c[0] == c_ec || c[0] == c_ni || utf8one(c)) {
@@ -487,4 +496,17 @@
if (p)
dohyph(sbuf_buf(&wb->sbuf), p, p != dp, w1, w2);
return !p;
+}
+
+void wb_italiccorrection(struct wb *wb)
+{
+ struct glyph *g = wb_prevglyph(wb);
+ if (g && g->ic)
+ wb_hmov(wb, charwid_base(R_F(wb), R_S(wb), g->ic));
+}
+
+void wb_italiccorrectionleft(struct wb *wb)
+{
+ wb_font(wb);
+ wb->icleft_ll = sbuf_len(&wb->sbuf);
}