shithub: neatroff

Download patch

ref: efdb89bcc0403e7ce60b49eea80ff52c10e5c92a
parent: acfc4e9fc9fd7cf704960d9d3182bea09e0ea681
author: Ali Gholami Rudi <[email protected]>
date: Thu Feb 20 14:54:39 EST 2014

wb: change the font just before inserting glyphs

Now wb.c applies font changes less eagerly; otherwise italic
correction does not work in situations like "\fIf\fR\/|".

--- a/wb.c
+++ b/wb.c
@@ -51,6 +51,13 @@
 	wb_stsb(wb);
 }
 
+/* pending font, size or color changes */
+static int wb_pendingfont(struct wb *wb)
+{
+	return wb->f != R_F(wb) || wb->s != R_S(wb) ||
+			(!n_cp && wb->m != R_M(wb));
+}
+
 void wb_hmov(struct wb *wb, int n)
 {
 	wb->h += n;
@@ -128,7 +135,7 @@
 
 static struct glyph *wb_prevglyph(struct wb *wb)
 {
-	return wb_prev(wb, 0) ? dev_glyph(wb_prev(wb, 0), R_F(wb)) : NULL;
+	return wb_prev(wb, 0) ? dev_glyph(wb_prev(wb, 0), wb->f) : NULL;
 }
 
 void wb_put(struct wb *wb, char *c)
@@ -154,10 +161,10 @@
 		memmove(c, c + 1, strlen(c));
 		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_font(wb);
 	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)) {
@@ -193,7 +200,8 @@
 	char *cs[LIGLEN + 2];
 	int i = -1;
 	int ligpos;
-	wb_font(wb);		/* apply font changes */
+	if (wb_pendingfont(wb))		/* font changes disable ligatures */
+		return 1;
 	cs[0] = c;
 	while (wb_prev(wb, ++i))
 		cs[i + 1] = wb_prev(wb, i);
@@ -213,8 +221,7 @@
 int wb_kern(struct wb *wb, char *c)
 {
 	int val;
-	wb_font(wb);		/* apply font changes */
-	if (!wb_prev(wb, 0))
+	if (wb_pendingfont(wb) || !wb_prev(wb, 0))
 		return 1;
 	val = font_kern(dev_font(R_F(wb)), wb_prev(wb, 0), c);
 	if (val)
@@ -502,11 +509,10 @@
 {
 	struct glyph *g = wb_prevglyph(wb);
 	if (g && g->ic)
-		wb_hmov(wb, charwid_base(R_F(wb), R_S(wb), g->ic));
+		wb_hmov(wb, charwid_base(wb->f, wb->s, g->ic));
 }
 
 void wb_italiccorrectionleft(struct wb *wb)
 {
-	wb_font(wb);
 	wb->icleft_ll = sbuf_len(&wb->sbuf);
 }