shithub: neatroff

Download patch

ref: 50a514828490db6eb2531f25d75779c2cd6e3046
parent: 8f26d07ded4858e6e782be11ee74fe896d713c79
author: Ali Gholami Rudi <[email protected]>
date: Wed Apr 5 20:46:04 EDT 2017

fmt: assume a stretchable space in lines containing a single word

--- a/fmt.c
+++ b/fmt.c
@@ -30,6 +30,7 @@
 	int hy;		/* hyphen width if inserted after this word */
 	int str;	/* does the space before it stretch */
 	int cost;	/* the extra cost of line break after this word */
+	int swid;	/* space width after this word (i.e., \w' ') */
 };
 
 struct line {
@@ -275,6 +276,7 @@
 	word->str = str;
 	word->gap = gap;
 	word->cost = cost;
+	word->swid = wb_swid(wb);
 }
 
 /* find explicit break positions: dashes, \:, \%, and \~ */
@@ -347,7 +349,7 @@
 		wb_catstr(&wbc, beg, end);
 		wb_fnszget(&wbc, &cf, &cs, &cm);
 		icost = i == n ? wb_cost(&wbc) : hygap[i] * 10000000;
-		igap = i == 0 ? gap : hygap[i - 1] * font_swid(dev_font(cf), cs, n_ss);
+		igap = i == 0 ? gap : hygap[i - 1] * wb_swid(&wbc);
 		fmt_wb2word(f, fmt_mkword(f), &wbc, ihy, istr, igap, icost);
 		wb_reset(&wbc);
 		wb_fnszset(&wbc, cf, cs, cm);		/* restoring wbc */
@@ -440,6 +442,7 @@
 	int lwid = 0;		/* current line length */
 	int swid = 0;		/* amount of stretchable spaces */
 	int nspc = 0;		/* number of stretchable spaces */
+	int dwid = 0;		/* equal to swid, unless swid is zero */
 	if (pos <= 0)
 		return 0;
 	if (f->best_pos[pos] >= 0)
@@ -457,7 +460,10 @@
 		}
 		if (lwid > llen + swid * n_ssh / 100 && i + 1 < pos)
 			break;
-		cur = fmt_findcost(f, i) + FMT_COST(llen, lwid, swid, nspc);
+		dwid = swid;
+		if (!dwid && i > 0)	/* no stretchable spaces */
+			dwid = f->words[i - 1].swid;
+		cur = fmt_findcost(f, i) + FMT_COST(llen, lwid, dwid, nspc);
 		if (hyphenated)
 			cur += hycost(1 + fmt_hydepth(f, i));
 		if (f->best_pos[pos] < 0 || cur < f->best[pos]) {
--- a/roff.h
+++ b/roff.h
@@ -276,6 +276,7 @@
 void wb_fnszget(struct wb *wb, int *fn, int *sz, int *m);
 void wb_fnszset(struct wb *wb, int fn, int sz, int m);
 int wb_hywid(struct wb *wb);
+int wb_swid(struct wb *wb);
 int c_eossent(char *s);
 int c_eostran(char *s);
 int c_hydash(char *s);
--- a/wb.c
+++ b/wb.c
@@ -527,5 +527,11 @@
 int wb_hywid(struct wb *wb)
 {
 	struct glyph *g = dev_glyph("hy", wb->f);
-	return g ? font_gwid(g->font, dev_font(wb->f), wb->s, g->wid) : 0;
+	return g ? font_gwid(g->font, dev_font(R_F(wb)), R_S(wb), g->wid) : 0;
+}
+
+/* return the size of space if appended to wb */
+int wb_swid(struct wb *wb)
+{
+	return font_swid(dev_font(R_F(wb)), R_S(wb), n_ss);
 }